hpw422移植新的sdk

This commit is contained in:
xushaoxiang
2026-07-03 18:08:25 +08:00
commit 945a5a5b0b
2583 changed files with 713209 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
/*!
* \file OnBoard.c
*
* \brief Target xc6xxx hal spi implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#include "OnBoard.h"
/*********************************************************************
* @fn _itoa
*
* @brief convert a 16bit number to ASCII
*
* @param num -
* buf -
* radix -
*
* @return void
*
*********************************************************************/
void _itoa(uint16 num, uint8 *buf, uint8 radix)
{
char c,i;
uint8 *p, rst[5];
p = rst;
for ( i=0; i<5; i++,p++ )
{
c = num % radix; // Isolate a digit
*p = c + (( c < 10 ) ? '0' : '7'); // Convert to Ascii
num /= radix;
if ( !num )
break;
}
for ( c=0 ; c<=i; c++ )
*buf++ = *p--; // Reverse character order
*buf = '\0';
}
/*********************************************************************
* @fn Onboard_rand
*
* @brief Random number generator
*
* @param none
*
* @return uint16 - new random number
*
*********************************************************************/
uint16 Onboard_rand( void )
{
return ( rand() );
}
+280
View File
@@ -0,0 +1,280 @@
/*!
* \file OnBoard.h
*
* \brief The header of OnBoard.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef ONBOARD_H
#define ONBOARD_H
#ifdef __cplusplus
extern "C"
{
#endif
/*********************************************************************
* INCLUDES
*/
// #include <intrinsics.h>
#include "hal_mcu.h"
// #include "hal_uart.h"
#include "hal_sleep.h"
#include "OSAL.h"
#include <stdlib.h>
/*********************************************************************
* GLOBAL VARIABLES
*/
/* 64-bit Extended Address of this device */
// extern uint8 aExtendedAddress[8];
/*********************************************************************
* CONSTANTS
*/
/* Timer clock and power-saving definitions */
#define TICK_COUNT 1 /* TIMAC requires this number to be 1 */
/* OSAL timer defines */
// #define TICK_TIME 1000 /* Timer per tick - in micro-sec */
/* These Key definitions are unique to this development system.
* They are used to bypass functions when starting up the device.
*/
// #define SW_BYPASS_NV /* Bypass Network layer NV restore*/
// #define SW_BYPASS_START /* Bypass Network initialization */
// /* LCD Support Defintions */
// #ifdef LCD_SUPPORTED
// #if !defined DEBUG
// #define DEBUG 0
// #endif
// #if LCD_SUPPORTED==DEBUG
// #define SERIAL_DEBUG_SUPPORTED /* Serial-debug */
// #endif
// #else /* No LCD support */
// #undef SERIAL_DEBUG_SUPPORTED /* No serial-debug */
// #endif
// /* Serial Port Definitions */
// #if defined (ZAPP_P1)
// #define ZAPP_PORT HAL_UART_PORT_0 /*SERIAL_PORT1 */
// #elif defined (ZAPP_P2)
// #define ZAPP_PORT HAL_UART_PORT_1 /*SERIAL_PORT2 */
// #else
// #undef ZAPP_PORT
// #endif
// #if defined (ZTOOL_P1)
// #define ZTOOL_PORT HAL_UART_PORT_0 /*SERIAL_PORT1 */
// #elif defined (ZTOOL_P2)
// #define ZTOOL_PORT HAL_UART_PORT_1 /*SERIAL_PORT2 */
// #else
// #undef ZTOOL_PORT
// #endif
// /* Tx and Rx buffer size defines used by SPIMgr.c */
// #define MT_UART_TX_BUFF_MAX 170
// #define MT_UART_RX_BUFF_MAX 120
// #define MT_UART_THRESHOLD 5
// #define MT_UART_IDLE_TIMEOUT 5
// #if !defined HAL_UART_PORT
// #define HAL_UART_PORT 0
// #endif
// /* SOC defines the ideal sizes in the
// * individual _hal_uart_dma/isr.c modules.
// */
// #define HAL_UART_FLOW_THRESHOLD 5
// #define HAL_UART_RX_BUF_SIZE 170
// #define HAL_UART_TX_BUF_SIZE 120
// #define HAL_UART_IDLE_TIMEOUT 5
/* Restart system from absolute beginning
* Disables interrupts, forces WatchDog reset
*/
// #define SystemReset()
/* Reset reason for reset indication */
// #define ResetReason() (0)
// #define BootLoader() /* Not yet implemented */
/* Power conservation */
#define OSAL_SET_CPU_INTO_SLEEP(timeout) halSleep(timeout); /* Called from OSAL_PwrMgr */
// /* Internal (MCU) RAM addresses */
// #define MCU_RAM_BEG 0x1100
// #define MCU_RAM_END 0x20FF
// #define MCU_RAM_LEN (MCU_RAM_END - MCU_RAM_BEG + 1)
// #ifdef __IAR_SYSTEMS_ICC__
// /* Internal (MCU) Stack addresses */
// #define CSTACK_BEG ((uint8 const *)(_Pragma("segment=\"CSTACK\"") __segment_begin("CSTACK")))
// #define CSTACK_END ((uint8 const *)(_Pragma("segment=\"CSTACK\"") __segment_end("CSTACK"))-1)
// /* Stack Initialization Value */
// #define STACK_INIT_VALUE 0xCD
// #else
// #error Check compiler compatibility.
// #endif
/* The following Heap sizes are setup for typical TI sample applications,
* and should be adjusted to your systems requirements.
*/
/* Internal (MCU) heap size */
#if !defined( INT_HEAP_LEN )
#define INT_HEAP_LEN 6144 /* 6.0K */
#endif
/* Memory Allocation Heap */
#define MAXMEMHEAP INT_HEAP_LEN /* Typically, 1.0-6.0K */
// /* Initialization levels */
// #define OB_COLD 0
// #define OB_WARM 1
// #define OB_READY 2
// #ifdef LCD_SUPPORTED
// #define BUZZER_OFF 0
// #define BUZZER_ON 1
// #define BUZZER_BLIP 2
// #endif
// #define VOLT_LEVEL_BAD 0
// #define VOLT_LEVEL_CAUTIOUS 1
// #define VOLT_LEVEL_GOOD 2
// #if defined (HAL_UART_USB)
// extern uint32 softReset;
// #define SystemResetSoft() \
// do{ \
// HAL_DISABLE_INTERRUPTS(); \
// softReset = SOFT_RESET; \
// HWREG(NVIC_APINT) = (NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ); \
// }while(0)
// #else
// #define SystemResetSoft() SystemReset()
// #endif
// /*********************************************************************
// * TYPEDEFS
// */
// typedef struct
// {
// osal_event_hdr_t hdr;
// uint8 state; /* shift */
// uint8 keys; /* keys */
// } keyChange_t;
// /*********************************************************************
// * FUNCTIONS
// */
// /*
// * Initialize the Peripherals
// * level: 0=cold, 1=warm, 2=ready
// */
// extern void InitBoard( uint8 level );
/*
* Get elapsed timer clock counts
*/
extern uint32 TimerElapsed( void );
// /*
// * Register for all key events
// */
// extern uint8 RegisterForKeys( uint8 task_id );
// /* Keypad Control Functions */
// /*
// * Send "Key Pressed" message to application
// */
// extern uint8 OnBoard_SendKeys( uint8 keys, uint8 state );
// /* Voltage Measurement Functions */
// /* Register a callback */
// extern void RegisterVoltageWarningCB( void (*pVoltWarnCB)(uint8) );
// /* Measure voltage and report */
// extern bool OnBoard_CheckVoltage( void );
/* LCD Emulation/Control Functions */
/*
* Convert an interger to an ascii string
*/
extern void _itoa( uint16 num, uint8 *buf, uint8 radix );
// extern void Dimmer( uint8 lvl );
// /* External I/O Processing Functions */
// /*
// * Turn on an external lamp
// */
// extern void BigLight_On( void );
// /*
// * Turn off an external lamp
// */
// extern void BigLight_Off( void );
// /*
// * Turn on/off an external buzzer
// * on: BUZZER_ON or BUZZER_OFF
// */
// extern void BuzzerControl( uint8 on );
// /*
// * Get setting of external dip switch
// */
// extern uint8 GetUserDipSw( void );
// /*
// * Calculate the size of used stack
// */
// extern uint16 OnBoard_stack_used( void );
// /*
// * Callback routine to handle keys
// */
// extern void OnBoard_KeyCallback ( uint8 keys, uint8 state );
/*
* Board specific random number generator
*/
extern uint16 Onboard_rand( void );
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* ONBOARD_H */
+269
View File
@@ -0,0 +1,269 @@
/*!
* \file hal_assert.c
*
* \brief Target xc6xxx hal spi implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* ------------------------------------------------------------------------------------------------
* Includes
* ------------------------------------------------------------------------------------------------
*/
#include "hal_assert.h"
#include "hal_types.h"
#include "hal_board.h"
#include "hal_defs.h"
#include "hal_mcu.h"
/* ------------------------------------------------------------------------------------------------
* Local Prototypes
* ------------------------------------------------------------------------------------------------
*/
void halAssertHazardLights(void);
/**************************************************************************************************
* @fn halAssertHandler
*
* @brief Logic to handle an assert.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void halAssertHandler( void )
{
#if defined( HAL_ASSERT_RESET )
HAL_SYSTEM_RESET();
#elif defined ( HAL_ASSERT_LIGHTS )
halAssertHazardLights();
#elif defined( HAL_ASSERT_SPIN )
volatile uint8 i = 1;
HAL_DISABLE_INTERRUPTS();
while(i);
#endif
return;
}
#if !defined ASSERT_WHILE
/**************************************************************************************************
* @fn halAssertHazardLights
*
* @brief Blink LEDs to indicate an error.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void halAssertHazardLights(void)
{
enum
{
DEBUG_DATA_RSTACK_HIGH_OFS,
DEBUG_DATA_RSTACK_LOW_OFS,
DEBUG_DATA_TX_ACTIVE_OFS,
DEBUG_DATA_RX_ACTIVE_OFS,
DEBUG_DATA_SIZE
};
uint8 buttonHeld;
uint8 debugData[DEBUG_DATA_SIZE] = {0};
/* disable all interrupts before anything else */
HAL_DISABLE_INTERRUPTS();
/*-------------------------------------------------------------------------------
* Initialize LEDs and turn them off.
*/
HAL_BOARD_INIT();
HAL_TURN_OFF_LED1();
HAL_TURN_OFF_LED2();
HAL_TURN_OFF_LED3();
HAL_TURN_OFF_LED4();
/*-------------------------------------------------------------------------------
* Master infinite loop.
*/
for (;;)
{
buttonHeld = 0;
/*-------------------------------------------------------------------------------
* "Hazard lights" loop. A held keypress will exit this loop.
*/
do
{
HAL_LED_BLINK_DELAY();
/* toggle LEDS, the #ifdefs are in case HAL has logically remapped non-existent LEDs */
#if (HAL_NUM_LEDS >= 1)
HAL_TOGGLE_LED1();
#if (HAL_NUM_LEDS >= 2)
HAL_TOGGLE_LED2();
#if (HAL_NUM_LEDS >= 3)
HAL_TOGGLE_LED3();
#if (HAL_NUM_LEDS >= 4)
HAL_TOGGLE_LED4();
#endif
#endif
#endif
#endif
/* escape hatch to continue execution, set escape to '1' to continue execution */
{
static uint8 escape = 0;
if (escape)
{
escape = 0;
return;
}
}
/* break out of loop if button is held long enough */
// if (HAL_PUSH_BUTTON1()) // TODO
// {
// buttonHeld++;
// }
// else
// {
// buttonHeld = 0;
// }
}
while (buttonHeld != 10); /* loop until button is held specified number of loops */
/*-------------------------------------------------------------------------------
* Just exited from "hazard lights" loop.
*/
/* turn off all LEDs */
HAL_TURN_OFF_LED1();
HAL_TURN_OFF_LED2();
HAL_TURN_OFF_LED3();
HAL_TURN_OFF_LED4();
/* wait for button release */
// HAL_DEBOUNCE(!HAL_PUSH_BUTTON1()); // TODO
/*-------------------------------------------------------------------------------
* Load debug data into memory.
*/
#ifdef HAL_MCU_AVR
{
uint8 * pStack;
pStack = (uint8 *) SP;
pStack++; /* point to return address on stack */
debugData[DEBUG_DATA_RSTACK_HIGH_OFS] = *pStack;
pStack++;
debugData[DEBUG_DATA_RSTACK_LOW_OFS] = *pStack;
}
debugData[DEBUG_DATA_INT_MASK_OFS] = EIMSK;
#endif
/* initialize for data dump loop */
{
uint8 iBit;
uint8 iByte;
iBit = 0;
iByte = 0;
/*-------------------------------------------------------------------------------
* Data dump loop. A button press cycles data bits to an LED.
*/
while (iByte < DEBUG_DATA_SIZE)
{
/* wait for key press */
// while(!HAL_PUSH_BUTTON1()); // TODO
/* turn on all LEDs for first bit of byte, turn on three LEDs if not first bit */
HAL_TURN_ON_LED1();
HAL_TURN_ON_LED2();
HAL_TURN_ON_LED3();
if (iBit == 0)
{
HAL_TURN_ON_LED4();
}
else
{
HAL_TURN_OFF_LED4();
}
/* wait for debounced key release */
// HAL_DEBOUNCE(!HAL_PUSH_BUTTON1()); // TODO
/* turn off all LEDs */
HAL_TURN_OFF_LED1();
HAL_TURN_OFF_LED2();
HAL_TURN_OFF_LED3();
HAL_TURN_OFF_LED4();
/* output value of data bit to LED1 */
if (debugData[iByte] & (1 << (7 - iBit)))
{
HAL_TURN_ON_LED1();
}
else
{
HAL_TURN_OFF_LED1();
}
/* advance to next bit */
iBit++;
if (iBit == 8)
{
iBit = 0;
iByte++;
}
}
}
/*
* About to enter "hazard lights" loop again. Turn off LED1 in case the last bit
* displayed happened to be one. This guarantees all LEDs are off at the start of
* the flashing loop which uses a toggle operation to change LED states.
*/
HAL_TURN_OFF_LED1();
}
}
#endif
/* ------------------------------------------------------------------------------------------------
* Compile Time Assertions
* ------------------------------------------------------------------------------------------------
*/
/* integrity check of type sizes */
HAL_ASSERT_SIZE( int8, 1);
HAL_ASSERT_SIZE( uint8, 1);
HAL_ASSERT_SIZE( int16, 2);
HAL_ASSERT_SIZE(uint16, 2);
HAL_ASSERT_SIZE( int32, 4);
HAL_ASSERT_SIZE(uint32, 4);
#pragma message("note: compile depend")
//HAL_ASSERT_SIZE( int32, 8); // TODO
//HAL_ASSERT_SIZE(uint32, 8); // TODO
/**************************************************************************************************
*/
+295
View File
@@ -0,0 +1,295 @@
/*!
* \file hal_drivers.c
*
* \brief Target xc6xxx hal spi implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/**************************************************************************************************
* INCLUDES
**************************************************************************************************/
// #include "hal_adc.h"
#if (defined HAL_AES) && (HAL_AES == TRUE)
#include "hal_aes.h"
#endif
#if (defined HAL_BUZZER) && (HAL_BUZZER == TRUE)
#include "hal_buzzer.h"
#endif
#if (defined HAL_DMA) && (HAL_DMA == TRUE)
#include "hal_dma.h"
#endif
#include "hal_drivers.h"
// #include "hal_key.h"
// #include "hal_lcd.h"
// #include "hal_led.h"
#include "hal_sleep.h"
#include "hal_timer.h"
#include "hal_types.h"
// #include "hal_uart.h"
#ifdef CC2591_COMPRESSION_WORKAROUND
#include "mac_rx.h"
#endif
#include "OSAL.h"
#if defined POWER_SAVING
#include "OSAL_PwrMgr.h"
#endif
#if (defined HAL_HID) && (HAL_HID == TRUE)
#include "usb_hid.h"
#endif
#if (defined HAL_SPI) && (HAL_SPI == TRUE)
#include "hal_spi.h"
#endif
#include "hal_mcu.h"
/**************************************************************************************************
* GLOBAL VARIABLES
**************************************************************************************************/
uint8 Hal_TaskID;
extern void HalLedUpdate( void ); /* Notes: This for internal only so it shouldn't be in hal_led.h */
/**************************************************************************************************
* @fn Hal_Init
*
* @brief Hal Initialization function.
*
* @param task_id - Hal TaskId
*
* @return None
**************************************************************************************************/
void Hal_Init( uint8 task_id )
{
/* Register task ID */
Hal_TaskID = task_id;
osal_start_reload_timer( Hal_TaskID, PERIOD_RSSI_RESET_EVT, 1000 );
#ifdef CC2591_COMPRESSION_WORKAROUND
osal_start_reload_timer( Hal_TaskID, PERIOD_RSSI_RESET_EVT, PERIOD_RSSI_RESET_TIMEOUT );
#endif
}
/**************************************************************************************************
* @fn Hal_DriverInit
*
* @brief Initialize HW - These need to be initialized before anyone.
*
* @param task_id - Hal TaskId
*
* @return None
**************************************************************************************************/
void HalDriverInit (void)
{
/* TIMER */
#if (defined HAL_TIMER) && (HAL_TIMER == TRUE)
#endif
/* ADC */
#if (defined HAL_ADC) && (HAL_ADC == TRUE)
HalAdcInit();
#endif
/* DMA */
#if (defined HAL_DMA) && (HAL_DMA == TRUE)
// Must be called before the init call to any module that uses DMA.
HalDmaInit();
#endif
/* AES */
#if (defined HAL_AES) && (HAL_AES == TRUE)
HalAesInit();
#endif
/* LCD */
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
HalLcdInit();
#endif
/* LED */
#if (defined HAL_LED) && (HAL_LED == TRUE)
HalLedInit();
#endif
/* UART */
#if (defined HAL_UART) && (HAL_UART == TRUE)
HalUARTInit();
#endif
/* KEY */
#if (defined HAL_KEY) && (HAL_KEY == TRUE)
HalKeyInit();
#endif
/* SPI */
#if (defined HAL_SPI) && (HAL_SPI == TRUE)
HalSpiInit();
#endif
/* HID */
#if (defined HAL_HID) && (HAL_HID == TRUE)
usbHidInit();
#endif
}
/**************************************************************************************************
* @fn Hal_ProcessEvent
*
* @brief Hal Process Event
*
* @param task_id - Hal TaskId
* events - events
*
* @return None
**************************************************************************************************/
uint16 Hal_ProcessEvent( uint8 task_id, uint16 events )
{
uint8 *msgPtr;
(void)task_id; // Intentionally unreferenced parameter
if ( events & SYS_EVENT_MSG )
{
msgPtr = osal_msg_receive(Hal_TaskID);
while (msgPtr)
{
/* Do something here - for now, just deallocate the msg and move on */
/* De-allocate */
osal_msg_deallocate( msgPtr );
/* Next */
msgPtr = osal_msg_receive( Hal_TaskID );
}
return events ^ SYS_EVENT_MSG;
}
#if (defined HAL_BUZZER) && (HAL_BUZZER == TRUE)
if (events & HAL_BUZZER_EVENT)
{
HalBuzzerStop();
return events ^ HAL_BUZZER_EVENT;
}
#endif
#ifdef CC2591_COMPRESSION_WORKAROUND
if ( events & PERIOD_RSSI_RESET_EVT )
{
macRxResetRssi();
return (events ^ PERIOD_RSSI_RESET_EVT);
}
#endif
if ( events & HAL_LED_BLINK_EVENT )
{
#if (defined (BLINK_LEDS)) && (HAL_LED == TRUE)
HalLedUpdate();
#endif /* BLINK_LEDS && HAL_LED */
return events ^ HAL_LED_BLINK_EVENT;
}
if ( events & PERIOD_RSSI_RESET_EVT )
{
#if (defined (BLINK_LEDS)) && (HAL_LED == TRUE)
HalLedUpdate();
#endif /* BLINK_LEDS && HAL_LED */
// TODO only for test
// printf("hal task system_clock = %ld\r\n", osal_GetSystemClock());
delay_ms(5);
return events ^ PERIOD_RSSI_RESET_EVT;
}
if (events & HAL_KEY_EVENT)
{
#if (defined HAL_KEY) && (HAL_KEY == TRUE)
/* Check for keys */
HalKeyPoll();
/* if interrupt disabled, do next polling */
if (!Hal_KeyIntEnable)
{
osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100);
}
#endif
return events ^ HAL_KEY_EVENT;
}
#if defined POWER_SAVING
if ( events & HAL_SLEEP_TIMER_EVENT )
{
halRestoreSleepLevel();
return events ^ HAL_SLEEP_TIMER_EVENT;
}
if ( events & HAL_PWRMGR_HOLD_EVENT )
{
(void)osal_pwrmgr_task_state(Hal_TaskID, PWRMGR_HOLD);
(void)osal_stop_timerEx(Hal_TaskID, HAL_PWRMGR_CONSERVE_EVENT);
(void)osal_clear_event(Hal_TaskID, HAL_PWRMGR_CONSERVE_EVENT);
return (events & ~(HAL_PWRMGR_HOLD_EVENT | HAL_PWRMGR_CONSERVE_EVENT));
}
if ( events & HAL_PWRMGR_CONSERVE_EVENT )
{
(void)osal_pwrmgr_task_state(Hal_TaskID, PWRMGR_CONSERVE);
return events ^ HAL_PWRMGR_CONSERVE_EVENT;
}
#endif
return 0;
}
/**************************************************************************************************
* @fn Hal_ProcessPoll
*
* @brief This routine will be called by OSAL to poll UART, TIMER...
*
* @param task_id - Hal TaskId
*
* @return None
**************************************************************************************************/
void Hal_ProcessPoll ()
{
#if defined( POWER_SAVING )
/* Allow sleep before the next OSAL event loop */
ALLOW_SLEEP_MODE();
#endif
/* UART Poll */
#if (defined HAL_UART) && (HAL_UART == TRUE)
HalUARTPoll();
#endif
/* SPI Poll */
#if (defined HAL_SPI) && (HAL_SPI == TRUE)
HalSpiPoll();
#endif
/* HID poll */
#if (defined HAL_HID) && (HAL_HID == TRUE)
usbHidProcessEvents();
#endif
}
/**************************************************************************************************
**************************************************************************************************/
+95
View File
@@ -0,0 +1,95 @@
/*!
* \file hal_assert.h
*
* \brief The header of hal_assert.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef HAL_ASSERT_H
#define HAL_ASSERT_H
/* ------------------------------------------------------------------------------------------------
* Macros
* ------------------------------------------------------------------------------------------------
*/
/*
* HAL_ASSERT( expression ) - The given expression must evaluate as "true" or else the assert
* handler is called. From here, the call stack feature of the debugger can pinpoint where
* the problem occurred.
*
* HAL_ASSERT_FORCED( ) - If asserts are in use, immediately calls the assert handler.
*
* HAL_ASSERT_STATEMENT( statement ) - Inserts the given C statement but only when asserts
* are in use. This macros allows debug code that is not part of an expression.
*
* HAL_ASSERT_DECLARATION( declaration ) - Inserts the given C declaration but only when asserts
* are in use. This macros allows debug code that is not part of an expression.
*
* Asserts can be disabled for optimum performance and minimum code size (ideal for
* finalized, debugged production code). To disable, define the preprocessor
* symbol HALNODEBUG at the project level.
*/
#ifdef HALNODEBUG
#define HAL_ASSERT(expr)
#define HAL_ASSERT_FORCED()
#define HAL_ASSERT_STATEMENT(statement)
#define HAL_ASSERT_DECLARATION(declaration)
#else
#define HAL_ASSERT(expr) st( if (!( expr )) halAssertHandler(); )
#define HAL_ASSERT_FORCED() halAssertHandler()
#define HAL_ASSERT_STATEMENT(statement) st( statement )
#define HAL_ASSERT_DECLARATION(declaration) declaration
#endif
/*
* This macro compares the size of the first parameter to the integer value
* of the second parameter. If they do not match, a compile time error for
* negative array size occurs (even gnu chokes on negative array size).
*
* This compare is done by creating a typedef for an array. No variables are
* created and no memory is consumed with this check. The created type is
* used for checking only and is not for use by any other code. The value
* of 10 in this macro is arbitrary, it just needs to be a value larger
* than one to result in a positive number for the array size.
*/
#define HAL_ASSERT_SIZE(x,y) typedef char x ## _assert_size_t[-1+10*(sizeof(x) == (y))]
/* ------------------------------------------------------------------------------------------------
* Prototypes
* ------------------------------------------------------------------------------------------------
*/
void halAssertHandler(void);
/**************************************************************************************************
*/
/**************************************************************************************************
* FUNCTIONS - API
**************************************************************************************************/
extern void halAssertHazardLights(void);
#endif
+1
View File
@@ -0,0 +1 @@
#include "hal_board_cfg.h"
+131
View File
@@ -0,0 +1,131 @@
/*!
* \file hal_defs.h
*
* \brief The header of hal_defs.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef HAL_DEFS_H
#define HAL_DEFS_H
#include "xc6xxx.h"
/* ------------------------------------------------------------------------------------------------
* Macros
* ------------------------------------------------------------------------------------------------
*/
#ifndef BV
#define BV(n) (1 << (n))
#endif
#ifndef BF
#define BF(x,b,s) (((x) & (b)) >> (s))
#endif
#ifndef MIN
#define MIN(n,m) (((n) < (m)) ? (n) : (m))
#endif
#ifndef MAX
#define MAX(n,m) (((n) < (m)) ? (m) : (n))
#endif
#ifndef ABS
#define ABS(n) (((n) < 0) ? -(n) : (n))
#endif
/* takes a byte out of a uint32 : var - uint32, ByteNum - byte to take out (0 - 3) */
#define BREAK_UINT32( var, ByteNum ) \
(uint8)((uint32)(((var) >>((ByteNum) * 8)) & 0x00FF))
#define BUILD_UINT32(Byte0, Byte1, Byte2, Byte3) \
((uint32)((uint32)((Byte0) & 0x00FF) \
+ ((uint32)((Byte1) & 0x00FF) << 8) \
+ ((uint32)((Byte2) & 0x00FF) << 16) \
+ ((uint32)((Byte3) & 0x00FF) << 24)))
#define BUILD_UINT16(loByte, hiByte) \
((uint16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8)))
#define HI_UINT16(a) (((a) >> 8) & 0xFF)
#define LO_UINT16(a) ((a) & 0xFF)
#define BUILD_UINT8(hiByte, loByte) \
((uint8)(((loByte) & 0x0F) + (((hiByte) & 0x0F) << 4)))
#define HI_UINT8(a) (((a) >> 4) & 0x0F)
#define LO_UINT8(a) ((a) & 0x0F)
// Write the 32bit value of 'val' in little endian format to the buffer pointed
// to by pBuf, and increment pBuf by 4
#define UINT32_TO_BUF_LITTLE_ENDIAN(pBuf,val) \
do { \
*(pBuf)++ = ((((uint32)(val)) >> 0) & 0xFF); \
*(pBuf)++ = ((((uint32)(val)) >> 8) & 0xFF); \
*(pBuf)++ = ((((uint32)(val)) >> 16) & 0xFF); \
*(pBuf)++ = ((((uint32)(val)) >> 24) & 0xFF); \
} while (0)
// Return the 32bit little-endian formatted value pointed to by pBuf, and increment pBuf by 4
#define BUF_TO_UINT32_LITTLE_ENDIAN(pBuf) (((pBuf) += 4), BUILD_UINT32((pBuf)[-4], (pBuf)[-3], (pBuf)[-2], (pBuf)[-1]))
#ifndef CHECK_BIT
#define CHECK_BIT(DISCS, IDX) ((DISCS) & (1<<(IDX)))
#endif
#ifndef GET_BIT
#define GET_BIT(DISCS, IDX) (((DISCS)[((IDX) / 8)] & BV((IDX) % 8)) ? TRUE : FALSE)
#endif
#ifndef SET_BIT
#define SET_BIT(DISCS, IDX) (((DISCS)[((IDX) / 8)] |= BV((IDX) % 8)))
#endif
#ifndef CLR_BIT
#define CLR_BIT(DISCS, IDX) (((DISCS)[((IDX) / 8)] &= (BV((IDX) % 8) ^ 0xFF)))
#endif
/*
* This macro is for use by other macros to form a fully valid C statement.
* Without this, the if/else conditionals could show unexpected behavior.
*
* For example, use...
* #define SET_REGS() st( ioreg1 = 0; ioreg2 = 0; )
* instead of ...
* #define SET_REGS() { ioreg1 = 0; ioreg2 = 0; }
* or
* #define SET_REGS() ioreg1 = 0; ioreg2 = 0;
* The last macro would not behave as expected in the if/else construct.
* The second to last macro will cause a compiler error in certain uses
* of if/else construct
*
* It is not necessary, or recommended, to use this macro where there is
* already a valid C statement. For example, the following is redundant...
* #define CALL_FUNC() st( func(); )
* This should simply be...
* #define CALL_FUNC() func()
*
* (The while condition below evaluates false without generating a
* constant-controlling-loop type of warning on most compilers.)
*/
#define st(x) do { x } while (__LINE__ == -1)
/**************************************************************************************************
*/
#endif
+91
View File
@@ -0,0 +1,91 @@
/*!
* \file hal_drivers.h
*
* \brief The header of hal_drivers.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef HAL_DRIVER_H
#define HAL_DRIVER_H
#ifdef __cplusplus
extern "C"
{
#endif
/**************************************************************************************************
* INCLUDES
**************************************************************************************************/
#include "hal_types.h"
/**************************************************************************************************
* CONSTANTS
**************************************************************************************************/
#define HAL_BUZZER_EVENT 0x0080
#define PERIOD_RSSI_RESET_EVT 0x0040
#define HAL_LED_BLINK_EVENT 0x0020
#define HAL_KEY_EVENT 0x0010
#if defined POWER_SAVING
#define HAL_SLEEP_TIMER_EVENT 0x0004
#define HAL_PWRMGR_HOLD_EVENT 0x0002
#define HAL_PWRMGR_CONSERVE_EVENT 0x0001
#endif
#define HAL_PWRMGR_CONSERVE_DELAY 10
#define PERIOD_RSSI_RESET_TIMEOUT 10
/**************************************************************************************************
* GLOBAL VARIABLES
**************************************************************************************************/
extern uint8 Hal_TaskID;
/**************************************************************************************************
* FUNCTIONS - API
**************************************************************************************************/
extern void Hal_Init ( uint8 task_id );
/*
* Process Serial Buffer
*/
extern uint16 Hal_ProcessEvent ( uint8 task_id, uint16 events );
/*
* Process Polls
*/
extern void Hal_ProcessPoll (void);
/*
* Initialize HW
*/
extern void HalDriverInit (void);
#ifdef __cplusplus
}
#endif
#endif
/**************************************************************************************************
**************************************************************************************************/
+71
View File
@@ -0,0 +1,71 @@
/*!
* \file hal_sleep.h
*
* \brief The header of hal_sleep.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef HAL_SLEEP_H
#define HAL_SLEEP_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "hal_types.h"
/*********************************************************************
* FUNCTIONS
*/
extern void system_sleep_init(void);
/*
* Execute power management procedure
*/
extern void halSleep( uint32 osal_timer );
/*
* Used in mac_mcu
*/
extern void halSleepWait(uint16 duration);
/*
* Used in hal_drivers, AN044 - DELAY EXTERNAL INTERRUPTS
*/
extern void halRestoreSleepLevel( void );
/*
* Used by the interrupt routines to exit from sleep.
*/
extern void halSleepExit(void);
/*
* Set the max sleep loop time lesser than the T2 rollover period.
*/
extern void halSetMaxSleepLoopTime(uint32 rolloverTime);
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif
+37
View File
@@ -0,0 +1,37 @@
/*!
* \file hal_timer.h
*
* \brief The header of hal_timer.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef TIMER_H
#define TIMER_H
#include "hal_types.h"
#define OSAL_TIMER (TIMER1_IDX)
void osal_timer_init(void);
void osal_timer_start(void);
void osal_timer_tick_set(uint32 tick);
uint32 getMcuPrecisionCount(void);
#endif
@@ -0,0 +1,78 @@
/*!
* \file hal_board_cfg.h
*
* \brief The header of xc_drv_aotimer.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef HAL_BOARD_CFG_H
#define HAL_BOARD_CFG_H
/* ------------------------------------------------------------------------------------------------
* Includes
* ------------------------------------------------------------------------------------------------
*/
#include "hal_mcu.h"
#include "hal_defs.h"
#include "hal_types.h"
/* ------------------------------------------------------------------------------------------------
* LED Configuration
* ------------------------------------------------------------------------------------------------
*/
#define HAL_LED_BLINK_DELAY() st( { volatile uint32 i; for (i=0; i<0x5800; i++) { }; } )
/* ----------- Debounce ---------- */
#define HAL_DEBOUNCE(expr) \
{ \
int i; \
for (i = 0; i < 500; i++) \
{ \
if (!(expr)) \
i = 0; \
} \
}
/* ----------- Push Buttons ---------- */
#define HAL_PUSH_BUTTON1()
#define HAL_PUSH_BUTTON2()
#define HAL_PUSH_BUTTON3()
#define HAL_PUSH_BUTTON4()
#define HAL_PUSH_BUTTON5()
#define HAL_PUSH_BUTTON6()
/* ----------- LED's ---------- */
#define HAL_TURN_ON_LED1()
#define HAL_TURN_ON_LED2()
#define HAL_TURN_ON_LED3()
#define HAL_TURN_ON_LED4()
#define HAL_TURN_OFF_LED1()
#define HAL_TURN_OFF_LED2()
#define HAL_TURN_OFF_LED3()
#define HAL_TURN_OFF_LED4()
#define HAL_BOARD_INIT()
#endif
/*******************************************************************************************************
*/
+151
View File
@@ -0,0 +1,151 @@
/*!
* \file hal_mcu.h
*
* \brief The header of hal_mcu.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef _HAL_MCU_H
#define _HAL_MCU_H
/* ------------------------------------------------------------------------------------------------
* Includes
* ------------------------------------------------------------------------------------------------
*/
#include "hal_defs.h"
#include "hal_types.h"
/* ------------------------------------------------------------------------------------------------
* Target Defines
* ------------------------------------------------------------------------------------------------
*/
// #define HAL_MCU_CC2530
/* ------------------------------------------------------------------------------------------------
* Compiler Abstraction
* ------------------------------------------------------------------------------------------------
*/
/* ---------------------- IAR Compiler ---------------------- */
#ifdef __IAR_SYSTEMS_ICC__
#include <ioCC2530.h>
#define HAL_COMPILER_IAR
#define HAL_MCU_LITTLE_ENDIAN() __LITTLE_ENDIAN__
#define _PRAGMA(x) _Pragma(#x)
#define HAL_ISR_FUNC_DECLARATION(f,v) _PRAGMA(vector=v) __near_func __interrupt void f(void)
#define HAL_ISR_FUNC_PROTOTYPE(f,v) _PRAGMA(vector=v) __near_func __interrupt void f(void)
#define HAL_ISR_FUNCTION(f,v) HAL_ISR_FUNC_PROTOTYPE(f,v); HAL_ISR_FUNC_DECLARATION(f,v)
/* ---------------------- Keil Compiler ---------------------- */
#elif defined __KEIL__ // TODO
//#include <CC2530.h>
//#define HAL_COMPILER_KEIL
//#define HAL_MCU_LITTLE_ENDIAN() 0
//#define HAL_ISR_FUNC_DECLARATION(f,v) void f(void) interrupt v
//#define HAL_ISR_FUNC_PROTOTYPE(f,v) void f(void)
//#define HAL_ISR_FUNCTION(f,v) HAL_ISR_FUNC_PROTOTYPE(f,v); HAL_ISR_FUNC_DECLARATION(f,v)
/* ------------------ Unrecognized Compiler ------------------ */
#else
// #error "ERROR: Unknown compiler."
#endif
/* ------------------------------------------------------------------------------------------------
* Interrupt Macros
* ------------------------------------------------------------------------------------------------
*/
#define HAL_ENABLE_INTERRUPTS() __enable_irq()
#define HAL_DISABLE_INTERRUPTS() __disable_irq()
#define HAL_INTERRUPTS_ARE_ENABLED() \
({ \
uint32 primask; \
__asm volatile("mrs %0, primask" : "=r"(primask)); \
(primask == 0); \
})
// typedef unsigned char halIntState_t;
static uint32 criticalNesting = 0;
#define HAL_ENTER_CRITICAL_SECTION() \
do \
{ \
if (criticalNesting == 0) \
{ \
HAL_DISABLE_INTERRUPTS(); \
} \
criticalNesting++; \
} while (0)
#define HAL_EXIT_CRITICAL_SECTION() \
do \
{ \
if (criticalNesting > 0) \
{ \
criticalNesting--; \
if (criticalNesting == 0) \
{ \
HAL_ENABLE_INTERRUPTS(); \
} \
} \
} while (0)
#define HAL_CRITICAL_STATEMENT(x) \
do \
{ \
HAL_ENTER_CRITICAL_SECTION(); \
x; \
HAL_EXIT_CRITICAL_SECTION(); \
} while (0)
#ifdef __IAR_SYSTEMS_ICC__
/* IAR library uses XCH instruction with EA. It may cause the higher priority interrupt to be
* locked out, therefore, may increase interrupt latency. It may also create a lockup condition.
* This workaround should only be used with 8051 using IAR compiler. When IAR fixes this by
* removing XCH usage in its library, compile the following macros to null to disable them.
*/
#define HAL_ENTER_ISR() { halIntState_t _isrIntState = EA; HAL_ENABLE_INTERRUPTS();
#define HAL_EXIT_ISR() EA = _isrIntState; }
#else
// #define HAL_ENTER_ISR() // TODO
// #define HAL_EXIT_ISR()
#endif /* __IAR_SYSTEMS_ICC__ */
/* Dummy for this platform */
// #define HAL_AES_ENTER_WORKAROUND() // TODO
// #define HAL_AES_EXIT_WORKAROUND()
#ifdef POWER_SAVING
// extern volatile __data uint8 halSleepPconValue;
extern volatile uint8 halSleepPconValue; // TODO
/* Any ISR that is used to wake up the chip shall call this macro. This prevents the race condition
* when the PCON IDLE bit is set after such a critical ISR fires during the prep for sleep.
*/
#define CLEAR_SLEEP_MODE() st( halSleepPconValue = 0; )
#define ALLOW_SLEEP_MODE() st( halSleepPconValue = 1; ) // TODO
#else
#define CLEAR_SLEEP_MODE()
#define ALLOW_SLEEP_MODE()
#endif
/**************************************************************************************************
*/
#endif
+304
View File
@@ -0,0 +1,304 @@
/*!
* \file hal_sleep.c
*
* \brief Target xc6xxx hal spi implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* ------------------------------------------------------------------------------------------------
* Includes
* ------------------------------------------------------------------------------------------------
*/
#include "hal_types.h"
#include "hal_mcu.h"
#include "hal_board.h"
#include "hal_sleep.h"
#include "OSAL.h"
#include "OSAL_Timers.h"
#include "OSAL_Tasks.h"
#include "OSAL_PwrMgr.h"
#include "OnBoard.h"
#include "hal_drivers.h"
#include "hal_assert.h"
#include "hal_timer.h"
#include "xc_drv_pwr.h"
#include "xc_drv_clock.h"
#include "xc6xxx.h"
#define WAKEUP_TIMER (TIMER0_IDX)
#define OSASL_MIN_SLEEP_TIME (5)
/* ------------------------------------------------------------------------------------------------
* Global Variables
* ------------------------------------------------------------------------------------------------
*/
volatile uint8 halSleepPconValue;
uint32 rtc_time_mod = 0;
/* ------------------------------------------------------------------------------------------------
* Function Prototypes
* ------------------------------------------------------------------------------------------------
*/
#if (0)
__RAM_CODE static uint32_t wakeup_timer_set(uint32_t ms)
{
uint32_t ticks;
cprao_aon_reg1__timer_ao_sleep_clksw__setf(0);
/* aotimer0 init */
if (cprao_aon_clken_grctl__timer_ao_pclk_en__getf() != ENABLE)
{
cprao_aon_clken_grctl__timer_ao_pclk_en__setf(ENABLE);
}
cprao_aon_clken_grctl__timer0_ao_pclk_en__setf(ENABLE);
cprao_aon_clken_grctl__timer1_ao_pclk_en__setf(ENABLE);
cpr_lp_ctl__timer_sysclk_sel__setf(ENABLE);
aotimer_tcr__tes__setf(WAKEUP_TIMER, DISABLE);
aotimer_tcr__tms__setf(WAKEUP_TIMER, (uint8_t)AOTIMER_MODE_SINGLE);
(void)aotimer_tic__tic__getf(WAKEUP_TIMER);
/* aotimer0 set value */
if (clock_cb.lfclk_in == CLOCK_LFCLK_IN_32768) {
ticks = 32 * ms + (768 * ms) / 1000;}
else if (clock_cb.lfclk_in == CLOCK_LFCLK_IN_32K) {
ticks = 32 * ms;}
ticks = ticks < AOTIMER_MIN_TLC_VAL ? AOTIMER_MIN_TLC_VAL : ticks;
aotimer_tcr__tes__setf(WAKEUP_TIMER, AOTIMER_TCR_TES_DISABLE);
aotimer_tlc_set(WAKEUP_TIMER, ticks);
/* aotimer0 start */
NVIC_EnableIRQ(TIMER_AO0_IRQn);
aotimer_tcr__tim__setf(WAKEUP_TIMER, DISABLE);
aotimer_tcr__tes__setf(WAKEUP_TIMER, ENABLE);
// Wait for timer enable
while (aotimer_tcr__tes__getf(WAKEUP_TIMER) != ENABLE)
{
__nop();
}
return ticks;
}
#endif
__RAM_CODE static uint32_t wakeup_timer_set(uint32_t ms)
{
uint32_t ticks;
/* wakeup timer init */
if (cpr_ctlapbclken_grctl__timer_pclk_en__getf() != ENABLE) {
cpr_ctlapbclken_grctl__timer_pclk_en__setf(ENABLE);}
cpr_timer0_clk_ctl__timer_clksel__setf((uint8_t)TIMER_CLK_SRC_32K);
cpr_timer0_clk_ctl__timer_clk0_div__setf((uint8_t)TIMER_DIV_CLK_32000Hz);
cpr_timer0_clk_ctl__timer_clk1_div__setf((uint8_t)TIMER_DIV_CLK_32000Hz);
if (cpr_lp_ctl__timer_sysclk_sel__getf() != ENABLE) {
cpr_lp_ctl__timer_sysclk_sel__setf(ENABLE);}
timer_tcr__tes__setf(WAKEUP_TIMER, TIMER_TCR_TES_DISABLE);
timer_tcr__tms__setf(WAKEUP_TIMER, (uint8_t)TIMER_MODE_SINGLE);
#if !defined(NO_SUPPORT_LFCLK_XTAL_32768)
/* wakeup timer set value */
if (clock_cb.lfclk_in == CLOCK_LFCLK_IN_32768) {
ticks = 32 * ms + (768 * ms) / 1000;}
else if (clock_cb.lfclk_in == CLOCK_LFCLK_IN_32K) {
ticks = 32 * ms;}
#else
ticks = 32 * ms;
#endif
ticks = ticks < TIMER_MIN_TLC_VAL ? TIMER_MIN_TLC_VAL : ticks;
// timer_tcr__tes__setf(WAKEUP_TIMER, TIMER_TCR_TES_DISABLE);
timer_tlc_set(WAKEUP_TIMER, ticks);
/* wakeup timer start */
NVIC_EnableIRQ(TIMER0_IRQn);
timer_tcr__tim__setf(WAKEUP_TIMER, TIMER_TCR_TIM_DISABLE);
timer_tcr__tes__setf(WAKEUP_TIMER, TIMER_TCR_TES_ENABLE);
// Wait for timer enable
while (timer_tcr__tes__getf(WAKEUP_TIMER) != ENABLE)
{
__nop();
}
return ticks;
}
static void bor_init(void)
{
cprao_aon_bor_ctr_reg0__bor_ctrl__setf(0x0);
cprao_aon_bor_ctr_reg0__bor_rstn_mask__setf(1);
cprao_aon_bor_ctr_reg0__bor_intr_mask__setf(0);
NVIC_EnableIRQ(MPU_IRQn);
}
static void system_lightsleep_cfg(void)
{
#if (USE_XIP != 1)
cprao_aon_puctrl1_set(0x4); /* puctrl1= 0x4 , SSI0RX must pulldown*/
#endif
cprao_aon_sys_time_set((RST_READY_TIME << 12) | (OSC32_STABLE_TIME));
xc_pwr_pd_lightsleep_set();
xc_pwr_sleepsrc_mask_set(0x1e001e);
xc_pwr_osc_off();
}
void system_sleep_init(void)
{
uint32_t wake_it_src;
bor_init();
#if (0)
#if !defined(NO_SUPPORT_ROM_FMC_SPI)
#if (USE_XIP == 1)
xc_fmc_spi_init_oprt();
#endif
#else
#if (USE_XIP == 1)
SPI_InitCfg_t spi_cfg = {0};
spi_cfg.Mode = SPI_MODE_MASTER;
spi_cfg.DataSize = SSI_CTRL0_DFS_LEN_8BIT;
spi_cfg.Direction = SSI_CTRL0_TMOD_WR;
spi_cfg.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
spi_cfg.CLKPolarity = SSI_CTRL0_SCPOL_LOW;
spi_cfg.CLKPhase = SPI_CPHA_LEAD;
spi_cfg.FirstBit = SPI_FirstBit_MSB;
xc_spi_init(XC_SPI0, &spi_cfg);
#endif
#endif
#endif
xc_pwr_gpio_sleep_config();
wake_it_src = GPIO_IRQn_WAKE | RTC_IRQn_WAKE | TIMER_AO0_IRQn_WAKE | TIMER0_IRQn_WAKE;
xc_pwr_wake_it_set(wake_it_src);
system_lightsleep_cfg();
}
__RAM_CODE void halSleep(uint32 osal_timeout)
{
uint32 before_sleep_tick, wakeup_timer_set_tick, wakeup_timer_current_tick, wakeup_timer_dlt_tick, wakeup_timer_dlt_us, temp_tick;
if (osal_timeout <= OSASL_MIN_SLEEP_TIME)
return;
NVIC_DisableIRQ(TIMER1_IRQn);
HAL_DISABLE_INTERRUPTS();
/* stop OSAL timer */
timer_tcr__tes__setf(OSAL_TIMER, TIMER_TCR_TES_DISABLE);
/* get before sleep tick */
before_sleep_tick = getMcuPrecisionCount();
/* set sleep time:ms */
wakeup_timer_set_tick = wakeup_timer_set(osal_timeout);
delay_us(100);
/* sleep */
xc_sleep();
xc_rc32k_soft_calib_enable();
wakeup_timer_current_tick = timer_tcv_get(WAKEUP_TIMER);
/* stop wakeup timer */
timer_tcr__tes__setf(WAKEUP_TIMER, TIMER_TCR_TES_DISABLE);
if (wakeup_timer_current_tick < wakeup_timer_set_tick) {
wakeup_timer_dlt_tick = wakeup_timer_set_tick - wakeup_timer_current_tick;}
else {
wakeup_timer_dlt_tick = 0xffffffff - wakeup_timer_current_tick + wakeup_timer_set_tick;}
#if !defined(NO_SUPPORT_LFCLK_XTAL_32768)
if (clock_cb.lfclk_in == CLOCK_LFCLK_IN_32768) {
wakeup_timer_dlt_us = (((wakeup_timer_dlt_tick << 7) - (wakeup_timer_dlt_tick << 2) - (wakeup_timer_dlt_tick << 1)) >> 2) + (((wakeup_timer_dlt_tick << 3) + wakeup_timer_dlt_tick) >> 9);}
else {
wakeup_timer_dlt_us = (wakeup_timer_dlt_tick * 125) >> 2;}
#else
wakeup_timer_dlt_us = (wakeup_timer_dlt_tick * 125) >> 2;
#endif
temp_tick = before_sleep_tick + wakeup_timer_dlt_us / 625;
rtc_time_mod += wakeup_timer_dlt_us % 625;
if (rtc_time_mod > 625)
{
temp_tick++;
rtc_time_mod = rtc_time_mod % 625;
}
/* update system tick */
osal_timer_tick_set(temp_tick);
osal_timer_start();
HAL_ENABLE_INTERRUPTS();
xc_rc32k_soft_calib_disable();
}
__RAM_CODE void MPU_Handler(void)
{
cprao_aon_slp_pd_mask_set(0x001);
#if XTAL_32K
#if !defined(NO_SUPPORT_LFCLK_XTAL_32768)
cprao_aon_ctl_clk32k_set(0x109);
#endif
#endif
printf("MPU_Handler\n");
WDT_InitCfg_t wdt_cfg;
wdt_cfg.WorkMode = WDT_WORK_MODE0;
wdt_cfg.ReloadValue = WDT_CLK_32M_RESET_MODE0_4096US;
wdt_cfg.PclkSel = WDT_WORK_32M;
xc_wdt_init(&wdt_cfg);
xc_wdt_start();
while (1);
}
/**************************************************************************************************
* @fn TimerElapsed
*
* @brief Determine the number of OSAL timer ticks elapsed during sleep.
* Deprecated for CC2538 and CC2430 SoC.
*
* input parameters
*
* @param None.
*
* output parameters
*
* None.
*
* @return Number of timer ticks elapsed during sleep.
**************************************************************************************************
*/
uint32 TimerElapsed( void )
{
/* Stubs */
return (0);
}
/**************************************************************************************************
* @fn halRestoreSleepLevel
*
* @brief Restore the deepest timer sleep level.
*
* input parameters
*
* @param None
*
* output parameters
*
* None.
*
* @return None.
**************************************************************************************************
*/
void halRestoreSleepLevel( void )
{
/* Stubs */
}
+81
View File
@@ -0,0 +1,81 @@
/*!
* \file hal_sleep.c
*
* \brief Target xc6xxx hal spi implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* ------------------------------------------------------------------------------------------------
* Includes
* ------------------------------------------------------------------------------------------------
*/
#include "hal_timer.h"
#include "OSAL_Clock.h"
#include "xc_drv_timer.h"
uint32 sys_tick_cnt;
__RAM_CODE void timer1_callback(void *context)
{
sys_tick_cnt++;
}
__RAM_CODE void osal_timer_init(void)
{
/* timer1 init */
if (cpr_ctlapbclken_grctl__timer_pclk_en__getf() != ENABLE)
cpr_ctlapbclken_grctl__timer_pclk_en__setf(ENABLE);
cpr_timer1_clk_ctl__timer_clksel__setf(TIMER_CLK_SRC_32M_DIV);
cpr_timer1_clk_ctl__timer_clk0_div__setf(TIMER_DIV_CLK_16MHzOr16K);
cpr_timer1_clk_ctl__timer_clk1_div__setf(TIMER_DIV_CLK_16MHzOr16K);
cpr_lp_ctl__timer_sysclk_sel__setf(ENABLE);
timer_tcr__tes__setf(OSAL_TIMER, TIMER_TCR_TES_DISABLE);
timer_tcr__tms__setf(OSAL_TIMER, TIMER_MODE_CYCLE);
/* value set */
timer_tlc_set(OSAL_TIMER, 10000); //625us = 10000tick
/* timer1 start */
NVIC_EnableIRQ(TIMER1_IRQn);
NVIC_SetPriority(TIMER1_IRQn,1);
timer_tcr__tim__setf(OSAL_TIMER, TIMER_TCR_TIM_DISABLE);
timer_tcr__tes__setf(OSAL_TIMER, TIMER_TCR_TES_ENABLE);
return;
}
__RAM_CODE void osal_timer_start(void)
{
NVIC_EnableIRQ(TIMER1_IRQn);
timer_tcr__tim__setf(OSAL_TIMER, TIMER_TCR_TIM_DISABLE);
timer_tcr__tes__setf(OSAL_TIMER, TIMER_TCR_TES_ENABLE);
}
__RAM_CODE void osal_timer_tick_set(uint32 tick)
{
sys_tick_cnt = tick;
}
__RAM_CODE uint32 getMcuPrecisionCount(void)
{
return sys_tick_cnt;
}
+101
View File
@@ -0,0 +1,101 @@
/*!
* \file hal_types.h
*
* \brief The header of hal_types.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef _HAL_TYPES_H
#define _HAL_TYPES_H
/* ------------------------------------------------------------------------------------------------
* Types
* ------------------------------------------------------------------------------------------------
*/
typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef signed long int32;
typedef unsigned long uint32;
//typedef unsigned char bool;
typedef uint32 halDataAlign_t;
#define POWER_SAVING
/* ------------------------------------------------------------------------------------------------
* Memory Attributes and Compiler Macros
* ------------------------------------------------------------------------------------------------
*/
/* ----------- IAR Compiler ----------- */
#ifdef __IAR_SYSTEMS_ICC__
#define CODE __code
#define XDATA __xdata
#define ASM_NOP asm("NOP")
/* ----------- KEIL Compiler ----------- */
#elif defined __KEIL__
#define CODE code
#define XDATA xdata
#define ASM_NOP __nop()
/* ----------- CCS Compiler ----------- */
#elif defined __TI_COMPILER_VERSION
#define ASM_NOP asm(" NOP")
/* ----------- GNU Compiler ----------- */
#elif defined __GNUC__
#define ASM_NOP __asm__ __volatile__ ("nop")
/* ---------- MSVC compiler ---------- */
#elif _MSC_VER
#define ASM_NOP __asm NOP
/* ----------- Unrecognized Compiler ----------- */
#else
#error "ERROR: Unknown compiler."
#endif
/* ------------------------------------------------------------------------------------------------
* Standard Defines
* ------------------------------------------------------------------------------------------------
*/
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
/**************************************************************************************************
*/
#endif
File diff suppressed because it is too large Load Diff
+368
View File
@@ -0,0 +1,368 @@
/*!
* \file OSAL_Clock.c
*
* \brief Target xc6xxx hal spi implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*********************************************************************
* INCLUDES
*/
#include "comdef.h"
#include "hal_board.h"
#include "OnBoard.h"
#include "OSAL.h"
#include "OSAL_Clock.h"
/*********************************************************************
* MACROS
*/
#define YearLength(yr) ((uint16)(IsLeapYear(yr) ? 366 : 365))
/*********************************************************************
* CONSTANTS
*/
// (MAXCALCTICKS * 5) + (max remainder) must be <= (uint16 max),
// so: (13105 * 5) + 7 <= 65535
#define MAXCALCTICKS ((uint16)(13105))
#define BEGYEAR 2000 // UTC started at 00:00:00 January 1, 2000
#define DAY 86400UL // 24 hours * 60 minutes * 60 seconds
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
extern uint32 getMcuPrecisionCount(void);
#define CONVERT_MS_TO_S_ELAPSED_REMAINDER( x, y, z ) st( \
y += x / 1000; \
z = x % 1000; \
)
/*********************************************************************
* LOCAL VARIABLES
*/
#ifndef USE_ICALL
static uint32 previousMacTimerTick = 0;
static uint16 remUsTicks = 0;
#endif /* !USE_ICALL */
static uint32 timeMSec = 0;
// number of seconds since 0 hrs, 0 minutes, 0 seconds, on the
// 1st of January 2000 UTC
UTCTime OSAL_timeSeconds = 0;
/*********************************************************************
* LOCAL FUNCTION PROTOTYPES
*/
static uint8 monthLength( uint8 lpyr, uint8 mon );
static void osalClockUpdate( uint32 elapsedMSec );
/*********************************************************************
* FUNCTIONS
*********************************************************************/
/*********************************************************************
* @fn osalTimeUpdate
*
* @brief Uses the free running rollover count of the MAC backoff timer;
* this timer runs freely with a constant 320 usec interval. The
* count of 320-usec ticks is converted to msecs and used to update
* the OSAL clock and Timers by invoking osalClockUpdate() and
* osalTimerUpdate(). This function is intended to be invoked
* from the background, not interrupt level.
*
* @param None.
*
* @return None.
*/
void osalTimeUpdate( void )
{
#ifndef USE_ICALL
/* Note that when ICall is in use the OSAL tick is not updated
* in this fashion but rather through real OS timer tick. */
//halIntState_t intState;
uint32 tmp;
uint16 ticks625us;
uint16 elapsedMSec = 0;
HAL_ENTER_CRITICAL_SECTION();
// Get the free-running count of 320us timer ticks
tmp = getMcuPrecisionCount();
HAL_EXIT_CRITICAL_SECTION();
if ( tmp != previousMacTimerTick )
{
// Calculate the elapsed ticks of the free-running timer.
ticks625us = tmp > previousMacTimerTick ? (tmp - previousMacTimerTick):(0xffffffffu)&(0x100000000 - previousMacTimerTick + tmp);
// Store the LL Timer tick count for the next time through this function.
previousMacTimerTick = tmp;
/* It is necessary to loop to convert the usecs to msecs in increments so as
* not to overflow the 16-bit variables.
*/
while ( ticks625us > MAXCALCTICKS )
{
ticks625us -= MAXCALCTICKS;
elapsedMSec += MAXCALCTICKS * 5 / 8;
remUsTicks += MAXCALCTICKS * 5 % 8;
}
// update converted number with remaining ticks from loop and the
// accumulated remainder from loop
tmp = (ticks625us * 5) + remUsTicks;
// Convert the 625 us ticks into milliseconds and a remainder
elapsedMSec += tmp / 8;
remUsTicks = tmp % 8;
// Update OSAL Clock and Timers
if ( elapsedMSec )
{
osalClockUpdate( elapsedMSec );
osalTimerUpdate( elapsedMSec );
}
}
#endif /* USE_ICALL */
}
/*********************************************************************
* @fn osalClockUpdate
*
* @brief Updates the OSAL Clock time with elapsed milliseconds.
*
* @param elapsedMSec - elapsed milliseconds
*
* @return none
*/
static void osalClockUpdate( uint32 elapsedMSec )
{
uint32 tmp;
//halIntState_t intState;
HAL_ENTER_CRITICAL_SECTION();
// Add elapsed milliseconds to the saved millisecond portion of time
timeMSec += elapsedMSec;
// Roll up milliseconds to the number of seconds
if ( timeMSec >= 1000 )
{
tmp = timeMSec;
CONVERT_MS_TO_S_ELAPSED_REMAINDER(tmp, OSAL_timeSeconds, timeMSec);
}
HAL_EXIT_CRITICAL_SECTION();
}
#if defined HAL_BOARD_CC2538 || defined USE_ICALL
/*********************************************************************
* @fn osalAdjustTimer
*
* @brief Updates the OSAL Clock and Timer with elapsed milliseconds.
*
* @param MSec - elapsed milliseconds
*
* @return none
*/
void osalAdjustTimer(uint32 Msec )
{
/* Disable SysTick interrupts */
SysTickIntDisable();
osalClockUpdate(Msec);
osalTimerUpdate(Msec);
/* Enable SysTick interrupts */
SysTickIntEnable();
}
#endif /* HAL_BOARD_CC2538 || USE_ICALL */
/*********************************************************************
* @fn osal_setClock
*
* @brief Set the new time. This will only set the seconds portion
* of time and doesn't change the factional second counter.
*
* @param newTime - number of seconds since 0 hrs, 0 minutes,
* 0 seconds, on the 1st of January 2000 UTC
*
* @return none
*/
void osal_setClock( UTCTime newTime )
{
HAL_CRITICAL_STATEMENT(OSAL_timeSeconds = newTime);
}
/*********************************************************************
* @fn osal_getClock
*
* @brief Gets the current time. This will only return the seconds
* portion of time and doesn't include the factional second
* counter.
*
* @param none
*
* @return number of seconds since 0 hrs, 0 minutes, 0 seconds,
* on the 1st of January 2000 UTC
*/
UTCTime osal_getClock( void )
{
return ( OSAL_timeSeconds );
}
/*********************************************************************
* @fn osal_ConvertUTCTime
*
* @brief Converts UTCTime to UTCTimeStruct
*
* @param tm - pointer to breakdown struct
*
* @param secTime - number of seconds since 0 hrs, 0 minutes,
* 0 seconds, on the 1st of January 2000 UTC
*
* @return none
*/
void osal_ConvertUTCTime( UTCTimeStruct *tm, UTCTime secTime )
{
// calculate the time less than a day - hours, minutes, seconds
{
uint32 day = secTime % DAY;
tm->seconds = day % 60UL;
tm->minutes = (day % 3600UL) / 60UL;
tm->hour = day / 3600UL;
}
// Fill in the calendar - day, month, year
{
uint16 numDays = secTime / DAY;
tm->year = BEGYEAR;
while ( numDays >= YearLength( tm->year ) )
{
numDays -= YearLength( tm->year );
tm->year++;
}
tm->month = 0;
while ( numDays >= monthLength( IsLeapYear( tm->year ), tm->month ) )
{
numDays -= monthLength( IsLeapYear( tm->year ), tm->month );
tm->month++;
}
tm->day = numDays;
}
}
/*********************************************************************
* @fn monthLength
*
* @param lpyr - 1 for leap year, 0 if not
*
* @param mon - 0 - 11 (jan - dec)
*
* @return number of days in specified month
*/
static uint8 monthLength( uint8 lpyr, uint8 mon )
{
uint8 days = 31;
if ( mon == 1 ) // feb
{
days = ( 28 + lpyr );
}
else
{
if ( mon > 6 ) // aug-dec
{
mon--;
}
if ( mon & 1 )
{
days = 30;
}
}
return ( days );
}
/*********************************************************************
* @fn osal_ConvertUTCSecs
*
* @brief Converts a UTCTimeStruct to UTCTime
*
* @param tm - pointer to provided struct
*
* @return number of seconds since 00:00:00 on 01/01/2000 (UTC)
*/
UTCTime osal_ConvertUTCSecs( UTCTimeStruct *tm )
{
uint32 seconds;
/* Seconds for the partial day */
seconds = (((tm->hour * 60UL) + tm->minutes) * 60UL) + tm->seconds;
/* Account for previous complete days */
{
/* Start with complete days in current month */
uint16 days = tm->day;
/* Next, complete months in current year */
{
int8 month = tm->month;
while ( --month >= 0 )
{
days += monthLength( IsLeapYear( tm->year ), month );
}
}
/* Next, complete years before current year */
{
uint16 year = tm->year;
while ( --year >= BEGYEAR )
{
days += YearLength( year );
}
}
/* Add total seconds before partial day */
seconds += (days * DAY);
}
return ( seconds );
}
+626
View File
@@ -0,0 +1,626 @@
/*!
* \file OSAL_Memory.c
*
* \brief Target xc6xxx hal spi implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* ------------------------------------------------------------------------------------------------
* Includes
* ------------------------------------------------------------------------------------------------
*/
#include <stdlib.h>
#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(); // 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(); // 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(); // 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(); // 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(); // 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(); // 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
/**************************************************************************************************
*/
+251
View File
@@ -0,0 +1,251 @@
/*!
* \file OSAL_pwrmgr.c
*
* \brief Target xc6xxx hal spi implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*********************************************************************
* INCLUDES
*/
#include "comdef.h"
#include "OnBoard.h"
#include "OSAL.h"
#include "OSAL_Tasks.h"
#include "OSAL_Timers.h"
#include "OSAL_PwrMgr.h"
// #include "ZGlobals.h"
#ifdef USE_ICALL
#include <ICall.h>
#endif /* USE_ICALL */
#ifdef OSAL_PORT2TIRTOS
/* Direct port to TI-RTOS API */
#if defined CC26XX
#include <ti/sysbios/family/arm/cc26xx/Power.h>
#include <ti/sysbios/family/arm/cc26xx/PowerCC2650.h>
#endif /* CC26XX */
#endif /* OSAL_PORT2TIRTOS */
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
/* This global variable stores the power management attributes.
*/
pwrmgr_attribute_t pwrmgr_attribute;
#if defined USE_ICALL || defined OSAL_PORT2TIRTOS
uint8 pwrmgr_initialized = FALSE;
#endif /* defined USE_ICALL || defined OSAL_PORT2TIRTOS */
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
/*********************************************************************
* LOCAL FUNCTION PROTOTYPES
*/
/*********************************************************************
* FUNCTIONS
*********************************************************************/
/*********************************************************************
* @fn osal_pwrmgr_init
*
* @brief Initialize the power management system.
*
* @param none.
*
* @return none.
*/
void osal_pwrmgr_init( void )
{
#if !defined USE_ICALL && !defined OSAL_PORT2TIRTOS
#if defined POWER_SAVING && ZSTACK_END_DEVICE_BUILD
pwrmgr_attribute.pwrmgr_device = PWRMGR_BATTERY; // Default to power conservation for ZED if power saving enabled.
#else
pwrmgr_attribute.pwrmgr_device = PWRMGR_ALWAYS_ON; // No power conservation for routing devices.
#endif
#endif /* USE_ICALL */
pwrmgr_attribute.pwrmgr_task_state = 0; // Cleared. All set to conserve
#if defined USE_ICALL || defined OSAL_PORT2TIRTOS
pwrmgr_initialized = TRUE;
#endif /* defined USE_ICALL || defined OSAL_PORT2TIRTOS */
}
#if !defined USE_ICALL && !defined OSAL_PORT2TIRTOS
/*********************************************************************
* @fn osal_pwrmgr_device
*
* @brief Sets the device power characteristic.
*
* @param pwrmgr_device - type of power devices. With PWRMGR_ALWAYS_ON
* selection, there is no power savings and the device is most
* likely on mains power. The PWRMGR_BATTERY selection allows the
* HAL sleep manager to enter sleep.
*
* @return none
*/
void osal_pwrmgr_device( uint8 pwrmgr_device )
{
pwrmgr_attribute.pwrmgr_device = pwrmgr_device;
}
#endif /* !defined USE_ICALL && !defined OSAL_PORT2TIRTOS*/
/*********************************************************************
* @fn osal_pwrmgr_task_state
*
* @brief This function is called by each task to state whether or
* not this task wants to conserve power.
*
* @param task_id - calling task ID.
* state - whether the calling task wants to
* conserve power or not.
*
* @return SUCCESS if task complete
*/
uint8 osal_pwrmgr_task_state( uint8 task_id, uint8 state )
{
//halIntState_t intState;
if ( task_id >= tasksCnt )
return ( INVALID_TASK );
#if defined USE_ICALL || defined OSAL_PORT2TIRTOS
if ( !pwrmgr_initialized )
{
/* If voting is made before this module is initialized,
* pwrmgr_task_state will reset later when the module is
* initialized, and cause incorrect activity count.
*/
return ( SUCCESS );
}
#endif /* defined USE_ICALL || defined OSAL_PORT2TIRTOS */
HAL_ENTER_CRITICAL_SECTION();
if ( state == PWRMGR_CONSERVE )
{
#if defined USE_ICALL || defined OSAL_PORT2TIRTOS
uint16 cache = pwrmgr_attribute.pwrmgr_task_state;
#endif /* defined USE_ICALL || defined OSAL_PORT2TIRTOS */
// Clear the task state flag
pwrmgr_attribute.pwrmgr_task_state &= ~(1 << task_id );
#if defined USE_ICALL || defined OSAL_PORT2TIRTOS
if (cache != 0 && pwrmgr_attribute.pwrmgr_task_state == 0)
{
#ifdef USE_ICALL
/* Decrement activity counter */
ICall_pwrUpdActivityCounter(FALSE);
#else /* USE_ICALL */
Power_releaseConstraint(Power_SD_DISALLOW);
Power_releaseConstraint(Power_SB_DISALLOW);
#endif /* USE_ICALL */
}
#endif /* defined USE_ICALL || defined OSAL_PORT2TIRTOS */
}
else
{
#if defined USE_ICALL || defined OSAL_PORT2TIRTOS
if (pwrmgr_attribute.pwrmgr_task_state == 0)
{
#ifdef USE_ICALL
/* Increment activity counter */
ICall_pwrUpdActivityCounter(TRUE);
#else /* USE_ICALL */
Power_setConstraint(Power_SD_DISALLOW);
Power_setConstraint(Power_SB_DISALLOW);
#endif /* USE_ICALL */
}
#endif /* defined USE_ICALL || defined OSAL_PORT2TIRTOS */
// Set the task state flag
pwrmgr_attribute.pwrmgr_task_state |= (1 << task_id);
}
HAL_EXIT_CRITICAL_SECTION();
return ( SUCCESS );
}
#if defined( POWER_SAVING ) && !(defined USE_ICALL || defined OSAL_PORT2TIRTOS)
/*********************************************************************
* @fn osal_pwrmgr_powerconserve
*
* @brief This function is called from the main OSAL loop when there are
* no events scheduled and shouldn't be called from anywhere else.
*
* @param none.
*
* @return none.
*/
void osal_pwrmgr_powerconserve( void )
{
#if (SLEEP_ENABLE)
uint32 next;
//halIntState_t intState;
// Should we even look into power conservation
if ( pwrmgr_attribute.pwrmgr_device != PWRMGR_ALWAYS_ON )
{
// Are all tasks in agreement to conserve
if ( pwrmgr_attribute.pwrmgr_task_state == 0 )
{
// Hold off interrupts.
HAL_ENTER_CRITICAL_SECTION();
// Get next time-out
next = osal_next_timeout();
// Re-enable interrupts.
HAL_EXIT_CRITICAL_SECTION();
// Put the processor into sleep mode
OSAL_SET_CPU_INTO_SLEEP( next );
}
}
#endif
}
#endif /* POWER_SAVING */
/*********************************************************************
*********************************************************************/
+335
View File
@@ -0,0 +1,335 @@
/*!
* \file OSAL_Task.c
*
* \brief Target xc6xxx hal spi implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if 0 // TODO
#include "FreeRTOS.h"
#include "task.h"
#include "StackMacros.h"
#include "osal_task.h"
/*---------------------------------------------------------------------------------------
Name: osal_task_create
Purpose: Creates a task
Parameters:
task_func Pointer to the task entry function. Tasks must be implemented to never
return (i.e. continuous loop).
task_name A descriptive name for the task. This is mainly used to facilitate
debugging. Max length defined by MAX_TASK_NAME_LEN.
stack_depth 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 stack_depth 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.
task_func_parameters Pointer that will be used as the parameter for the task being
created.
task_priority The priority at which the task should run.
task_handle Used to pass back a handle by which the created task can be referenced.
returns: OSAL_SUCCESS if the task was successfully created and added to a ready list
OSAL_ERROR
NOTES: handle is passed back to the user by which the created task can be referenced.
---------------------------------------------------------------------------------------*/
int32 osal_task_create( void (*task_func)( void * ), const int8 *task_name, uint16 stack_depth,
void *task_func_parameters, uint32 task_priority, void **task_handle )
{
int32 status ;
if(( task_func == NULL ) || ( task_name == NULL ))
{
return OSAL_ERROR;
}
if(strlen((const char *)task_name) >= OSAL_MAX_TASK_NAME_LEN)
{
return OSAL_ERROR;
}
if ( task_priority > OSAL_MAX_PRIORITY )
{
return OSAL_ERROR;
}
status = xTaskCreate( task_func, task_name, stack_depth, task_func_parameters, task_priority, task_handle );
return status;
}
/*---------------------------------------------------------------------------------------
Name: osal_task_delete
Purpose: Deletes a task
Parameters:
task_handle The handle of the task to be deleted. Passing NULL will cause the calling
task to be deleted
returns:
void
---------------------------------------------------------------------------------------*/
void osal_task_delete( void **task_handle )
{
vTaskDelete( task_handle );
}
/*---------------------------------------------------------------------------------------
Name: osal_task_suspend
Purpose: suspends a task. Passing a NULL handle will cause the calling task to
be suspended.
Parameters:
task_handle Handle to the task being suspended. Passing a NULL handle will cause
the calling task to be suspended.
returns:
void
---------------------------------------------------------------------------------------*/
void osal_task_suspend( void **task_handle )
{
vTaskSuspend( task_handle );
}
/*---------------------------------------------------------------------------------------
Name: osal_task_resume
Purpose: resumes a suspended task
Parameters:
task_handle Handle to the task being readied.
returns: OSAL_ERROR if error
OSAL_SUCCESS if success
---------------------------------------------------------------------------------------*/
void osal_task_resume( void **task_handle )
{
vTaskResume( task_handle );
}
/*---------------------------------------------------------------------------------------
Name: osal_task_priority_get
Purpose: gets the priority of the task.
Parameters:
task_handle Handle to the task for which the priority is being set. Passing a NULL
handle results in the priority of the calling task being returned.
returns: The priority of task
---------------------------------------------------------------------------------------*/
uint32 osal_task_priority_get( void **task_handle )
{
uint32 status;
status = uxTaskPriorityGet( task_handle );
return status;
}
/*---------------------------------------------------------------------------------------
Name: osal_task_priority_set
Purpose: sets the priority of the task.
Parameters:
task_handle 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.
task_priority The priority to which the task will be set.
returns: The priority of task
---------------------------------------------------------------------------------------*/
void osal_task_priority_set( void **task_handle, uint32 task_priority )
{
vTaskPrioritySet( task_handle, task_priority );
}
/*---------------------------------------------------------------------------------------
Name: osal_task_delay
Purpose: Delay a task for a given number of ticks. The actual time that the task remains
blocked depends on the tick rate. The constant TICK_RATE_MS can be used to
calculate real time from the tick rate - with the resolution of one tick period.
Parameters:
ticks_to_delay The amount of time, in tick periods, that the calling task should
block
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_delay( uint32 ticks_to_delay )
{
vTaskDelay( ticks_to_delay );
}
/*---------------------------------------------------------------------------------------
Name: osal_task_delay_until
Purpose: Delay a task until a specified time. This function can be used by cyclical
tasks to ensure a constant execution frequency.
Parameters:
prev_wake_time 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.
time_increment The cycle time period. The task will be unblocked at time
(prev_wake_time+time_increment). Calling osal_task_delay_until with
the same time_increment parameter value will cause the task to execute
with a fixed interval period
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_delay_until( uint32* const prev_wake_time, uint32 time_increment )
{
vTaskDelayUntil( prev_wake_time, time_increment );
}
/*---------------------------------------------------------------------------------------
Name: osal_task_start_scheduler
Purpose: Starts the real time kernel tick processing. After calling the kernel has control
over which tasks are executed and when.
Parameters:
void
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_start_scheduler( void )
{
vTaskStartScheduler();
}
/*---------------------------------------------------------------------------------------
Name: osal_task_end_scheduler
Purpose: 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
Parameters:
void
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_end_scheduler( void )
{
vTaskEndScheduler();
}
/*---------------------------------------------------------------------------------------
Name: osal_task_suspend_all
Purpose: Suspends all real time kernel activity while keeping interrupts (including
the kernel tick) enabled.
Parameters:
void
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_suspend_all( void )
{
vTaskSuspendAll();
}
/*---------------------------------------------------------------------------------------
Name: osal_task_resume_all
Purpose: Resumes real time kernel activity following a call to osal_task_suspend_all().
After a call to osal_task_suspend_all() the kernel will take control of which
task is executing at any time.
Parameters:
void
Returns
True or False. True if context switch happens, else false
---------------------------------------------------------------------------------------*/
long osal_task_resume_all( void )
{
return ( xTaskResumeAll() );
}
/*---------------------------------------------------------------------------------------
Name: osal_task_yield
Purpose: Forces a context switch.
Parameters:
void
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_yield( void )
{
taskYIELD();
}
/*---------------------------------------------------------------------------------------
Name: osal_queue_create
Purpose: Creates a queue, used to pass items between tasks.
Parameters:
max_items Maximum number of items that the queue can contain.
item_size Size, in bytes, of each item in the queue.
Returns
void* Ptr to queue handle
---------------------------------------------------------------------------------------*/
void *osal_queue_create( uint32 max_items, uint32 item_size )
{
return ( xQueueCreate( max_items, item_size ) );
}
/*---------------------------------------------------------------------------------------
Name: osal_queue_receive
Purpose: Receives (reads) an item from a queue.
Parameters:
handle Pointer to handle of the queue from which data is received.
buffer Pointer to memory into which received data will be copied.
wait_ticks Maximum time to block task waiting for data to be available.
Returns
status OSAL_SUCCESS is read successful, OSAL_ERROR if data not read
---------------------------------------------------------------------------------------*/
uint32 osal_queue_receive( void *handle, void *buffer, uint32 wait_ticks )
{
return ( xQueueReceive( handle, buffer, wait_ticks ) );
}
/*---------------------------------------------------------------------------------------
Name: osal_queue_send
Purpose: Sends (writes) an item to a queue.
Parameters:
handle Pointer to handle of the queue to which data is written.
buffer Pointer to memory from which data will be copied.
wait_ticks Maximum time to block task waiting for space to be available.
Returns
status OSAL_SUCCESS is send successful, OSAL_ERROR if data not written
---------------------------------------------------------------------------------------*/
uint32 osal_queue_send( void *handle, void *buffer, uint32 wait_ticks )
{
return ( xQueueSend( handle, buffer, wait_ticks ) );
}
#endif
+600
View File
@@ -0,0 +1,600 @@
/*!
* \file OSAL_Timers.c
*
* \brief Target xc6xxx hal spi implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*********************************************************************
* 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(); // Hold off interrupts.
// Add timer
newTimer = osalAddTimer( taskID, event_id, timeout_value );
HAL_EXIT_CRITICAL_SECTION(); // 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(); // 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(); // 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(); // Hold off interrupts.
// Find the timer to stop
foundTimer = osalFindTimer( task_id, event_id );
if ( foundTimer )
{
osalDeleteTimer( foundTimer );
}
HAL_EXIT_CRITICAL_SECTION(); // 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(); // Hold off interrupts.
tmr = osalFindTimer( task_id, event_id );
if ( tmr )
{
rtrn = tmr->timeout.time32;
}
HAL_EXIT_CRITICAL_SECTION(); // 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(); // 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(); // 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(); // Hold off interrupts.
// Update the system time
osal_systemClock += updateTime;
HAL_EXIT_CRITICAL_SECTION(); // 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(); // 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(); // 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 );
}
/*********************************************************************
*********************************************************************/
+343
View File
@@ -0,0 +1,343 @@
/*!
* \file OSAL.h
*
* \brief The header of OSAL.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef OSAL_H
#define OSAL_H
#ifdef __cplusplus
extern "C"
{
#endif
/*********************************************************************
* INCLUDES
*/
#include <limits.h>
#include "comdef.h"
#include "OSAL_Memory.h"
#include "OSAL_Timers.h"
#ifdef USE_ICALL
#include <ICall.h>
#endif /* USE_ICALL */
/*********************************************************************
* MACROS
*/
#if ( UINT_MAX == 65535 ) /* 8-bit and 16-bit devices */
#define osal_offsetof(type, member) ((uint16) &(((type *) 0)->member))
#else /* 32-bit devices */
#define osal_offsetof(type, member) ((uint32) &(((type *) 0)->member))
#endif
#define OSAL_MSG_NEXT(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->next
#define OSAL_MSG_Q_INIT(q_ptr) *(q_ptr) = NULL
#define OSAL_MSG_Q_EMPTY(q_ptr) (*(q_ptr) == NULL)
#define OSAL_MSG_Q_HEAD(q_ptr) (*(q_ptr))
#define OSAL_MSG_LEN(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->len
#define OSAL_MSG_ID(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->dest_id
/*********************************************************************
* CONSTANTS
*/
/*** Interrupts ***/
#define INTS_ALL 0xFF
/*********************************************************************
* TYPEDEFS
*/
#ifdef USE_ICALL
typedef ICall_MsgHdr osal_msg_hdr_t;
#else /* USE_ICALL */
typedef struct
{
void *next;
#ifdef OSAL_PORT2TIRTOS
/* Limited OSAL port to TI-RTOS requires compatibility with ROM
* code compiled with USE_ICALL compile flag. */
uint32 reserved;
#endif /* OSAL_PORT2TIRTOS */
uint16 len;
uint8 dest_id;
} osal_msg_hdr_t;
#endif /* USE_ICALL */
typedef struct
{
uint8 event;
uint8 status;
} osal_event_hdr_t;
typedef void * osal_msg_q_t;
#ifdef USE_ICALL
/* High resolution timer callback function type */
typedef void (*osal_highres_timer_cback_t)(void *arg);
#endif /* USE_ICALL */
/*********************************************************************
* GLOBAL VARIABLES
*/
#ifdef USE_ICALL
extern ICall_Semaphore osal_semaphore;
extern ICall_EntityID osal_entity;
extern uint_least32_t osal_tickperiod;
extern void (*osal_eventloop_hook)(void);
#endif /* USE_ICALL */
/*********************************************************************
* FUNCTIONS
*/
/*** Message Management ***/
/*
* Task Message Allocation
*/
extern uint8 * osal_msg_allocate(uint16 len );
/*
* Task Message Deallocation
*/
extern uint8 osal_msg_deallocate( uint8 *msg_ptr );
/*
* Send a Task Message
*/
extern uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr );
/*
* Push a Task Message to head of queue
*/
extern uint8 osal_msg_push_front( uint8 destination_task, uint8 *msg_ptr );
/*
* Receive a Task Message
*/
extern uint8 *osal_msg_receive( uint8 task_id );
/*
* Find in place a matching Task Message / Event.
*/
extern osal_event_hdr_t *osal_msg_find(uint8 task_id, uint8 event);
/*
* Count the number of queued OSAL messages matching Task ID / Event.
*/
extern uint8 osal_msg_count(uint8 task_id, uint8 event);
/*
* Enqueue a Task Message
*/
extern void osal_msg_enqueue( osal_msg_q_t *q_ptr, void *msg_ptr );
/*
* Enqueue a Task Message Up to Max
*/
extern uint8 osal_msg_enqueue_max( osal_msg_q_t *q_ptr, void *msg_ptr, uint8 max );
/*
* Dequeue a Task Message
*/
extern void *osal_msg_dequeue( osal_msg_q_t *q_ptr );
/*
* Push a Task Message to head of queue
*/
extern void osal_msg_push( osal_msg_q_t *q_ptr, void *msg_ptr );
/*
* Extract and remove a Task Message from queue
*/
extern void osal_msg_extract( osal_msg_q_t *q_ptr, void *msg_ptr, void *prev_ptr );
#ifdef USE_ICALL
extern ICall_Errno osal_service_entry(ICall_FuncArgsHdr *args);
#endif /* USE_ICALL */
/*** Task Synchronization ***/
/*
* Set a Task Event
*/
extern uint8 osal_set_event( uint8 task_id, uint16 event_flag );
/*
* Clear a Task Event
*/
extern uint8 osal_clear_event( uint8 task_id, uint16 event_flag );
/*** Interrupt Management ***/
/*
* Register Interrupt Service Routine (ISR)
*/
extern uint8 osal_isr_register( uint8 interrupt_id, void (*isr_ptr)( uint8* ) );
/*
* Enable Interrupt
*/
extern uint8 osal_int_enable( uint8 interrupt_id );
/*
* Disable Interrupt
*/
extern uint8 osal_int_disable( uint8 interrupt_id );
/*** Task Management ***/
#ifdef USE_ICALL
/*
* Enroll dispatcher registered entity ID
*/
extern void osal_enroll_dispatchid(uint8 taskid,
ICall_EntityID dispatchid);
/*
* Enroll an OSAL task to use another OSAL task's enrolled entity ID
* when sending a message.
*/
extern void osal_enroll_senderid(uint8 taskid, ICall_EntityID dispatchid);
/*
* Enroll entity ID to be used as sender entity ID for non OSAL task
*/
extern void osal_enroll_notasksender(ICall_EntityID dispatchid);
#endif /* USE_ICALL */
/*
* Initialize the Task System
*/
extern uint8 osal_init_system( void );
/*
* System Processing Loop
*/
#if defined (ZBIT)
extern __declspec(dllexport) void osal_start_system( void );
#else
extern void osal_start_system( void );
#endif
/*
* One Pass Throu the OSAL Processing Loop
*/
extern void osal_run_system( void );
/*
* Get the active task ID
*/
extern uint8 osal_self( void );
/*** Helper Functions ***/
/*
* String Length
*/
extern int osal_strlen( char *pString );
/*
* Memory copy
*/
extern void *osal_memcpy( void*, const void GENERIC *, unsigned int );
/*
* Memory Duplicate - allocates and copies
*/
extern void *osal_memdup( const void GENERIC *src, unsigned int len );
/*
* Reverse Memory copy
*/
extern void *osal_revmemcpy( void*, const void GENERIC *, unsigned int );
/*
* Memory compare
*/
extern uint8 osal_memcmp( const void GENERIC *src1, const void GENERIC *src2, unsigned int len );
/*
* Memory set
*/
extern void *osal_memset( void *dest, uint8 value, int len );
/*
* Build a uint16 out of 2 bytes (0 then 1).
*/
extern uint16 osal_build_uint16( uint8 *swapped );
/*
* Build a uint32 out of sequential bytes.
*/
extern uint32 osal_build_uint32( uint8 *swapped, uint8 len );
/*
* Convert long to ascii string
*/
#if !defined ( ZBIT ) && !defined ( ZBIT2 ) && !defined (UBIT)
extern uint8 *_ltoa( uint32 l, uint8 * buf, uint8 radix );
#endif
/*
* Random number generator
*/
extern uint16 osal_rand( void );
/*
* Buffer an uint32 value - LSB first.
*/
extern uint8* osal_buffer_uint32( uint8 *buf, uint32 val );
/*
* Buffer an uint24 value - LSB first
*/
extern uint8* osal_buffer_uint24( uint8 *buf, uint24 val );
/*
* Is all of the array elements set to a value?
*/
extern uint8 osal_isbufset( uint8 *buf, uint8 val, uint8 len );
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* OSAL_H */
+124
View File
@@ -0,0 +1,124 @@
/*!
* \file OSAL_Clock.h
*
* \brief The header of OSAL_Clock.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef OSAL_CLOCK_H
#define OSAL_CLOCK_H
#ifdef __cplusplus
extern "C"
{
#endif
/*********************************************************************
* INCLUDES
*/
/*********************************************************************
* MACROS
*/
#define IsLeapYear(yr) (!((yr) % 400) || (((yr) % 100) && !((yr) % 4)))
/*********************************************************************
* CONSTANTS
*/
/*********************************************************************
* TYPEDEFS
*/
// number of seconds since 0 hrs, 0 minutes, 0 seconds, on the
// 1st of January 2000 UTC
typedef uint32 UTCTime;
// To be used with
typedef struct
{
uint8 seconds; // 0-59
uint8 minutes; // 0-59
uint8 hour; // 0-23
uint8 day; // 0-30
uint8 month; // 0-11
uint16 year; // 2000+
} UTCTimeStruct;
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* FUNCTIONS
*/
/*
* Updates the OSAL clock and Timers from the MAC 320us timer tick.
*/
extern void osalTimeUpdate( void );
/*
* Set the new time. This will only set the seconds portion
* of time and doesn't change the factional second counter.
* newTime - number of seconds since 0 hrs, 0 minutes,
* 0 seconds, on the 1st of January 2000 UTC
*/
extern void osal_setClock( UTCTime newTime );
/*
* Gets the current time. This will only return the seconds
* portion of time and doesn't include the factional second counter.
* returns: number of seconds since 0 hrs, 0 minutes,
* 0 seconds, on the 1st of January 2000 UTC
*/
extern UTCTime osal_getClock( void );
/*
* Converts UTCTime to UTCTimeStruct
*
* secTime - number of seconds since 0 hrs, 0 minutes,
* 0 seconds, on the 1st of January 2000 UTC
* tm - pointer to breakdown struct
*/
extern void osal_ConvertUTCTime( UTCTimeStruct *tm, UTCTime secTime );
/*
* Converts UTCTimeStruct to UTCTime (seconds since 00:00:00 01/01/2000)
*
* tm - pointer to UTC time struct
*/
extern UTCTime osal_ConvertUTCSecs( UTCTimeStruct *tm );
/*
* Update/Adjust the osal clock and timers
* Msec - elapsed time in milli seconds
*/
extern void osalAdjustTimer( uint32 Msec );
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* OSAL_CLOCK_H */
+130
View File
@@ -0,0 +1,130 @@
/*!
* \file OSAL_Memory.h
*
* \brief The header of OSAL_Memory.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#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 TRUE
#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 */
+124
View File
@@ -0,0 +1,124 @@
/*!
* \file OSAL_Nv.h
*
* \brief The header of OSAL_Nv.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef OSAL_NV_H
#define OSAL_NV_H
#ifdef __cplusplus
extern "C"
{
#endif
/*********************************************************************
* INCLUDES
*/
#include "hal_types.h"
/*********************************************************************
* CONSTANTS
*/
/*********************************************************************
* MACROS
*/
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* FUNCTIONS
*/
/*
* Initialize NV service
*/
extern void osal_nv_init( void *p );
/*
* Initialize an item in NV
*/
extern uint8 osal_nv_item_init( uint16 id, uint16 len, void *buf );
/*
* Read an NV attribute
*/
extern uint8 osal_nv_read( uint16 id, uint16 offset, uint16 len, void *buf );
/*
* Write an NV attribute
*/
extern uint8 osal_nv_write( uint16 id, uint16 offset, uint16 len, void *buf );
/*
* Get the length of an NV item.
*/
extern uint16 osal_nv_item_len( uint16 id );
/*
* Delete an NV item.
*/
extern uint8 osal_nv_delete( uint16 id, uint16 len );
#if defined ( OSAL_NV_EXTENDED )
/*
* Initialize an item in NV (extended format)
*/
extern uint8 osal_nv_item_init_ex( uint16 id, uint16 subId, uint16 len, void *buf );
/*
* Read an NV attribute (extended format)
*/
extern uint8 osal_nv_read_ex( uint16 id, uint16 subId, uint16 offset, uint16 len, void *buf );
/*
* Write an NV attribute (extended format)
*/
extern uint8 osal_nv_write_ex( uint16 id, uint16 subId, uint16 offset, uint16 len, void *buf );
/*
* Get the length of an NV item (extended format).
*/
extern uint16 osal_nv_item_len_ex( uint16 id, uint16 subId );
/*
* Delete an NV item (extended format).
*/
extern uint8 osal_nv_delete_ex( uint16 id, uint16 subId, uint16 len );
#endif // OSAL_NV_EXTENDED
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* OSAL_NV.H */
+126
View File
@@ -0,0 +1,126 @@
/*!
* \file OSAL_PwrMgr.h
*
* \brief The header of OSAL_PwrMgr.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef OSAL_PWRMGR_H
#define OSAL_PWRMGR_H
#ifdef __cplusplus
extern "C"
{
#endif
/*********************************************************************
* INCLUDES
*/
/*********************************************************************
* MACROS
*/
/*********************************************************************
* TYPEDEFS
*/
/* These attributes define sleep beheaver. The attributes can be changed
* for each sleep cycle or when the device characteristic change.
*/
typedef struct
{
uint16 pwrmgr_task_state;
#if !defined USE_ICALL && !defined OSAL_PORT2TIRTOS
uint16 pwrmgr_next_timeout;
uint16 accumulated_sleep_time;
uint8 pwrmgr_device;
#endif /* !defined USE_ICALL && !defined OSAL_PORT2TIRTOS */
} pwrmgr_attribute_t;
/* With PWRMGR_ALWAYS_ON selection, there is no power savings and the
* device is most likely on mains power. The PWRMGR_BATTERY selection allows
* the HAL sleep manager to enter SLEEP LITE state or SLEEP DEEP state.
*/
#define PWRMGR_ALWAYS_ON 0
#define PWRMGR_BATTERY 1
/* The PWRMGR_CONSERVE selection turns power savings on, all tasks have to
* agree. The PWRMGR_HOLD selection turns power savings off.
*/
#define PWRMGR_CONSERVE 0
#define PWRMGR_HOLD 1
/*********************************************************************
* GLOBAL VARIABLES
*/
/* This global variable stores the power management attributes.
*/
extern pwrmgr_attribute_t pwrmgr_attribute;
/*********************************************************************
* FUNCTIONS
*/
/*
* Initialize the power management system.
* This function is called from OSAL.
*
*/
extern void osal_pwrmgr_init( void );
/*
* This function is called by each task to state whether or not this
* task wants to conserve power. The task will call this function to
* vote whether it wants the OSAL to conserve power or it wants to
* hold off on the power savings. By default, when a task is created,
* its own power state is set to conserve. If the task always wants
* to converse power, it doesn't need to call this function at all.
* It is important for the task that changed the power manager task
* state to PWRMGR_HOLD to switch back to PWRMGR_CONSERVE when the
* hold period ends.
*/
extern uint8 osal_pwrmgr_task_state( uint8 task_id, uint8 state );
/*
* This function is called on power-up, whenever the device characteristic
* change (ex. Battery backed coordinator). This function works with the timer
* to set HAL's power manager sleep state when power saving is entered.
* This function should be called form HAL initialization. After power up
* initialization, it should only be called from NWK or ZDO.
*/
extern void osal_pwrmgr_device( uint8 pwrmgr_device );
/*
* This function is called from the main OSAL loop when there are
* no events scheduled and shouldn't be called from anywhere else.
*/
extern void osal_pwrmgr_powerconserve( void );
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* OSAL_PWRMGR_H */
+83
View File
@@ -0,0 +1,83 @@
/*!
* \file OSAL_Tasks.h
*
* \brief The header of OSAL_Tasks.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef OSAL_TASKS_H
#define OSAL_TASKS_H
#ifdef __cplusplus
extern "C"
{
#endif
/*********************************************************************
* INCLUDES
*/
#include "hal_types.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
#ifdef USE_ICALL
#define TASK_NO_TASK ICALL_UNDEF_DEST_ID
#else /* USE_ICALL */
#define TASK_NO_TASK 0xFF
#endif /* USE_ICALL */
/*********************************************************************
* TYPEDEFS
*/
/*
* Event handler function prototype
*/
typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );
/*********************************************************************
* GLOBAL VARIABLES
*/
extern const pTaskEventHandlerFn tasksArr[];
extern const uint8 tasksCnt;
extern uint16 *tasksEvents;
/*********************************************************************
* FUNCTIONS
*/
/*
* Call each of the tasks initailization functions.
*/
extern void osalInitTasks( void );
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* OSAL_TASKS_H */
+131
View File
@@ -0,0 +1,131 @@
/*!
* \file OSAL_Timers.h
*
* \brief The header of OSAL_Timers.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#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 */
+474
View File
@@ -0,0 +1,474 @@
/*!
* \file ZComDef.h
*
* \brief The header of ZComDef.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef ZCOMDEF_H
#define ZCOMDEF_H
#ifdef __cplusplus
extern "C"
{
#endif
/*********************************************************************
* INCLUDES
*/
#include "comdef.h"
// #include "saddr.h"
/*********************************************************************
* CONSTANTS
*/
#define osal_cpyExtAddr(a, b) sAddrExtCpy((a), (const uint8 *)(b))
#define osal_ExtAddrEqual(a, b) sAddrExtCmp((const uint8 *)(a), (const uint8 *)(b))
#define osal_copyAddress(a, b) sAddrCpy( (sAddr_t *)(a), (const sAddr_t *)(b) )
/*********************************************************************
* CONSTANTS
*/
// Build Device Types - Used during compilation
// These are the types of devices to build
// Bit masked into ZSTACK_DEVICE_BUILD
#define DEVICE_BUILD_COORDINATOR 0x01
#define DEVICE_BUILD_ROUTER 0x02
#define DEVICE_BUILD_ENDDEVICE 0x04
/*** Return Values ***/
#define ZSUCCESS SUCCESS
/*** Component IDs ***/
#define COMPID_OSAL 0
#define COMPID_MTEL 1
#define COMPID_MTSPCI 2
#define COMPID_NWK 3
#define COMPID_NWKIF 4
#define COMPID_MACCB 5
#define COMPID_MAC 6
#define COMPID_APP 7
#define COMPID_TEST 8
#define COMPID_RTG 9
#define COMPID_DATA 11
/* Temp CompIDs for testing */
#define COMPID_TEST_NWK_STARTUP 20
#define COMPID_TEST_SCAN_CONFIRM 21
#define COMPID_TEST_ASSOC_CONFIRM 22
#define COMPID_TEST_REMOTE_DATA_CONFIRM 23
// OSAL NV Item IDs
#define ZCD_NV_EX_LEGACY 0x0000
#define ZCD_NV_EX_ADDRMGR 0x0001
#define ZCD_NV_EX_BINDING_TABLE 0x0002
#define ZCD_NV_EX_DEVICE_LIST 0x0003
// OSAL NV item IDs
#define ZCD_NV_EXTADDR 0x0001
#define ZCD_NV_BOOTCOUNTER 0x0002
#define ZCD_NV_STARTUP_OPTION 0x0003
#define ZCD_NV_START_DELAY 0x0004
// NWK Layer NV item IDs
#define ZCD_NV_NIB 0x0021
#define ZCD_NV_DEVICE_LIST 0x0022
#define ZCD_NV_ADDRMGR 0x0023
#define ZCD_NV_POLL_RATE_OLD16 0x0024 // Deprecated when poll rate changed from 16 to 32 bits
#define ZCD_NV_POLL_RATE 0x0035
#define ZCD_NV_QUEUED_POLL_RATE 0x0025
#define ZCD_NV_RESPONSE_POLL_RATE 0x0026
#define ZCD_NV_REJOIN_POLL_RATE 0x0027
#define ZCD_NV_DATA_RETRIES 0x0028
#define ZCD_NV_POLL_FAILURE_RETRIES 0x0029
#define ZCD_NV_STACK_PROFILE 0x002A
#define ZCD_NV_INDIRECT_MSG_TIMEOUT 0x002B
#define ZCD_NV_ROUTE_EXPIRY_TIME 0x002C
#define ZCD_NV_EXTENDED_PAN_ID 0x002D
#define ZCD_NV_BCAST_RETRIES 0x002E
#define ZCD_NV_PASSIVE_ACK_TIMEOUT 0x002F
#define ZCD_NV_BCAST_DELIVERY_TIME 0x0030
#define ZCD_NV_NWK_MODE 0x0031
#define ZCD_NV_CONCENTRATOR_ENABLE 0x0032
#define ZCD_NV_CONCENTRATOR_DISCOVERY 0x0033
#define ZCD_NV_CONCENTRATOR_RADIUS 0x0034
// 0x0035 used above for new 32 bit Poll Rate
#define ZCD_NV_CONCENTRATOR_RC 0x0036
#define ZCD_NV_NWK_MGR_MODE 0x0037
#define ZCD_NV_SRC_RTG_EXPIRY_TIME 0x0038
#define ZCD_NV_ROUTE_DISCOVERY_TIME 0x0039
#define ZCD_NV_NWK_ACTIVE_KEY_INFO 0x003A
#define ZCD_NV_NWK_ALTERN_KEY_INFO 0x003B
#define ZCD_NV_ROUTER_OFF_ASSOC_CLEANUP 0x003C
#define ZCD_NV_NWK_LEAVE_REQ_ALLOWED 0x003D
#define ZCD_NV_NWK_CHILD_AGE_ENABLE 0x003E
#define ZCD_NV_DEVICE_LIST_KA_TIMEOUT 0x003F
// APS Layer NV item IDs
#define ZCD_NV_BINDING_TABLE 0x0041
#define ZCD_NV_GROUP_TABLE 0x0042
#define ZCD_NV_APS_FRAME_RETRIES 0x0043
#define ZCD_NV_APS_ACK_WAIT_DURATION 0x0044
#define ZCD_NV_APS_ACK_WAIT_MULTIPLIER 0x0045
#define ZCD_NV_BINDING_TIME 0x0046
#define ZCD_NV_APS_USE_EXT_PANID 0x0047
#define ZCD_NV_APS_USE_INSECURE_JOIN 0x0048
#define ZCD_NV_COMMISSIONED_NWK_ADDR 0x0049
#define ZCD_NV_APS_NONMEMBER_RADIUS 0x004B // Multicast non_member radius
#define ZCD_NV_APS_LINK_KEY_TABLE 0x004C
#define ZCD_NV_APS_DUPREJ_TIMEOUT_INC 0x004D
#define ZCD_NV_APS_DUPREJ_TIMEOUT_COUNT 0x004E
#define ZCD_NV_APS_DUPREJ_TABLE_SIZE 0x004F
// System statistics and metrics NV ID
#define ZCD_NV_DIAGNOSTIC_STATS 0x0050
// Additional NWK Layer NV item IDs
#define ZCD_NV_NWK_PARENT_INFO 0x0051
#define ZCD_NV_NWK_ENDDEV_TIMEOUT_DEF 0x0052
#define ZCD_NV_END_DEV_TIMEOUT_VALUE 0x0053
#define ZCD_NV_END_DEV_CONFIGURATION 0x0054
#define ZCD_NV_BDBNODEISONANETWORK 0x0055 //bdbNodeIsOnANetwork attribute
#define ZCD_NV_BDBREPORTINGCONFIG 0x0056
// Security NV Item IDs
#define ZCD_NV_SECURITY_LEVEL 0x0061
#define ZCD_NV_PRECFGKEY 0x0062
#define ZCD_NV_PRECFGKEYS_ENABLE 0x0063
#define ZCD_NV_SECURITY_MODE 0x0064
#define ZCD_NV_SECURE_PERMIT_JOIN 0x0065
#define ZCD_NV_APS_LINK_KEY_TYPE 0x0066
#define ZCD_NV_APS_ALLOW_R19_SECURITY 0x0067
#define ZCD_NV_DISTRIBUTED_KEY 0x0068 //Default distributed nwk key Id. Nv ID not in use
#define ZCD_NV_IMPLICIT_CERTIFICATE 0x0069
#define ZCD_NV_DEVICE_PRIVATE_KEY 0x006A
#define ZCD_NV_CA_PUBLIC_KEY 0x006B
#define ZCD_NV_KE_MAX_DEVICES 0x006C
#define ZCD_NV_USE_DEFAULT_TCLK 0x006D
//deprecated: TRUSTCENTER_ADDR (16-bit) 0x006E
#define ZCD_NV_RNG_COUNTER 0x006F
#define ZCD_NV_RANDOM_SEED 0x0070
#define ZCD_NV_TRUSTCENTER_ADDR 0x0071
#define ZCD_NV_CERT_283 0x0072
#define ZCD_NV_PRIVATE_KEY_283 0x0073
#define ZCD_NV_PUBLIC_KEY_283 0x0074
#define ZCD_NV_NWK_SEC_MATERIAL_TABLE_START 0x0075
#define ZCD_NV_NWK_SEC_MATERIAL_TABLE_END 0x0080
// ZDO NV Item IDs
#define ZCD_NV_USERDESC 0x0081
#define ZCD_NV_NWKKEY 0x0082
#define ZCD_NV_PANID 0x0083
#define ZCD_NV_CHANLIST 0x0084
#define ZCD_NV_LEAVE_CTRL 0x0085
#define ZCD_NV_SCAN_DURATION 0x0086
#define ZCD_NV_LOGICAL_TYPE 0x0087
#define ZCD_NV_NWKMGR_MIN_TX 0x0088
#define ZCD_NV_NWKMGR_ADDR 0x0089
#define ZCD_NV_ZDO_DIRECT_CB 0x008F
// ZCL NV item IDs
#define ZCD_NV_SCENE_TABLE 0x0091
#define ZCD_NV_MIN_FREE_NWK_ADDR 0x0092
#define ZCD_NV_MAX_FREE_NWK_ADDR 0x0093
#define ZCD_NV_MIN_FREE_GRP_ID 0x0094
#define ZCD_NV_MAX_FREE_GRP_ID 0x0095
#define ZCD_NV_MIN_GRP_IDS 0x0096
#define ZCD_NV_MAX_GRP_IDS 0x0097
#define ZCD_NV_OTA_BLOCK_REQ_DELAY 0x0098
// Non-standard NV item IDs
#define ZCD_NV_SAPI_ENDPOINT 0x00A1
// NV Items Reserved for Commissioning Cluster Startup Attribute Set (SAS):
// 0x00B1 - 0x00BF: Parameters related to APS and NWK layers
// 0x00C1 - 0x00CF: Parameters related to Security
// 0x00D1 - 0x00DF: Current key parameters
#define ZCD_NV_SAS_SHORT_ADDR 0x00B1
#define ZCD_NV_SAS_EXT_PANID 0x00B2
#define ZCD_NV_SAS_PANID 0x00B3
#define ZCD_NV_SAS_CHANNEL_MASK 0x00B4
#define ZCD_NV_SAS_PROTOCOL_VER 0x00B5
#define ZCD_NV_SAS_STACK_PROFILE 0x00B6
#define ZCD_NV_SAS_STARTUP_CTRL 0x00B7
#define ZCD_NV_SAS_TC_ADDR 0x00C1
#define ZCD_NV_SAS_TC_MASTER_KEY 0x00C2
#define ZCD_NV_SAS_NWK_KEY 0x00C3
#define ZCD_NV_SAS_USE_INSEC_JOIN 0x00C4
#define ZCD_NV_SAS_PRECFG_LINK_KEY 0x00C5
#define ZCD_NV_SAS_NWK_KEY_SEQ_NUM 0x00C6
#define ZCD_NV_SAS_NWK_KEY_TYPE 0x00C7
#define ZCD_NV_SAS_NWK_MGR_ADDR 0x00C8
#define ZCD_NV_SAS_CURR_TC_MASTER_KEY 0x00D1
#define ZCD_NV_SAS_CURR_NWK_KEY 0x00D2
#define ZCD_NV_SAS_CURR_PRECFG_LINK_KEY 0x00D3
// NV Items Reserved for Trust Center Link Key Table entries
// 0x0101 - 0x01FF
#define ZCD_NV_TCLK_SEED 0x0101 //Seed
#define ZCD_NV_TCLK_JOIN_DEV 0x0102 //Nv Id where Joining device store their APS key. Key is in plain text.
#define ZCD_NV_TCLK_DEFAULT 0x0103 //Not accually a Nv Item but Id used by SecMgr
#define ZCD_NV_TCLK_IC_TABLE_START 0x0104 //IC keys, refered with shift byte
#define ZCD_NV_TCLK_IC_TABLE_END 0x0110
#define ZCD_NV_TCLK_TABLE_START 0x0111 //Entries to store users of the keys
#define ZCD_NV_TCLK_TABLE_END 0x01FF
// NV Items Reserved for APS Link Key Table entries
// 0x0201 - 0x02FF
#define ZCD_NV_APS_LINK_KEY_DATA_START 0x0201 // APS key data
#define ZCD_NV_APS_LINK_KEY_DATA_END 0x02FF
// NV items used to duplicate system elements
#define ZCD_NV_DUPLICATE_BINDING_TABLE 0x0300
#define ZCD_NV_DUPLICATE_DEVICE_LIST 0x0301
#define ZCD_NV_DUPLICATE_DEVICE_LIST_KA_TIMEOUT 0x0302
// NV Items Reserved for Proxy Table entries
// 0x0310 - 0x033F
#define ZCD_NV_PROXY_TABLE_START 0x0310
#define ZCD_NV_PROXY_TABLE_END 0x033F
// NV Items Reserved for applications (user applications)
// 0x0401 0x0FFF
// ZCD_NV_STARTUP_OPTION values
// These are bit weighted - you can OR these together.
// Setting one of these bits will set their associated NV items
// to code initialized values.
#define ZCD_STARTOPT_DEFAULT_CONFIG_STATE 0x01
#define ZCD_STARTOPT_DEFAULT_NETWORK_STATE 0x02
#define ZCD_STARTOPT_AUTO_START 0x04
#define ZCD_STARTOPT_CLEAR_CONFIG ZCD_STARTOPT_DEFAULT_CONFIG_STATE
#define ZCD_STARTOPT_CLEAR_STATE ZCD_STARTOPT_DEFAULT_NETWORK_STATE
//FrameCounter should be persistence across factory new resets, this should not
//used as part of FN reset procedure. Set to reset the FrameCounter of all
//Nwk Security Material
#define ZCD_STARTOPT_CLEAR_NWK_FRAME_COUNTER 0x80
#define ZCL_KE_IMPLICIT_CERTIFICATE_LEN 48
#define ZCL_KE_CA_PUBLIC_KEY_LEN 22
#define ZCL_KE_DEVICE_PRIVATE_KEY_LEN 21
/*********************************************************************
* TYPEDEFS
*/
/*** Data Types ***/
typedef uint8 byte;
typedef uint16 UINT16;
typedef int16 INT16;
enum
{
AddrNotPresent = 0,
AddrGroup = 1,
Addr16Bit = 2,
Addr64Bit = 3,
AddrBroadcast = 15
};
#define Z_EXTADDR_LEN 8
typedef byte ZLongAddr_t[Z_EXTADDR_LEN];
typedef struct
{
union
{
uint16 shortAddr;
ZLongAddr_t extAddr;
} addr;
byte addrMode;
} zAddrType_t;
// Redefined Generic Status Return Values for code backwards compatibility
#define ZSuccess SUCCESS
#define ZFailure FAILURE
#define ZInvalidParameter INVALIDPARAMETER
// ZStack status values must start at 0x10, after the generic status values (defined in comdef.h)
#define ZMemError 0x10
#define ZBufferFull 0x11
#define ZUnsupportedMode 0x12
#define ZMacMemError 0x13
#define ZSapiInProgress 0x20
#define ZSapiTimeout 0x21
#define ZSapiInit 0x22
#define ZNotAuthorized 0x7E
#define ZMalformedCmd 0x80
#define ZUnsupClusterCmd 0x81
// OTA Status values
#define ZOtaAbort 0x95
#define ZOtaImageInvalid 0x96
#define ZOtaWaitForData 0x97
#define ZOtaNoImageAvailable 0x98
#define ZOtaRequireMoreImage 0x99
// APS status values
#define ZApsFail 0xb1
#define ZApsTableFull 0xb2
#define ZApsIllegalRequest 0xb3
#define ZApsInvalidBinding 0xb4
#define ZApsUnsupportedAttrib 0xb5
#define ZApsNotSupported 0xb6
#define ZApsNoAck 0xb7
#define ZApsDuplicateEntry 0xb8
#define ZApsNoBoundDevice 0xb9
#define ZApsNotAllowed 0xba
#define ZApsNotAuthenticated 0xbb
// Security status values
#define ZSecNoKey 0xa1
#define ZSecOldFrmCount 0xa2
#define ZSecMaxFrmCount 0xa3
#define ZSecCcmFail 0xa4
#define ZSecFailure 0xad
// NWK status values
#define ZNwkInvalidParam 0xc1
#define ZNwkInvalidRequest 0xc2
#define ZNwkNotPermitted 0xc3
#define ZNwkStartupFailure 0xc4
#define ZNwkAlreadyPresent 0xc5
#define ZNwkSyncFailure 0xc6
#define ZNwkTableFull 0xc7
#define ZNwkUnknownDevice 0xc8
#define ZNwkUnsupportedAttribute 0xc9
#define ZNwkNoNetworks 0xca
#define ZNwkLeaveUnconfirmed 0xcb
#define ZNwkNoAck 0xcc // not in spec
#define ZNwkNoRoute 0xcd
// MAC status values
#define ZMacSuccess 0x00
#define ZMacBeaconLoss 0xe0
#define ZMacChannelAccessFailure 0xe1
#define ZMacDenied 0xe2
#define ZMacDisableTrxFailure 0xe3
#define ZMacFailedSecurityCheck 0xe4
#define ZMacFrameTooLong 0xe5
#define ZMacInvalidGTS 0xe6
#define ZMacInvalidHandle 0xe7
#define ZMacInvalidParameter 0xe8
#define ZMacNoACK 0xe9
#define ZMacNoBeacon 0xea
#define ZMacNoData 0xeb
#define ZMacNoShortAddr 0xec
#define ZMacOutOfCap 0xed
#define ZMacPANIDConflict 0xee
#define ZMacRealignment 0xef
#define ZMacTransactionExpired 0xf0
#define ZMacTransactionOverFlow 0xf1
#define ZMacTxActive 0xf2
#define ZMacUnAvailableKey 0xf3
#define ZMacUnsupportedAttribute 0xf4
#define ZMacUnsupported 0xf5
#define ZMacSrcMatchInvalidIndex 0xff
typedef Status_t ZStatus_t;
typedef struct
{
uint8 txCounter; // Counter of transmission success/failures
uint8 txCost; // Average of sending rssi values if link staus is enabled
// i.e. NWK_LINK_STATUS_PERIOD is defined as non zero
uint8 rxLqi; // average of received rssi values
// needs to be converted to link cost (1-7) before used
uint8 inKeySeqNum; // security key sequence number
uint32 inFrmCntr; // security frame counter..
uint16 txFailure; // higher values indicate more failures
} linkInfo_t;
/*********************************************************************
* Global System Messages
*/
#define SPI_INCOMING_ZTOOL_PORT 0x21 // Raw data from ZTool Port (not implemented)
#define SPI_INCOMING_ZAPP_DATA 0x22 // Raw data from the ZAPP port (see serialApp.c)
#define MT_SYS_APP_MSG 0x23 // Raw data from an MT Sys message
#define MT_SYS_APP_RSP_MSG 0x24 // Raw data output for an MT Sys message
#define MT_SYS_OTA_MSG 0x25 // Raw data output for an MT OTA Rsp
#define MT_SYS_APP_PB_ZCL_CMD 0x26 // MT APP PB ZCL command
#define AF_DATA_CONFIRM_CMD 0xFD // Data confirmation
#define AF_REFLECT_ERROR_CMD 0xFE // Reflected message error message
#define AF_INCOMING_MSG_CMD 0x1A // Incoming MSG type message
#define AF_INCOMING_KVP_CMD 0x1B // Incoming KVP type message
#define AF_INCOMING_GRP_KVP_CMD 0x1C // Incoming Group KVP type message
//#define KEY_CHANGE 0xC0 // Key Events
#define ZDO_NEW_DSTADDR 0xD0 // ZDO has received a new DstAddr for this app
#define ZDO_STATE_CHANGE 0xD1 // ZDO has changed the device's network state
#define ZDO_MATCH_DESC_RSP_SENT 0xD2 // ZDO match descriptor response was sent
#define ZDO_CB_MSG 0xD3 // ZDO incoming message callback
#define ZDO_NETWORK_REPORT 0xD4 // ZDO received a Network Report message
#define ZDO_NETWORK_UPDATE 0xD5 // ZDO received a Network Update message
#define ZDO_ADDR_CHANGE_IND 0xD6 // ZDO was informed of device address change
#define NM_CHANNEL_INTERFERE 0x31 // NwkMgr received a Channel Interference message
#define NM_ED_SCAN_CONFIRM 0x32 // NwkMgr received an ED Scan Confirm message
#define SAPS_CHANNEL_CHANGE 0x33 // Stub APS has changed the device's channel
#define ZCL_INCOMING_MSG 0x34 // Incoming ZCL foundation message
#define ZCL_KEY_ESTABLISH_IND 0x35 // ZCL Key Establishment Completion Indication
#define ZCL_OTA_CALLBACK_IND 0x36 // ZCL OTA Completion Indication
// OSAL System Message IDs/Events Reserved for applications (user applications)
// 0xE0 0xFC
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* FUNCTIONS
*/
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* ZCOMDEF_H */
+146
View File
@@ -0,0 +1,146 @@
/*!
* \file comdef.h
*
* \brief The header of comdef.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#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 */
+287
View File
@@ -0,0 +1,287 @@
/*!
* \file osal_task.h
*
* \brief The header of osal_task.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef OSAL_TASK_H
#define OSAL_TASK_H
#ifdef __cplusplus
extern "C"
{
#endif
#if 0 // TODO
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "StackMacros.h"
#include "hal_types.h"
#define OSAL_SUCCESS 1
#define OSAL_ERROR 0
#define OSAL_PREEMPTION configUSE_PREEMPTION
#define OSAL_MAX_TASK_NAME_LEN configMAX_TASK_NAME_LEN
#define OSAL_MAX_PRIORITY configMAX_PRIORITIES
#define OSAL_MIN_STACK_SIZE configMINIMAL_STACK_SIZE
#define OSAL_TASK_YIELD taskYIELD
#define OSAL_TASK_ENTER_CRITICAL taskENTER_CRITICAL
#define OSAL_TASK_EXIT_CRITICAL taskENTER_CRITICAL
#define OSAL_DISABLE_INTERRUPTS taskDISABLE_INTERRUPTS
#define OSAL_ENABLE_INTERRUPTS taskENABLE_INTERRUPTS
#define OSAL_IDLE_TASK_PRIORITY (unsigned long) 0
#define OSAL_TASK_PRIORITY_ONE (unsigned long) 1
#define OSAL_TASK_PRIORITY_TWO (unsigned long) 2
#define OSAL_TASK_PRIORITY_THREE (unsigned long) 3
#define OSAL_TASK_PRIORITY_FOUR (unsigned long) 4
#define OSAL_TASK_PRIORITY_HIGH (unsigned long) 5
/*---------------------------------------------------------------------------------------
Name: osal_task_create
Purpose: Creates a task
Parameters:
task_func Pointer to the task entry function. Tasks must be implemented to never
return (i.e. continuous loop).
task_name A descriptive name for the task. This is mainly used to facilitate
debugging. Max length defined by MAX_TASK_NAME_LEN.
stack_depth 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 stack_depth 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.
task_func_parameters Pointer that will be used as the parameter for the task being
created.
task_priority The priority at which the task should run.
task_handle Used to pass back a handle by which the created task can be referenced.
returns: OSAL_SUCCESS if the task was successfully created and added to a ready list
OSAL_ERROR
NOTES: handle is passed back to the user by which the created task can be referenced.
---------------------------------------------------------------------------------------*/
long osal_task_create( void (*task_func)( void * ), const int8 *task_name, uint16 stack_depth,
void *task_func_parameters, uint32 task_priority, void **task_handle );
/*---------------------------------------------------------------------------------------
Name: osal_task_delete
Purpose: Deletes a task
Parameters:
task_handle The handle of the task to be deleted. Passing NULL will cause the calling
task to be deleted
returns:
void
---------------------------------------------------------------------------------------*/
void osal_task_delete( void **task_handle );
/*---------------------------------------------------------------------------------------
Name: osal_task_suspend
Purpose: suspends a task. Passing a NULL handle will cause the calling task to
be suspended.
Parameters:
task_handle Handle to the task being suspended. Passing a NULL handle will cause
the calling task to be suspended.
returns:
void
---------------------------------------------------------------------------------------*/
void osal_task_suspend( void **task_handle );
/*---------------------------------------------------------------------------------------
Name: osal_task_resume
Purpose: resumes a suspended task
Parameters:
task_handle Handle to the task being readied.
returns: OSAL_ERROR if error
OSAL_SUCCESS if success
---------------------------------------------------------------------------------------*/
void osal_task_resume( void **task_handle );
/*---------------------------------------------------------------------------------------
Name: osal_task_priority_get
Purpose: gets the priority of the task.
Parameters:
task_handle Handle to the task for which the priority is being set. Passing a NULL
handle results in the priority of the calling task being returned.
returns: The priority of task
---------------------------------------------------------------------------------------*/
unsigned long osal_task_priority_get( void **task_handle );
/*---------------------------------------------------------------------------------------
Name: osal_task_priority_set
Purpose: sets the priority of the task.
Parameters:
task_handle 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.
task_priority The priority to which the task will be set.
returns: The priority of task
---------------------------------------------------------------------------------------*/
void osal_task_priority_set( void **task_handle, uint32 task_priority );
/*---------------------------------------------------------------------------------------
Name: osal_task_delay
Purpose: Delay a task for a given number of ticks. The actual time that the task remains
blocked depends on the tick rate. The constant TICK_RATE_MS can be used to
calculate real time from the tick rate - with the resolution of one tick period.
Parameters:
ticks_to_delay The amount of time, in tick periods, that the calling task should
block
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_delay( uint32 ticks_to_delay );
/*---------------------------------------------------------------------------------------
Name: osal_task_delay_until
Purpose: Delay a task until a specified time. This function can be used by cyclical
tasks to ensure a constant execution frequency.
Parameters:
prev_wake_time 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.
time_increment The cycle time period. The task will be unblocked at time
(prev_wake_time+time_increment). Calling osal_task_delay_until with
the same time_increment parameter value will cause the task to execute
with a fixed interval period
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_delay_until( uint32 * const prev_wake_time, uint32 time_increment );
/*---------------------------------------------------------------------------------------
Name: osal_task_start_scheduler
Purpose: Starts the real time kernel tick processing. After calling the kernel has control
over which tasks are executed and when.
Parameters:
void
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_start_scheduler( void );
/*---------------------------------------------------------------------------------------
Name: osal_task_end_scheduler
Purpose: 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
Parameters:
void
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_end_scheduler( void );
/*---------------------------------------------------------------------------------------
Name: osal_task_suspend_all
Purpose: Suspends all real time kernel activity while keeping interrupts (including
the kernel tick) enabled.
Parameters:
void
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_suspend_all( void );
/*---------------------------------------------------------------------------------------
Name: osal_task_resume_all
Purpose: Resumes real time kernel activity following a call to osal_task_suspend_all().
After a call to osal_task_suspend_all() the kernel will take control of which
task is executing at any time.
Parameters:
void
Returns
True or False. True if context switch happens, else false
---------------------------------------------------------------------------------------*/
long osal_task_resume_all( void );
/*---------------------------------------------------------------------------------------
Name: osal_task_yield
Purpose: Forces a context switch.
Parameters:
void
Returns
void
---------------------------------------------------------------------------------------*/
void osal_task_yield( void );
/*---------------------------------------------------------------------------------------
Name: osal_queue_create
Purpose: Creates a queue, used to pass items between tasks.
Parameters:
max_items Maximum number of items that the queue can contain.
item_size Size, in bytes, of each item in the queue.
Returns
void* Ptr to queue handle
---------------------------------------------------------------------------------------*/
void *osal_queue_create( uint32 max_items, uint32 item_size );
/*---------------------------------------------------------------------------------------
Name: osal_queue_receive
Purpose: Creates a queue, used to pass items between tasks.
Parameters:
handle Pointer to handle of the queue from which data is received.
buffer Pointer to memory into which received data will be copied.
wait_ticks Maximum time to block task waiting for data to be available.
Returns
status OSAL_SUCCESS is read successful, OSAL_ERROR if data not read
---------------------------------------------------------------------------------------*/
uint32 osal_queue_receive( void *handle, void *buffer, uint32 wait_ticks );
/*---------------------------------------------------------------------------------------
Name: osal_queue_send
Purpose: Sends (writes) an item to a queue.
Parameters:
handle Pointer to handle of the queue to which data is written.
buffer Pointer to memory from which data will be copied.
wait_ticks Maximum time to block task waiting for space to be available.
Returns
status OSAL_SUCCESS is send successful, OSAL_ERROR if data not written
---------------------------------------------------------------------------------------*/
uint32 osal_queue_send( void *handle, void *buffer, uint32 wait_ticks );
#endif
#ifdef __cplusplus
}
#endif
#endif