rt-thread/bsp/imxrt/libraries/MIMXRT1170/MIMXRT1176/drivers/fsl_gpc.c

336 lines
12 KiB
C

/*
* Copyright 2019-2021 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_gpc.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.gpc_3"
#endif
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief GPC submodule step registers offset */
static uint32_t const s_cmRegOffset[] = GPC_CM_STEP_REG_OFFSET;
static uint32_t const s_spRegOffset[] = GPC_SP_STEP_REG_OFFSET;
static uint32_t const s_stbyRegOffset[] = GPC_STBY_STEP_REG_OFFSET;
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief Enable IRQ wakeup request.
*
* This function enables the IRQ request which can wakeup the CPU platform.
*
* param base GPC CPU module base address.
* param irqId ID of the IRQ, accessible range is 0-255.
* param enable Enable the IRQ request or not.
*/
void GPC_CM_EnableIrqWakeup(GPC_CPU_MODE_CTRL_Type *base, uint32_t irqId, bool enable)
{
assert(irqId < (GPC_CPU_MODE_CTRL_CM_IRQ_WAKEUP_MASK_COUNT * 32UL));
uint32_t irqGroup = irqId / 32UL;
uint32_t irqMask = irqId % 32UL;
if (true == enable)
{
base->CM_IRQ_WAKEUP_MASK[irqGroup] &= ~(1UL << irqMask);
}
else
{
base->CM_IRQ_WAKEUP_MASK[irqGroup] |= (1UL << irqMask);
}
}
/*!
* brief Get the status of the IRQ wakeup request.
*
* param base GPC CPU module base address.
* param irqId ID of the IRQ, accessible range is 0-255.
* return Indicate the IRQ request is asserted or not.
*/
bool GPC_CM_GetIrqWakeupStatus(GPC_CPU_MODE_CTRL_Type *base, uint32_t irqId)
{
assert(irqId < (GPC_CPU_MODE_CTRL_CM_IRQ_WAKEUP_MASK_COUNT * 32UL));
uint32_t irqGroup = irqId / 32UL;
uint32_t irqMask = irqId % 32UL;
bool irqStatus = false;
irqStatus = (((base->CM_IRQ_WAKEUP_STAT[irqGroup] >> irqMask) & 0x1UL) == 0x1UL) ? true : false;
return irqStatus;
}
/*!
* brief Config the cpu mode transition step.
*
* note This function can not config the setpoint sleep/wakeup operation for those
* operation is controlled by setpoint control. This funcion can not config the standby
* sleep/wakeup too, because those operation is controlled by standby controlled.
*
* param base GPC CPU module base address.
* param step step type, refer to "gpc_cm_tran_step_t".
* param config transition step configuration, refer to "gpc_tran_step_config_t".
*/
void GPC_CM_ConfigCpuModeTransitionStep(GPC_CPU_MODE_CTRL_Type *base,
gpc_cm_tran_step_t step,
const gpc_tran_step_config_t *config)
{
if (!((step >= kGPC_CM_SleepSP) && (step <= kGPC_CM_WakeupSP)))
{
uint32_t tmp32 = *(uint32_t *)((uint32_t)base + s_cmRegOffset[step]);
if (config->enableStep)
{
tmp32 &= ~(GPC_CPU_MODE_CTRL_CM_SLEEP_SSAR_CTRL_STEP_CNT_MASK |
GPC_CPU_MODE_CTRL_CM_SLEEP_SSAR_CTRL_CNT_MODE_MASK);
tmp32 |= GPC_CPU_MODE_CTRL_CM_SLEEP_SSAR_CTRL_CNT_MODE(config->cntMode);
if (config->cntMode != kGPC_StepCounterDisableMode)
{
tmp32 |= GPC_CPU_MODE_CTRL_CM_SLEEP_SSAR_CTRL_STEP_CNT(config->stepCount);
}
tmp32 &= ~GPC_CPU_MODE_CTRL_CM_SLEEP_SSAR_CTRL_DISABLE_MASK;
}
else
{
tmp32 |= GPC_CPU_MODE_CTRL_CM_SLEEP_SSAR_CTRL_DISABLE_MASK;
}
*(uint32_t *)((uint32_t)base + s_cmRegOffset[step]) = tmp32;
}
}
/*!
* brief Request a set point transition before the CPU transfers into a sleep mode.
*
* This function triggers the set point transition during a CPU Sleep/wakeup event and selects which one the CMC want
* to transfer to.
*
* param base GPC CPU module base address.
* param setPointSleep The set point CPU want the system to transit to on next CPU platform sleep sequence.
* param setPointWakeup The set point CPU want the system to transit to on next CPU platform wakeup sequence.
* param wakeupSel Select the set point transition on the next CPU platform wakeup sequence.
*/
void GPC_CM_RequestSleepModeSetPointTransition(GPC_CPU_MODE_CTRL_Type *base,
uint8_t setPointSleep,
uint8_t setPointWakeup,
gpc_cm_wakeup_sp_sel_t wakeupSel)
{
uint32_t tmp32 = base->CM_SP_CTRL;
tmp32 &= ~(GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_RUN_EN_MASK | GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_SLEEP_MASK |
GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_WAKEUP_MASK | GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_WAKEUP_SEL_MASK);
/* Config set point transition in the next sleep sequence. */
tmp32 |=
GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_SLEEP_EN_MASK | GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_SLEEP(setPointSleep);
/* Config set point transition in the next wakeup sequence. */
tmp32 |= GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_WAKEUP_EN_MASK |
GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_WAKEUP(setPointWakeup) |
GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_WAKEUP_SEL(wakeupSel);
base->CM_SP_CTRL = tmp32;
}
/*!
* brief Request a set point transition during run mode.
*
* This function triggers the set point transition and selects which one the CMC want to transfer to.
*
* param base GPC CPU module base address.
* param setPointRun The set point CPU want the system to transit in the run mode.
*/
void GPC_CM_RequestRunModeSetPointTransition(GPC_CPU_MODE_CTRL_Type *base, uint8_t setPointRun)
{
uint32_t tmp32 = base->CM_SP_CTRL;
tmp32 &= ~(GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_RUN_MASK);
tmp32 |= GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_RUN_EN_MASK | GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_RUN(setPointRun);
base->CM_SP_CTRL = tmp32;
while ((base->CM_SP_CTRL & GPC_CPU_MODE_CTRL_CM_SP_CTRL_CPU_SP_RUN_EN_MASK) != 0UL)
{
}
}
/*
* brief Set the set point mapping value for each cpu mode.
*
* This function configures which set point is allowed when CPU enters RUN/WAIT/STOP/SUSPEND. If there are multiple
* setpoints, use:
* code
* map = kkGPC_SetPoint0 | kGPC_SetPoint1 | ... | kGPC_SetPoint15;
* encode
*
* param base GPC CPU module base address.
* param mode CPU mode. Refer to "gpc_cpu_mode_t".
* param map Map value of the set point. Refer to "_gpc_setpoint_map".
*/
void GPC_CM_SetCpuModeSetPointMapping(GPC_CPU_MODE_CTRL_Type *base, gpc_cpu_mode_t mode, uint32_t map)
{
/* Ensure the allowed set point is in the accessible range (0-15). */
map = map & 0xFFFFUL;
switch (mode)
{
case kGPC_RunMode:
base->CM_RUN_MODE_MAPPING = map;
break;
case kGPC_WaitMode:
base->CM_WAIT_MODE_MAPPING = map;
break;
case kGPC_StopMode:
base->CM_STOP_MODE_MAPPING = map;
break;
case kGPC_SuspendMode:
base->CM_SUSPEND_MODE_MAPPING = map;
break;
default:
assert(false);
break;
}
}
/*
* brief Request the chip into standby mode.
*
* param base GPC CPU module base address.
* param mode CPU mode. Refer to "gpc_cpu_mode_t".
*/
void GPC_CM_RequestStandbyMode(GPC_CPU_MODE_CTRL_Type *base, const gpc_cpu_mode_t mode)
{
assert(mode != kGPC_RunMode);
switch (mode)
{
case kGPC_WaitMode:
base->CM_STBY_CTRL |= GPC_CPU_MODE_CTRL_CM_STBY_CTRL_STBY_WAIT_MASK;
break;
case kGPC_StopMode:
base->CM_STBY_CTRL |= GPC_CPU_MODE_CTRL_CM_STBY_CTRL_STBY_STOP_MASK;
break;
case kGPC_SuspendMode:
base->CM_STBY_CTRL |= GPC_CPU_MODE_CTRL_CM_STBY_CTRL_STBY_SUSPEND_MASK;
break;
default:
/* This branch should never be hit. */
break;
}
}
/*
* brief Clear the standby mode request.
*
* param base GPC CPU module base address.
* param mode CPU mode. Refer to "gpc_cpu_mode_t".
*/
void GPC_CM_ClearStandbyModeRequest(GPC_CPU_MODE_CTRL_Type *base, const gpc_cpu_mode_t mode)
{
assert(mode != kGPC_RunMode);
switch (mode)
{
case kGPC_WaitMode:
base->CM_STBY_CTRL &= ~GPC_CPU_MODE_CTRL_CM_STBY_CTRL_STBY_WAIT_MASK;
break;
case kGPC_StopMode:
base->CM_STBY_CTRL &= ~GPC_CPU_MODE_CTRL_CM_STBY_CTRL_STBY_STOP_MASK;
break;
case kGPC_SuspendMode:
base->CM_STBY_CTRL &= ~GPC_CPU_MODE_CTRL_CM_STBY_CTRL_STBY_SUSPEND_MASK;
break;
default:
/* This branch should never be hit. */
break;
}
}
/*!
* brief Clears CPU module interrut status flags.
*
* param base GPC CPU module base address.
* param mask The interrupt status flags to be cleared. Should be the OR'ed value of _gpc_cm_interrupt_status_flag.
*/
void GPC_CM_ClearInterruptStatusFlags(GPC_CPU_MODE_CTRL_Type *base, uint32_t mask)
{
uint32_t temp32;
temp32 = base->CM_INT_CTRL;
temp32 &= ~(GPC_CM_ALL_INTERRUPT_STATUS);
base->CM_INT_CTRL = (mask | temp32);
}
/*!
* brief Config the set point transition step.
*
* param base GPC Setpoint controller base address.
* param step step type, refer to "gpc_sp_tran_step_t".
* param config transition step configuration, refer to "gpc_tran_step_config_t".
*/
void GPC_SP_ConfigSetPointTransitionStep(GPC_SET_POINT_CTRL_Type *base,
gpc_sp_tran_step_t step,
const gpc_tran_step_config_t *config)
{
uint32_t tmp32 = *(uint32_t *)((uint32_t)base + s_spRegOffset[step]);
if (config->enableStep)
{
tmp32 &=
~(GPC_SET_POINT_CTRL_SP_SSAR_SAVE_CTRL_STEP_CNT_MASK | GPC_SET_POINT_CTRL_SP_SSAR_SAVE_CTRL_CNT_MODE_MASK);
tmp32 |= GPC_SET_POINT_CTRL_SP_SSAR_SAVE_CTRL_CNT_MODE(config->cntMode);
if (config->cntMode != kGPC_StepCounterDisableMode)
{
tmp32 |= GPC_SET_POINT_CTRL_SP_SSAR_SAVE_CTRL_STEP_CNT(config->stepCount);
}
tmp32 &= ~GPC_SET_POINT_CTRL_SP_SSAR_SAVE_CTRL_DISABLE_MASK;
}
else
{
tmp32 |= GPC_SET_POINT_CTRL_SP_SSAR_SAVE_CTRL_DISABLE_MASK;
}
*(uint32_t *)((uint32_t)base + s_spRegOffset[step]) = tmp32;
}
/*!
* brief Config the standby transition step.
*
* param base GPC Setpoint controller base address.
* param step step type, refer to "gpc_stby_tran_step_t".
* param config transition step configuration, refer to "gpc_tran_step_config_t".
*/
void GPC_STBY_ConfigStandbyTransitionStep(GPC_STBY_CTRL_Type *base,
gpc_stby_tran_step_t step,
const gpc_tran_step_config_t *config)
{
uint32_t tmp32 = *(uint32_t *)((uint32_t)base + s_stbyRegOffset[step]);
if (config->enableStep)
{
tmp32 &= ~(GPC_STBY_CTRL_STBY_LPCG_IN_CTRL_STEP_CNT_MASK | GPC_STBY_CTRL_STBY_LPCG_IN_CTRL_CNT_MODE_MASK);
tmp32 |= GPC_STBY_CTRL_STBY_LPCG_IN_CTRL_CNT_MODE(config->cntMode);
if (config->cntMode != kGPC_StepCounterDisableMode)
{
tmp32 |= GPC_STBY_CTRL_STBY_LPCG_IN_CTRL_STEP_CNT(config->stepCount);
}
tmp32 &= ~GPC_STBY_CTRL_STBY_LPCG_IN_CTRL_DISABLE_MASK;
}
else
{
tmp32 |= GPC_STBY_CTRL_STBY_LPCG_IN_CTRL_DISABLE_MASK;
}
*(uint32_t *)((uint32_t)base + s_stbyRegOffset[step]) = tmp32;
}