Files
MXC-A36_2024.04.18/fr3092_mcu/components/modules/rpmsg-lite/lib/rpmsg_lite/porting/platform/imxrt600_m33/rpmsg_platform.c
2024-04-17 19:45:26 +08:00

304 lines
6.1 KiB
C

/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <string.h>
#include "rpmsg_platform.h"
#include "rpmsg_env.h"
#include "fsl_device_registers.h"
#include "fsl_mu.h"
#if defined(RL_USE_MCMGR_IPC_ISR_HANDLER) && (RL_USE_MCMGR_IPC_ISR_HANDLER == 1)
#include "mcmgr.h"
#endif
#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0"
#endif
#define APP_MU_IRQ_PRIORITY (3U)
/* The MU instance used for CM33 and DSP core communication */
#define APP_MU MUA
#define APP_MU_IRQn MU_A_IRQn
static int32_t isr_counter = 0;
static int32_t disable_counter = 0;
static void *platform_lock;
#if defined(RL_USE_MCMGR_IPC_ISR_HANDLER) && (RL_USE_MCMGR_IPC_ISR_HANDLER == 1)
static void mcmgr_event_handler(uint16_t vring_idx, void *context)
{
env_isr((uint32_t)vring_idx);
}
#else
void MU_A_IRQHandler(void)
{
uint32_t flags;
flags = MU_GetStatusFlags(APP_MU);
if (((uint32_t)kMU_GenInt0Flag & flags) != 0UL)
{
MU_ClearStatusFlags(APP_MU, (uint32_t)kMU_GenInt0Flag);
env_isr(0);
}
if (((uint32_t)kMU_GenInt1Flag & flags) != 0UL)
{
MU_ClearStatusFlags(APP_MU, (uint32_t)kMU_GenInt1Flag);
env_isr(1);
}
}
#endif
static void platform_global_isr_disable(void)
{
__asm volatile("cpsid i");
}
static void platform_global_isr_enable(void)
{
__asm volatile("cpsie i");
}
int32_t platform_init_interrupt(uint32_t vector_id, void *isr_data)
{
/* Register ISR to environment layer */
env_register_isr(vector_id, isr_data);
env_lock_mutex(platform_lock);
RL_ASSERT(0 <= isr_counter);
if (isr_counter < 2)
{
MU_EnableInterrupts(APP_MU, 1UL << (31UL - vector_id));
}
isr_counter++;
env_unlock_mutex(platform_lock);
return 0;
}
int32_t platform_deinit_interrupt(uint32_t vector_id)
{
/* Prepare the MU Hardware */
env_lock_mutex(platform_lock);
RL_ASSERT(0 < isr_counter);
isr_counter--;
if (isr_counter < 2)
{
MU_DisableInterrupts(APP_MU, 1UL << (31UL - vector_id));
}
/* Unregister ISR from environment layer */
env_unregister_isr(vector_id);
env_unlock_mutex(platform_lock);
return 0;
}
void platform_notify(uint32_t vector_id)
{
env_lock_mutex(platform_lock);
#if defined(RL_USE_MCMGR_IPC_ISR_HANDLER) && (RL_USE_MCMGR_IPC_ISR_HANDLER == 1)
(void)MCMGR_TriggerEvent(kMCMGR_RemoteRPMsgEvent, RL_GET_Q_ID(vector_id));
env_unlock_mutex(platform_lock);
#else
(void)MU_TriggerInterrupts(APP_MU, 1UL << (19UL - RL_GET_Q_ID(vector_id)));
#endif
env_unlock_mutex(platform_lock);
}
/**
* platform_time_delay
*
* @param num_msec Delay time in ms.
*
* This is not an accurate delay, it ensures at least num_msec passed when return.
*/
void platform_time_delay(uint32_t num_msec)
{
uint32_t loop;
/* Recalculate the CPU frequency */
SystemCoreClockUpdate();
/* Calculate the CPU loops to delay, each loop has 3 cycles */
loop = SystemCoreClock / 3U / 1000U * num_msec;
/* There's some difference among toolchains, 3 or 4 cycles each loop */
while (loop > 0U)
{
__NOP();
loop--;
}
}
/**
* platform_in_isr
*
* Return whether CPU is processing IRQ
*
* @return True for IRQ, false otherwise.
*
*/
int32_t platform_in_isr(void)
{
return (((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0UL) ? 1 : 0);
}
/**
* platform_interrupt_enable
*
* Enable peripheral-related interrupt
*
* @param vector_id Virtual vector ID that needs to be converted to IRQ number
*
* @return vector_id Return value is never checked.
*
*/
int32_t platform_interrupt_enable(uint32_t vector_id)
{
RL_ASSERT(0 < disable_counter);
platform_global_isr_disable();
disable_counter--;
if (disable_counter == 0)
{
NVIC_EnableIRQ(APP_MU_IRQn);
}
platform_global_isr_enable();
return ((int32_t)vector_id);
}
/**
* platform_interrupt_disable
*
* Disable peripheral-related interrupt.
*
* @param vector_id Virtual vector ID that needs to be converted to IRQ number
*
* @return vector_id Return value is never checked.
*
*/
int32_t platform_interrupt_disable(uint32_t vector_id)
{
RL_ASSERT(0 <= disable_counter);
platform_global_isr_disable();
/* virtqueues use the same NVIC vector
if counter is set - the interrupts are disabled */
if (disable_counter == 0)
{
NVIC_DisableIRQ(APP_MU_IRQn);
}
disable_counter++;
platform_global_isr_enable();
return ((int32_t)vector_id);
}
/**
* platform_map_mem_region
*
* Dummy implementation
*
*/
void platform_map_mem_region(uint32_t vrt_addr, uint32_t phy_addr, uint32_t size, uint32_t flags)
{
}
/**
* platform_cache_all_flush_invalidate
*
* Dummy implementation
*
*/
void platform_cache_all_flush_invalidate(void)
{
}
/**
* platform_cache_disable
*
* Dummy implementation
*
*/
void platform_cache_disable(void)
{
}
/**
* platform_vatopa
*
* Dummy implementation
*
*/
uint32_t platform_vatopa(void *addr)
{
return ((uint32_t)(char *)addr);
}
/**
* platform_patova
*
* Dummy implementation
*
*/
void *platform_patova(uint32_t addr)
{
return ((void *)(char *)addr);
}
/**
* platform_init
*
* platform/environment init
*/
int32_t platform_init(void)
{
#if defined(RL_USE_MCMGR_IPC_ISR_HANDLER) && (RL_USE_MCMGR_IPC_ISR_HANDLER == 1)
mcmgr_status_t retval = kStatus_MCMGR_Error;
retval = MCMGR_RegisterEvent(kMCMGR_RemoteRPMsgEvent, mcmgr_event_handler, ((void *)0));
if (kStatus_MCMGR_Success != retval)
{
return -1;
}
#else
MU_Init(APP_MU);
NVIC_SetPriority(APP_MU_IRQn, APP_MU_IRQ_PRIORITY);
NVIC_EnableIRQ(APP_MU_IRQn);
#endif
/* Create lock used in multi-instanced RPMsg */
if (0 != env_create_mutex(&platform_lock, 1))
{
return -1;
}
return 0;
}
/**
* platform_deinit
*
* platform/environment deinit process
*/
int32_t platform_deinit(void)
{
MU_Deinit(APP_MU);
/* Delete lock used in multi-instanced RPMsg */
env_delete_mutex(platform_lock);
platform_lock = ((void *)0);
return 0;
}