initial commit
This commit is contained in:
310
lib/amb1_sdk/soc/realtek/8195a/misc/os/freertos_pmu_8195a.c
Normal file
310
lib/amb1_sdk/soc/realtek/8195a/misc/os/freertos_pmu_8195a.c
Normal file
@@ -0,0 +1,310 @@
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#include "freertos_pmu.h"
|
||||
|
||||
#include <platform_opts.h>
|
||||
|
||||
#include "platform_autoconf.h"
|
||||
#include "sys_api.h"
|
||||
#include "sleep_ex_api.h"
|
||||
|
||||
#ifndef portNVIC_SYSTICK_CURRENT_VALUE_REG
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||
#endif
|
||||
|
||||
uint32_t missing_tick = 0;
|
||||
|
||||
static uint32_t wakelock = DEFAULT_WAKELOCK;
|
||||
static uint32_t wakeup_event = DEFAULT_WAKEUP_EVENT;
|
||||
|
||||
typedef struct {
|
||||
uint32_t nDeviceId;
|
||||
PSM_HOOK_FUN sleep_hook_fun;
|
||||
void* sleep_param_ptr;
|
||||
PSM_HOOK_FUN wakeup_hook_fun;
|
||||
void* wakeup_param_ptr;
|
||||
} PSM_DD_HOOK_INFO;
|
||||
|
||||
#define MAX_PSM_DD_HOOK_INFO_SIZE 8
|
||||
uint32_t psm_dd_hook_info_size = 0;
|
||||
PSM_DD_HOOK_INFO psm_dd_hook_infos[MAX_PSM_DD_HOOK_INFO_SIZE];
|
||||
|
||||
static uint8_t last_wakelock_state[32] = {
|
||||
DEFAULT_WAKELOCK & 0x01, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static uint32_t last_acquire_wakelock_time[32] = {0};
|
||||
static uint32_t hold_wakelock_time[32] = {0};
|
||||
static uint32_t base_sys_time = 0;
|
||||
|
||||
static uint32_t sys_sleep_time = 0;
|
||||
|
||||
unsigned char reserve_pll = 0;
|
||||
unsigned char generate_wakelock_stats = 0;
|
||||
|
||||
/* ++++++++ FreeRTOS macro implementation ++++++++ */
|
||||
|
||||
/*
|
||||
* It is called in idle task.
|
||||
*
|
||||
* @return true : System is ready to check conditions that if it can enter sleep.
|
||||
* false : System keep awake.
|
||||
**/
|
||||
/*
|
||||
* It is called when freertos is going to sleep.
|
||||
* At this moment, all sleep conditons are satisfied. All freertos' sleep pre-processing are done.
|
||||
*
|
||||
* @param expected_idle_time : The time that FreeRTOS expect to sleep.
|
||||
* If we set this value to 0 then FreeRTOS will do nothing in its sleep function.
|
||||
**/
|
||||
void freertos_pre_sleep_processing(unsigned int *expected_idle_time) {
|
||||
|
||||
#ifdef CONFIG_SOC_PS_MODULE
|
||||
|
||||
uint32_t i;
|
||||
uint32_t stime;
|
||||
uint32_t tick_before_sleep;
|
||||
uint32_t tick_after_sleep;
|
||||
uint32_t tick_passed;
|
||||
uint32_t backup_systick_reg;
|
||||
unsigned char IsDramOn = 1;
|
||||
unsigned char suspend_sdram = 1;
|
||||
|
||||
/* To disable freertos sleep function and use our sleep function,
|
||||
* we can set original expected idle time to 0. */
|
||||
stime = *expected_idle_time;
|
||||
*expected_idle_time = 0;
|
||||
|
||||
for (i=0; i<psm_dd_hook_info_size; i++) {
|
||||
if ( psm_dd_hook_infos[i].sleep_hook_fun != NULL) {
|
||||
psm_dd_hook_infos[i].sleep_hook_fun( stime, psm_dd_hook_infos[i].sleep_param_ptr );
|
||||
}
|
||||
}
|
||||
|
||||
// Store gtimer timestamp before sleep
|
||||
tick_before_sleep = us_ticker_read();
|
||||
|
||||
if ( sys_is_sdram_power_on() == 0 ) {
|
||||
IsDramOn = 0;
|
||||
}
|
||||
|
||||
if (IsDramOn) {
|
||||
#if defined(FREERTOS_PMU_TICKLESS_SUSPEND_SDRAM) && (FREERTOS_PMU_TICKLESS_SUSPEND_SDRAM==0)
|
||||
// sdram is turned on, and we don't want suspend sdram
|
||||
suspend_sdram = 0;
|
||||
#endif
|
||||
} else {
|
||||
// sdram didn't turned on, we should not suspend it
|
||||
suspend_sdram = 0;
|
||||
}
|
||||
|
||||
backup_systick_reg = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
|
||||
// sleep
|
||||
sleep_ex_selective(wakeup_event, stime, reserve_pll, suspend_sdram);
|
||||
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = backup_systick_reg;
|
||||
|
||||
// update kernel tick by calculating passed tick from gtimer
|
||||
{
|
||||
// get current gtimer timestamp
|
||||
tick_after_sleep = us_ticker_read();
|
||||
|
||||
// calculated passed time
|
||||
if (tick_after_sleep > tick_before_sleep) {
|
||||
tick_passed = tick_after_sleep - tick_before_sleep;
|
||||
} else {
|
||||
// overflow
|
||||
tick_passed = (0xffffffff - tick_before_sleep) + tick_after_sleep;
|
||||
}
|
||||
|
||||
/* If there is a rapid interrupt (<1ms), it makes tick_passed less than 1ms.
|
||||
* The tick_passed would be rounded and make OS can't step tick.
|
||||
* We collect the rounded tick_passed into missing_tick and step tick properly.
|
||||
* */
|
||||
tick_passed += missing_tick;
|
||||
if (tick_passed > stime * 1000) {
|
||||
missing_tick = tick_passed - stime * 1000;
|
||||
tick_passed = stime * 1000;
|
||||
} else {
|
||||
missing_tick = tick_passed % 1000;
|
||||
}
|
||||
|
||||
// update kernel tick
|
||||
vTaskStepTick( tick_passed/1000 );
|
||||
}
|
||||
|
||||
sys_sleep_time += tick_passed/1000;
|
||||
|
||||
for (i=0; i<psm_dd_hook_info_size; i++) {
|
||||
if ( psm_dd_hook_infos[i].wakeup_hook_fun != NULL) {
|
||||
psm_dd_hook_infos[i].wakeup_hook_fun( stime, psm_dd_hook_infos[i].wakeup_param_ptr );
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
// If PS is not enabled, then use freertos sleep function
|
||||
#endif
|
||||
}
|
||||
|
||||
void freertos_post_sleep_processing(unsigned int *expected_idle_time) {
|
||||
#ifndef configSYSTICK_CLOCK_HZ
|
||||
*expected_idle_time = 1 + ( portNVIC_SYSTICK_CURRENT_VALUE_REG / ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) );
|
||||
#else
|
||||
*expected_idle_time = 1 + ( portNVIC_SYSTICK_CURRENT_VALUE_REG / ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) );
|
||||
#endif
|
||||
}
|
||||
/* -------- FreeRTOS macro implementation -------- */
|
||||
|
||||
int freertos_ready_to_sleep() {
|
||||
return wakelock == 0;
|
||||
}
|
||||
|
||||
void pmu_acquire_wakelock(uint32_t lock_id) {
|
||||
|
||||
wakelock |= BIT(lock_id);
|
||||
|
||||
if (generate_wakelock_stats) {
|
||||
uint32_t i;
|
||||
uint32_t current_timestamp = osKernelSysTick();
|
||||
for (i=0; i<32; i++) {
|
||||
if ( (1<<i & BIT(lock_id)) && (last_wakelock_state[i] == 0) ) {
|
||||
last_acquire_wakelock_time[i] = current_timestamp;
|
||||
last_wakelock_state[i] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pmu_release_wakelock(uint32_t lock_id) {
|
||||
wakelock &= ~BIT(lock_id);
|
||||
|
||||
if (generate_wakelock_stats) {
|
||||
uint32_t i;
|
||||
uint32_t current_timestamp = osKernelSysTick();
|
||||
for (i=0; i<32; i++) {
|
||||
if ( (1<<i & BIT(lock_id)) && (last_wakelock_state[i] == 1) ) {
|
||||
hold_wakelock_time[i] += current_timestamp - last_acquire_wakelock_time[i];
|
||||
last_wakelock_state[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t pmu_get_wakelock_status() {
|
||||
return wakelock;
|
||||
}
|
||||
|
||||
void pmu_enable_wakelock_stats(unsigned char enable) {
|
||||
generate_wakelock_stats = enable;
|
||||
}
|
||||
|
||||
void pmu_get_wakelock_hold_stats( char *pcWriteBuffer, unsigned int BufferSize) {
|
||||
uint32_t i;
|
||||
uint32_t current_timestamp = osKernelSysTick();
|
||||
|
||||
if (pcWriteBuffer == NULL)
|
||||
return;
|
||||
|
||||
*pcWriteBuffer = 0x00;
|
||||
|
||||
if (generate_wakelock_stats) {
|
||||
// print header
|
||||
snprintf(pcWriteBuffer, BufferSize, "wakelock_id\tholdtime\r\n");
|
||||
pcWriteBuffer += strlen( pcWriteBuffer );
|
||||
|
||||
for (i=0; i<32; i++) {
|
||||
if (last_wakelock_state[i] == 1) {
|
||||
snprintf(pcWriteBuffer, BufferSize, "%x\t\t%d\r\n", i, hold_wakelock_time[i] + (current_timestamp - last_acquire_wakelock_time[i]));
|
||||
} else {
|
||||
if (hold_wakelock_time[i] > 0) {
|
||||
snprintf(pcWriteBuffer, BufferSize, "%x\t\t%d\r\n", i, hold_wakelock_time[i]);
|
||||
}
|
||||
}
|
||||
pcWriteBuffer += strlen( pcWriteBuffer );
|
||||
}
|
||||
snprintf(pcWriteBuffer, BufferSize, "time passed: %d ms, system sleep %d ms\r\n", current_timestamp - base_sys_time, sys_sleep_time);
|
||||
}
|
||||
}
|
||||
|
||||
void pmu_clean_wakelock_stat() {
|
||||
uint32_t i;
|
||||
base_sys_time = osKernelSysTick();
|
||||
for (i=0; i<32; i++) {
|
||||
hold_wakelock_time[i] = 0;
|
||||
if (last_wakelock_state[i] == 1) {
|
||||
last_acquire_wakelock_time[i] = base_sys_time;
|
||||
}
|
||||
}
|
||||
sys_sleep_time = 0;
|
||||
}
|
||||
|
||||
void pmu_add_wakeup_event(uint32_t event) {
|
||||
wakeup_event |= event;
|
||||
}
|
||||
|
||||
void pmu_del_wakeup_event(uint32_t event) {
|
||||
wakeup_event &= ~event;
|
||||
// To fulfill tickless design, system timer is required to be wakeup event
|
||||
wakeup_event |= SLEEP_WAKEUP_BY_STIMER;
|
||||
}
|
||||
|
||||
void pmu_register_sleep_callback(uint32_t nDeviceId, PSM_HOOK_FUN sleep_hook_fun, void* sleep_param_ptr, PSM_HOOK_FUN wakeup_hook_fun, void* wakeup_param_ptr) {
|
||||
uint32_t i;
|
||||
for (i=0; i<psm_dd_hook_info_size; i++) {
|
||||
if (psm_dd_hook_infos[i].nDeviceId == nDeviceId) {
|
||||
psm_dd_hook_infos[i].sleep_hook_fun = sleep_hook_fun;
|
||||
psm_dd_hook_infos[i].sleep_param_ptr = sleep_param_ptr;
|
||||
psm_dd_hook_infos[i].wakeup_hook_fun = wakeup_hook_fun;
|
||||
psm_dd_hook_infos[i].wakeup_param_ptr = wakeup_param_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == psm_dd_hook_info_size) {
|
||||
psm_dd_hook_infos[psm_dd_hook_info_size].nDeviceId = nDeviceId;
|
||||
psm_dd_hook_infos[psm_dd_hook_info_size].sleep_hook_fun = sleep_hook_fun;
|
||||
psm_dd_hook_infos[psm_dd_hook_info_size].sleep_param_ptr = sleep_param_ptr;
|
||||
psm_dd_hook_infos[psm_dd_hook_info_size].wakeup_hook_fun = wakeup_hook_fun;
|
||||
psm_dd_hook_infos[psm_dd_hook_info_size].wakeup_param_ptr = wakeup_param_ptr;
|
||||
psm_dd_hook_info_size++;
|
||||
}
|
||||
}
|
||||
|
||||
void pmu_unregister_sleep_callback(uint32_t nDeviceId) {
|
||||
uint32_t i;
|
||||
for (i=0; i<psm_dd_hook_info_size; i++) {
|
||||
if (psm_dd_hook_infos[i].nDeviceId == nDeviceId) {
|
||||
if (psm_dd_hook_info_size > 1) {
|
||||
// if we have more than 2 items, just swap the last item into current slot
|
||||
psm_dd_hook_infos[i].nDeviceId = psm_dd_hook_infos[psm_dd_hook_info_size-1].nDeviceId;
|
||||
psm_dd_hook_infos[i].sleep_hook_fun = psm_dd_hook_infos[psm_dd_hook_info_size-1].sleep_hook_fun;
|
||||
psm_dd_hook_infos[i].sleep_param_ptr = psm_dd_hook_infos[psm_dd_hook_info_size-1].sleep_param_ptr;
|
||||
psm_dd_hook_infos[i].wakeup_hook_fun = psm_dd_hook_infos[psm_dd_hook_info_size-1].wakeup_hook_fun;
|
||||
psm_dd_hook_infos[i].wakeup_param_ptr = psm_dd_hook_infos[psm_dd_hook_info_size-1].wakeup_param_ptr;
|
||||
|
||||
// Then erase the last item
|
||||
psm_dd_hook_infos[psm_dd_hook_info_size-1].nDeviceId = 0;
|
||||
psm_dd_hook_infos[psm_dd_hook_info_size-1].sleep_hook_fun = NULL;
|
||||
psm_dd_hook_infos[psm_dd_hook_info_size-1].sleep_param_ptr = NULL;
|
||||
psm_dd_hook_infos[psm_dd_hook_info_size-1].wakeup_hook_fun = NULL;
|
||||
psm_dd_hook_infos[psm_dd_hook_info_size-1].wakeup_param_ptr = NULL;
|
||||
} else {
|
||||
// we only have one item, just erase it
|
||||
psm_dd_hook_infos[i].nDeviceId = 0;
|
||||
psm_dd_hook_infos[i].sleep_hook_fun = NULL;
|
||||
psm_dd_hook_infos[i].sleep_param_ptr = NULL;
|
||||
psm_dd_hook_infos[i].wakeup_hook_fun = NULL;
|
||||
psm_dd_hook_infos[i].wakeup_param_ptr = NULL;
|
||||
}
|
||||
psm_dd_hook_info_size--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pmu_set_pll_reserved(unsigned char reserve) {
|
||||
reserve_pll = reserve;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef _FREERTOS_PMU_8195A_H_
|
||||
#define _FREERTOS_PMU_8195A_H_
|
||||
|
||||
#endif
|
||||
555
lib/amb1_sdk/soc/realtek/8195a/misc/os/mailbox.c
Normal file
555
lib/amb1_sdk/soc/realtek/8195a/misc/os/mailbox.c
Normal file
@@ -0,0 +1,555 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*
|
||||
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#define _MAILBOX_C_
|
||||
|
||||
#include "mailbox.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Function Prototype Declaration
|
||||
******************************************************************************/
|
||||
static PRTL_MAILBOX RtlMBoxIdToHdl(IN u8 MBoxId);
|
||||
|
||||
PRTL_MAILBOX RtlMailboxCreate(IN u8 MboxID, IN u32 MboxSize, IN _Sema *pWakeSema);
|
||||
|
||||
VOID RtlMailboxDel(IN PRTL_MAILBOX MboxHdl);
|
||||
|
||||
u8 RtlMailboxSendToBack(
|
||||
IN u8 MboxID,
|
||||
IN MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
);
|
||||
|
||||
u8 RtlMailboxSendToFront(
|
||||
IN u8 MboxID,
|
||||
IN MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
);
|
||||
|
||||
u8 RtlMailboxReceive(
|
||||
IN u8 MboxID,
|
||||
OUT MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
);
|
||||
|
||||
u8 RtlMailboxPeek(
|
||||
IN u8 MboxID,
|
||||
OUT MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
);
|
||||
|
||||
u32 RtlMailboxMsgWaiting(
|
||||
IN u8 MboxID,
|
||||
IN u8 IsFromISR
|
||||
);
|
||||
|
||||
/******************************************************************************
|
||||
* Global Variable Declaration
|
||||
******************************************************************************/
|
||||
static RTL_MBOX_ROOT MBox_Entry;
|
||||
|
||||
/******************************************************************************
|
||||
* External Function & Variable Declaration
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlMBoxIdToHdl
|
||||
* Desc: Map a mailbox ID to the mailbox pointer.
|
||||
* Para:
|
||||
* MBoxId: The Mailbox ID
|
||||
* Return: The pointer of the mailbox. If didn't found match mailbox,
|
||||
* return NULL.
|
||||
*
|
||||
******************************************************************************/
|
||||
static PRTL_MAILBOX RtlMBoxIdToHdl(
|
||||
IN u8 MBoxId
|
||||
)
|
||||
{
|
||||
RTL_MAILBOX *pMbox=NULL;
|
||||
RTL_MAILBOX *pTmpMbox;
|
||||
_LIST *pHead;
|
||||
_LIST *pList;
|
||||
|
||||
// if the Mailbox root entry initialed ? if not, initial it
|
||||
if (!MBox_Entry.isInitialed) {
|
||||
RtlMutexInit(&MBox_Entry.Mutex); // Init the Mutex for the mailbox add/delete procedure protection
|
||||
RtlInitListhead(&MBox_Entry.mbox_list); // Init the link list head to chain all created mailbox
|
||||
MBox_Entry.isInitialed = 1;
|
||||
MSG_MBOX_INFO("MBox Entry Initial...\n");
|
||||
}
|
||||
|
||||
pHead = &MBox_Entry.mbox_list;
|
||||
RtlDownMutex(&MBox_Entry.Mutex);
|
||||
pList = RtlListGetNext(&MBox_Entry.mbox_list);
|
||||
while (pList != pHead) {
|
||||
pTmpMbox = CONTAINER_OF(pList, RTL_MAILBOX, mbox_list);
|
||||
if (MBoxId == pTmpMbox->mbox_id) {
|
||||
pMbox = pTmpMbox;
|
||||
break;
|
||||
}
|
||||
pList = RtlListGetNext(pList);
|
||||
}
|
||||
RtlUpMutex(&MBox_Entry.Mutex);
|
||||
|
||||
return pMbox;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlMailboxCreate
|
||||
* Desc: To create a mailbox with a given mailbox ID and size
|
||||
* Para:
|
||||
* MboxID: A number to identify this created mailbox. A message block can
|
||||
* be send to a mailbox by a given MboxID. The MboxID must be unique
|
||||
* in the whole system. If this MboxID is conflict with a created
|
||||
* mailbox, the mailbox creation will fail and return NULL.
|
||||
* MboxSize: The size of this mailbox to be created. It means maximum number
|
||||
* of message blocks can be stored in this mailbox.
|
||||
* pWakeSema: The semaphore to wake up the receiving task to receive the new
|
||||
* message. If the receiving task doesn't need a semaphore to wakeup
|
||||
* it, then just let this pointer is NULL.
|
||||
* Return: The created mailbox pointer. If it failed, return NULL.
|
||||
******************************************************************************/
|
||||
PRTL_MAILBOX RtlMailboxCreate(
|
||||
IN u8 MboxID,
|
||||
IN u32 MboxSize,
|
||||
IN _Sema *pWakeSema
|
||||
)
|
||||
{
|
||||
PRTL_MAILBOX pMBox=NULL;
|
||||
|
||||
// if the Mailbox root entry initialed ? if not, initial it
|
||||
if (!MBox_Entry.isInitialed) {
|
||||
RtlMutexInit(&MBox_Entry.Mutex); // Init the Mutex for the mailbox add/delete procedure protection
|
||||
RtlInitListhead(&MBox_Entry.mbox_list); // Init the link list head to chain all created mailbox
|
||||
MBox_Entry.isInitialed = 1;
|
||||
MSG_MBOX_INFO("MBox Entry Initial...\n");
|
||||
}
|
||||
|
||||
// check if this mailbox ID is ocupied ?
|
||||
pMBox = RtlMBoxIdToHdl(MboxID);
|
||||
if (NULL != pMBox) {
|
||||
MSG_MBOX_ERR("RtlMailboxCreate: The Mailbox ID %d is used by someone!!\n", MboxID);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pMBox = (RTL_MAILBOX *)RtlZmalloc(sizeof(RTL_MAILBOX));
|
||||
if (NULL==pMBox) {
|
||||
MSG_MBOX_ERR("RtlMailboxCreate: MAlloc Failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RtlInitListhead(&pMBox->mbox_list); // Init the link list to be chained into the created mailbox list
|
||||
pMBox->mbox_id = MboxID;
|
||||
pMBox->pWakeSema = pWakeSema;
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
pMBox->mbox_hdl = xQueueCreate(MboxSize, sizeof(MSG_BLK));
|
||||
if (NULL == pMBox->mbox_hdl) {
|
||||
MSG_MBOX_ERR("RtlMailboxCreate: xQueueCreate Failed\n");
|
||||
RtlMfree((void *)pMBox, sizeof(RTL_MAILBOX));
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef PLATFORM_ECOS
|
||||
// TODO: Create mailbox
|
||||
#endif
|
||||
|
||||
// Add this mailbox to the link list of created mailbox
|
||||
RtlDownMutex(&MBox_Entry.Mutex);
|
||||
RtlListInsertTail(&pMBox->mbox_list, &MBox_Entry.mbox_list);
|
||||
RtlUpMutex(&MBox_Entry.Mutex);
|
||||
|
||||
MSG_MBOX_INFO("A Mailbox Created: Size=%d\n", MboxSize);
|
||||
|
||||
return pMBox;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlMailboxDel
|
||||
* Desc: To delete a mailbox by a given mailbox handle.
|
||||
* Para:
|
||||
* MboxHdl: The handle of the mailbox to be deleted.
|
||||
* Return: None.
|
||||
******************************************************************************/
|
||||
VOID RtlMailboxDel(
|
||||
IN PRTL_MAILBOX MboxHdl
|
||||
)
|
||||
{
|
||||
if (NULL == MboxHdl) {
|
||||
MSG_MBOX_ERR("RtlMailboxDel: Try to delete a NULL mailbox\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove this mailbox from the link list of created mailbox
|
||||
RtlDownMutex(&MBox_Entry.Mutex);
|
||||
RtlListDelete(&MboxHdl->mbox_list);
|
||||
RtlUpMutex(&MBox_Entry.Mutex);
|
||||
|
||||
// delete the Queue/Mailbox
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
vQueueDelete((xQueueHandle)(MboxHdl->mbox_hdl));
|
||||
#endif
|
||||
#ifdef PLATFORM_ECOS
|
||||
// TODO: Delete mailbox
|
||||
#endif
|
||||
|
||||
RtlMfree((void *)MboxHdl, sizeof(RTL_MAILBOX));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlMailboxSendToBack
|
||||
* Desc: To put a message block to the tail of a given mailbox.
|
||||
* Para:
|
||||
* MboxID: The identifier of the target mailbox.
|
||||
* pMsg: The pointer of the message block to be put into the mailbox.
|
||||
* MSToWait: If the mailbox is full, this value gives a time to wait to put
|
||||
* this message. The time unit is millisecond.
|
||||
* The special values are:
|
||||
* 0: no waiting;
|
||||
* 0xffffffff: wait without timeout.
|
||||
* If the waiting is timeout, the message sending is failed and
|
||||
* return _FAIL.
|
||||
* IsFromISR: Is this function is called from an ISR ?
|
||||
* Return: _SUCCESS or _FAIL.
|
||||
******************************************************************************/
|
||||
u8 RtlMailboxSendToBack(
|
||||
IN u8 MboxID,
|
||||
IN MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
)
|
||||
{
|
||||
RTL_MAILBOX *pMbox=NULL;
|
||||
u32 wait_ticks;
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
portBASE_TYPE ret;
|
||||
#endif
|
||||
|
||||
pMbox = RtlMBoxIdToHdl(MboxID);
|
||||
|
||||
if (NULL == pMbox) {
|
||||
MSG_MBOX_ERR("RtlMailboxSendToBack: Didn't find matched MBoxID=%d\n", MboxID);
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
|
||||
wait_ticks = portMAX_DELAY;
|
||||
}
|
||||
else if (MBOX_WAIT_NONE == MSToWait) {
|
||||
wait_ticks = 0;
|
||||
}
|
||||
else {
|
||||
wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
|
||||
}
|
||||
|
||||
if (IsFromISR) {
|
||||
ret = xQueueSendToBackFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//(portTickType) wait_ticks);
|
||||
}
|
||||
else {
|
||||
ret = xQueueSendToBack(pMbox->mbox_hdl, (void *)pMsg, (portTickType) wait_ticks);
|
||||
}
|
||||
|
||||
if(ret != pdPASS ) {
|
||||
// send message to the queue failed
|
||||
MSG_MBOX_ERR("RtlMailboxSendToBack: Put Msg to Queue Failed, MBoxID=%d\n", MboxID);
|
||||
ret = _FAIL;
|
||||
}
|
||||
else {
|
||||
// try to give a semaphore to wake up the receiving task
|
||||
if (pMbox->pWakeSema) {
|
||||
RtlUpSema(pMbox->pWakeSema);
|
||||
}
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_ECOS
|
||||
// TODO: Put the message to a mailbox
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlMailboxSendToFront
|
||||
* Desc: To put a message block to the head of a mailbox.
|
||||
* Para:
|
||||
* MboxID: The identifier of the target mailbox.
|
||||
* pMsg: The pointer of the message block to be put into the mailbox.
|
||||
* MSToWait: If the mailbox is full, this value gives a time to wait to put
|
||||
* this message. The time unit is millisecond.
|
||||
* The special values are:
|
||||
* 0: no waiting;
|
||||
* 0xffffffff: wait without timeout.
|
||||
* If the waiting is timeout, the message sending is failed and
|
||||
* return _FAIL.
|
||||
* IsFromISR: Is this function is called from an ISR ?
|
||||
* Return: _SUCCESS or _FAIL.
|
||||
******************************************************************************/
|
||||
u8 RtlMailboxSendToFront(
|
||||
IN u8 MboxID,
|
||||
IN MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
)
|
||||
{
|
||||
RTL_MAILBOX *pMbox=NULL;
|
||||
u32 wait_ticks;
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
portBASE_TYPE ret;
|
||||
#endif
|
||||
|
||||
pMbox = RtlMBoxIdToHdl(MboxID);
|
||||
|
||||
if (NULL == pMbox) {
|
||||
MSG_MBOX_ERR("RtlMailboxSendToBack: Didn't find matched MBoxID=%d\n", MboxID);
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
|
||||
wait_ticks = portMAX_DELAY;
|
||||
}
|
||||
else if (MBOX_WAIT_NONE == MSToWait) {
|
||||
wait_ticks = 0;
|
||||
}
|
||||
else {
|
||||
wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
|
||||
}
|
||||
|
||||
if (IsFromISR) {
|
||||
ret = xQueueSendToFrontFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//(portTickType) wait_ticks);
|
||||
}
|
||||
else {
|
||||
ret = xQueueSendToFront(pMbox->mbox_hdl, (void *)pMsg, (portTickType) wait_ticks);
|
||||
}
|
||||
|
||||
if(ret != pdPASS ) {
|
||||
// send message to the queue failed
|
||||
MSG_MBOX_ERR("RtlMailboxSendToBack: Put Msg to Queue Failed, MBoxID=%d\n", MboxID);
|
||||
ret = _FAIL;
|
||||
}
|
||||
else {
|
||||
// try to give a semaphore to wake up the receiving task
|
||||
if (pMbox->pWakeSema) {
|
||||
RtlUpSema(pMbox->pWakeSema);
|
||||
}
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_ECOS
|
||||
// TODO: eCos has no API to put message to the head of a mailbox
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlMailboxSendToFront
|
||||
* Desc: To get a message block from a given mailbox.
|
||||
* Para:
|
||||
* MboxID: The identifier of the target mailbox.
|
||||
* pMsg: The message block to store the gotten message.
|
||||
* MSToWait: If the mailbox is full, this value gives a time to wait to put
|
||||
* this message. The time unit is millisecond.
|
||||
* The special values are:
|
||||
* 0: no waiting;
|
||||
* 0xffffffff: wait without timeout.
|
||||
* If the waiting is timeout, the message sending is failed and
|
||||
* return _FAIL.
|
||||
* IsFromISR: Is this function is called from an ISR ?
|
||||
* Return: _SUCCESS or _FAIL.
|
||||
******************************************************************************/
|
||||
u8 RtlMailboxReceive(
|
||||
IN u8 MboxID,
|
||||
OUT MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
)
|
||||
{
|
||||
RTL_MAILBOX *pMbox=NULL;
|
||||
u32 wait_ticks;
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
portBASE_TYPE ret;
|
||||
#endif
|
||||
|
||||
pMbox = RtlMBoxIdToHdl(MboxID);
|
||||
|
||||
if (NULL == pMbox) {
|
||||
MSG_MBOX_ERR("RtlMailboxReceive: Didn't find the MBox with ID=%d\n", MboxID);
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
if (MBOX_WAIT_NONE == MSToWait) {
|
||||
wait_ticks = 0;
|
||||
}
|
||||
else if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
|
||||
wait_ticks = portMAX_DELAY;
|
||||
}
|
||||
else {
|
||||
wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
|
||||
}
|
||||
|
||||
if (IsFromISR) {
|
||||
ret = xQueueReceiveFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//( portTickType ) wait_ticks);
|
||||
}
|
||||
else {
|
||||
ret = xQueueReceive(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks);
|
||||
|
||||
}
|
||||
|
||||
if(ret != pdTRUE ) {
|
||||
// receive message failed
|
||||
if (0 != MSToWait) {
|
||||
MSG_MBOX_ERR("RtlMailboxReceive: Receive Msg Failed, MBoxID=%d\n", MboxID);
|
||||
}
|
||||
ret = _FAIL;
|
||||
}
|
||||
else {
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_ECOS
|
||||
// TODO: Get a message from the mailbox
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlMailboxPeek
|
||||
* Desc: To copy the head message from a given mailbox without move this
|
||||
* message block out from the mailbox.
|
||||
* Para:
|
||||
* MboxID: The identifier of the target mailbox.
|
||||
* pMsg: The message block to store the gotten message.
|
||||
* MSToWait: If the mailbox is full, this value gives a time to wait to put
|
||||
* this message. The time unit is millisecond.
|
||||
* The special values are:
|
||||
* 0: no waiting;
|
||||
* 0xffffffff: wait without timeout.
|
||||
* If the waiting is timeout, the message sending is failed and
|
||||
* return _FAIL.
|
||||
* IsFromISR: Is this function is called from an ISR ?
|
||||
* Return: _SUCCESS or _FAIL.
|
||||
******************************************************************************/
|
||||
u8 RtlMailboxPeek(
|
||||
IN u8 MboxID,
|
||||
OUT MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
)
|
||||
{
|
||||
RTL_MAILBOX *pMbox=NULL;
|
||||
u32 wait_ticks;
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
portBASE_TYPE ret;
|
||||
#endif
|
||||
|
||||
pMbox = RtlMBoxIdToHdl(MboxID);
|
||||
|
||||
if (NULL == pMbox) {
|
||||
MSG_MBOX_ERR("RtlMailboxPeek: Didn't find the MBox with ID=%d\n", MboxID);
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
if (MBOX_WAIT_NONE == MSToWait) {
|
||||
wait_ticks = 0;
|
||||
}
|
||||
else if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
|
||||
wait_ticks = portMAX_DELAY;
|
||||
}
|
||||
else {
|
||||
wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
|
||||
}
|
||||
|
||||
if (IsFromISR) {
|
||||
// ret = xQueuePeekFromISR(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks);
|
||||
// TODO: check why we have no "xQueuePeekFromISR"
|
||||
MSG_MBOX_ERR("RtlMailboxPeek: Current version has no 'xQueuePeekFromISR'\n");
|
||||
ret = pdFALSE;
|
||||
}
|
||||
else {
|
||||
ret = xQueuePeek(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks);
|
||||
|
||||
}
|
||||
|
||||
if(ret != pdTRUE ) {
|
||||
// receive message failed
|
||||
MSG_MBOX_ERR("RtlMailboxReceive: Receive Msg Failed, MBoxID=%d\n", MboxID);
|
||||
ret = _FAIL;
|
||||
}
|
||||
else {
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_ECOS
|
||||
// TODO: Get a message from the mailbox
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlMailboxMsgWaiting
|
||||
* Desc: To get the number of message blocks are storing in a given mailbox.
|
||||
* Para:
|
||||
* MboxID: The identifier of the target mailbox.
|
||||
* IsFromISR: Is this function is called from an ISR ?
|
||||
* Return: The number of message blocks are storing in this mailbox.
|
||||
******************************************************************************/
|
||||
u32 RtlMailboxMsgWaiting(
|
||||
IN u8 MboxID,
|
||||
IN u8 IsFromISR
|
||||
)
|
||||
{
|
||||
RTL_MAILBOX *pMbox=NULL;
|
||||
u32 msg_num=0;
|
||||
|
||||
pMbox = RtlMBoxIdToHdl(MboxID);
|
||||
|
||||
if (NULL == pMbox) {
|
||||
MSG_MBOX_ERR("RtlMailboxMsgWaiting: Didn't find the MBox with ID=%d\n", MboxID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
if (IsFromISR) {
|
||||
msg_num = uxQueueMessagesWaitingFromISR(pMbox->mbox_hdl);
|
||||
}
|
||||
else {
|
||||
msg_num = uxQueueMessagesWaiting(pMbox->mbox_hdl);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_ECOS
|
||||
// TODO: call eCos API to implement this function
|
||||
#endif
|
||||
|
||||
return msg_num;
|
||||
|
||||
}
|
||||
|
||||
117
lib/amb1_sdk/soc/realtek/8195a/misc/os/mailbox.h
Normal file
117
lib/amb1_sdk/soc/realtek/8195a/misc/os/mailbox.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*
|
||||
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __MAILBOX_H_
|
||||
#define __MAILBOX_H_
|
||||
|
||||
#include "hal_api.h"
|
||||
#include "osdep_api.h"
|
||||
#include "hal_util.h"
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
#include "queue.h"
|
||||
#endif
|
||||
|
||||
#define MBOX_WAIT_NO_TIMEOUT 0xffffffff // waiting for send/receive message with no timeout
|
||||
#define MBOX_WAIT_NONE 0 // No wait for send/receive message
|
||||
|
||||
typedef enum _MAILBOX_ID_ {
|
||||
MBOX_ID_WLAN = 0,
|
||||
MBOX_ID_UART = 1,
|
||||
MBOX_ID_I2C = 2,
|
||||
MBOX_ID_I2S = 3,
|
||||
MBOX_ID_SPI = 4,
|
||||
MBOX_ID_SDIO = 5,
|
||||
MBOX_ID_SDIO_MP = 6,
|
||||
|
||||
MBOX_ID_MAX = 0xff
|
||||
} MAILBOX_ID;
|
||||
|
||||
#if defined(CONFIG_SDIO_DEVICE_EN) && defined(CONFIG_SDIO_DEVICE_NORMAL)
|
||||
typedef enum _MSG_TYPE_SDIO {
|
||||
MSG_SDIO_RX_PKT=1, // request to send a SDIO RX packet to the host side
|
||||
MSG_SDIO_C2H=2, // request to send a C2H message
|
||||
MSG_SDIO_RPWM=3, // request to set the RPWM
|
||||
MSG_SDIO_MP_LOOP_TXPKT=4, // request to loopback this TX packet
|
||||
|
||||
MSG_SDIO_MAX=0xff
|
||||
} MSG_TYPE_SDIO;
|
||||
#endif // end of "#ifdef CONFIG_SDIO_DEVICE_EN"
|
||||
|
||||
/* the data structure of a MailBox to deliver message blocks */
|
||||
typedef struct _RTL_MAILBOX_ {
|
||||
void *mbox_hdl; // the mailbox handle which return from OS create queue API
|
||||
_Sema *pWakeSema; // the semaphore to wakeup the message receiving task
|
||||
_LIST mbox_list; // the link list to chain all created mailbox
|
||||
u8 mbox_id; /* the ID of this Mailbox, this ID is
|
||||
used to locate the MBox for send/get message */
|
||||
} RTL_MAILBOX, *PRTL_MAILBOX;
|
||||
|
||||
/* the data structure of a message block */
|
||||
typedef struct _RTL_MSG_BLK {
|
||||
u8 MsgType; // the message type
|
||||
u8 Reserved; // reserved
|
||||
u16 DateLen; // the vaild data length of the pBuf
|
||||
u32 Para; // the optional parameters associated with this message type
|
||||
u8 *pBuf; // point to a data buffer associated with this message type
|
||||
} MSG_BLK, *PMSG_BLK;
|
||||
|
||||
/* the data structure for system level message block management */
|
||||
typedef struct _RTL_MBOX_ROOT_ {
|
||||
_LIST mbox_list; // the link list of all created mailbox
|
||||
_Mutex Mutex; // the Mutex to protect the mailbox create/delete procedure
|
||||
u8 isInitialed; // is this Mailbox link-list initialed
|
||||
} RTL_MBOX_ROOT, *PRTL_MBOX_ROOT;
|
||||
|
||||
// Export Funcction API
|
||||
extern PRTL_MAILBOX RtlMailboxCreate(
|
||||
IN u8 MboxID,
|
||||
IN u32 MboxSize,
|
||||
IN _Sema *pWakeSema
|
||||
);
|
||||
|
||||
extern VOID RtlMailboxDel(
|
||||
IN PRTL_MAILBOX MboxHdl
|
||||
);
|
||||
|
||||
extern u8 RtlMailboxSendToBack(
|
||||
IN u8 MboxID,
|
||||
IN MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
);
|
||||
|
||||
extern u8 RtlMailboxSendToFront(
|
||||
IN u8 MboxID,
|
||||
IN MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
);
|
||||
|
||||
extern u8 RtlMailboxReceive(
|
||||
IN u8 MboxID,
|
||||
OUT MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
);
|
||||
|
||||
extern u8 RtlMailboxPeek(
|
||||
IN u8 MboxID,
|
||||
OUT MSG_BLK *pMsg,
|
||||
IN u32 MSToWait,
|
||||
IN u8 IsFromISR
|
||||
);
|
||||
|
||||
extern u32 RtlMailboxMsgWaiting(
|
||||
IN u8 MboxID,
|
||||
IN u8 IsFromISR
|
||||
);
|
||||
|
||||
|
||||
#endif // #ifndef __MAILBOX_H_
|
||||
|
||||
36
lib/amb1_sdk/soc/realtek/8195a/misc/os/os_support.h
Normal file
36
lib/amb1_sdk/soc/realtek/8195a/misc/os/os_support.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: sys-support.h - System type support for Linux
|
||||
* $Revision: 1.1.1.1 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __OS_SUPPORT_H__
|
||||
#define __OS_SUPPORT_H__
|
||||
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <basic_types.h>
|
||||
#include "task.h"
|
||||
#include "osdep_service.h"
|
||||
|
||||
#define RTL_HZ 100
|
||||
|
||||
#define RtlKmalloc(size, flag) pvPortMalloc(size)
|
||||
#define RtlKfree(pv) vPortFreeAligned(pv)
|
||||
|
||||
|
||||
#ifdef CONFIG_TIMER_MODULE
|
||||
#define __Delay(t) HalDelayUs(t)
|
||||
#else
|
||||
static __inline__ u32 __Delay(u32 us)
|
||||
{
|
||||
DBG_8195A("No Delay: please enable hardware Timer\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define Mdelay(t) __Delay(t*1000)
|
||||
#define Udelay(t) __Delay(t)
|
||||
|
||||
#endif /* __SYS_SUPPORT_H__ */
|
||||
165
lib/amb1_sdk/soc/realtek/8195a/misc/os/os_timer.h
Normal file
165
lib/amb1_sdk/soc/realtek/8195a/misc/os/os_timer.h
Normal file
@@ -0,0 +1,165 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: sys-support.h - System type support for Linux
|
||||
* $Revision: 1.1.1.1 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __OS_TIMER_H__
|
||||
#define __OS_TIMER_H__
|
||||
|
||||
#include "diag.h"
|
||||
#include "os_support.h"
|
||||
#include "osdep_service.h"
|
||||
|
||||
|
||||
#define JIFFIES xTaskGetTickCount()
|
||||
|
||||
enum {
|
||||
TIMER_NO_INIT = 0,
|
||||
TIMER_INIT = 1,
|
||||
TIMER_START = 2,
|
||||
TIMER_DISABLE = 3
|
||||
};
|
||||
|
||||
struct TIMER_LIST {
|
||||
_timerHandle TimeHdl;
|
||||
u32 Flag;
|
||||
unsigned long Data;
|
||||
VOID (*Function)(void *);
|
||||
u32 TimerID;
|
||||
};
|
||||
|
||||
static inline VOID InitTimer(IN struct TIMER_LIST *Timer)
|
||||
{
|
||||
u32 TimerID = Timer->TimerID;
|
||||
VOID (*Function)(VOID *) = Timer->Function;
|
||||
|
||||
save_and_cli();
|
||||
|
||||
if (Timer->Flag != TIMER_DISABLE) {
|
||||
if (Timer->Flag == TIMER_NO_INIT) {
|
||||
Timer->TimeHdl = rtw_timerCreate( (const char *)"Timer", // Just a test name, not used by the kernel.
|
||||
( 100 ), // The timer period in ticks.
|
||||
_FALSE, // The timers will auto-reload themselves when they expire.
|
||||
( void * ) TimerID, // Assign each timer a unique id equal to its array index.
|
||||
Function
|
||||
#ifdef RTK_MODE_TIMER
|
||||
,data // Each timer calls the same callback when it expires.
|
||||
#endif
|
||||
);
|
||||
if (NULL == Timer->TimeHdl) {
|
||||
DBG_ERROR_LOG("\rInitial Timer fail !!!!!!!!!\n");
|
||||
}
|
||||
else {
|
||||
TimerID++;
|
||||
}
|
||||
|
||||
Timer->Flag = TIMER_INIT;
|
||||
}
|
||||
else if (Timer->Flag == TIMER_START) {
|
||||
rtw_timerStop(Timer->TimeHdl,0);
|
||||
Timer->Flag = TIMER_DISABLE;
|
||||
}
|
||||
}
|
||||
|
||||
restore_flags();
|
||||
}
|
||||
|
||||
static inline void ModTimer(IN struct TIMER_LIST *Timer, IN u32 TimeoutTicks)
|
||||
{
|
||||
#ifndef PLATFORM_FREERTOS
|
||||
u32 Flags;
|
||||
#endif
|
||||
|
||||
void (*Function)(void *) = Timer->Function;
|
||||
|
||||
save_and_cli();
|
||||
|
||||
if (Timer->Flag == TIMER_NO_INIT) {
|
||||
if (Timer->Function) {
|
||||
Timer->TimeHdl = rtw_timerCreate((const char *)"Timer", // Just a text name, not used by the kernel.
|
||||
( 100 ), // The timer period in ticks.
|
||||
_FALSE, // The timers will auto-reload themselves when they expire.
|
||||
( void * ) Timer->TimerID, // Assign each timer a unique id equal to its array index.
|
||||
Function
|
||||
#ifdef RTK_MODE_TIMER
|
||||
,Timer->Data // Each timer calls the same callback when it expires.
|
||||
#endif
|
||||
);
|
||||
if (NULL == Timer->TimeHdl) {
|
||||
DBG_ERROR_LOG("\rInitial Timer fail !!!!!!!!!\n");
|
||||
}
|
||||
else {
|
||||
Timer->TimerID++;
|
||||
}
|
||||
|
||||
Timer->Flag = TIMER_INIT;
|
||||
}
|
||||
else {
|
||||
restore_flags();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (Timer->Flag == TIMER_START) {
|
||||
rtw_timerStop(Timer->TimeHdl,0);
|
||||
Timer->Flag = TIMER_DISABLE;
|
||||
}
|
||||
|
||||
TimeoutTicks -= rtw_get_current_time();
|
||||
if (TimeoutTicks <= 0)
|
||||
TimeoutTicks = 2;
|
||||
|
||||
if (xTimerStart(Timer->TimeHdl, TimeoutTicks ))
|
||||
Timer->Flag = TIMER_START;
|
||||
else
|
||||
DBG_ERROR_LOG("\r###mod_timer() - no slots available###\n");
|
||||
restore_flags();
|
||||
}
|
||||
|
||||
|
||||
static inline int TimerPending (IN const struct TIMER_LIST *Timer)
|
||||
{
|
||||
if (Timer->TimeHdl && Timer->Flag != TIMER_NO_INIT)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void DelTimerSync(IN struct TIMER_LIST *Timer)
|
||||
{
|
||||
save_and_cli();
|
||||
|
||||
if (Timer->TimeHdl && Timer->Flag != TIMER_INIT) {
|
||||
if (Timer->Flag == TIMER_START)
|
||||
rtw_timerStop(Timer->TimeHdl, 0);
|
||||
|
||||
rtw_timerDelete(Timer->TimeHdl, 0);
|
||||
Timer->Flag = TIMER_NO_INIT;
|
||||
}
|
||||
|
||||
restore_flags();
|
||||
}
|
||||
|
||||
/*
|
||||
* These inlines deal with timer wrapping correctly. You are
|
||||
* strongly encouraged to use them
|
||||
* 1. Because people otherwise forget
|
||||
* 2. Because if the timer wrap changes in future you wont have to
|
||||
* alter your driver code.
|
||||
*
|
||||
* time_after(a,b) returns true if the time a is after time b.
|
||||
*
|
||||
* Do this with "<0" and ">=0" to only test the sign of the result. A
|
||||
* good compiler would generate better code (and a really good compiler
|
||||
* wouldn't care). Gcc is currently neither.
|
||||
*/
|
||||
#define TIME_AFTER(a,b) ((long)(b) - (long)(a) < 0)
|
||||
#define TIMER_BEFORE(a,b) TIME_AFTER(b,a)
|
||||
|
||||
#define TIME_AFTER_EQ(a,b) ((long)(a) - (long)(b) >= 0)
|
||||
#define TIMER_BEFORE_EQ(a,b) TIME_AFTER_EQ(b,a)
|
||||
|
||||
|
||||
|
||||
#endif //__OS_TIMER_H__
|
||||
524
lib/amb1_sdk/soc/realtek/8195a/misc/os/osdep_api.c
Normal file
524
lib/amb1_sdk/soc/realtek/8195a/misc/os/osdep_api.c
Normal file
@@ -0,0 +1,524 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*
|
||||
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#define _OSDEP_API_C_
|
||||
|
||||
#include <osdep_api.h>
|
||||
#include "osdep_service.h"
|
||||
|
||||
extern _LONG_CALL_ char *_strcpy(char *dest, const char *src);
|
||||
extern _LONG_CALL_ VOID *_memset(void *dst0, int Val,SIZE_T length);
|
||||
|
||||
u8* RtlMalloc(IN u32 sz)
|
||||
{
|
||||
u8 *pbuf=NULL;
|
||||
|
||||
pbuf = rtw_malloc((u32)sz);
|
||||
|
||||
return pbuf;
|
||||
}
|
||||
|
||||
|
||||
u8* RtlZmalloc(IN u32 sz)
|
||||
{
|
||||
u8 *pbuf;
|
||||
|
||||
pbuf= rtw_malloc((u32)sz);
|
||||
|
||||
if (pbuf != NULL) {
|
||||
_memset(pbuf, 0, sz);
|
||||
}
|
||||
|
||||
return pbuf;
|
||||
}
|
||||
|
||||
VOID RtlMfree(IN u8 *pbuf, IN u32 sz)
|
||||
{
|
||||
rtw_mfree(pbuf, sz);
|
||||
}
|
||||
|
||||
VOID* RtlMalloc2d(IN u32 h, IN u32 w, IN u32 size)
|
||||
{
|
||||
u32 j;
|
||||
|
||||
VOID **a = (VOID **) rtw_malloc2d(h, w, size);
|
||||
if(a == NULL)
|
||||
{
|
||||
DBG_ERROR_LOG("%s: alloc memory fail!\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
VOID RtlMfree2d(IN VOID *pbuf, IN u32 h, IN u32 w, IN u32 size)
|
||||
{
|
||||
rtw_mfree2d(pbuf, h, w, size);
|
||||
}
|
||||
|
||||
VOID RtlInitSema(IN _Sema *sema, IN u32 init_val)
|
||||
{
|
||||
rtw_init_sema(sema, init_val);
|
||||
}
|
||||
|
||||
VOID RtlFreeSema(IN _Sema *sema)
|
||||
{
|
||||
rtw_free_sema(sema);
|
||||
}
|
||||
|
||||
VOID RtlUpSema(IN _Sema *sema)
|
||||
{
|
||||
rtw_up_sema(sema);
|
||||
}
|
||||
|
||||
VOID RtlUpSemaFromISR(IN _Sema *sema)
|
||||
{
|
||||
rtw_up_sema_from_isr(sema);
|
||||
}
|
||||
|
||||
u32 RtlDownSema(IN _Sema *sema)
|
||||
{
|
||||
rtw_down_sema(sema);
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
u32 RtlDownSemaWithTimeout(IN _Sema *sema,IN u32 ms)
|
||||
{
|
||||
return rtw_down_timeout_sema(sema, ms);
|
||||
}
|
||||
|
||||
VOID RtlMutexInit(IN _Mutex *pmutex)
|
||||
{
|
||||
rtw_mutex_init(pmutex);
|
||||
}
|
||||
|
||||
VOID RtlMutexFree(IN _Mutex *pmutex)
|
||||
{
|
||||
rtw_mutex_free(pmutex);
|
||||
}
|
||||
|
||||
VOID RtlSpinlockInit(IN _Lock *plock)
|
||||
{
|
||||
rtw_spinlock_init((_lock *)plock);
|
||||
}
|
||||
|
||||
VOID RtlSpinlockFree(IN _Lock *plock)
|
||||
{
|
||||
rtw_spinlock_free((_lock *)plock);
|
||||
}
|
||||
|
||||
VOID RtlSpinlock(IN _Lock *plock)
|
||||
{
|
||||
rtw_spin_lock((_lock *)plock);
|
||||
}
|
||||
|
||||
VOID RtlSpinunlock(IN _Lock *plock)
|
||||
{
|
||||
rtw_spin_unlock((_lock *)plock);
|
||||
}
|
||||
|
||||
VOID RtlSpinlockEx(IN _Lock *plock)
|
||||
{
|
||||
}
|
||||
|
||||
VOID RtlSpinunlockEx(IN _Lock *plock)
|
||||
{
|
||||
}
|
||||
|
||||
u32 RtlGetCurrentTime(VOID)
|
||||
{
|
||||
return rtw_get_current_time();
|
||||
}
|
||||
|
||||
VOID RtlSleepSchedulable(IN u32 ms)
|
||||
{
|
||||
}
|
||||
|
||||
VOID RtlMsleepOS(IN u32 ms)
|
||||
{
|
||||
rtw_msleep_os(ms);
|
||||
}
|
||||
|
||||
VOID RtlUsleepOS(IN u32 us)
|
||||
{
|
||||
rtw_usleep_os(us);
|
||||
}
|
||||
|
||||
VOID RtlMdelayOS(IN u32 ms)
|
||||
{
|
||||
rtw_mdelay_os(ms);
|
||||
}
|
||||
|
||||
VOID RtlUdelayOS(IN u32 us)
|
||||
{
|
||||
rtw_udelay_os(us);
|
||||
}
|
||||
|
||||
VOID RtlYieldOS(VOID)
|
||||
{
|
||||
rtw_yield_os();
|
||||
}
|
||||
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
u64 RtlModular64(IN u64 n, IN u64 base)
|
||||
{
|
||||
unsigned int __base = (base);
|
||||
unsigned int __rem;
|
||||
//(void)(((typeof((n)) *)0) == ((__uint64_t *)0));
|
||||
if (((n) >> 32) == 0) {
|
||||
__rem = (unsigned int)(n) % __base;
|
||||
(n) = (unsigned int)(n) / __base;
|
||||
} else
|
||||
__rem = __Div64_32(&(n), __base);
|
||||
return __rem;
|
||||
|
||||
}
|
||||
#else
|
||||
u64 RtlModular64(IN u64 x, IN u64 y)
|
||||
{
|
||||
return rtw_modular64(x, y);
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlTimerCallbckEntry
|
||||
* Desc: This function is a timer callback wrapper. All OS timer callback
|
||||
* will call this function and then call the real callback function inside
|
||||
* this function.
|
||||
*
|
||||
* Para:
|
||||
* pxTimer: The FreeRTOS timer handle which is expired and call this callback.
|
||||
*
|
||||
* Return: None
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
void RtlTimerCallbckEntry (IN _timerHandle pxTimer)
|
||||
{
|
||||
PRTL_TIMER pTimer;
|
||||
|
||||
if (NULL == pxTimer) {
|
||||
MSG_TIMER_ERR("RtlTimerCallbckEntry: NULL Timer Handle Err!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pTimer = (PRTL_TIMER) rtw_timerGetID( pxTimer );
|
||||
pTimer->CallBackFunc(pTimer->Context);
|
||||
}
|
||||
#endif // end of "#ifdef PLATFORM_FREERTOS"
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlTimerCreate
|
||||
* Desc: To create a software timer.
|
||||
*
|
||||
* Para:
|
||||
* pTimerName: A string for the timer name.
|
||||
* TimerPeriodMS: The timer period, the unit is milli-second.
|
||||
* CallbckFunc: The callback function of this timer.
|
||||
* pContext: A pointer will be used as the parameter to call the timer
|
||||
* callback function.
|
||||
* isPeriodical: Is this timer periodical ? (Auto reload after expired)
|
||||
* Return: The created timer handle, a pointer. It can be used to delete the
|
||||
* timer. If timer createion failed, return NULL.
|
||||
*
|
||||
******************************************************************************/
|
||||
PRTL_TIMER RtlTimerCreate(
|
||||
IN char *pTimerName,
|
||||
IN u32 TimerPeriodMS,
|
||||
IN RTL_TIMER_CALL_BACK CallbckFunc,
|
||||
IN void *pContext,
|
||||
IN u8 isPeriodical)
|
||||
{
|
||||
PRTL_TIMER pTimer;
|
||||
u32 timer_ticks;
|
||||
int i;
|
||||
|
||||
pTimer = (PRTL_TIMER)RtlZmalloc(sizeof(RTL_TIMER));
|
||||
if (NULL == pTimer) {
|
||||
MSG_TIMER_ERR("RtlTimerCreate: Alloc Mem Err!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (portTICK_RATE_MS >= TimerPeriodMS) {
|
||||
timer_ticks = 1; // at least 1 system tick
|
||||
}
|
||||
else {
|
||||
timer_ticks = TimerPeriodMS/portTICK_RATE_MS;
|
||||
}
|
||||
|
||||
pTimer->TimerHandle = rtw_timerCreate ((const char*)(pTimer->TimerName), timer_ticks,
|
||||
(portBASE_TYPE)isPeriodical, (void *) pTimer, RtlTimerCallbckEntry);
|
||||
|
||||
#ifdef PLATFORM_FREERTOS // if any RTOS is used
|
||||
if (pTimer->TimerHandle) {
|
||||
pTimer->msPeriod = TimerPeriodMS;
|
||||
pTimer->CallBackFunc = CallbckFunc;
|
||||
pTimer->Context = pContext;
|
||||
pTimer->isPeriodical = isPeriodical;
|
||||
// copy the timer name
|
||||
if (NULL != pTimerName) {
|
||||
for(i = 0; i < sizeof(pTimer->TimerName); i++)
|
||||
{
|
||||
pTimer->TimerName[i] = pTimerName[i];
|
||||
if(pTimerName[i] == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
_strcpy((char*)(pTimer->TimerName), "None");
|
||||
}
|
||||
MSG_TIMER_INFO("RtlTimerCreate: SW Timer Created: Name=%s Period=%d isPeriodical=%d\n", \
|
||||
pTimer->TimerName, pTimer->msPeriod, pTimer->isPeriodical);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
RtlMfree((u8 *)pTimer, sizeof(RTL_TIMER));
|
||||
pTimer = NULL;
|
||||
MSG_TIMER_ERR("RtlTimerCreate: OS Create Timer Failed!\n");
|
||||
}
|
||||
|
||||
return (pTimer);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlTimerDelete
|
||||
* Desc: To delete a created software timer.
|
||||
*
|
||||
* Para:
|
||||
* pTimerHdl: The timer to be deleted
|
||||
*
|
||||
* Return: None
|
||||
*
|
||||
******************************************************************************/
|
||||
VOID RtlTimerDelete(IN PRTL_TIMER pTimerHdl)
|
||||
{
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
portBASE_TYPE ret;
|
||||
#endif
|
||||
|
||||
if (NULL == pTimerHdl) {
|
||||
MSG_TIMER_ERR("RtlTimerDelete: NULL Timer Handle!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
MSG_TIMER_INFO("RtlTimerDelete: Name=%s\n", pTimerHdl->TimerName);
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
/* try to delete the soft timer and wait max RTL_TIMER_API_MAX_BLOCK_TICKS
|
||||
to send the delete command to the timer command queue */
|
||||
ret = rtw_timerDelete(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS);
|
||||
if (pdPASS != ret) {
|
||||
MSG_TIMER_ERR("RtlTimerDelete: Delete OS Timer Failed!\n");
|
||||
}
|
||||
#endif
|
||||
RtlMfree((u8 *)pTimerHdl, sizeof(RTL_TIMER));
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlTimerStart
|
||||
* Desc: To start a created timer..
|
||||
*
|
||||
* Para:
|
||||
* pTimerHdl: The timer to be started.
|
||||
* isFromISR: The flag to indicate that is this function is called from an ISR.
|
||||
*
|
||||
* Return: _SUCCESS or _FAIL
|
||||
*
|
||||
******************************************************************************/
|
||||
u8 RtlTimerStart(IN PRTL_TIMER pTimerHdl, IN u8 isFromISR)
|
||||
{
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
u8 ret=_FAIL;
|
||||
portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
|
||||
|
||||
if (isFromISR) {
|
||||
if (pdPASS == rtw_timerStartFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken))
|
||||
{
|
||||
// start OS timer successful
|
||||
if (pdFALSE != HigherPriorityTaskWoken) {
|
||||
rtw_yield_os();
|
||||
}
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
else {
|
||||
MSG_TIMER_ERR("RtlTimerStart: Start Timer(%s) from ISR failed\n", pTimerHdl->TimerName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pdPASS == rtw_timerStart(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
else {
|
||||
MSG_TIMER_ERR("RtlTimerStart: Start Timer(%s) failed\n", pTimerHdl->TimerName);
|
||||
}
|
||||
}
|
||||
|
||||
MSG_TIMER_INFO("RtlTimerStart: SW Timer %s Started\n", pTimerHdl->TimerName);
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlTimerStop
|
||||
* Desc: To stop a running timer..
|
||||
*
|
||||
* Para:
|
||||
* pTimerHdl: The timer to be stoped.
|
||||
* isFromISR: The flag to indicate that is this function is called from an ISR.
|
||||
*
|
||||
* Return: _SUCCESS or _FAIL
|
||||
*
|
||||
******************************************************************************/
|
||||
u8 RtlTimerStop(IN PRTL_TIMER pTimerHdl, IN u8 isFromISR)
|
||||
{
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
u8 ret=_FAIL;
|
||||
portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
|
||||
|
||||
if (isFromISR) {
|
||||
if (pdPASS == rtw_timerStopFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken))
|
||||
{
|
||||
// start OS timer successful
|
||||
if (pdFALSE != HigherPriorityTaskWoken) {
|
||||
rtw_yield_os();
|
||||
}
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pdPASS == rtw_timerStop(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (_FAIL == ret) {
|
||||
MSG_TIMER_ERR("RtlTimerStop: Stop Timer(%s) Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR);
|
||||
}
|
||||
|
||||
MSG_TIMER_INFO("RtlTimerStop: SW Timer %s Stoped\n", pTimerHdl->TimerName);
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlTimerReset
|
||||
* Desc: To reset a timer. A reset will get a re-start and reset
|
||||
* the timer ticks counting. A running timer expired time is relative
|
||||
* to the time when Reset function be called. Please ensure the timer
|
||||
* is in active state (Started). A stopped timer also will be started
|
||||
* when this function is called.
|
||||
*
|
||||
* Para:
|
||||
* pTimerHdl: The timer to be reset.
|
||||
* isFromISR: The flag to indicate that is this function is called from an ISR.
|
||||
*
|
||||
* Return: _SUCCESS or _FAIL
|
||||
*
|
||||
******************************************************************************/
|
||||
u8
|
||||
RtlTimerReset(
|
||||
IN PRTL_TIMER pTimerHdl,
|
||||
IN u8 isFromISR
|
||||
)
|
||||
{
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
u8 ret=_FAIL;
|
||||
portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
|
||||
|
||||
if (isFromISR) {
|
||||
if (pdPASS == rtw_timerResetFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken))
|
||||
{
|
||||
// start OS timer successful
|
||||
if (pdFALSE != HigherPriorityTaskWoken) {
|
||||
rtw_yield_os();
|
||||
}
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pdPASS == rtw_timerReset(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (_FAIL == ret) {
|
||||
MSG_TIMER_ERR("RtlTimerReset: Reset Timer(%s) Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR);
|
||||
}
|
||||
|
||||
MSG_TIMER_INFO("RtlTimerReset: SW Timer %s Reset\n", pTimerHdl->TimerName);
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: RtlTimerChangePeriod
|
||||
* Desc: To change the period of a timer that was created previously.
|
||||
*
|
||||
* Para:
|
||||
* pTimerHdl: The timer handle to be changed the priod.
|
||||
* NewPeriodMS: The new timer period, in milli-second.
|
||||
* isFromISR: The flag to indicate that is this function is called from an ISR.
|
||||
*
|
||||
* Return: _SUCCESS or _FAIL
|
||||
*
|
||||
******************************************************************************/
|
||||
u8 RtlTimerChangePeriod(
|
||||
IN PRTL_TIMER pTimerHdl,
|
||||
IN u32 NewPeriodMS,
|
||||
IN u8 isFromISR)
|
||||
{
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
u32 timer_ticks;
|
||||
u8 ret=_FAIL;
|
||||
portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
|
||||
|
||||
if (portTICK_RATE_MS >= NewPeriodMS) {
|
||||
timer_ticks = 1; // at least 1 system tick
|
||||
}
|
||||
else {
|
||||
timer_ticks = NewPeriodMS/portTICK_RATE_MS;
|
||||
}
|
||||
|
||||
if (isFromISR) {
|
||||
if (pdPASS == rtw_timerChangePeriodFromISR(pTimerHdl->TimerHandle, timer_ticks, &HigherPriorityTaskWoken))
|
||||
{
|
||||
// start OS timer successful
|
||||
if (pdFALSE != HigherPriorityTaskWoken) {
|
||||
taskYIELD();
|
||||
}
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pdPASS == rtw_timerChangePeriod(pTimerHdl->TimerHandle, timer_ticks, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
|
||||
ret = _SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (_FAIL == ret) {
|
||||
MSG_TIMER_ERR("RtlTimerChangePeriod: Change Timer(%s) Period Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR);
|
||||
}
|
||||
else {
|
||||
pTimerHdl->msPeriod = NewPeriodMS;
|
||||
MSG_TIMER_INFO("RtlTimerChangePeriod: SW Timer %s change period to %d\n", pTimerHdl->TimerName, pTimerHdl->msPeriod);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
352
lib/amb1_sdk/soc/realtek/8195a/misc/os/osdep_api.h
Normal file
352
lib/amb1_sdk/soc/realtek/8195a/misc/os/osdep_api.h
Normal file
@@ -0,0 +1,352 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*
|
||||
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __OSDEP_API_H_
|
||||
#define __OSDEP_API_H_
|
||||
|
||||
#include "os_timer.h"
|
||||
#include "os_support.h"
|
||||
#include "osdep_service.h"
|
||||
|
||||
|
||||
#define MAX_SEMA_COUNT 32 /* the maximum count of a semaphore */
|
||||
|
||||
typedef _sema _Sema;
|
||||
typedef _mutex _Mutex;
|
||||
typedef u32 _Lock;
|
||||
typedef struct TIMER_LIST _Timer;
|
||||
typedef unsigned long _IRQL;
|
||||
typedef _thread_hdl_ _THREAD_HDL_;
|
||||
typedef VOID THREAD_RETURN;
|
||||
typedef VOID THREAD_CONTEXT;
|
||||
|
||||
|
||||
#ifndef mdelay
|
||||
#define mdelay(t) ((t/portTICK_RATE_MS)>0)?(vTaskDelay(t/portTICK_RATE_MS)):(vTaskDelay(1))
|
||||
#endif
|
||||
|
||||
#ifndef udelay
|
||||
#define udelay(t) ((t/(portTICK_RATE_MS*1000))>0)?vTaskDelay(t/(portTICK_RATE_MS*1000)):(vTaskDelay(1))
|
||||
#endif
|
||||
|
||||
/* to delete/start/stop a timer it will send a message to the timer task through a message queue,
|
||||
so we define the max wait time for message sending */
|
||||
#define RTL_TIMER_API_MAX_BLOCK_TIME 1000 // unit is ms
|
||||
#define RTL_TIMER_API_MAX_BLOCK_TICKS (RTL_TIMER_API_MAX_BLOCK_TIME/portTICK_RATE_MS)
|
||||
|
||||
typedef VOID (*RTL_TIMER_CALL_BACK)(void *pContext);
|
||||
|
||||
typedef struct _RTL_TIMER{
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
_timerHandle TimerHandle; // The timer handle of created FreeRTOS soft-timer
|
||||
#endif
|
||||
RTL_TIMER_CALL_BACK CallBackFunc; // Callback function of this timer
|
||||
u32 msPeriod; // The period of this timer
|
||||
void *Context; // Timer specific context.
|
||||
u8 isPeriodical; // Is a periodical timer
|
||||
u8 TimerName[35]; // The Name of timer
|
||||
}RTL_TIMER, *PRTL_TIMER;
|
||||
|
||||
__inline static VOID RtlEnterCritical(VOID)
|
||||
{
|
||||
rtw_enter_critical(NULL, NULL);
|
||||
}
|
||||
|
||||
__inline static VOID RtlExitCritical(VOID)
|
||||
{
|
||||
rtw_exit_critical(NULL, NULL);
|
||||
}
|
||||
|
||||
__inline static VOID RtlEnterCriticalBh(IN _Lock *plock, IN _IRQL *pirqL)
|
||||
{
|
||||
rtw_enter_critical_bh((_lock *)plock, pirqL);
|
||||
}
|
||||
|
||||
__inline static VOID RtlExitCriticalBh(IN _Lock *plock, IN _IRQL *pirqL)
|
||||
{
|
||||
rtw_exit_critical_bh((_lock *)plock, pirqL);
|
||||
}
|
||||
|
||||
__inline static u32 RtlEnterCriticalMutex(IN _Mutex *pmutex, IN _IRQL *pirqL)
|
||||
{
|
||||
return rtw_enter_critical_mutex(pmutex, pirqL);
|
||||
}
|
||||
|
||||
__inline static VOID RtlExitCriticalMutex(IN _Mutex *pmutex,IN _IRQL *pirqL)
|
||||
{
|
||||
rtw_exit_critical_mutex(pmutex, pirqL);
|
||||
}
|
||||
|
||||
__inline static VOID RtlInitTimer(
|
||||
IN _Timer *ptimer,
|
||||
IN VOID *Data,
|
||||
IN VOID (*pfunc)(VOID *),
|
||||
IN VOID* cntx
|
||||
)
|
||||
{
|
||||
ptimer->Function = pfunc;
|
||||
ptimer->Data = (unsigned long)cntx;
|
||||
InitTimer(ptimer);
|
||||
}
|
||||
|
||||
__inline static VOID RtlSetTimer(
|
||||
IN _Timer *ptimer,
|
||||
IN u32 delay_time
|
||||
)
|
||||
{
|
||||
ModTimer(ptimer , (JIFFIES+(delay_time*RTL_HZ/1000)));
|
||||
}
|
||||
|
||||
__inline static VOID RtlCancelTimer(
|
||||
IN _Timer *ptimer,
|
||||
IN u8 *bcancelled
|
||||
)
|
||||
{
|
||||
DelTimerSync(ptimer);
|
||||
*bcancelled= _TRUE;//TRUE ==1; FALSE==0
|
||||
}
|
||||
|
||||
__inline static u32 RtlSystime2Ms(IN u32 systime)
|
||||
{
|
||||
return rtw_systime_to_ms(systime);
|
||||
}
|
||||
|
||||
__inline static u32 RtlMs2Systime(IN u32 ms)
|
||||
{
|
||||
return rtw_ms_to_systime(ms);
|
||||
}
|
||||
|
||||
extern u8* RtlZmalloc(u32 sz);
|
||||
extern u8* RtlMalloc(u32 sz);
|
||||
extern VOID RtlMfree(u8 *pbuf, u32 sz);
|
||||
|
||||
extern VOID* RtlMalloc2d(u32 h, u32 w, u32 size);
|
||||
extern VOID RtlMfree2d(VOID *pbuf, u32 h, u32 w, u32 size);
|
||||
|
||||
extern VOID RtlInitSema(_Sema *sema, u32 init_val);
|
||||
extern VOID RtlFreeSema(_Sema *sema);
|
||||
extern VOID RtlUpSema(_Sema *sema);
|
||||
extern VOID RtlUpSemaFromISR(_Sema *sema);
|
||||
extern u32 RtlDownSema(_Sema *sema);
|
||||
extern u32 RtlDownSemaWithTimeout(_Sema *sema, u32 ms);
|
||||
|
||||
extern VOID RtlMutexInit(_Mutex *pmutex);
|
||||
extern VOID RtlMutexFree(_Mutex *pmutex);
|
||||
|
||||
extern VOID RtlSpinlockInit(_Lock *plock);
|
||||
extern VOID RtlSpinlockFree(_Lock *plock);
|
||||
extern VOID RtlSpinlock(_Lock *plock);
|
||||
extern VOID RtlSpinunlock(_Lock *plock);
|
||||
extern VOID RtlSpinlockEx(_Lock *plock);
|
||||
extern VOID RtlSpinunlockEx(_Lock *plock);
|
||||
|
||||
extern VOID RtlSleepSchedulable(u32 ms);
|
||||
|
||||
extern VOID RtlMsleepOS(u32 ms);
|
||||
extern VOID RtlUsleepOS(u32 us);
|
||||
extern VOID RtlMdelayOS(u32 ms);
|
||||
extern VOID RtlUdelayOS(u32 us);
|
||||
extern VOID RtlYieldOS(VOID);
|
||||
|
||||
#define RtlUpMutex(mutex) RtlUpSema(mutex)
|
||||
#define RtlDownMutex(mutex) RtlDownSema(mutex)
|
||||
|
||||
__inline static u8 RtlCancelTimerEx(IN _Timer *ptimer)
|
||||
{
|
||||
DelTimerSync(ptimer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static __inline VOID ThreadEnter(IN char *name)
|
||||
{
|
||||
DBG_8195A("\rRTKTHREAD_enter %s\n", name);
|
||||
}
|
||||
|
||||
#define ThreadExit() do{DBG_8195A("\rRTKTHREAD_exit %s\n", __FUNCTION__);}while(0)
|
||||
|
||||
__inline static VOID FlushSignalsThread(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#define RTL_RND(sz, r) ((((sz)+((r)-1))/(r))*(r))
|
||||
#define RTL_RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0: 1)) << 2)
|
||||
|
||||
__inline static u32 RtlRnd4(IN u32 sz)
|
||||
{
|
||||
|
||||
u32 val;
|
||||
|
||||
val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2;
|
||||
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
__inline static u32 RtlRnd8(IN u32 sz)
|
||||
{
|
||||
|
||||
u32 val;
|
||||
|
||||
val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3;
|
||||
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
__inline static u32 RtlRnd128(IN u32 sz)
|
||||
{
|
||||
|
||||
u32 val;
|
||||
|
||||
val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7;
|
||||
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
__inline static u32 RtlRnd256(IN u32 sz)
|
||||
{
|
||||
|
||||
u32 val;
|
||||
|
||||
val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8;
|
||||
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
__inline static u32 RtlRnd512(IN u32 sz)
|
||||
{
|
||||
|
||||
u32 val;
|
||||
|
||||
val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9;
|
||||
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
__inline static u32 BitShift(IN u32 BitMask)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i <= 31; i++)
|
||||
if (((BitMask>>i) & 0x1) == 1) break;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
//#ifdef __GNUC__
|
||||
#ifdef PLATFORM_LINUX
|
||||
#define STRUCT_PACKED __attribute__ ((packed))
|
||||
#else
|
||||
#define STRUCT_PACKED
|
||||
#endif
|
||||
|
||||
|
||||
//Atomic integer operations
|
||||
#define RTL_ATOMIC_T atomic_t
|
||||
|
||||
static inline VOID RTL_ATOMIC_SET(IN RTL_ATOMIC_T *v, IN u32 i)
|
||||
{
|
||||
ATOMIC_SET(v,i);
|
||||
}
|
||||
|
||||
static inline uint32_t RTL_ATOMIC_READ(IN RTL_ATOMIC_T *v)
|
||||
{
|
||||
return ATOMIC_READ(v);
|
||||
}
|
||||
|
||||
static inline VOID RTL_ATOMIC_ADD(IN RTL_ATOMIC_T *v, IN u32 i)
|
||||
{
|
||||
ATOMIC_ADD(v,i);
|
||||
}
|
||||
|
||||
static inline VOID RTL_ATOMIC_SUB(IN RTL_ATOMIC_T *v, IN u32 i)
|
||||
{
|
||||
ATOMIC_SUB(v,i);
|
||||
}
|
||||
|
||||
static inline VOID RTL_ATOMIC_INC(IN RTL_ATOMIC_T *v)
|
||||
{
|
||||
ATOMIC_INC(v);
|
||||
}
|
||||
|
||||
static inline VOID RTL_ATOMIC_DEC(IN RTL_ATOMIC_T *v)
|
||||
{
|
||||
ATOMIC_DEC(v);
|
||||
}
|
||||
|
||||
static inline u32 RTL_ATOMIC_ADD_RETURN(IN RTL_ATOMIC_T *v, IN u32 i)
|
||||
{
|
||||
return ATOMIC_ADD_RETURN(v, i);
|
||||
}
|
||||
|
||||
static inline u32 RTL_ATOMIC_SUB_RETURN(IN RTL_ATOMIC_T *v, IN u32 i)
|
||||
{
|
||||
return ATOMIC_SUB_RETURN(v, i);
|
||||
}
|
||||
|
||||
static inline u32 RTL_ATOMIC_INC_RETURN(IN RTL_ATOMIC_T *v)
|
||||
{
|
||||
return ATOMIC_INC_RETURN(v);
|
||||
}
|
||||
|
||||
static inline u32 RTL_ATOMIC_DEC_RETURN(IN RTL_ATOMIC_T *v)
|
||||
{
|
||||
return ATOMIC_DEC_RETURN(v);
|
||||
}
|
||||
|
||||
extern u64 RtlModular64(u64 x, u64 y);
|
||||
|
||||
extern PRTL_TIMER
|
||||
RtlTimerCreate(
|
||||
IN char *pTimerName,
|
||||
IN u32 TimerPeriodMS,
|
||||
IN RTL_TIMER_CALL_BACK CallbckFunc,
|
||||
IN void *pContext,
|
||||
IN u8 isPeriodical
|
||||
);
|
||||
|
||||
extern VOID
|
||||
RtlTimerDelete(
|
||||
IN PRTL_TIMER pTimerHdl
|
||||
);
|
||||
|
||||
extern u8
|
||||
RtlTimerStart(
|
||||
IN PRTL_TIMER pTimerHdl,
|
||||
IN u8 isFromISR
|
||||
);
|
||||
|
||||
extern u8
|
||||
RtlTimerStop(
|
||||
IN PRTL_TIMER pTimerHdl,
|
||||
IN u8 isFromISR
|
||||
);
|
||||
|
||||
extern u8
|
||||
RtlTimerReset(
|
||||
IN PRTL_TIMER pTimerHdl,
|
||||
IN u8 isFromISR
|
||||
);
|
||||
|
||||
extern u8
|
||||
RtlTimerChangePeriod(
|
||||
IN PRTL_TIMER pTimerHdl,
|
||||
IN u32 NewPeriodMS,
|
||||
IN u8 isFromISR
|
||||
);
|
||||
|
||||
#endif //#ifndef __OSDEP_API_H_
|
||||
|
||||
|
||||
Reference in New Issue
Block a user