From e322b295f28c0cecd8bde2ed6ad2061fea4de524 Mon Sep 17 00:00:00 2001 From: Jose Date: Sun, 23 Feb 2025 20:53:04 +0100 Subject: [PATCH] modified: Makefile new file: include/OSAL_Memory.c new file: include/OSAL_Memory.h new file: include/OSAL_Timers.c new file: include/OSAL_Timers.h new file: include/comdef.h new file: include/saddr.c new file: include/saddr.h modified: main.c --- Makefile | 7 +- include/OSAL_Memory.c | 642 ++++++++++++++++++++++++++++++++++++++++++ include/OSAL_Memory.h | 145 ++++++++++ include/OSAL_Timers.c | 615 ++++++++++++++++++++++++++++++++++++++++ include/OSAL_Timers.h | 146 ++++++++++ include/comdef.h | 161 +++++++++++ include/saddr.c | 227 +++++++++++++++ include/saddr.h | 175 ++++++++++++ main.c | 2 +- 9 files changed, 2117 insertions(+), 3 deletions(-) create mode 100644 include/OSAL_Memory.c create mode 100644 include/OSAL_Memory.h create mode 100644 include/OSAL_Timers.c create mode 100644 include/OSAL_Timers.h create mode 100644 include/comdef.h create mode 100644 include/saddr.c create mode 100644 include/saddr.h diff --git a/Makefile b/Makefile index 181282d..e64b304 100644 --- a/Makefile +++ b/Makefile @@ -8,13 +8,16 @@ INCLUDE_DIRS = -I$(ZSTACK_DIR) # Compiler settings CC = sdcc # sdcc compiler -CFLAGS = -mmcs51 $(INCLUDE_DIRS) # add include paths to compiler flags +CFLAGS = -mmcs51 -DSDCC $(INCLUDE_DIRS) # add include paths to compiler flags +# Source files (all .c files in the directory) SRC=$(wildcard *.c) + +# Headers HEADERS = main.h zigbee_comm.h sensors/bme280.h sensors/wind_vane.h sensors/rain_gauge.h sensors/anemometer.h config.h include/hal_types.h include/hal_defs.h include/hal_timer.h include/ZComDef.h include/OSAL.h include/i2c.h # Object files (replace .c with .o) -OBJS = $(SRCS:.c=.o) +OBJS = $(SRC:.c=.o) # Output file OUTPUT=output.ihx diff --git a/include/OSAL_Memory.c b/include/OSAL_Memory.c new file mode 100644 index 0000000..f47354f --- /dev/null +++ b/include/OSAL_Memory.c @@ -0,0 +1,642 @@ +/************************************************************************************************** + Filename: OSAL_Memory.c + Revised: $Date: 2014-11-24 18:26:24 -0800 (Mon, 24 Nov 2014) $ + Revision: $Revision: 41234 $ + + Description: OSAL Heap Memory management functions. There is an Application Note that + should be read before studying and/or modifying this module: + SWRA204 "Heap Memory Management" + + Copyright 2004-2010 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ + +#include + +#include "comdef.h" +#include "OSAL.h" +#include "OSAL_Memory.h" +#include "OnBoard.h" +#include "hal_mcu.h" +#include "hal_assert.h" + +/* ------------------------------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------------------------------ + */ + +#define OSALMEM_IN_USE 0x8000 +#if (MAXMEMHEAP & OSALMEM_IN_USE) +#error MAXMEMHEAP is too big to manage! +#endif + +#define OSALMEM_HDRSZ sizeof(osalMemHdr_t) + +// Round a value up to the ceiling of OSALMEM_HDRSZ for critical dependencies on even multiples. +#define OSALMEM_ROUND(X) ((((X) + OSALMEM_HDRSZ - 1) / OSALMEM_HDRSZ) * OSALMEM_HDRSZ) + +/* Minimum wasted bytes to justify splitting a block before allocation. + * Adjust accordingly to attempt to balance the tradeoff of wasted space and runtime throughput + * spent splitting blocks into sizes that may not be practically usable when sandwiched between + * two blocks in use (and thereby not able to be coalesced.) + * Ensure that this size is an even multiple of OSALMEM_HDRSZ. + */ +#if !defined OSALMEM_MIN_BLKSZ +#define OSALMEM_MIN_BLKSZ (OSALMEM_ROUND((OSALMEM_HDRSZ * 2))) +#endif + +#if !defined OSALMEM_LL_BLKSZ +#if defined NONWK +#define OSALMEM_LL_BLKSZ (OSALMEM_ROUND(6) + (1 * OSALMEM_HDRSZ)) +#else +/* + * Profiling the sample apps with default settings shows the following long-lived allocations + * which should live at the bottom of the small-block bucket so that they are never iterated over + * by osal_mem_alloc/free(), nor ever considered for coalescing, etc. This saves significant + * run-time throughput (on 8051 SOC if not also MSP). This is dynamic "dead space" and is not + * available to the small-block bucket heap. + * + * Adjust this size accordingly to accomodate application-specific changes including changing the + * size of long-lived objects profiled by sample apps and long-lived objects added by application. + */ +#if defined ZCL_KEY_ESTABLISH_OLD // CBKE no longer uses long lived memory allocations. +#define OSALMEM_LL_BLKSZ (OSALMEM_ROUND(526) + (32 * OSALMEM_HDRSZ)) +#elif defined TC_LINKKEY_JOIN +#define OSALMEM_LL_BLKSZ (OSALMEM_ROUND(454) + (21 * OSALMEM_HDRSZ)) +#elif ((defined SECURE) && (SECURE != 0)) +#define OSALMEM_LL_BLKSZ (OSALMEM_ROUND(418) + (19 * OSALMEM_HDRSZ)) +#else +#define OSALMEM_LL_BLKSZ (OSALMEM_ROUND(417) + (19 * OSALMEM_HDRSZ)) +#endif +#endif +#endif + +/* Adjust accordingly to attempt to accomodate the block sizes of the vast majority of + * very high frequency allocations/frees by profiling the system runtime. + * This default of 16 accomodates the OSAL timers block, osalTimerRec_t, and many others. + * Ensure that this size is an even multiple of OSALMEM_MIN_BLKSZ for run-time efficiency. + */ +#if !defined OSALMEM_SMALL_BLKSZ +#define OSALMEM_SMALL_BLKSZ (OSALMEM_ROUND(16)) +#endif +#if !defined OSALMEM_SMALL_BLKCNT +#define OSALMEM_SMALL_BLKCNT 8 +#endif + +/* + * These numbers setup the size of the small-block bucket which is reserved at the front of the + * heap for allocations of OSALMEM_SMALL_BLKSZ or smaller. + */ + +// Size of the heap bucket reserved for small block-sized allocations. +// Adjust accordingly to attempt to accomodate the vast majority of very high frequency operations. +#define OSALMEM_SMALLBLK_BUCKET ((OSALMEM_SMALL_BLKSZ * OSALMEM_SMALL_BLKCNT) + OSALMEM_LL_BLKSZ) +// Index of the first available osalMemHdr_t after the small-block heap which will be set in-use in +// order to prevent the small-block bucket from being coalesced with the wilderness. +#define OSALMEM_SMALLBLK_HDRCNT (OSALMEM_SMALLBLK_BUCKET / OSALMEM_HDRSZ) +// Index of the first available osalMemHdr_t after the small-block heap which will be set in-use in +#define OSALMEM_BIGBLK_IDX (OSALMEM_SMALLBLK_HDRCNT + 1) +// The size of the wilderness after losing the small-block heap, the wasted header to block the +// small-block heap from being coalesced, and the wasted header to mark the end of the heap. +#define OSALMEM_BIGBLK_SZ (MAXMEMHEAP - OSALMEM_SMALLBLK_BUCKET - OSALMEM_HDRSZ*2) +// Index of the last available osalMemHdr_t at the end of the heap which will be set to zero for +// fast comparisons with zero to determine the end of the heap. +#define OSALMEM_LASTBLK_IDX ((MAXMEMHEAP / OSALMEM_HDRSZ) - 1) + +// For information about memory profiling, refer to SWRA204 "Heap Memory Management", section 1.5. +#if !defined OSALMEM_PROFILER +#define OSALMEM_PROFILER FALSE // Enable/disable the memory usage profiling buckets. +#endif +#if !defined OSALMEM_PROFILER_LL +#define OSALMEM_PROFILER_LL FALSE // Special profiling of the Long-Lived bucket. +#endif + +#if OSALMEM_PROFILER +#define OSALMEM_INIT 'X' +#define OSALMEM_ALOC 'A' +#define OSALMEM_REIN 'F' +#endif + +/* ------------------------------------------------------------------------------------------------ + * Typedefs + * ------------------------------------------------------------------------------------------------ + */ + +typedef struct { + // The 15 LSB's of 'val' indicate the total item size, including the header, in 8-bit bytes. + unsigned len : 15; + // The 1 MSB of 'val' is used as a boolean to indicate in-use or freed. + unsigned inUse : 1; +} osalMemHdrHdr_t; + +typedef union { + /* Dummy variable so compiler forces structure to alignment of largest element while not wasting + * space on targets when the halDataAlign_t is smaller than a UINT16. + */ + halDataAlign_t alignDummy; + uint16 val; + osalMemHdrHdr_t hdr; +} osalMemHdr_t; + +/* ------------------------------------------------------------------------------------------------ + * Local Variables + * ------------------------------------------------------------------------------------------------ + */ + +#if !defined ( ZBIT ) && defined ewarm +static __no_init osalMemHdr_t theHeap[MAXMEMHEAP / OSALMEM_HDRSZ]; +static __no_init osalMemHdr_t *ff1; // First free block in the small-block bucket. +#else +static osalMemHdr_t theHeap[MAXMEMHEAP / OSALMEM_HDRSZ]; +static osalMemHdr_t *ff1; // First free block in the small-block bucket. +#endif + +static uint8 osalMemStat; // Discrete status flags: 0x01 = kicked. + +#if OSALMEM_METRICS +static uint16 blkMax; // Max cnt of all blocks ever seen at once. +static uint16 blkCnt; // Current cnt of all blocks. +static uint16 blkFree; // Current cnt of free blocks. +static uint16 memAlo; // Current total memory allocated. +static uint16 memMax; // Max total memory ever allocated at once. +#endif + +#if OSALMEM_PROFILER +#define OSALMEM_PROMAX 8 +/* The profiling buckets must differ by at least OSALMEM_MIN_BLKSZ; the + * last bucket must equal the max alloc size. Set the bucket sizes to + * whatever sizes necessary to show how your application is using memory. + */ +static uint16 proCnt[OSALMEM_PROMAX] = { +OSALMEM_SMALL_BLKSZ, 48, 112, 176, 192, 224, 256, 65535 }; +static uint16 proCur[OSALMEM_PROMAX] = { 0 }; +static uint16 proMax[OSALMEM_PROMAX] = { 0 }; +static uint16 proTot[OSALMEM_PROMAX] = { 0 }; +static uint16 proSmallBlkMiss; +#endif + +/* ------------------------------------------------------------------------------------------------ + * Global Variables + * ------------------------------------------------------------------------------------------------ + */ + +#ifdef DPRINTF_HEAPTRACE +extern int dprintf(const char *fmt, ...); +#endif /* DPRINTF_HEAPTRACE */ + +/************************************************************************************************** + * @fn osal_mem_init + * + * @brief This function is the OSAL heap memory management initialization callback. + * + * input parameters + * + * None. + * + * output parameters + * + * None. + * + * @return None. + */ +void osal_mem_init(void) +{ + HAL_ASSERT(((OSALMEM_MIN_BLKSZ % OSALMEM_HDRSZ) == 0)); + HAL_ASSERT(((OSALMEM_LL_BLKSZ % OSALMEM_HDRSZ) == 0)); + HAL_ASSERT(((OSALMEM_SMALL_BLKSZ % OSALMEM_HDRSZ) == 0)); + +#if OSALMEM_PROFILER + (void)osal_memset(theHeap, OSALMEM_INIT, MAXMEMHEAP); +#endif + + // Setup a NULL block at the end of the heap for fast comparisons with zero. + theHeap[OSALMEM_LASTBLK_IDX].val = 0; + + // Setup the small-block bucket. + ff1 = theHeap; + ff1->val = OSALMEM_SMALLBLK_BUCKET; // Set 'len' & clear 'inUse' field. + // Set 'len' & 'inUse' fields - this is a 'zero data bytes' lifetime allocation to block the + // small-block bucket from ever being coalesced with the wilderness. + theHeap[OSALMEM_SMALLBLK_HDRCNT].val = (OSALMEM_HDRSZ | OSALMEM_IN_USE); + + // Setup the wilderness. + theHeap[OSALMEM_BIGBLK_IDX].val = OSALMEM_BIGBLK_SZ; // Set 'len' & clear 'inUse' field. + +#if ( OSALMEM_METRICS ) + /* Start with the small-block bucket and the wilderness - don't count the + * end-of-heap NULL block nor the end-of-small-block NULL block. + */ + blkCnt = blkFree = 2; +#endif +} + +/************************************************************************************************** + * @fn osal_mem_kick + * + * @brief This function is the OSAL task initialization callback. + * @brief Kick the ff1 pointer out past the long-lived OSAL Task blocks. + * Invoke this once after all long-lived blocks have been allocated - + * presently at the end of osal_init_system(). + * + * input parameters + * + * None. + * + * output parameters + * + * None. + * + * @return None. + */ +void osal_mem_kick(void) +{ + halIntState_t intState; + osalMemHdr_t *tmp = osal_mem_alloc(1); + + HAL_ASSERT((tmp != NULL)); + HAL_ENTER_CRITICAL_SECTION(intState); // Hold off interrupts. + + /* All long-lived allocations have filled the LL block reserved in the small-block bucket. + * Set 'osalMemStat' so searching for memory in this bucket from here onward will only be done + * for sizes meeting the OSALMEM_SMALL_BLKSZ criteria. + */ + ff1 = tmp - 1; // Set 'ff1' to point to the first available memory after the LL block. + osal_mem_free(tmp); + osalMemStat = 0x01; // Set 'osalMemStat' after the free because it enables memory profiling. + + HAL_EXIT_CRITICAL_SECTION(intState); // Re-enable interrupts. +} + +/************************************************************************************************** + * @fn osal_mem_alloc + * + * @brief This function implements the OSAL dynamic memory allocation functionality. + * + * input parameters + * + * @param size - the number of bytes to allocate from the HEAP. + * + * output parameters + * + * None. + * + * @return None. + */ +#ifdef DPRINTF_OSALHEAPTRACE +void *osal_mem_alloc_dbg( uint16 size, const char *fname, unsigned lnum ) +#else /* DPRINTF_OSALHEAPTRACE */ +void *osal_mem_alloc( uint16 size ) +#endif /* DPRINTF_OSALHEAPTRACE */ +{ + osalMemHdr_t *prev = NULL; + osalMemHdr_t *hdr; + halIntState_t intState; + uint8 coal = 0; + + size += OSALMEM_HDRSZ; + + // Calculate required bytes to add to 'size' to align to halDataAlign_t. + if ( sizeof( halDataAlign_t ) == 2 ) + { + size += (size & 0x01); + } + else if ( sizeof( halDataAlign_t ) != 1 ) + { + const uint8 mod = size % sizeof( halDataAlign_t ); + + if ( mod != 0 ) + { + size += (sizeof( halDataAlign_t ) - mod); + } + } + + HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts. + + // Smaller allocations are first attempted in the small-block bucket, and all long-lived + // allocations are channeled into the LL block reserved within this bucket. + if ((osalMemStat == 0) || (size <= OSALMEM_SMALL_BLKSZ)) + { + hdr = ff1; + } + else + { + hdr = (theHeap + OSALMEM_BIGBLK_IDX); + } + + do + { + if ( hdr->hdr.inUse ) + { + coal = 0; + } + else + { + if ( coal != 0 ) + { +#if ( OSALMEM_METRICS ) + blkCnt--; + blkFree--; +#endif + + prev->hdr.len += hdr->hdr.len; + + if ( prev->hdr.len >= size ) + { + hdr = prev; + break; + } + } + else + { + if ( hdr->hdr.len >= size ) + { + break; + } + + coal = 1; + prev = hdr; + } + } + + hdr = (osalMemHdr_t *)((uint8 *)hdr + hdr->hdr.len); + + if ( hdr->val == 0 ) + { + hdr = NULL; + break; + } + } while (1); + + if ( hdr != NULL ) + { + uint16 tmp = hdr->hdr.len - size; + + // Determine whether the threshold for splitting is met. + if ( tmp >= OSALMEM_MIN_BLKSZ ) + { + // Split the block before allocating it. + osalMemHdr_t *next = (osalMemHdr_t *)((uint8 *)hdr + size); + next->val = tmp; // Set 'len' & clear 'inUse' field. + hdr->val = (size | OSALMEM_IN_USE); // Set 'len' & 'inUse' field. + +#if ( OSALMEM_METRICS ) + blkCnt++; + if ( blkMax < blkCnt ) + { + blkMax = blkCnt; + } + memAlo += size; +#endif + } + else + { +#if ( OSALMEM_METRICS ) + memAlo += hdr->hdr.len; + blkFree--; +#endif + + hdr->hdr.inUse = TRUE; + } + +#if ( OSALMEM_METRICS ) + if ( memMax < memAlo ) + { + memMax = memAlo; + } +#endif + +#if ( OSALMEM_PROFILER ) +#if !OSALMEM_PROFILER_LL + if (osalMemStat != 0) // Don't profile until after the LL block is filled. +#endif + { + uint8 idx; + + for ( idx = 0; idx < OSALMEM_PROMAX; idx++ ) + { + if ( hdr->hdr.len <= proCnt[idx] ) + { + break; + } + } + proCur[idx]++; + if ( proMax[idx] < proCur[idx] ) + { + proMax[idx] = proCur[idx]; + } + proTot[idx]++; + + /* A small-block could not be allocated in the small-block bucket. + * When this occurs significantly frequently, increase the size of the + * bucket in order to restore better worst case run times. Set the first + * profiling bucket size in proCnt[] to the small-block bucket size and + * divide proSmallBlkMiss by the corresponding proTot[] size to get % miss. + * Best worst case time on TrasmitApp was achieved at a 0-15% miss rate + * during steady state Tx load, 0% during idle and steady state Rx load. + */ + if ((hdr->hdr.len <= OSALMEM_SMALL_BLKSZ) && (hdr >= (theHeap + OSALMEM_BIGBLK_IDX))) + { + proSmallBlkMiss++; + } + } + + (void)osal_memset((uint8 *)(hdr+1), OSALMEM_ALOC, (hdr->hdr.len - OSALMEM_HDRSZ)); +#endif + + if ((osalMemStat != 0) && (ff1 == hdr)) + { + ff1 = (osalMemHdr_t *)((uint8 *)hdr + hdr->hdr.len); + } + + hdr++; + } + + HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts. + + HAL_ASSERT(((size_t)hdr % sizeof(halDataAlign_t)) == 0); + +#ifdef DPRINTF_OSALHEAPTRACE + dprintf("osal_mem_alloc(%u)->%lx:%s:%u\n", size, (unsigned) hdr, fname, lnum); +#endif /* DPRINTF_OSALHEAPTRACE */ + return (void *)hdr; +} + +/************************************************************************************************** + * @fn osal_mem_free + * + * @brief This function implements the OSAL dynamic memory de-allocation functionality. + * + * input parameters + * + * @param ptr - A valid pointer (i.e. a pointer returned by osal_mem_alloc()) to the memory to free. + * + * output parameters + * + * None. + * + * @return None. + */ +#ifdef DPRINTF_OSALHEAPTRACE +void osal_mem_free_dbg(void *ptr, const char *fname, unsigned lnum) +#else /* DPRINTF_OSALHEAPTRACE */ +void osal_mem_free(void *ptr) +#endif /* DPRINTF_OSALHEAPTRACE */ +{ + osalMemHdr_t *hdr = (osalMemHdr_t *)ptr - 1; + halIntState_t intState; + +#ifdef DPRINTF_OSALHEAPTRACE + dprintf("osal_mem_free(%lx):%s:%u\n", (unsigned) ptr, fname, lnum); +#endif /* DPRINTF_OSALHEAPTRACE */ + + HAL_ASSERT(((uint8 *)ptr >= (uint8 *)theHeap) && ((uint8 *)ptr < (uint8 *)theHeap+MAXMEMHEAP)); + HAL_ASSERT(hdr->hdr.inUse); + + HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts. + hdr->hdr.inUse = FALSE; + + if (ff1 > hdr) + { + ff1 = hdr; + } + +#if OSALMEM_PROFILER +#if !OSALMEM_PROFILER_LL + if (osalMemStat != 0) // Don't profile until after the LL block is filled. +#endif + { + uint8 idx; + + for (idx = 0; idx < OSALMEM_PROMAX; idx++) + { + if (hdr->hdr.len <= proCnt[idx]) + { + break; + } + } + + proCur[idx]--; + } + + (void)osal_memset((uint8 *)(hdr+1), OSALMEM_REIN, (hdr->hdr.len - OSALMEM_HDRSZ) ); +#endif +#if OSALMEM_METRICS + memAlo -= hdr->hdr.len; + blkFree++; +#endif + + HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts. +} + +#if OSALMEM_METRICS +/********************************************************************* + * @fn osal_heap_block_max + * + * @brief Return the maximum number of blocks ever allocated at once. + * + * @param none + * + * @return Maximum number of blocks ever allocated at once. + */ +uint16 osal_heap_block_max( void ) +{ + return blkMax; +} + +/********************************************************************* + * @fn osal_heap_block_cnt + * + * @brief Return the current number of blocks now allocated. + * + * @param none + * + * @return Current number of blocks now allocated. + */ +uint16 osal_heap_block_cnt( void ) +{ + return blkCnt; +} + +/********************************************************************* + * @fn osal_heap_block_free + * + * @brief Return the current number of free blocks. + * + * @param none + * + * @return Current number of free blocks. + */ +uint16 osal_heap_block_free( void ) +{ + return blkFree; +} + +/********************************************************************* + * @fn osal_heap_mem_used + * + * @brief Return the current number of bytes allocated. + * + * @param none + * + * @return Current number of bytes allocated. + */ +uint16 osal_heap_mem_used( void ) +{ + return memAlo; +} +#endif + +#if defined (ZTOOL_P1) || defined (ZTOOL_P2) +/********************************************************************* + * @fn osal_heap_high_water + * + * @brief Return the highest byte ever allocated in the heap. + * + * @param none + * + * @return Highest number of bytes ever used by the stack. + */ +uint16 osal_heap_high_water( void ) +{ +#if ( OSALMEM_METRICS ) + return memMax; +#else + return MAXMEMHEAP; +#endif +} +#endif + +/************************************************************************************************** +*/ diff --git a/include/OSAL_Memory.h b/include/OSAL_Memory.h new file mode 100644 index 0000000..c8984dd --- /dev/null +++ b/include/OSAL_Memory.h @@ -0,0 +1,145 @@ +/************************************************************************************************** + Filename: OSAL_Memory.h + Revised: $Date: 2010-07-28 08:42:48 -0700 (Wed, 28 Jul 2010) $ + Revision: $Revision: 23160 $ + + Description: This module defines the OSAL memory control functions. + + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef OSAL_MEMORY_H +#define OSAL_MEMORY_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + * INCLUDES + */ +#include "comdef.h" + +/********************************************************************* + * CONSTANTS + */ + +#if !defined ( OSALMEM_METRICS ) + #define OSALMEM_METRICS FALSE +#endif + +/********************************************************************* + * MACROS + */ + +#define osal_stack_used() OnBoard_stack_used() + +/********************************************************************* + * TYPEDEFS + */ + +/********************************************************************* + * GLOBAL VARIABLES + */ + +/********************************************************************* + * FUNCTIONS + */ + + /* + * Initialize memory manager. + */ + void osal_mem_init( void ); + + /* + * Setup efficient search for the first free block of heap. + */ + void osal_mem_kick( void ); + + /* + * Allocate a block of memory. + */ +#ifdef DPRINTF_OSALHEAPTRACE + void *osal_mem_alloc_dbg( uint16 size, const char *fname, unsigned lnum ); +#define osal_mem_alloc(_size ) osal_mem_alloc_dbg(_size, __FILE__, __LINE__) +#else /* DPRINTF_OSALHEAPTRACE */ + void *osal_mem_alloc( uint16 size ); +#endif /* DPRINTF_OSALHEAPTRACE */ + + /* + * Free a block of memory. + */ +#ifdef DPRINTF_OSALHEAPTRACE + void osal_mem_free_dbg( void *ptr, const char *fname, unsigned lnum ); +#define osal_mem_free(_ptr ) osal_mem_free_dbg(_ptr, __FILE__, __LINE__) +#else /* DPRINTF_OSALHEAPTRACE */ + void osal_mem_free( void *ptr ); +#endif /* DPRINTF_OSALHEAPTRACE */ + +#if ( OSALMEM_METRICS ) + /* + * Return the maximum number of blocks ever allocated at once. + */ + uint16 osal_heap_block_max( void ); + + /* + * Return the current number of blocks now allocated. + */ + uint16 osal_heap_block_cnt( void ); + + /* + * Return the current number of free blocks. + */ + uint16 osal_heap_block_free( void ); + + /* + * Return the current number of bytes allocated. + */ + uint16 osal_heap_mem_used( void ); +#endif + +#if defined (ZTOOL_P1) || defined (ZTOOL_P2) + /* + * Return the highest number of bytes ever used in the heap. + */ + uint16 osal_heap_high_water( void ); +#endif + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef OSAL_MEMORY_H */ diff --git a/include/OSAL_Timers.c b/include/OSAL_Timers.c new file mode 100644 index 0000000..8924ece --- /dev/null +++ b/include/OSAL_Timers.c @@ -0,0 +1,615 @@ +/************************************************************************************************** + Filename: OSAL_Timers.c + Revised: $Date: 2014-06-16 15:12:16 -0700 (Mon, 16 Jun 2014) $ + Revision: $Revision: 39036 $ + + Description: OSAL Timer definition and manipulation functions. + + + Copyright 2004-2012 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/********************************************************************* + * INCLUDES + */ + +#include "comdef.h" +#include "OnBoard.h" +#include "OSAL.h" +#include "OSAL_Timers.h" +#include "hal_timer.h" + +/********************************************************************* + * MACROS + */ + +/********************************************************************* + * CONSTANTS + */ + +/********************************************************************* + * TYPEDEFS + */ + +typedef union { + uint32 time32; + uint16 time16[2]; + uint8 time8[4]; +} osalTime_t; + +typedef struct +{ + void *next; + osalTime_t timeout; + uint16 event_flag; + uint8 task_id; + uint32 reloadTimeout; +} osalTimerRec_t; + +/********************************************************************* + * GLOBAL VARIABLES + */ + +osalTimerRec_t *timerHead; + +/********************************************************************* + * EXTERNAL VARIABLES + */ + +/********************************************************************* + * EXTERNAL FUNCTIONS + */ + +/********************************************************************* + * LOCAL VARIABLES + */ +// Milliseconds since last reboot +static uint32 osal_systemClock; + +/********************************************************************* + * LOCAL FUNCTION PROTOTYPES + */ +osalTimerRec_t *osalAddTimer( uint8 task_id, uint16 event_flag, uint32 timeout ); +osalTimerRec_t *osalFindTimer( uint8 task_id, uint16 event_flag ); +void osalDeleteTimer( osalTimerRec_t *rmTimer ); + +/********************************************************************* + * FUNCTIONS + *********************************************************************/ + +/********************************************************************* + * @fn osalTimerInit + * + * @brief Initialization for the OSAL Timer System. + * + * @param none + * + * @return + */ +void osalTimerInit( void ) +{ + osal_systemClock = 0; +} + +/********************************************************************* + * @fn osalAddTimer + * + * @brief Add a timer to the timer list. + * Ints must be disabled. + * + * @param task_id + * @param event_flag + * @param timeout + * + * @return osalTimerRec_t * - pointer to newly created timer + */ +osalTimerRec_t * osalAddTimer( uint8 task_id, uint16 event_flag, uint32 timeout ) +{ + osalTimerRec_t *newTimer; + osalTimerRec_t *srchTimer; + + // Look for an existing timer first + newTimer = osalFindTimer( task_id, event_flag ); + if ( newTimer ) + { + // Timer is found - update it. + newTimer->timeout.time32 = timeout; + + return ( newTimer ); + } + else + { + // New Timer + newTimer = osal_mem_alloc( sizeof( osalTimerRec_t ) ); + + if ( newTimer ) + { + // Fill in new timer + newTimer->task_id = task_id; + newTimer->event_flag = event_flag; + newTimer->timeout.time32 = timeout; + newTimer->next = (void *)NULL; + newTimer->reloadTimeout = 0; + + // Does the timer list already exist + if ( timerHead == NULL ) + { + // Start task list + timerHead = newTimer; + } + else + { + // Add it to the end of the timer list + srchTimer = timerHead; + + // Stop at the last record + while ( srchTimer->next ) + srchTimer = srchTimer->next; + + // Add to the list + srchTimer->next = newTimer; + } + + return ( newTimer ); + } + else + { + return ( (osalTimerRec_t *)NULL ); + } + } +} + +/********************************************************************* + * @fn osalFindTimer + * + * @brief Find a timer in a timer list. + * Ints must be disabled. + * + * @param task_id + * @param event_flag + * + * @return osalTimerRec_t * + */ +osalTimerRec_t *osalFindTimer( uint8 task_id, uint16 event_flag ) +{ + osalTimerRec_t *srchTimer; + + // Head of the timer list + srchTimer = timerHead; + + // Stop when found or at the end + while ( srchTimer ) + { + if ( srchTimer->event_flag == event_flag && + srchTimer->task_id == task_id ) + { + break; + } + + // Not this one, check another + srchTimer = srchTimer->next; + } + + return ( srchTimer ); +} + +/********************************************************************* + * @fn osalDeleteTimer + * + * @brief Delete a timer from a timer list. + * + * @param table + * @param rmTimer + * + * @return none + */ +void osalDeleteTimer( osalTimerRec_t *rmTimer ) +{ + // Does the timer list really exist + if ( rmTimer ) + { + // Clear the event flag and osalTimerUpdate() will delete + // the timer from the list. + rmTimer->event_flag = 0; + } +} + +/********************************************************************* + * @fn osal_start_timerEx + * + * @brief + * + * This function is called to start a timer to expire in n mSecs. + * When the timer expires, the calling task will get the specified event. + * + * @param uint8 taskID - task id to set timer for + * @param uint16 event_id - event to be notified with + * @param uint32 timeout_value - in milliseconds. + * + * @return SUCCESS, or NO_TIMER_AVAIL. + */ +uint8 osal_start_timerEx( uint8 taskID, uint16 event_id, uint32 timeout_value ) +{ + halIntState_t intState; + osalTimerRec_t *newTimer; + + HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts. + + // Add timer + newTimer = osalAddTimer( taskID, event_id, timeout_value ); + + HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts. + + return ( (newTimer != NULL) ? SUCCESS : NO_TIMER_AVAIL ); +} + +/********************************************************************* + * @fn osal_start_reload_timer + * + * @brief + * + * This function is called to start a timer to expire in n mSecs. + * When the timer expires, the calling task will get the specified event + * and the timer will be reloaded with the timeout value. + * + * @param uint8 taskID - task id to set timer for + * @param uint16 event_id - event to be notified with + * @param UNINT16 timeout_value - in milliseconds. + * + * @return SUCCESS, or NO_TIMER_AVAIL. + */ +uint8 osal_start_reload_timer( uint8 taskID, uint16 event_id, uint32 timeout_value ) +{ + halIntState_t intState; + osalTimerRec_t *newTimer; + + HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts. + + // Add timer + newTimer = osalAddTimer( taskID, event_id, timeout_value ); + if ( newTimer ) + { + // Load the reload timeout value + newTimer->reloadTimeout = timeout_value; + } + + HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts. + + return ( (newTimer != NULL) ? SUCCESS : NO_TIMER_AVAIL ); +} + +/********************************************************************* + * @fn osal_stop_timerEx + * + * @brief + * + * This function is called to stop a timer that has already been started. + * If ZSUCCESS, the function will cancel the timer and prevent the event + * associated with the timer from being set for the calling task. + * + * @param uint8 task_id - task id of timer to stop + * @param uint16 event_id - identifier of the timer that is to be stopped + * + * @return SUCCESS or INVALID_EVENT_ID + */ +uint8 osal_stop_timerEx( uint8 task_id, uint16 event_id ) +{ + halIntState_t intState; + osalTimerRec_t *foundTimer; + + HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts. + + // Find the timer to stop + foundTimer = osalFindTimer( task_id, event_id ); + if ( foundTimer ) + { + osalDeleteTimer( foundTimer ); + } + + HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts. + + return ( (foundTimer != NULL) ? SUCCESS : INVALID_EVENT_ID ); +} + +/********************************************************************* + * @fn osal_get_timeoutEx + * + * @brief + * + * @param uint8 task_id - task id of timer to check + * @param uint16 event_id - identifier of timer to be checked + * + * @return Return the timer's tick count if found, zero otherwise. + */ +uint32 osal_get_timeoutEx( uint8 task_id, uint16 event_id ) +{ + halIntState_t intState; + uint32 rtrn = 0; + osalTimerRec_t *tmr; + + HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts. + + tmr = osalFindTimer( task_id, event_id ); + + if ( tmr ) + { + rtrn = tmr->timeout.time32; + } + + HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts. + + return rtrn; +} + +/********************************************************************* + * @fn osal_timer_num_active + * + * @brief + * + * This function counts the number of active timers. + * + * @return uint8 - number of timers + */ +uint8 osal_timer_num_active( void ) +{ + halIntState_t intState; + uint8 num_timers = 0; + osalTimerRec_t *srchTimer; + + HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts. + + // Head of the timer list + srchTimer = timerHead; + + // Count timers in the list + while ( srchTimer != NULL ) + { + num_timers++; + srchTimer = srchTimer->next; + } + + HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts. + + return num_timers; +} + +/********************************************************************* + * @fn osalTimerUpdate + * + * @brief Update the timer structures for a timer tick. + * + * @param none + * + * @return none + *********************************************************************/ +void osalTimerUpdate( uint32 updateTime ) +{ + halIntState_t intState; + osalTimerRec_t *srchTimer; + osalTimerRec_t *prevTimer; + + osalTime_t timeUnion; + timeUnion.time32 = updateTime; + + HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts. + // Update the system time + osal_systemClock += updateTime; + HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts. + + // Look for open timer slot + if ( timerHead != NULL ) + { + // Add it to the end of the timer list + srchTimer = timerHead; + prevTimer = (void *)NULL; + + // Look for open timer slot + while ( srchTimer ) + { + osalTimerRec_t *freeTimer = NULL; + + HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts. + + // To minimize time in this critical section, avoid 32-bit math + if ((timeUnion.time16[1] == 0) && (timeUnion.time8[1] == 0)) + { + // If upper 24 bits are zero, check lower 8 bits for roll over + if (srchTimer->timeout.time8[0] >= timeUnion.time8[0]) + { + // 8-bit math + srchTimer->timeout.time8[0] -= timeUnion.time8[0]; + } + else + { + // 32-bit math + if (srchTimer->timeout.time32 > timeUnion.time32) + { + srchTimer->timeout.time32 -= timeUnion.time32; + } + else + { + srchTimer->timeout.time32 = 0; + } + } + } + else + { + // 32-bit math + if (srchTimer->timeout.time32 > timeUnion.time32) + { + srchTimer->timeout.time32 -= timeUnion.time32; + } + else + { + srchTimer->timeout.time32 = 0; + } + } + + // Check for reloading + if ( (srchTimer->timeout.time16[0] == 0) && (srchTimer->timeout.time16[1] == 0) && + (srchTimer->reloadTimeout) && (srchTimer->event_flag) ) + { + // Notify the task of a timeout + osal_set_event( srchTimer->task_id, srchTimer->event_flag ); + + // Reload the timer timeout value + srchTimer->timeout.time32 = srchTimer->reloadTimeout; + } + + // When timeout or delete (event_flag == 0) + if ( ((srchTimer->timeout.time16[0] == 0) && (srchTimer->timeout.time16[1] == 0)) || + (srchTimer->event_flag == 0) ) + { + // Take out of list + if ( prevTimer == NULL ) + { + timerHead = srchTimer->next; + } + else + { + prevTimer->next = srchTimer->next; + } + + // Setup to free memory + freeTimer = srchTimer; + + // Next + srchTimer = srchTimer->next; + } + else + { + // Get next + prevTimer = srchTimer; + srchTimer = srchTimer->next; + } + + HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts. + + if ( freeTimer ) + { + if ( (freeTimer->timeout.time16[0] == 0) && (freeTimer->timeout.time16[1] == 0) ) + { + osal_set_event( freeTimer->task_id, freeTimer->event_flag ); + } + osal_mem_free( freeTimer ); + } + } + } +} + +#ifdef POWER_SAVING +/********************************************************************* + * @fn osal_adjust_timers + * + * @brief Update the timer structures for elapsed ticks. + * + * @param none + * + * @return none + *********************************************************************/ +void osal_adjust_timers( void ) +{ + uint32 eTime; + + if ( timerHead != NULL ) + { + // Compute elapsed time (msec) + eTime = TimerElapsed() / TICK_COUNT; + + if ( eTime ) + { + osalTimerUpdate( eTime ); + } + } +} +#endif /* POWER_SAVING */ + +#if defined POWER_SAVING || defined USE_ICALL +/********************************************************************* + * @fn osal_next_timeout + * + * @brief + * + * Search timer table to return the lowest timeout value. If the + * timer list is empty, then the returned timeout will be zero. + * + * @param none + * + * @return none + *********************************************************************/ +uint32 osal_next_timeout( void ) +{ + uint32 nextTimeout; + osalTimerRec_t *srchTimer; + + if ( timerHead != NULL ) + { + // Head of the timer list + srchTimer = timerHead; + nextTimeout = OSAL_TIMERS_MAX_TIMEOUT; + + // Look for the next timeout timer + while ( srchTimer != NULL ) + { + if (srchTimer->timeout.time32 < nextTimeout) + { + nextTimeout = srchTimer->timeout.time32; + } + // Check next timer + srchTimer = srchTimer->next; + } + } + else + { + // No timers + nextTimeout = 0; + } + + return ( nextTimeout ); +} +#endif // POWER_SAVING || USE_ICALL + +/********************************************************************* + * @fn osal_GetSystemClock() + * + * @brief Read the local system clock. + * + * @param none + * + * @return local clock in milliseconds + */ +uint32 osal_GetSystemClock( void ) +{ + return ( osal_systemClock ); +} + +/********************************************************************* +*********************************************************************/ diff --git a/include/OSAL_Timers.h b/include/OSAL_Timers.h new file mode 100644 index 0000000..d4de494 --- /dev/null +++ b/include/OSAL_Timers.h @@ -0,0 +1,146 @@ +/************************************************************************************************** + Filename: OSAL_Timers.h + Revised: $Date: 2011-09-16 19:09:24 -0700 (Fri, 16 Sep 2011) $ + Revision: $Revision: 27618 $ + + Description: This file contains the OSAL Timer definition and manipulation functions. + + + Copyright 2004-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef OSAL_TIMERS_H +#define OSAL_TIMERS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + * INCLUDES + */ + +/********************************************************************* + * MACROS + */ + +/********************************************************************* + * CONSTANTS + * the unit is chosen such that the 320us tick equivalent can fit in + * 32 bits. + */ + #define OSAL_TIMERS_MAX_TIMEOUT 0x28f5c28e /* unit is ms*/ + +/********************************************************************* + * TYPEDEFS + */ + +/********************************************************************* + * GLOBAL VARIABLES + */ + +/********************************************************************* + * FUNCTIONS + */ + + /* + * Initialization for the OSAL Timer System. + */ + extern void osalTimerInit( void ); + + /* + * Set a Timer + */ + extern uint8 osal_start_timerEx( uint8 task_id, uint16 event_id, uint32 timeout_value ); + + /* + * Set a timer that reloads itself. + */ + extern uint8 osal_start_reload_timer( uint8 taskID, uint16 event_id, uint32 timeout_value ); + + /* + * Stop a Timer + */ + extern uint8 osal_stop_timerEx( uint8 task_id, uint16 event_id ); + + /* + * Get the tick count of a Timer. + */ + extern uint32 osal_get_timeoutEx( uint8 task_id, uint16 event_id ); + + /* + * Simulated Timer Interrupt Service Routine + */ + + extern void osal_timer_ISR( void ); + + /* + * Adjust timer tables + */ + extern void osal_adjust_timers( void ); + + /* + * Update timer tables + */ + extern void osalTimerUpdate( uint32 updateTime ); + + /* + * Count active timers + */ + extern uint8 osal_timer_num_active( void ); + + /* + * Set the hardware timer interrupts for sleep mode. + * These functions should only be called in OSAL_PwrMgr.c + */ + extern void osal_sleep_timers( void ); + extern void osal_unsleep_timers( void ); + + /* + * Read the system clock - returns milliseconds + */ + extern uint32 osal_GetSystemClock( void ); + + /* + * Get the next OSAL timer expiration. + * This function should only be called in OSAL_PwrMgr.c + */ + extern uint32 osal_next_timeout( void ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* OSAL_TIMERS_H */ diff --git a/include/comdef.h b/include/comdef.h new file mode 100644 index 0000000..a73899c --- /dev/null +++ b/include/comdef.h @@ -0,0 +1,161 @@ +/************************************************************************************************** + Filename: comdef.h + Revised: $Date: 2010-07-28 08:42:48 -0700 (Wed, 28 Jul 2010) $ + Revision: $Revision: 23160 $ + + Description: Type definitions and macros. + + + Copyright 2004-2008 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef COMDEF_H +#define COMDEF_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/********************************************************************* + * INCLUDES + */ + +/* HAL */ +#include "hal_types.h" +#include "hal_defs.h" + +/********************************************************************* + * Lint Keywords + */ +#define VOID (void) + +#define NULL_OK +#define INP +#define OUTP +#define UNUSED +#define ONLY +#define READONLY +#define SHARED +#define KEEP +#define RELAX + +/********************************************************************* + * CONSTANTS + */ + +#ifndef false + #define false 0 +#endif + +#ifndef true + #define true 1 +#endif + +#ifndef CONST + #define CONST const +#endif + +#ifndef GENERIC + #define GENERIC +#endif + +/*** Generic Status Return Values ***/ +#define SUCCESS 0x00 +#define FAILURE 0x01 +#define INVALIDPARAMETER 0x02 +#define INVALID_TASK 0x03 +#define MSG_BUFFER_NOT_AVAIL 0x04 +#define INVALID_MSG_POINTER 0x05 +#define INVALID_EVENT_ID 0x06 +#define INVALID_INTERRUPT_ID 0x07 +#define NO_TIMER_AVAIL 0x08 +#define NV_ITEM_UNINIT 0x09 +#define NV_OPER_FAILED 0x0A +#define INVALID_MEM_SIZE 0x0B +#define NV_BAD_ITEM_LEN 0x0C +#define NV_INVALID_DATA 0x0D + +/*** NV Error Mask ***/ +#define NV_NIB_INIT_FAILURE 0x01 +#define NV_ADDR_MGR_INIT_FAILURE 0x02 +#define NV_ASSOC_INIT_FAILURE 0x04 +#define NV_BIND_TBL_INIT_FAILURE 0x08 +#define NV_GRPS_INIT_FAILURE 0x10 +#define NV_SEC_MGR_FAILURE 0x20 + +/********************************************************************* + * TYPEDEFS + */ + +// Generic Status return +typedef uint8 Status_t; + +// Data types +typedef int32 int24; +typedef uint32 uint24; + +/********************************************************************* + * Global System Events + */ + +#define SYS_EVENT_MSG 0x8000 // A message is waiting event + +/********************************************************************* + * Global Generic System Messages + */ + +#define KEY_CHANGE 0xC0 // Key Events + +// OSAL System Message IDs/Events Reserved for applications (user applications) +// 0xE0 – 0xFC + +/********************************************************************* + * MACROS + */ + +/********************************************************************* + * GLOBAL VARIABLES + */ + +/********************************************************************* + * FUNCTIONS + */ + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* COMDEF_H */ diff --git a/include/saddr.c b/include/saddr.c new file mode 100644 index 0000000..a953419 --- /dev/null +++ b/include/saddr.c @@ -0,0 +1,227 @@ +/**************************************************************************** + Filename: saddr.c + Revised: $Date: 2014-11-06 11:03:55 -0800 (Thu, 06 Nov 2014) $ + Revision: $Revision: 41021 $ + + Description: Zigbee and 802.15.4 device address utility functions. + + + Copyright 2005-2014 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +****************************************************************************/ + +/**************************************************************************** + * INCLUDES + */ +#include "hal_types.h" +#include "OSAL.h" +#include "saddr.h" + +#include "R2R_FlashJT.h" +#if defined (CC26XX) +#include "R2F_FlashJT.h" +#endif /* CC26XX */ + +/**************************************************************************** + * @fn sAddrCmp + * + * @brief Compare two device addresses. + * + * input parameters + * + * @param pAddr1 - Pointer to first address. + * @param pAddr2 - Pointer to second address. + * + * output parameters + * + * @return TRUE if addresses are equal, FALSE otherwise + */ +bool sAddrCmp(const sAddr_t *pAddr1, const sAddr_t *pAddr2) +{ + if (pAddr1->addrMode != pAddr2->addrMode) + { + return FALSE; + } + else if (pAddr1->addrMode == SADDR_MODE_NONE) + { + return FALSE; + } + else if (pAddr1->addrMode == SADDR_MODE_SHORT) + { + return (bool) (pAddr1->addr.shortAddr == pAddr2->addr.shortAddr); + } + else if (pAddr1->addrMode == SADDR_MODE_EXT) + { + return (MAP_sAddrExtCmp(pAddr1->addr.extAddr, pAddr2->addr.extAddr)); + } + else + { + return FALSE; + } +} + +/**************************************************************************** + * @fn sAddrIden + * + * @brief Check if two device addresses are identical. + * + * This routine is virtually the same as sAddrCmp, which is used + * to determine if two different addresses are the same. However, + * this routine can be used to determine if an address is the + * same as a previously stored address. The key difference is in + * the former case, if the address mode is "none", then the + * assumption is that the two addresses can not be the same. But + * in the latter case, the address mode itself is being compared. + * So two addresses can be identical even if the address mode is + * "none", as long as the address mode of both addresses being + * compared is "none". + * + * input parameters + * + * @param pAddr1 - Pointer to first address. + * @param pAddr2 - Pointer to second address. + * + * output parameters + * + * @return TRUE if addresses are identical, FALSE otherwise + */ +bool sAddrIden(const sAddr_t *pAddr1, const sAddr_t *pAddr2) +{ + // first check if the address modes are the same + if (pAddr1->addrMode != pAddr2->addrMode) + { + // no, so no point in comparing any further + return FALSE; + } + // the address modes are the same; check if there is no address + else if (pAddr1->addrMode == SADDR_MODE_NONE) + { + // no address, so no need to compare any further as both addresses have the + // same address mode but no address, so they are identical + return TRUE; + } + // there's an address; check if it is short + else if (pAddr1->addrMode == SADDR_MODE_SHORT) + { + // compare short addresses + return (bool) (pAddr1->addr.shortAddr == pAddr2->addr.shortAddr); + } + // there's an address; check if it is extended + else if (pAddr1->addrMode == SADDR_MODE_EXT) + { + // compare extended addresses + return (MAP_sAddrExtCmp(pAddr1->addr.extAddr, pAddr2->addr.extAddr)); + } + else // unknown error + { + return FALSE; + } +} + +/**************************************************************************** + * @fn sAddrCpy + * + * @brief Copy a device address. + * + * input parameters + * + * @param pSrc - Pointer to address to copy. + * + * output parameters + * + * @param pDest - Pointer to address of copy. + * + * @return None. + */ +void sAddrCpy(sAddr_t *pDest, const sAddr_t *pSrc) +{ + pDest->addrMode = pSrc->addrMode; + + if (pDest->addrMode == SADDR_MODE_EXT) + { + MAP_sAddrExtCpy(pDest->addr.extAddr, pSrc->addr.extAddr); + } + else + { + pDest->addr.shortAddr = pSrc->addr.shortAddr; + } +} + +/**************************************************************************** + * @fn sAddrExtCmp + * + * @brief Compare two extended addresses. + * + * input parameters + * + * @param pAddr1 - Pointer to first address. + * @param pAddr2 - Pointer to second address. + * + * output parameters + * + * @return TRUE if addresses are equal, FALSE otherwise + */ +bool sAddrExtCmp(const uint8 * pAddr1, const uint8 * pAddr2) +{ + uint8 i; + + for (i = SADDR_EXT_LEN; i != 0; i--) + { + if (*pAddr1++ != *pAddr2++) + { + return FALSE; + } + } + return TRUE; +} + +/**************************************************************************** + * @fn sAddrExtCpy + * + * @brief Copy an extended address. + * + * input parameters + * + * @param pSrc - Pointer to address to copy. + * + * output parameters + * + * @param pDest - Pointer to address of copy. + * + * @return pDest + SADDR_EXT_LEN. + */ +void *sAddrExtCpy(uint8 * pDest, const uint8 * pSrc) +{ + return osal_memcpy(pDest, pSrc, SADDR_EXT_LEN); +} + + + + diff --git a/include/saddr.h b/include/saddr.h new file mode 100644 index 0000000..0b4f646 --- /dev/null +++ b/include/saddr.h @@ -0,0 +1,175 @@ +/************************************************************************************************** + Filename: saddr.h + Revised: $Date: 2009-12-10 08:32:15 -0800 (Thu, 10 Dec 2009) $ + Revision: $Revision: 21311 $ + + Description: Zigbee and 802.15.4 device address utility functions. + + + Copyright 2005-2010 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef SADDR_H +#define SADDR_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************************************************************** + * MACROS + */ + +/* Extended address length */ +#define SADDR_EXT_LEN 8 + +/* Address modes */ +#define SADDR_MODE_NONE 0 /* Address not present */ +#define SADDR_MODE_SHORT 2 /* Short address */ +#define SADDR_MODE_EXT 3 /* Extended address */ + +/**************************************************************************** + * TYPEDEFS + */ + +/* Extended address */ +typedef uint8 sAddrExt_t[SADDR_EXT_LEN]; + +/* Combined short/extended device address */ +typedef struct +{ + union + { + uint16 shortAddr; /* Short address */ + sAddrExt_t extAddr; /* Extended address */ + } addr; + uint8 addrMode; /* Address mode */ +} sAddr_t; + +/**************************************************************************** + * @fn sAddrCmp + * + * @brief Compare two device addresses. + * + * input parameters + * + * @param pAddr1 - Pointer to first address. + * @param pAddr2 - Pointer to second address. + * + * output parameters + * + * @return TRUE if addresses are equal, FALSE otherwise + */ +extern bool sAddrCmp(const sAddr_t *pAddr1, const sAddr_t *pAddr2); + +/**************************************************************************** + * @fn sAddrIden + * + * @brief Check if two device addresses are identical. + * + * This routine is virtually the same as sAddrCmp, which is used + * to determine if two different addresses are the same. However, + * this routine can be used to determine if an address is the + * same as a previously stored address. The key difference is in + * the former case, if the address mode is "none", then the + * assumption is that the two addresses can not be the same. But + * in the latter case, the address mode itself is being compared. + * So two addresses can be identical even if the address mode is + * "none", as long as the address mode of both addresses being + * compared is the "none". + * + * input parameters + * + * @param pAddr1 - Pointer to first address. + * @param pAddr2 - Pointer to second address. + * + * output parameters + * + * @return TRUE if addresses are identical, FALSE otherwise + */ +extern bool sAddrIden(const sAddr_t *pAddr1, const sAddr_t *pAddr2); + +/**************************************************************************** + * @fn sAddrCpy + * + * @brief Copy a device address. + * + * input parameters + * + * @param pSrc - Pointer to address to copy. + * + * output parameters + * + * @param pDest - Pointer to address of copy. + * + * @return None. + */ +extern void sAddrCpy(sAddr_t *pDest, const sAddr_t *pSrc); + +/**************************************************************************** + * @fn sAddrExtCmp + * + * @brief Compare two extended addresses. + * + * input parameters + * + * @param pAddr1 - Pointer to first address. + * @param pAddr2 - Pointer to second address. + * + * output parameters + * + * @return TRUE if addresses are equal, FALSE otherwise + */ +extern bool sAddrExtCmp(const uint8 * pAddr1, const uint8 * pAddr2); + +/**************************************************************************** + * @fn sAddrExtCpy + * + * @brief Copy an extended address. + * + * input parameters + * + * @param pSrc - Pointer to address to copy. + * + * output parameters + * + * @param pDest - Pointer to address of copy. + * + * @return pDest + SADDR_EXT_LEN. + */ +void *sAddrExtCpy(uint8 * pDest, const uint8 * pSrc); + +#ifdef __cplusplus +} +#endif + +#endif /* SADDR_H */ diff --git a/main.c b/main.c index 8f5cb95..7bfc871 100644 --- a/main.c +++ b/main.c @@ -4,7 +4,7 @@ #include "hal_timer.h" #include "ZComDef.h" #include "OSAL.h" -#include "ZStack.h" +// #include "ZStack.h" #include "i2c.h" // Include necessary libraries for the sensors (BME280, Wind Vane, etc.) #include "bme280.h"