mirror of
https://github.com/Dev-KATECH/ADM.git
synced 2026-05-17 01:43:59 +09:00
2156 lines
93 KiB
C
2156 lines
93 KiB
C
/*==================================================================================================
|
|
* Project : RTD AUTOSAR 4.4
|
|
* Platform : CORTEXM
|
|
* Peripheral : Emios Flexio
|
|
* Dependencies : none
|
|
*
|
|
* Autosar Version : 4.4.0
|
|
* Autosar Revision : ASR_REL_4_4_REV_0000
|
|
* Autosar Conf.Variant :
|
|
* SW Version : 0.9.0
|
|
* Build Version : S32K3_RTD_0_9_0__ASR_REL_4_4_REV_0000_20210326
|
|
*
|
|
* (c) Copyright 2020 - 2021 NXP Semiconductors
|
|
* All Rights Reserved.
|
|
*
|
|
* NXP Confidential. This software is owned or controlled by NXP and may only be
|
|
* used strictly in accordance with the applicable license terms. By expressly
|
|
* accepting such terms or by downloading, installing, activating and/or otherwise
|
|
* using the software, you are agreeing that you have read, and that you agree to
|
|
* comply with and are bound by, such license terms. If you do not agree to be
|
|
* bound by the applicable license terms, then you may not retain, install,
|
|
* activate or otherwise use the software.
|
|
==================================================================================================*/
|
|
|
|
/**
|
|
* @file Emios_Pwm_Ip.c
|
|
*
|
|
* @addtogroup emios_pwm_ip Emios Pwm IPL
|
|
* @{
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"{
|
|
#endif
|
|
|
|
|
|
/*==================================================================================================
|
|
* INCLUDE FILES
|
|
* 1) system and project includes
|
|
* 2) needed interfaces from external units
|
|
* 3) internal and external interfaces from this unit
|
|
==================================================================================================*/
|
|
#include "Emios_Pwm_Ip.h"
|
|
#include "Emios_Pwm_Ip_HwAccess.h"
|
|
#include "Emios_Mcl_Ip.h"
|
|
#include "SchM_Pwm.h"
|
|
|
|
/*==================================================================================================
|
|
* SOURCE FILE VERSION INFORMATION
|
|
==================================================================================================*/
|
|
#define EMIOS_PWM_IP_VENDOR_ID_C 43
|
|
#define EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION_C 4
|
|
#define EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION_C 4
|
|
#define EMIOS_PWM_IP_AR_RELEASE_REVISION_VERSION_C 0
|
|
#define EMIOS_PWM_IP_SW_MAJOR_VERSION_C 0
|
|
#define EMIOS_PWM_IP_SW_MINOR_VERSION_C 9
|
|
#define EMIOS_PWM_IP_SW_PATCH_VERSION_C 0
|
|
|
|
/*==================================================================================================
|
|
* FILE VERSION CHECKS
|
|
==================================================================================================*/
|
|
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
|
|
/* Check if header file and Emios_Mcl_Ip.h are of the same AUTOSAR version */
|
|
#if ((EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION_C != EMIOS_MCL_IP_AR_RELEASE_MAJOR_VERSION_H) || \
|
|
(EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION_C != EMIOS_MCL_IP_AR_RELEASE_MINOR_VERSION_H))
|
|
#error "AUTOSAR Version Numbers of Emios_Pwm_Ip.c and Emios_Mcl_Ip.h are different"
|
|
#endif
|
|
|
|
/* Check if this source file and SchM_Pwm.h file are of the same Autosar version */
|
|
#if ((EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION_C != SCHM_PWM_AR_RELEASE_MAJOR_VERSION) || \
|
|
(EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION_C != SCHM_PWM_AR_RELEASE_MINOR_VERSION))
|
|
#error "AutoSar Version Numbers of Emios_Pwm_Ip.c and SchM_Pwm.h are different"
|
|
#endif
|
|
#endif
|
|
|
|
/* Check if source file and Emios_Pwm_Ip.h file are of the same vendor */
|
|
#if (EMIOS_PWM_IP_VENDOR_ID_C != EMIOS_PWM_IP_VENDOR_ID)
|
|
#error "Vendor IDs of Emios_Pwm_Ip.c and Emios_Pwm_Ip.h are different."
|
|
#endif
|
|
|
|
/* Check if source file and Emios_Pwm_Ip.h file are of the same AUTOSAR version */
|
|
#if ((EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION_C != EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION) || \
|
|
(EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION_C != EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION) || \
|
|
(EMIOS_PWM_IP_AR_RELEASE_REVISION_VERSION_C != EMIOS_PWM_IP_AR_RELEASE_REVISION_VERSION))
|
|
#error "AUTOSAR version numbers of Emios_Pwm_Ip.c and Emios_Pwm_Ip.h are different."
|
|
#endif
|
|
|
|
/* Check if source file and Emios_Pwm_Ip.h file are of the same Software version */
|
|
#if ((EMIOS_PWM_IP_SW_MAJOR_VERSION_C != EMIOS_PWM_IP_SW_MAJOR_VERSION) || \
|
|
(EMIOS_PWM_IP_SW_MINOR_VERSION_C != EMIOS_PWM_IP_SW_MINOR_VERSION) || \
|
|
(EMIOS_PWM_IP_SW_PATCH_VERSION_C != EMIOS_PWM_IP_SW_PATCH_VERSION))
|
|
#error "Software version numbers of Emios_Pwm_Ip.c and Emios_Pwm_Ip.h are different."
|
|
#endif
|
|
|
|
/* Check if source file and Emios_Pwm_Ip_HwAccess.h file are of the same vendor */
|
|
#if (EMIOS_PWM_IP_VENDOR_ID_C != EMIOS_PWM_IP_HWACCESS_VENDOR_ID)
|
|
#error "Vendor IDs of Emios_Pwm_Ip.c and Emios_Pwm_Ip_HwAccess.h are different."
|
|
#endif
|
|
|
|
/* Check if source file and Emios_Pwm_Ip_HwAccess.h file are of the same AUTOSAR version */
|
|
#if ((EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION_C != EMIOS_PWM_IP_HWACCESS_AR_RELEASE_MAJOR_VERSION) || \
|
|
(EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION_C != EMIOS_PWM_IP_HWACCESS_AR_RELEASE_MINOR_VERSION) || \
|
|
(EMIOS_PWM_IP_AR_RELEASE_REVISION_VERSION_C != EMIOS_PWM_IP_HWACCESS_AR_RELEASE_REVISION_VERSION))
|
|
#error "AUTOSAR version numbers of Emios_Pwm_Ip.c and Emios_Pwm_Ip_HwAccess.h are different."
|
|
#endif
|
|
|
|
/* Check if source file and Emios_Pwm_Ip_HwAccess.h file are of the same Software version */
|
|
#if ((EMIOS_PWM_IP_SW_MAJOR_VERSION_C != EMIOS_PWM_IP_HWACCESS_SW_MAJOR_VERSION) || \
|
|
(EMIOS_PWM_IP_SW_MINOR_VERSION_C != EMIOS_PWM_IP_HWACCESS_SW_MINOR_VERSION) || \
|
|
(EMIOS_PWM_IP_SW_PATCH_VERSION_C != EMIOS_PWM_IP_HWACCESS_SW_PATCH_VERSION))
|
|
#error "Software version numbers of Emios_Pwm_Ip.c and Emios_Pwm_Ip_HwAccess.h are different."
|
|
#endif
|
|
|
|
/*==================================================================================================
|
|
* LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* LOCAL MACROS
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* LOCAL CONSTANTS
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* LOCAL VARIABLES
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* GLOBAL CONSTANTS
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* GLOBAL VARIABLES
|
|
==================================================================================================*/
|
|
#define PWM_START_SEC_CONST_UNSPECIFIED
|
|
#include "Pwm_MemMap.h"
|
|
|
|
/** @brief Array with base addresses for Emios instances available on platform */
|
|
Emios_Pwm_Ip_HwAddrType *const Emios_Pwm_Ip_aBasePtr[EMIOS_PWM_INSTANCE_COUNT] = eMIOS_BASE_PTRS;
|
|
|
|
#define PWM_STOP_SEC_CONST_UNSPECIFIED
|
|
#include "Pwm_MemMap.h"
|
|
|
|
#define PWM_START_SEC_VAR_INIT_UNSPECIFIED
|
|
#include "Pwm_MemMap.h"
|
|
/** @brief Array with notification handlers for all configurable channels */
|
|
Emios_Pwm_Ip_NotificationType const *Emios_Pwm_Ip_aNotificationPtr[EMIOS_PWM_INSTANCE_COUNT][EMIOS_PWM_CHANNEL_COUNT] = EMIOS_PWM_NOTIFICATION_HANDLERS;
|
|
|
|
#define PWM_STOP_SEC_VAR_INIT_UNSPECIFIED
|
|
#include "Pwm_MemMap.h"
|
|
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
#define PWM_START_SEC_VAR_INIT_32
|
|
#include "Pwm_MemMap.h"
|
|
|
|
/* Array with available pwm modes for each Emios channel */
|
|
static uint32 Emios_Pwm_Ip_ChannelModes[EMIOS_PWM_INSTANCE_COUNT][EMIOS_PWM_MODES] = EMIOS_PWM_CHANNEL_MODES;
|
|
|
|
#define PWM_STOP_SEC_VAR_INIT_32
|
|
#include "Pwm_MemMap.h"
|
|
#endif
|
|
|
|
#define PWM_START_SEC_VAR_INIT_16
|
|
#include "Pwm_MemMap.h"
|
|
/** @brief Array with period for OPWFMB channels */
|
|
uint16 Emios_Pwm_Ip_aPeriod[EMIOS_PWM_INSTANCE_COUNT][EMIOS_PWM_CHANNEL_COUNT] = EMIOS_PWM_INIT_VALUE_UINT16;
|
|
uint16 Emios_Pwm_Ip_aRegA[EMIOS_PWM_INSTANCE_COUNT][EMIOS_PWM_CHANNEL_COUNT] = EMIOS_PWM_INIT_VALUE_UINT16;
|
|
uint16 Emios_Pwm_Ip_aDaocDuty[EMIOS_PWM_INSTANCE_COUNT][EMIOS_PWM_CHANNEL_COUNT] = EMIOS_PWM_INIT_VALUE_UINT16;
|
|
|
|
#define PWM_STOP_SEC_VAR_INIT_16
|
|
#include "Pwm_MemMap.h"
|
|
|
|
#define PWM_START_SEC_VAR_INIT_8
|
|
#include "Pwm_MemMap.h"
|
|
|
|
uint8 Emios_Pwm_Ip_aNotif[EMIOS_PWM_INSTANCE_COUNT][EMIOS_PWM_CHANNEL_COUNT] = EMIOS_PWM_INIT_VALUE_UINT8;
|
|
uint8 Emios_Pwm_Ip_aCheckEnableNotif[EMIOS_PWM_INSTANCE_COUNT][EMIOS_PWM_CHANNEL_COUNT] = EMIOS_PWM_INIT_VALUE_UINT8;
|
|
uint8 Emios_Pwm_Ip_aPolarity[EMIOS_PWM_INSTANCE_COUNT][EMIOS_PWM_CHANNEL_COUNT] = EMIOS_PWM_INIT_VALUE_UINT8;
|
|
uint8 Emios_Pwm_Ip_aCheckState[EMIOS_PWM_INSTANCE_COUNT][EMIOS_PWM_CHANNEL_COUNT] = EMIOS_PWM_INIT_VALUE_UINT8;
|
|
|
|
#define PWM_STOP_SEC_VAR_INIT_8
|
|
#include "Pwm_MemMap.h"
|
|
|
|
/*==================================================================================================
|
|
* LOCAL FUNCTION PROTOTYPES
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* LOCAL FUNCTIONS
|
|
==================================================================================================*/
|
|
#define PWM_START_SEC_CODE
|
|
#include "Pwm_MemMap.h"
|
|
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/*---------------------Validation API------------------------*/
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_ValidateMode
|
|
* Description : Validate a eMIOS mode can run on the channel or not.
|
|
*END**************************************************************************/
|
|
static inline boolean Emios_Pwm_Ip_ValidateMode(uint8 instance,
|
|
uint8 channel,
|
|
Emios_Pwm_Ip_PwmType mode)
|
|
{
|
|
return ((((Emios_Pwm_Ip_ChannelModes[instance][(uint8)mode] >> channel) & 0x01UL) == 1UL) ? TRUE : FALSE);
|
|
}
|
|
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_GetCounterBusPeriod
|
|
* Description : Return the period for channel using an external counter bus.
|
|
* Only used for channels in OPWMB/OPWMCB/OPWMT modes
|
|
*
|
|
*END**************************************************************************/
|
|
static uint16 Emios_Pwm_Ip_GetCounterBusPeriod(uint8 instance,
|
|
uint8 channel,
|
|
Emios_Pwm_Ip_CounterBusSourceType counterBus)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
uint16 chPeriod = 0U;
|
|
|
|
if (EMIOS_PWM_BUS_A == counterBus)
|
|
{
|
|
chPeriod = Emios_Pwm_Ip_GetUCRegA(base, EMIOS_PWM_COUNTER_BUS_A);
|
|
}
|
|
else if (EMIOS_PWM_BUS_F == counterBus)
|
|
{
|
|
chPeriod = Emios_Pwm_Ip_GetUCRegA(base, EMIOS_PWM_COUNTER_BUS_F);
|
|
}
|
|
else if (EMIOS_PWM_BUS_BCDE == counterBus)
|
|
{
|
|
chPeriod = Emios_Pwm_Ip_GetUCRegA(base, (channel & (uint8)EMIOS_PWM_COUNTER_BUS_BCDE));
|
|
}
|
|
else
|
|
{
|
|
/* Nothing to do. Internal Counter Cannot be selected for these modes. */
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(FALSE);
|
|
#endif
|
|
}
|
|
|
|
return chPeriod;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_GetCounterBusMode
|
|
* Description : Return the counter bus mode for channel using an external counter bus.
|
|
* Only used for channels in OPWMB/OPWMCB/OPWMT modes
|
|
*
|
|
*END**************************************************************************/
|
|
static Emios_Pwm_Ip_MasterBusModeType Emios_Pwm_Ip_GetCounterBusMode(uint8 instance,
|
|
uint8 channel,
|
|
Emios_Pwm_Ip_CounterBusSourceType counterBus)
|
|
{
|
|
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_MasterBusModeType counterBusMode = EMIOS_PWM_IP_MC_UP_COUNTER_START;
|
|
switch (counterBus)
|
|
{
|
|
case EMIOS_PWM_BUS_A:
|
|
counterBusMode = (Emios_Pwm_Ip_MasterBusModeType)Emios_Pwm_Ip_GetChannelPwmMode(base, EMIOS_PWM_COUNTER_BUS_A);
|
|
break;
|
|
case EMIOS_PWM_BUS_BCDE:
|
|
counterBusMode = (Emios_Pwm_Ip_MasterBusModeType)Emios_Pwm_Ip_GetChannelPwmMode(base, (channel & (uint8)EMIOS_PWM_COUNTER_BUS_BCDE));
|
|
break;
|
|
case EMIOS_PWM_BUS_F:
|
|
counterBusMode = (Emios_Pwm_Ip_MasterBusModeType)Emios_Pwm_Ip_GetChannelPwmMode(base, EMIOS_PWM_COUNTER_BUS_F);
|
|
break;
|
|
default:
|
|
/* internal counter bus */
|
|
counterBusMode = EMIOS_PWM_IP_NODEFINE_COUNTER;
|
|
break;
|
|
}
|
|
|
|
return counterBusMode;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_InitPeriodDutyCycleMode
|
|
* Description : Initial Output Pulse Width and Frequency Modulation Buffered (OPWFMB) Mode.
|
|
* This mode provides waveforms with variable duty cycle and frequency. The internal channel counter
|
|
* is automatically selected as the time base when this mode is selected.
|
|
*END**************************************************************************/
|
|
static void Emios_Pwm_Ip_InitPeriodDutyCycleMode(uint8 instance,
|
|
Emios_Pwm_Ip_ChannelConfigType const *userChCfg)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(NULL_PTR != userChCfg);
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > userChCfg->channelId);
|
|
/* Check Selected channel is set for OPWFMB */
|
|
DevAssert((userChCfg->mode == EMIOS_PWM_MODE_OPWFMB_FLAG) ||
|
|
(userChCfg->mode == EMIOS_PWM_MODE_OPWFMB_FLAG_BOTH));
|
|
/* Check that channel has internal counter for this mode */
|
|
DevAssert(TRUE == Emios_Pwm_Ip_ValidateMode(instance, userChCfg->channelId, EMIOS_PWM_HW_MODE_OPWFMB));
|
|
/* Validate opwfmb parametter */
|
|
DevAssert(EMIOS_PWM_MIN_CNT_VAL < userChCfg->periodCount);
|
|
DevAssert(userChCfg->dutyCycle <= userChCfg->periodCount);
|
|
#endif
|
|
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
/* Configure OPWFMB special parameters */
|
|
/* Configure Counter Bus used by this channel */
|
|
Emios_Pwm_Ip_SetCounterBus(base, userChCfg->channelId, userChCfg->timebase);
|
|
/* Configure DutyCycle in reg A */
|
|
Emios_Pwm_Ip_SetUCRegA(base, userChCfg->channelId, userChCfg->dutyCycle);
|
|
/* Configure Period in reg B */
|
|
Emios_Pwm_Ip_SetUCRegB(base, userChCfg->channelId, userChCfg->periodCount);
|
|
/* Transition from GPIO mode to OPWFMB mode */
|
|
Emios_Pwm_Ip_SetPwmMode(base, userChCfg->channelId, userChCfg->mode);
|
|
/* Configure output pin polarity */
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId,(userChCfg->outputPolarity == EMIOS_PWM_ACTIVE_HIGH) ? EMIOS_PWM_ACTIVE_LOW : EMIOS_PWM_ACTIVE_HIGH );
|
|
|
|
Emios_Pwm_Ip_aPeriod[instance][userChCfg->channelId] = userChCfg->periodCount;
|
|
|
|
if (userChCfg->periodCount == userChCfg->dutyCycle)
|
|
{ /* 100% dutyCycle is desired. */
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)1U;
|
|
}
|
|
else if(0U == userChCfg->dutyCycle)
|
|
{
|
|
/* 0% dutyCycle is desired. */
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)1U;
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)0U;
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetDutyCycleOpwfmb
|
|
* Description : Set new duty cycle for the channel in OPWFMB mode
|
|
* This function will check the specific duty cycle and set new duty cycle for
|
|
* this channel
|
|
*
|
|
*END**************************************************************************/
|
|
static Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleOpwfmb(uint8 instance,
|
|
uint8 channel,
|
|
uint16 newDutyCycle)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_StatusType ret = EMIOS_PWM_STATUS_SUCCESS;
|
|
|
|
/* OPWFMB mode */
|
|
if ((newDutyCycle > Emios_Pwm_Ip_aPeriod[instance][channel]) && ((uint16)0U != Emios_Pwm_Ip_aPeriod[instance][channel]))
|
|
{ /* Duty cycle value should not be greater than the channel Period. */
|
|
ret = EMIOS_PWM_STATUS_ERROR;
|
|
}
|
|
else if ((uint16)0U == Emios_Pwm_Ip_aPeriod[instance][channel])
|
|
{
|
|
/* Disable and clear interrupt flag */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
/* If new period is 0, set duty cycle to 0 */
|
|
Emios_Pwm_Ip_SetUCRegA(base, channel, (uint16)0U);
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)1U;
|
|
}
|
|
else
|
|
{
|
|
if(newDutyCycle == 0U)
|
|
{
|
|
/* Disable and clear interrupt flag */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)1U;
|
|
}
|
|
else if (newDutyCycle == Emios_Pwm_Ip_aPeriod[instance][channel])
|
|
{
|
|
/* Disable and clear interrupt flag */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)1U;
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)0U;
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, (Emios_Pwm_Ip_aCheckEnableNotif[instance][channel] == 0U)? FALSE : TRUE);
|
|
}
|
|
|
|
Emios_Pwm_Ip_SetUCRegA(base, channel, newDutyCycle);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_InitDeadTimeMode
|
|
* Description : Initial Center Aligned Output Pulse Width Modulation with Dead Time Insertion Buffered (OPWMCB) Mode.
|
|
* This operation mode generates a center aligned PWM with dead time insertion to the leading or trailing edge.
|
|
* Allow smooth output signal generation when changing duty cycle and deadtime values.
|
|
*
|
|
* The time base selected for a channel configured to OPWMCB mode should be a channel configured to MCB Up/Down mode.
|
|
* It is recommended to start the MCB channel time base after the OPWMCB mode is entered
|
|
* in order to avoid missing A matches at the very first duty cycle.
|
|
*
|
|
* The internal counter runs in the internal prescaler ratio, while the selected time base
|
|
* may be running in a different prescaler ratio.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Emios_Pwm_Ip_InitDeadTimeMode(uint8 instance,
|
|
Emios_Pwm_Ip_ChannelConfigType const *userChCfg)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(NULL_PTR != userChCfg);
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > userChCfg->channelId);
|
|
/* Check Selected channel is set for OPWMCB */
|
|
DevAssert((userChCfg->mode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
|
|
(userChCfg->mode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH) ||
|
|
(userChCfg->mode == EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG) ||
|
|
(userChCfg->mode == EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH));
|
|
/* Check selected channel supports OPWMCB mode */
|
|
DevAssert(TRUE == Emios_Pwm_Ip_ValidateMode(instance, userChCfg->channelId, EMIOS_PWM_HW_MODE_OPWMCB));
|
|
/* Check selected counter bus is configured in MCB Up-Down Mode */
|
|
DevAssert(EMIOS_PWM_IP_MCB_UP_DOWN_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(instance, userChCfg->channelId, userChCfg->timebase));
|
|
/* Validate OPWMCB parametter */
|
|
DevAssert(((2U * Emios_Pwm_Ip_GetCounterBusPeriod(instance, userChCfg->channelId, userChCfg->timebase)) - 2U) >= userChCfg->dutyCycle);
|
|
#endif
|
|
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
uint16 dutyCycle = 0U;
|
|
|
|
if (userChCfg->periodCount == userChCfg->dutyCycle)
|
|
{ /* 100% dutyCycle is desired. */
|
|
dutyCycle = 1U;
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)1U;
|
|
}
|
|
else if((0U == userChCfg->dutyCycle) || (1U == userChCfg->dutyCycle))
|
|
{
|
|
/* 0% dutyCycle is desired. */
|
|
dutyCycle = Emios_Pwm_Ip_GetCounterBusPeriod(instance, userChCfg->channelId, userChCfg->timebase) + (uint8)1U;
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)1U;
|
|
}
|
|
else
|
|
{
|
|
dutyCycle = (userChCfg->dutyCycle) >> (uint8)1U;
|
|
dutyCycle = Emios_Pwm_Ip_GetCounterBusPeriod(instance, userChCfg->channelId, userChCfg->timebase) - dutyCycle;
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)0U;
|
|
}
|
|
|
|
/* Configure OPWMCB special parameters */
|
|
/* Configure Counter Bus used by this channel */
|
|
Emios_Pwm_Ip_SetCounterBus(base, userChCfg->channelId, userChCfg->timebase);
|
|
/* Configure DutyCycle in reg A */
|
|
Emios_Pwm_Ip_SetUCRegA(base, userChCfg->channelId, dutyCycle);
|
|
/* Configure DeadTime in reg B */
|
|
Emios_Pwm_Ip_SetUCRegB(base, userChCfg->channelId, userChCfg->deadTime);
|
|
/* To avoid spike pulse
|
|
If duty cycle = 100%, when enter mode, EDPOL bit get complement of polarity
|
|
after that, EDPOL bit is restored valid value */
|
|
if (userChCfg->periodCount == userChCfg->dutyCycle)
|
|
{
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId,(userChCfg->outputPolarity == EMIOS_PWM_ACTIVE_HIGH) ? EMIOS_PWM_ACTIVE_LOW : EMIOS_PWM_ACTIVE_HIGH );
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId, userChCfg->outputPolarity);
|
|
}
|
|
/* Transition from GPIO mode to OPWMCB mode */
|
|
Emios_Pwm_Ip_SetPwmMode(base, userChCfg->channelId, userChCfg->mode);
|
|
/* Configure output pin polarity */
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId, userChCfg->outputPolarity);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetDutyCycleOpwmcb
|
|
* Description : Set new duty cycle for the channel in OPWMCB mode
|
|
* This function will check the specific duty cycle and set new duty cycle for
|
|
* this channel
|
|
*
|
|
*END**************************************************************************/
|
|
static Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleOpwmcb(uint8 instance,
|
|
uint8 channel,
|
|
uint16 newDutyCycle)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_StatusType ret = EMIOS_PWM_STATUS_SUCCESS;
|
|
Emios_Pwm_Ip_PwmModeType chMode = Emios_Pwm_Ip_GetPwmMode(base, channel);
|
|
uint16 chPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel));
|
|
|
|
/* OPWMCB mode */
|
|
if(newDutyCycle > ((chPeriod * 2U) - 2U))
|
|
{ /* Duty cycle value should not be greater than the channel Period. */
|
|
ret = EMIOS_PWM_STATUS_ERROR;
|
|
}
|
|
else if(0U == newDutyCycle)
|
|
{
|
|
/* Disable and clear interrupt flag */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
|
|
Emios_Pwm_Ip_SetUCRegA(base, channel, chPeriod + 1U);
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)1U;
|
|
/* This statement is required to avoid limitation of 0% duty cycle (if call 100% to 0%) */
|
|
if(1U == Emios_Pwm_Ip_GetUCRegA(base, channel))
|
|
{
|
|
if((chMode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH))
|
|
{
|
|
Emios_Pwm_Ip_SetForceMatchB(base, channel, TRUE);
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_SetForceMatchA(base, channel, TRUE);
|
|
}
|
|
}
|
|
}
|
|
else if(newDutyCycle == ((chPeriod * 2U) - 2U))
|
|
{
|
|
/* Disable and clear interrupt flag */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
|
|
Emios_Pwm_Ip_SetUCRegA(base, channel, 1U);
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)1U;
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_SetUCRegA(base, channel, (uint16)(chPeriod - (newDutyCycle >> 1U)));
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)0U;
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, (Emios_Pwm_Ip_aCheckEnableNotif[instance][channel] == 0U)? FALSE : TRUE);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_InitEdgePlacementMode
|
|
* Description : Initial Output Pulse Width Modulation Buffered (OPWMB) Mode.
|
|
* OPWMB mode is used to generate pulses with programmable leading and trailing edge placement.
|
|
* An external counter driven in MCB Up mode must be selected from one of the counter buses.
|
|
* userChCfg defines the first edge and the second edge. The output signal polarity is defined
|
|
* by outputPolarity in userChCfg.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Emios_Pwm_Ip_InitEdgePlacementMode(uint8 instance,
|
|
Emios_Pwm_Ip_ChannelConfigType const *userChCfg)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(NULL_PTR != userChCfg);
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > userChCfg->channelId);
|
|
/* Check Selected channel is set for OPWMB */
|
|
DevAssert((userChCfg->mode == EMIOS_PWM_MODE_OPWMB_FLAG) ||
|
|
(userChCfg->mode == EMIOS_PWM_MODE_OPWMB_FLAG_BOTH));
|
|
/* Check selected channel supports OPWMB mode */
|
|
DevAssert(TRUE == Emios_Pwm_Ip_ValidateMode(instance, userChCfg->channelId, EMIOS_PWM_HW_MODE_OPWMB));
|
|
/* Check selected counter bus is configured in MCB Up-Down Mode */
|
|
DevAssert(EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(instance, userChCfg->channelId, userChCfg->timebase));
|
|
/* Validate OPWMB parametter */
|
|
/* Phase Shift and DutyCycle cannot be bigger than the counter bus period */
|
|
DevAssert((Emios_Pwm_Ip_GetCounterBusPeriod(instance, userChCfg->channelId, userChCfg->timebase)) >= (userChCfg->phaseShift + userChCfg->dutyCycle));
|
|
DevAssert(EMIOS_PWM_MAX_CNT_VAL >= (uint32)((uint32)userChCfg->phaseShift + (uint32)userChCfg->dutyCycle));
|
|
#endif
|
|
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
Emios_Pwm_Ip_aRegA[instance][userChCfg->channelId] = userChCfg->phaseShift;
|
|
|
|
/* Configure Counter Bus used by this channel */
|
|
Emios_Pwm_Ip_SetCounterBus(base, userChCfg->channelId, userChCfg->timebase);
|
|
/* Configure Phase Shift in reg A */
|
|
Emios_Pwm_Ip_SetUCRegA(base, userChCfg->channelId, userChCfg->phaseShift);
|
|
/* Configure Trailing edge in reg B */
|
|
Emios_Pwm_Ip_SetUCRegB(base, userChCfg->channelId, userChCfg->phaseShift + userChCfg->dutyCycle);
|
|
/* Transition from GPIO mode to OPWMB mode */
|
|
Emios_Pwm_Ip_SetPwmMode(base, userChCfg->channelId, userChCfg->mode);
|
|
/* Configure output pin polarity */
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId, userChCfg->outputPolarity);
|
|
|
|
if (userChCfg->periodCount == userChCfg->dutyCycle)
|
|
{ /* 100% dutyCycle is desired. */
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)1U;
|
|
}
|
|
else if((0U == userChCfg->dutyCycle) || (1U == userChCfg->dutyCycle))
|
|
{
|
|
/* 0% dutyCycle is desired. */
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)1U;
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)0U;
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetDutyCycleOpwmb
|
|
* Description : Set new duty cycle for the channel in OPWMB mode
|
|
* This function will check the specific duty cycle and set new duty cycle for
|
|
* this channel
|
|
*
|
|
*END**************************************************************************/
|
|
static Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleOpwmb(uint8 instance,
|
|
uint8 channel,
|
|
uint16 newDutyCycle)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_StatusType ret = EMIOS_PWM_STATUS_SUCCESS;
|
|
uint16 chPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel));
|
|
|
|
/* OPWMB mode */
|
|
if ((newDutyCycle + Emios_Pwm_Ip_aRegA[instance][channel]) > chPeriod)
|
|
{ /* New duty cycle puts trailing edge outside of counter bus period. */
|
|
ret = EMIOS_PWM_STATUS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
if(newDutyCycle == 0U)
|
|
{
|
|
/* Disable and clear interrupt flag */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)1U;
|
|
}
|
|
else if (newDutyCycle == chPeriod)
|
|
{
|
|
/* Disable and clear interrupt flag */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)1U;
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)0U;
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, (Emios_Pwm_Ip_aCheckEnableNotif[instance][channel] == 0U)? FALSE : TRUE);
|
|
}
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, (newDutyCycle + Emios_Pwm_Ip_aRegA[instance][channel]));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_InitTriggerMode
|
|
* Description : Initial Output Pulse Width Modulation with Trigger (OPWMT) Mode
|
|
* OPWMT mode is intended to support the generation of Pulse Width Modulation signals where
|
|
* the period is not modified while the signal is being output, but where the duty cycle will
|
|
* be varied and must not create glitches. The mode is intended to be used in conjunction with
|
|
* other channels executing in the same mode and sharing a common timebase. It will support each
|
|
* channel with a fixed PWM leading edge position with respect to the other channels and the
|
|
* ability to generate a trigger signal at any point in the period that can be output from
|
|
* the module to initiate activity in other parts of the SoC such as starting ADC conversions.
|
|
*
|
|
* An external counter driven in either MC Up or MCB Up mode must be selected from one of the counter buses.
|
|
*
|
|
* The leading edge can be configured with any value within the range of the selected time base. Note that registers
|
|
* loaded with 0x0 will not produce matches if the timebase is driven by a channel in MCB mode.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Emios_Pwm_Ip_InitTriggerMode(uint8 instance,
|
|
Emios_Pwm_Ip_ChannelConfigType const *userChCfg)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(NULL_PTR != userChCfg);
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > userChCfg->channelId);
|
|
/* Check Selected channel is set for OPWMT */
|
|
DevAssert(userChCfg->mode == EMIOS_PWM_MODE_OPWMT);
|
|
/* Check selected channel supports OPWMT mode */
|
|
DevAssert(TRUE == Emios_Pwm_Ip_ValidateMode(instance, userChCfg->channelId, EMIOS_PWM_HW_MODE_OPWMT));
|
|
/* Check selected counter bus is configured in MCB Up Mode or MC Up mode */
|
|
DevAssert((EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(instance, userChCfg->channelId, userChCfg->timebase)) ||
|
|
(EMIOS_PWM_IP_MC_UP_COUNTER_START == Emios_Pwm_Ip_GetCounterBusMode(instance, userChCfg->channelId, userChCfg->timebase)) ||
|
|
(EMIOS_PWM_IP_MC_UP_COUNTER_END == Emios_Pwm_Ip_GetCounterBusMode(instance, userChCfg->channelId, userChCfg->timebase)));
|
|
#endif
|
|
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
uint16 counterBusPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(instance, userChCfg->channelId, userChCfg->timebase);
|
|
uint16 trailingEdge = 0x0000U;
|
|
uint8 counterStart = 0U;
|
|
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Validate OPWMT parameters */
|
|
/* Phase Shift must be in the counter bus period range. */
|
|
DevAssert(counterBusPeriod >= userChCfg->phaseShift);
|
|
/* If 100% duty cycle must be implemented the maximum counter value for the time base is 0xFFFE */
|
|
DevAssert(EMIOS_PWM_MAX_CNT_VAL > counterBusPeriod);
|
|
/* Duty cycle must not exceed the counter bus period. If 100% duty is desired dutycycle must be counterbus period +1U */
|
|
DevAssert((counterBusPeriod + 1U) >= userChCfg->dutyCycle);
|
|
/* Trigger point must be inside the counter bus period */
|
|
DevAssert(counterBusPeriod >= userChCfg->triggerPosition);
|
|
#endif
|
|
|
|
if (EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(instance, userChCfg->channelId, userChCfg->timebase))
|
|
{
|
|
counterStart = 1U;
|
|
}
|
|
else
|
|
{
|
|
counterStart = 0U;
|
|
}
|
|
|
|
if (counterBusPeriod == userChCfg->dutyCycle)
|
|
{ /* 100% dutyCycle is desired. Trailing edge must be placed outside counter bus period. */
|
|
trailingEdge = userChCfg->dutyCycle + 1U;
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)1U;
|
|
}
|
|
else if (0U == userChCfg->dutyCycle)
|
|
{
|
|
trailingEdge = userChCfg->phaseShift;
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)1U;
|
|
}
|
|
else
|
|
{ /* Calculate trailing edge postion. Wrap-around if dutyCycle extends the signal past the counterbus period. */
|
|
trailingEdge = (userChCfg->phaseShift + userChCfg->dutyCycle) % counterBusPeriod;
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)0U;
|
|
}
|
|
|
|
Emios_Pwm_Ip_aRegA[instance][userChCfg->channelId] = userChCfg->phaseShift + counterStart;
|
|
|
|
/* Configure Counter Bus used by this channel */
|
|
Emios_Pwm_Ip_SetCounterBus(base, userChCfg->channelId, userChCfg->timebase);
|
|
/* Configure Leading Edge in reg A */
|
|
Emios_Pwm_Ip_SetUCRegA(base, userChCfg->channelId, (userChCfg->phaseShift + counterStart));
|
|
/* Configure Trailing Edge in reg B */
|
|
Emios_Pwm_Ip_SetUCRegB(base, userChCfg->channelId, (trailingEdge + counterStart));
|
|
/* Configure Triggerpoint in reg ALTA */
|
|
Emios_Pwm_Ip_SetTrigger(base, userChCfg->channelId, (userChCfg->triggerPosition + counterStart));
|
|
/* To avoid spike pulse
|
|
If duty cycle = 100%, when enter mode, EDPOL bit get complement of polarity
|
|
after that, EDPOL bit is restored valid value */
|
|
if (counterBusPeriod == userChCfg->dutyCycle)
|
|
{
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId,(userChCfg->outputPolarity == EMIOS_PWM_ACTIVE_HIGH) ? EMIOS_PWM_ACTIVE_LOW : EMIOS_PWM_ACTIVE_HIGH );
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId, userChCfg->outputPolarity);
|
|
}
|
|
/* Transition from GPIO mode to OPWMT mode */
|
|
Emios_Pwm_Ip_SetPwmMode(base, userChCfg->channelId, userChCfg->mode);
|
|
/* Configure output pin polarity */
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId, userChCfg->outputPolarity);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetDutyCycleOpwmt
|
|
* Description : Set new duty cycle for the channel in OPWMT mode
|
|
* This function will check the specific duty cycle and set new duty cycle for
|
|
* this channel
|
|
*
|
|
*END**************************************************************************/
|
|
static Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleOpwmt(uint8 instance,
|
|
uint8 channel,
|
|
uint16 newDutyCycle)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_StatusType ret = EMIOS_PWM_STATUS_SUCCESS;
|
|
uint16 chPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel));
|
|
|
|
/* OPWMT mode */
|
|
if (newDutyCycle > chPeriod)
|
|
{ /* Duty cycle value should not be greater than the channel Period. */
|
|
ret = EMIOS_PWM_STATUS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
if (chPeriod == newDutyCycle)
|
|
{ /* 100% dutyCycle is desired. Trailing edge must be placed outside counter bus period. */
|
|
/* Disable and clear interrupt flag */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, (newDutyCycle + 1U));
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)1U;
|
|
}
|
|
else if(0U == newDutyCycle)
|
|
{
|
|
/* 0% dutyCycle is desired. */
|
|
/* Disable and clear interrupt flag */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, Emios_Pwm_Ip_aRegA[instance][channel]);
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)1U;
|
|
}
|
|
else
|
|
{ /* Calculate trailing edge postion. Wrap-around if dutyCycle extends the signal past the counterbus period. */
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, (Emios_Pwm_Ip_aRegA[instance][channel] + newDutyCycle) % chPeriod);
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)0U;
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, (Emios_Pwm_Ip_aCheckEnableNotif[instance][channel] == 0U)? FALSE : TRUE);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_InitDoubleCompareMode
|
|
* Description : Initial Double Action Output Compare (DAOC) Mode.
|
|
* This mode provides waveforms with variable duty cycle and frequency.
|
|
* In DAOC mode, at the end of period, the A register and B register need re-calculated to
|
|
* enable next match A. This calculation and first pulse must be done by software.
|
|
* Calculate the duty tick follow period and Duty cycle
|
|
* Always enable interrupt. Because in this mode, the A register and B register is re-calculated
|
|
* with period and duty at the end of period by software.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Emios_Pwm_Ip_InitDoubleCompareMode(uint8 instance,
|
|
Emios_Pwm_Ip_ChannelConfigType const *userChCfg)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(NULL_PTR != userChCfg);
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > userChCfg->channelId);
|
|
/* Check Selected channel is set for DAOC mode */
|
|
DevAssert((userChCfg->mode == EMIOS_PWM_MODE_DAOC_FLAG) ||
|
|
(userChCfg->mode == EMIOS_PWM_MODE_DAOC_FLAG_BOTH));
|
|
/* Validate opwfmb parametter */
|
|
DevAssert(EMIOS_PWM_MIN_CNT_VAL < userChCfg->periodCount);
|
|
DevAssert(userChCfg->dutyCycle <= userChCfg->periodCount);
|
|
#endif
|
|
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_aPeriod[instance][userChCfg->channelId] = userChCfg->periodCount;
|
|
Emios_Pwm_Ip_aPolarity[instance][userChCfg->channelId] = (userChCfg->outputPolarity == EMIOS_PWM_ACTIVE_HIGH)? 1U : 0U;
|
|
uint16 daocRegA = 0U;
|
|
uint16 counterMax = Emios_Pwm_Ip_GetUCRegA(base, Emios_Pwm_Ip_GetMasterBusChannel(instance, userChCfg->channelId));
|
|
|
|
/* FLAG event enabled */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, userChCfg->channelId, TRUE);
|
|
/* Configure Counter Bus used by this channel */
|
|
Emios_Pwm_Ip_SetCounterBus(base, userChCfg->channelId, userChCfg->timebase);
|
|
|
|
if (userChCfg->periodCount == userChCfg->dutyCycle)
|
|
{
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId,(userChCfg->outputPolarity == EMIOS_PWM_ACTIVE_HIGH) ? EMIOS_PWM_ACTIVE_LOW : EMIOS_PWM_ACTIVE_HIGH );
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId, userChCfg->outputPolarity);
|
|
}
|
|
/* Transition from GPIO mode to DAOC mode */
|
|
Emios_Pwm_Ip_SetPwmMode(base, userChCfg->channelId, userChCfg->mode);
|
|
/* Configure output pin polarity */
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId, userChCfg->outputPolarity);
|
|
/* With Duty cycle 0% */
|
|
if(0U == userChCfg->dutyCycle)
|
|
{
|
|
daocRegA = 1U;
|
|
Emios_Pwm_Ip_aDaocDuty[instance][userChCfg->channelId] = 0U;
|
|
|
|
Emios_Pwm_Ip_SetForceMatchB(base, userChCfg->channelId, TRUE);
|
|
/* Configure Leading Edge in reg A */
|
|
Emios_Pwm_Ip_SetUCRegA(base, userChCfg->channelId, daocRegA);
|
|
/* Configure Trailing Edge in reg B */
|
|
Emios_Pwm_Ip_SetUCRegB(base, userChCfg->channelId, (userChCfg->dutyCycle + 1U));
|
|
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId, userChCfg->outputPolarity);
|
|
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)1U;
|
|
|
|
}
|
|
else if(userChCfg->dutyCycle == userChCfg->periodCount)
|
|
{
|
|
daocRegA = (Emios_Pwm_Ip_aPeriod[instance][userChCfg->channelId] + Emios_Pwm_Ip_GetUCRegA(base, userChCfg->channelId)) % counterMax;
|
|
|
|
Emios_Pwm_Ip_aDaocDuty[instance][userChCfg->channelId] = 0U;
|
|
|
|
Emios_Pwm_Ip_SetForceMatchA(base, userChCfg->channelId, TRUE);
|
|
/* Configure Leading Edge in reg A */
|
|
Emios_Pwm_Ip_SetUCRegA(base, userChCfg->channelId, (daocRegA == 0U)? counterMax : daocRegA);
|
|
/* Configure Trailing Edge in reg B */
|
|
Emios_Pwm_Ip_SetUCRegB(base, userChCfg->channelId, (daocRegA == 0U)? counterMax : daocRegA);
|
|
/* Invert the EDGE POLARITY in control register */
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId,(userChCfg->outputPolarity == EMIOS_PWM_ACTIVE_HIGH) ? EMIOS_PWM_ACTIVE_LOW : EMIOS_PWM_ACTIVE_HIGH);
|
|
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)1U;
|
|
}
|
|
else
|
|
{
|
|
daocRegA = 1U;
|
|
Emios_Pwm_Ip_aDaocDuty[instance][userChCfg->channelId] = userChCfg->dutyCycle;
|
|
|
|
/* Configure Leading Edge in reg A */
|
|
Emios_Pwm_Ip_SetUCRegA(base, userChCfg->channelId, daocRegA);
|
|
/* Configure Trailing Edge in reg B */
|
|
Emios_Pwm_Ip_SetUCRegB(base, userChCfg->channelId, (userChCfg->dutyCycle + 1U));
|
|
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, userChCfg->channelId, userChCfg->outputPolarity);
|
|
|
|
Emios_Pwm_Ip_aNotif[instance][userChCfg->channelId] = (uint8)0U;
|
|
}
|
|
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetDutyCycleDaoc
|
|
* Description : Set new duty cycle for the channel in DAOC mode
|
|
* This function will check the specific duty cycle and set new duty cycle for
|
|
* this channel
|
|
*
|
|
*END**************************************************************************/
|
|
static Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleDaoc(uint8 instance,
|
|
uint8 channel,
|
|
uint16 newDutyCycle)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_StatusType ret = EMIOS_PWM_STATUS_SUCCESS;
|
|
uint16 daocRegA = 0U;
|
|
uint16 counterMax = Emios_Pwm_Ip_GetUCRegA(base, Emios_Pwm_Ip_GetMasterBusChannel(instance, channel));
|
|
|
|
/* DAOC mode */
|
|
if ((newDutyCycle > Emios_Pwm_Ip_aPeriod[instance][channel]) && ((uint16)0U != Emios_Pwm_Ip_aPeriod[instance][channel]))
|
|
{ /* Duty cycle value should not be greater than the channel Period. */
|
|
ret = EMIOS_PWM_STATUS_ERROR;
|
|
}
|
|
else if (((uint16)0U == Emios_Pwm_Ip_aPeriod[instance][channel]) || ((uint16)0U == newDutyCycle))
|
|
{
|
|
/* Disable and clear interrupt flag */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
|
|
/* If new period is 0, set duty cycle to 0 */
|
|
Emios_Pwm_Ip_aDaocDuty[instance][channel] = 0U;
|
|
|
|
Emios_Pwm_Ip_SetForceMatchB(base, channel, TRUE);
|
|
/* Configure Leading Edge in reg A */
|
|
Emios_Pwm_Ip_SetUCRegA(base, channel, 1U);
|
|
/* Configure Trailing Edge in reg B */
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, (newDutyCycle + 1U));
|
|
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, channel, (Emios_Pwm_Ip_aPolarity[instance][channel] == 1U)? EMIOS_PWM_ACTIVE_HIGH : EMIOS_PWM_ACTIVE_LOW);
|
|
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)1U;
|
|
}
|
|
else if(newDutyCycle == Emios_Pwm_Ip_aPeriod[instance][channel])
|
|
{
|
|
/* Disable and clear interrupt flag */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
|
|
Emios_Pwm_Ip_aDaocDuty[instance][channel] = 0U;
|
|
daocRegA = (Emios_Pwm_Ip_aPeriod[instance][channel] + Emios_Pwm_Ip_GetUCRegA(base, channel)) % counterMax;
|
|
|
|
Emios_Pwm_Ip_SetForceMatchA(base, channel, TRUE);
|
|
/* Configure Leading Edge in reg A */
|
|
Emios_Pwm_Ip_SetUCRegA(base, channel, (daocRegA == 0U)? counterMax : daocRegA);
|
|
/* Configure Trailing Edge in reg B */
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, (daocRegA == 0U)? counterMax : daocRegA);
|
|
/* Invert the EDGE POLARITY in control register */
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, channel,(Emios_Pwm_Ip_aPolarity[instance][channel] == 1U)? EMIOS_PWM_ACTIVE_LOW : EMIOS_PWM_ACTIVE_HIGH);
|
|
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)1U;
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_aDaocDuty[instance][channel] = newDutyCycle;
|
|
/* Configure Leading Edge in reg A */
|
|
Emios_Pwm_Ip_SetUCRegA(base, channel, 1U);
|
|
/* Configure Trailing Edge in reg B */
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, newDutyCycle + 1U);
|
|
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, channel, (Emios_Pwm_Ip_aPolarity[instance][channel] == 1U)? EMIOS_PWM_ACTIVE_HIGH : EMIOS_PWM_ACTIVE_LOW);
|
|
|
|
Emios_Pwm_Ip_aNotif[instance][channel] = (uint8)0U;
|
|
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
/*==================================================================================================
|
|
* GLOBAL FUNCTIONS
|
|
==================================================================================================*/
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_InitChannel
|
|
* Description : Initialize PWM mode.
|
|
* Select main mode
|
|
* - EMIOS OPWFMB
|
|
* Initialize Output Pulse Width and Frequency Modulation Buffered (OPWFMB) Mode.
|
|
* This mode provides waveforms with variable duty cycle and frequency. The internal channel counter
|
|
* is automatically selected as the time base when this mode is selected.
|
|
*
|
|
* - EMIOS OPWMB
|
|
* Initialize Output Pulse Width Modulation Buffered (OPWMB) Mode.
|
|
* OPWMB mode is used to generate pulses with programmable leading and trailing edge placement.
|
|
* An external counter driven in MCB Up mode must be selected from one of the counter buses.
|
|
* userChCfg defines the first edge and the second edge. The output signal polarity is defined
|
|
* by outputPolarity in userChCfg.
|
|
*
|
|
* - EMIOS OPWMCB
|
|
* Initialize Center Aligned Output Pulse Width Modulation with Dead Time Insertion Buffered (OPWMCB) Mode.
|
|
* This operation mode generates a center aligned PWM with dead time insertion to the leading or trailing edge.
|
|
* Allow smooth output signal generation when changing duty cycle and deadtime values.
|
|
*
|
|
* - EMIOS OPWMT
|
|
* Initialize Output Pulse Width Modulation with Trigger (OPWMT) Mode
|
|
* OPWMT mode is intended to support the generation of Pulse Width Modulation signals where
|
|
* the period is not modified while the signal is being output, but where the duty cycle will
|
|
* be varied and must not create glitches. The mode is intended to be used in conjunction with
|
|
* other channels executing in the same mode and sharing a common timebase. It will support each
|
|
* channel with a fixed PWM leading edge position with respect to the other channels and the
|
|
* ability to generate a trigger signal at any point in the period that can be output from
|
|
* the module to initiate activity in other parts of the SoC such as starting ADC conversions.
|
|
* Implements : Emios_Pwm_Ip_InitChannel_Activity
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_InitChannel(uint8 instance,
|
|
Emios_Pwm_Ip_ChannelConfigType const *userChCfg)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(NULL_PTR != userChCfg);
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
|
|
/* Check that a valid notification structure is defined for interrupt mode */
|
|
if (EMIOS_PWM_INTERRUPT_REQUEST == userChCfg->irqMode)
|
|
{
|
|
DevAssert(NULL_PTR != userChCfg->userCallback.cbFunction);
|
|
}
|
|
#endif
|
|
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
uint8 channel = userChCfg->channelId;
|
|
|
|
/* Disable channel pre-scaler (reset default) */
|
|
Emios_Pwm_Ip_aBasePtr[instance]->CH.UC[userChCfg->channelId].C = 0UL;
|
|
|
|
/* Enable the Output Update for channel */
|
|
Emios_Pwm_Ip_SetOutputUpdate(base, channel, TRUE);
|
|
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Configure debug freeze enable */
|
|
if ((FALSE == Emios_Pwm_Ip_GetDebugMode(base)) &&
|
|
(TRUE == userChCfg->debugMode))
|
|
{
|
|
DevAssert(FALSE);
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_SetFreezeEnable(base, userChCfg->channelId, userChCfg->debugMode);
|
|
}
|
|
#endif
|
|
|
|
/* Configure output disable feature */
|
|
if (EMIOS_PWM_OUTPUT_DISABLE_NONE != userChCfg->outputDisableSource)
|
|
{
|
|
Emios_Pwm_Ip_SetOutDisable(base, userChCfg->channelId, TRUE);
|
|
Emios_Pwm_Ip_SetOutDisableSource(base, userChCfg->channelId, userChCfg->outputDisableSource);
|
|
}
|
|
|
|
/* Configure Interrupt/DMA request */
|
|
if (EMIOS_PWM_NOTIFICATION_DISABLED != userChCfg->irqMode)
|
|
{
|
|
if (EMIOS_PWM_INTERRUPT_REQUEST == userChCfg->irqMode)
|
|
{
|
|
/* Register the notification structure */
|
|
Emios_Pwm_Ip_aNotificationPtr[instance][userChCfg->channelId] = &(userChCfg->userCallback);
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_SetDMARequest(base, userChCfg->channelId, TRUE);
|
|
}
|
|
}
|
|
|
|
/* Configure counterBus, dutyCycle, period, trigger, phase shift for selected mode */
|
|
switch (userChCfg->mode)
|
|
{
|
|
case EMIOS_PWM_MODE_OPWFMB_FLAG:
|
|
case EMIOS_PWM_MODE_OPWFMB_FLAG_BOTH:
|
|
/* OPWFMB mode initialization */
|
|
Emios_Pwm_Ip_InitPeriodDutyCycleMode(instance, userChCfg);
|
|
break;
|
|
case EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG:
|
|
case EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH:
|
|
case EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG:
|
|
case EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH:
|
|
/* OPWMCB mode initialization */
|
|
Emios_Pwm_Ip_InitDeadTimeMode(instance, userChCfg);
|
|
break;
|
|
case EMIOS_PWM_MODE_OPWMB_FLAG:
|
|
case EMIOS_PWM_MODE_OPWMB_FLAG_BOTH:
|
|
/* OPWMB mode initialization */
|
|
Emios_Pwm_Ip_InitEdgePlacementMode(instance, userChCfg);
|
|
break;
|
|
case EMIOS_PWM_MODE_OPWMT:
|
|
/* OPWMT mode initialization */
|
|
Emios_Pwm_Ip_InitTriggerMode(instance, userChCfg);
|
|
break;
|
|
case EMIOS_PWM_MODE_DAOC_FLAG:
|
|
case EMIOS_PWM_MODE_DAOC_FLAG_BOTH:
|
|
/* DAOC mode initialization */
|
|
Emios_Pwm_Ip_InitDoubleCompareMode(instance, userChCfg);
|
|
break;
|
|
default:
|
|
/* Nothing to do. All Pwm mode are already treated. */
|
|
break;
|
|
}
|
|
|
|
/* Configure internal prescaler */
|
|
if (EMIOS_PWM_CLOCK_NONE != userChCfg->internalPs)
|
|
{
|
|
Emios_Pwm_Ip_SetExtendedPrescaler(base, userChCfg->channelId, userChCfg->internalPs);
|
|
Emios_Pwm_Ip_SetPrescalerSource(base, userChCfg->channelId, userChCfg->internalPsSrc);
|
|
Emios_Pwm_Ip_SetPrescalerEnable(base, userChCfg->channelId, TRUE);
|
|
}
|
|
/* Confirm the channel is active*/
|
|
Emios_Pwm_Ip_aCheckState[instance][userChCfg->channelId] = (uint8)1U;
|
|
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_DeInitChannel
|
|
* Description : Reset eMIOS channel to GPIO mode (reset default)
|
|
* Implements : Emios_Pwm_Ip_DeInitChannel_Activity
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_DeInitChannel(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
/* Clear control register 2 and stop clock for channel */
|
|
base->CH.UC[channel].C2 = 0UL;
|
|
/* Clear control register for channel */
|
|
base->CH.UC[channel].C = 0UL;
|
|
/* Clear An and Bn registers */
|
|
Emios_Pwm_Ip_SetUCRegA(base, channel, 0U);
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, 0U);
|
|
/* Clear ALTAn if in PWM Trigger mode */
|
|
if (Emios_Pwm_Ip_GetPwmMode(base, channel) == EMIOS_PWM_MODE_OPWMT)
|
|
{
|
|
Emios_Pwm_Ip_SetTrigger(base, channel, 0U);
|
|
}
|
|
|
|
Emios_Pwm_Ip_aCheckEnableNotif[instance][channel] = (uint8)0U;
|
|
|
|
/* Confirm the channel is inactive*/
|
|
Emios_Pwm_Ip_aCheckState[instance][channel] = (uint8)0U;
|
|
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_ForceMatchLeadingEdge
|
|
* Description : Force the output flip-flop to the level corresponding to a match on Leading edge
|
|
* In Center Aligned Output Pulse Width Modulation with Dead Time Insertion Buffered (OPWMCB) Mode
|
|
* FORCMA has different behaviors depending upon the selected dead time
|
|
* insertion mode, lead or trail. In lead dead time insertion FORCMA force a transition
|
|
* in the output flipflop to the opposite of EDPOL. In trail dead time insertion the
|
|
* output flip-flop is forced to the value of EDPOL bit.
|
|
* FORCMA bit set does not set the internal time-base to 0x1 as a regular A1 match.
|
|
* Implements : Emios_Pwm_Ip_ForceMatchLeadingEdge_Activity
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_ForceMatchLeadingEdge(uint8 instance,
|
|
uint8 channel,
|
|
boolean enable)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_14();
|
|
/* Force Match A bit */
|
|
Emios_Pwm_Ip_SetForceMatchA(base, channel, enable);
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_14();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_ForceMatchTrailingEdge
|
|
* Description : Force the output flipflop to the level corresponding to a match on Trailing edge
|
|
*
|
|
* In Center Aligned Output Pulse Width Modulation with Dead Time Insertion Buffered (OPWMCB) Mode
|
|
* If FORCMB bit is set, the output flip-flop value depends upon the selected dead time
|
|
* insertion mode. In lead dead time insertion FORCMB forces the output flip-flop to transition to EDPOL
|
|
* bit value. In trail dead time insertion the output flip-flop is forced to the opposite of EDPOL bit value.
|
|
* Implements : Emios_Pwm_Ip_ForceMatchTrailingEdge_Activity
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_ForceMatchTrailingEdge(uint8 instance,
|
|
uint8 channel,
|
|
boolean enable)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_15();
|
|
/* Force Match B bit */
|
|
Emios_Pwm_Ip_SetForceMatchB(base, channel, enable);
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_15();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_GetPeriod
|
|
* Description : Get period of waveforms in PWM mode.
|
|
* Implements : Emios_Pwm_Ip_GetPeriod_Activity
|
|
*END**************************************************************************/
|
|
uint16 Emios_Pwm_Ip_GetPeriod(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_PwmModeType chMode = Emios_Pwm_Ip_GetPwmMode(base, channel);
|
|
uint16 chPeriod = 0x00U;
|
|
|
|
if ((chMode == EMIOS_PWM_MODE_OPWFMB_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWFMB_FLAG_BOTH))
|
|
{ /* OPWFMB mode */
|
|
chPeriod = Emios_Pwm_Ip_GetUCRegB(base, channel);
|
|
}
|
|
else if ((chMode == EMIOS_PWM_MODE_DAOC_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_DAOC_FLAG_BOTH))
|
|
{ /* DAOC mode */
|
|
chPeriod = Emios_Pwm_Ip_aPeriod[instance][channel];
|
|
}
|
|
else
|
|
{ /* OPWMCB mode or OPWMB or OPWMT mode */
|
|
chPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel));
|
|
}
|
|
|
|
return chPeriod;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetPeriod
|
|
* Description : Setup period of waveforms in OPWFMB mode.
|
|
* With PWM mode, the OPWFMB(Output Pulse Width and Frequency Modulation Buffered) can set
|
|
* period. All other PWM modes can not, because OPWFMB mode using internal counter. All other
|
|
* modes use external timebase and their period is timebase period.
|
|
* Implements : Emios_Pwm_Ip_SetPeriod_Activity
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_SetPeriod(uint8 instance,
|
|
uint8 channel,
|
|
uint16 newPeriod)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
Emios_Pwm_Ip_PwmModeType chMode = Emios_Pwm_Ip_GetPwmMode(base, channel);
|
|
#endif
|
|
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
/* Check channel mode is OPWFMB */
|
|
DevAssert((EMIOS_PWM_MODE_OPWFMB_FLAG == chMode) ||
|
|
(EMIOS_PWM_MODE_OPWFMB_FLAG_BOTH == chMode) ||
|
|
(EMIOS_PWM_MODE_DAOC_FLAG == chMode) ||
|
|
(EMIOS_PWM_MODE_DAOC_FLAG_BOTH == chMode));
|
|
#endif
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_16();
|
|
/* If new period is 0, No change the period */
|
|
if((uint16)0U == newPeriod)
|
|
{
|
|
/* Do Nothing */
|
|
}
|
|
else
|
|
{
|
|
/* Set new period */
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, newPeriod);
|
|
}
|
|
/* Store new period */
|
|
Emios_Pwm_Ip_aPeriod[instance][channel] = newPeriod;
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_16();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_GetDutyCycle
|
|
* Description : Get duty cycle of waveforms in PWM mode. Duty cycle is signal active time in a period.
|
|
* Implements : Emios_Pwm_Ip_GetDutyCycle_Activity
|
|
*END**************************************************************************/
|
|
uint16 Emios_Pwm_Ip_GetDutyCycle(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_PwmModeType chMode = Emios_Pwm_Ip_GetPwmMode(base, channel);
|
|
uint16 regAValue = Emios_Pwm_Ip_GetUCRegA(base, channel);
|
|
uint16 regBValue = Emios_Pwm_Ip_GetUCRegB(base, channel);
|
|
uint16 chPeriod = 0U;
|
|
uint16 dutyCycle = 0U;
|
|
|
|
switch (chMode)
|
|
{
|
|
case EMIOS_PWM_MODE_OPWFMB_FLAG:
|
|
case EMIOS_PWM_MODE_OPWFMB_FLAG_BOTH:
|
|
case EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG:
|
|
case EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH:
|
|
case EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG:
|
|
case EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH:
|
|
/* OPWFMB or OPWMCB mode */
|
|
dutyCycle = regAValue;
|
|
break;
|
|
case EMIOS_PWM_MODE_OPWMB_FLAG:
|
|
case EMIOS_PWM_MODE_OPWMB_FLAG_BOTH:
|
|
/* OPWMB mode */
|
|
dutyCycle = regBValue - regAValue;
|
|
break;
|
|
case EMIOS_PWM_MODE_OPWMT:
|
|
/* OPWMT mode */
|
|
/* Get channel period */
|
|
chPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel));
|
|
if (regBValue > chPeriod)
|
|
{ /* 100% dutyCycle when B value is greater than channel period. */
|
|
dutyCycle = regBValue;
|
|
}
|
|
else if (regBValue < regAValue)
|
|
{ /* PhaseShift of signal wrapped around the duty cycle */
|
|
dutyCycle = (chPeriod - regAValue) + regBValue;
|
|
}
|
|
else
|
|
{
|
|
dutyCycle = regBValue - regAValue;
|
|
}
|
|
break;
|
|
case EMIOS_PWM_MODE_DAOC_FLAG:
|
|
case EMIOS_PWM_MODE_DAOC_FLAG_BOTH:
|
|
/* DAOC mode */
|
|
dutyCycle = Emios_Pwm_Ip_aDaocDuty[instance][channel];
|
|
break;
|
|
default:
|
|
/* Nothing to do */
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(FALSE);
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
return dutyCycle;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetDutyCycle
|
|
* Description : Setup duty cycle of waveforms in OPWFMB mode.
|
|
* Duty cycle should be not greater period value. When set duty cycle value greater period value
|
|
* (and do not over 16 bits counter register) 100% duty cycle signal generated.
|
|
* Implements : Emios_Pwm_Ip_SetDutyCycle_Activity
|
|
*END**************************************************************************/
|
|
Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycle(uint8 instance,
|
|
uint8 channel,
|
|
uint16 newDutyCycle)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_StatusType ret = EMIOS_PWM_STATUS_SUCCESS;
|
|
Emios_Pwm_Ip_PwmModeType chMode = Emios_Pwm_Ip_GetPwmMode(base, channel);
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_17();
|
|
if ((chMode == EMIOS_PWM_MODE_OPWFMB_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWFMB_FLAG_BOTH))
|
|
{
|
|
/* OPWFMB mode */
|
|
ret = Emios_Pwm_Ip_SetDutyCycleOpwfmb(instance, channel, newDutyCycle);
|
|
}
|
|
else if ((chMode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH))
|
|
{
|
|
/* OPWMCB mode */
|
|
ret = Emios_Pwm_Ip_SetDutyCycleOpwmcb(instance, channel, newDutyCycle);
|
|
}
|
|
else if ((chMode == EMIOS_PWM_MODE_OPWMB_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMB_FLAG_BOTH))
|
|
{
|
|
/* OPWMB mode */
|
|
ret = Emios_Pwm_Ip_SetDutyCycleOpwmb(instance, channel, newDutyCycle);
|
|
}
|
|
else if((chMode == EMIOS_PWM_MODE_DAOC_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_DAOC_FLAG_BOTH))
|
|
{
|
|
/* DAOC mode */
|
|
ret = Emios_Pwm_Ip_SetDutyCycleDaoc(instance, channel, newDutyCycle);
|
|
}
|
|
else
|
|
{
|
|
/* OPWMT mode */
|
|
ret = Emios_Pwm_Ip_SetDutyCycleOpwmt(instance, channel, newDutyCycle);
|
|
}
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_17();
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_GetPhaseShift
|
|
* Description : Get Leading edge position of waveforms in OPWMB & OPWMT mode.
|
|
* Implements : Emios_Pwm_Ip_GetPhaseShift_Activity
|
|
*END**************************************************************************/
|
|
uint16 Emios_Pwm_Ip_GetPhaseShift(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
Emios_Pwm_Ip_PwmModeType chMode = Emios_Pwm_Ip_GetPwmMode(base, channel);
|
|
|
|
DevAssert((EMIOS_PWM_MODE_OPWMB_FLAG == chMode) ||
|
|
(EMIOS_PWM_MODE_OPWMB_FLAG_BOTH == chMode) ||
|
|
(EMIOS_PWM_MODE_OPWMT == chMode));
|
|
#endif
|
|
|
|
return Emios_Pwm_Ip_GetUCRegA(base, channel);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetPhaseShift
|
|
* Description : Set Leading edge position of waveforms in OPWMB & OPWMT mode.
|
|
* DutyCycle will be kept the same value.
|
|
* Implements : Emios_Pwm_Ip_SetPhaseShift_Activity
|
|
*END**************************************************************************/
|
|
Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetPhaseShift(uint8 instance,
|
|
uint8 channel,
|
|
uint16 phaseShift)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
|
|
Emios_Pwm_Ip_StatusType status = EMIOS_PWM_STATUS_SUCCESS;
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_PwmModeType chMode = Emios_Pwm_Ip_GetPwmMode(base, channel);
|
|
uint16 chPeriod = 0U;
|
|
uint16 dutyCycle = 0U;
|
|
uint8 counterStart = 0U;
|
|
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert((EMIOS_PWM_MODE_OPWMB_FLAG == chMode) ||
|
|
(EMIOS_PWM_MODE_OPWMB_FLAG_BOTH == chMode) ||
|
|
(EMIOS_PWM_MODE_OPWMT == chMode));
|
|
#endif
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_18();
|
|
chPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel));
|
|
dutyCycle = Emios_Pwm_Ip_GetDutyCycle(instance, channel);
|
|
|
|
if (EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel)))
|
|
{
|
|
counterStart = 1U;
|
|
}
|
|
else
|
|
{
|
|
counterStart = 0U;
|
|
}
|
|
|
|
Emios_Pwm_Ip_aRegA[instance][channel] = phaseShift + counterStart;
|
|
|
|
/* Check that phase shift can be applied to the selected channel */
|
|
if ((EMIOS_PWM_MODE_OPWMB_FLAG == chMode) ||
|
|
(EMIOS_PWM_MODE_OPWMB_FLAG_BOTH == chMode))
|
|
{
|
|
if ((phaseShift + dutyCycle) > chPeriod)
|
|
{
|
|
status = EMIOS_PWM_STATUS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
/* Set the new phase shift */
|
|
Emios_Pwm_Ip_SetUCRegA(base, channel, (phaseShift + counterStart));
|
|
/* Move trailing edge to keep the same duty cycle */
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, (phaseShift + dutyCycle + counterStart));
|
|
}
|
|
}
|
|
else if (EMIOS_PWM_MODE_OPWMT == chMode)
|
|
{
|
|
if (phaseShift > chPeriod)
|
|
{
|
|
status = EMIOS_PWM_STATUS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
/* Set the new phase shift */
|
|
Emios_Pwm_Ip_SetUCRegA(base, channel, (phaseShift + counterStart));
|
|
/* Move trailing edge to keep the same duty cycle */
|
|
if (dutyCycle < (chPeriod + 1U))
|
|
{
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, (((phaseShift + dutyCycle) % chPeriod) + counterStart));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = EMIOS_PWM_STATUS_ERROR;
|
|
}
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_18();
|
|
|
|
return status;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_GetDeadTime
|
|
* Description : Get Dead time value of waveforms in OPWMCB mode.
|
|
* Implements : Emios_Pwm_Ip_GetDeadTime_Activity
|
|
*END**************************************************************************/
|
|
uint16 Emios_Pwm_Ip_GetDeadTime(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
Emios_Pwm_Ip_PwmModeType chMode = Emios_Pwm_Ip_GetPwmMode(base, channel);
|
|
|
|
DevAssert((chMode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH));
|
|
#endif
|
|
/* Get the configured dead time */
|
|
return Emios_Pwm_Ip_GetUCRegB(base, channel);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetDeadTime
|
|
* Description : Set Dead time value of waveforms in OPWMCB mode. New dead time should
|
|
* be no greater than 0xFFFF (16 bits).
|
|
* Implements : Emios_Pwm_Ip_SetDeadTime_Activity
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_SetDeadTime(uint8 instance,
|
|
uint8 channel,
|
|
uint16 newDeadTime)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
Emios_Pwm_Ip_PwmModeType chMode = Emios_Pwm_Ip_GetPwmMode(base, channel);
|
|
|
|
DevAssert((chMode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH));
|
|
#endif
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_19();
|
|
/* Set the new dead time */
|
|
Emios_Pwm_Ip_SetUCRegB(base, channel, newDeadTime);
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_19();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_GetTriggerPlacement
|
|
* Description : Get Trigger placement value in OPWMT mode
|
|
* Implements : Emios_Pwm_Ip_GetTriggerPlacement_Activity
|
|
*END**************************************************************************/
|
|
uint32 Emios_Pwm_Ip_GetTriggerPlacement(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(Emios_Pwm_Ip_GetPwmMode(base, channel) == EMIOS_PWM_MODE_OPWMT);
|
|
#endif
|
|
/* Get the configured trigger */
|
|
return Emios_Pwm_Ip_GetTrigger(base, channel);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetTriggerPlacement
|
|
* Description : Set Trigger placement value in OPWMT mode. New trigger placement
|
|
* should be no larger than 0xFFFFFF(24 bits).
|
|
* Implements : Emios_Pwm_Ip_SetTriggerPlacement_Activity
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_SetTriggerPlacement(uint8 instance,
|
|
uint8 channel,
|
|
uint32 newTriggerPlacement)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
uint8 counterStart = 0U;
|
|
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(Emios_Pwm_Ip_GetPwmMode(base, channel) == EMIOS_PWM_MODE_OPWMT);
|
|
/* Check selected counter bus is configured in MCB Up Mode or MC Up mode */
|
|
DevAssert((EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel))) ||
|
|
(EMIOS_PWM_IP_MC_UP_COUNTER_START == Emios_Pwm_Ip_GetCounterBusMode(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel))) ||
|
|
(EMIOS_PWM_IP_MC_UP_COUNTER_END == Emios_Pwm_Ip_GetCounterBusMode(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel)))
|
|
);
|
|
DevAssert((Emios_Pwm_Ip_GetCounterBusPeriod(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel))) > newTriggerPlacement);
|
|
#endif
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_20();
|
|
if (EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(instance, channel, Emios_Pwm_Ip_GetCounterBus(base, channel)))
|
|
{
|
|
counterStart = 1U;
|
|
}
|
|
else
|
|
{
|
|
counterStart = 0U;
|
|
}
|
|
/* Set the new trigger value */
|
|
Emios_Pwm_Ip_SetTrigger(base, channel, (uint16)(newTriggerPlacement + counterStart));
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_20();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_ChannelEnterDebugMode
|
|
* Description : To set a channel enters freeze state, should be setting
|
|
* Emios_Pwm_Ip_AllowEnterDebugMode first.
|
|
* Implements : Emios_Pwm_Ip_ChannelEnterDebugMode_Activity
|
|
*END**************************************************************************/
|
|
Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_ChannelEnterDebugMode(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_StatusType ret = EMIOS_PWM_STATUS_SUCCESS;
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_21();
|
|
if (Emios_Pwm_Ip_GetDebugMode(base) == TRUE)
|
|
{
|
|
Emios_Pwm_Ip_SetFreezeEnable(base, channel, TRUE);
|
|
}
|
|
else
|
|
{
|
|
ret = EMIOS_PWM_STATUS_GLOBAL_FREEZE_DISABLED;
|
|
}
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_21();
|
|
return ret;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_ChannelStopDebugMode
|
|
* Description : Release a channel from freeze state
|
|
* Implements : Emios_Pwm_Ip_ChannelStopDebugMode_Activity
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_ChannelStopDebugMode(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_22();
|
|
Emios_Pwm_Ip_SetFreezeEnable(base, channel, FALSE);
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_22();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_GetFlagRequest
|
|
* Description : Configure what the FLAG event should do. Generate Interrupt request,
|
|
* Generate DMA request or do nothing.
|
|
* Implements : Emios_Pwm_Ip_GetFlagRequest_Activity
|
|
*END**************************************************************************/
|
|
Emios_Pwm_Ip_InterruptType Emios_Pwm_Ip_GetFlagRequest(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_InterruptType eventType = EMIOS_PWM_NOTIFICATION_DISABLED;
|
|
|
|
if (Emios_Pwm_Ip_GetInterruptRequest(base, channel) == TRUE)
|
|
{
|
|
if (Emios_Pwm_Ip_GetDMARequest(base, channel) == TRUE)
|
|
{
|
|
eventType = EMIOS_PWM_DMA_REQUEST;
|
|
}
|
|
else
|
|
{
|
|
eventType = EMIOS_PWM_INTERRUPT_REQUEST;
|
|
}
|
|
}
|
|
|
|
return eventType;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetFlagRequest
|
|
* Description : Configure what the FLAG event should do. Generate Interrupt request,
|
|
* Generate DMA request or do nothing.
|
|
* Implements : Emios_Pwm_Ip_SetFlagRequest_Activity
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_SetFlagRequest(uint8 instance,
|
|
uint8 channel,
|
|
Emios_Pwm_Ip_InterruptType event)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_23();
|
|
/* Clear Interrupt flag */
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
|
|
switch (event)
|
|
{
|
|
case EMIOS_PWM_INTERRUPT_REQUEST:
|
|
if ((uint8)0U == Emios_Pwm_Ip_aNotif[instance][channel])
|
|
{
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, TRUE);
|
|
Emios_Pwm_Ip_SetDMARequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_aCheckEnableNotif[instance][channel] = (uint8)1U;
|
|
}
|
|
break;
|
|
case EMIOS_PWM_DMA_REQUEST:
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, TRUE);
|
|
Emios_Pwm_Ip_SetDMARequest(base, channel, TRUE);
|
|
break;
|
|
case EMIOS_PWM_NOTIFICATION_DISABLED:
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_SetDMARequest(base, channel, FALSE);
|
|
Emios_Pwm_Ip_aCheckEnableNotif[instance][channel] = (uint8)0U;
|
|
break;
|
|
default:
|
|
/*Nothig to do. All cases are treated. */
|
|
break;
|
|
}
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_23();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_GetOutputState
|
|
* Description : Get the Unified Channel output pin logic level
|
|
*
|
|
* Implements : Emios_Pwm_Ip_GetOutputState_Activity
|
|
*END**************************************************************************/
|
|
Emios_Pwm_Ip_OutputStateType Emios_Pwm_Ip_GetOutputState(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
return (Emios_Pwm_Ip_GetOutputPinState(base, channel) == FALSE)? EMIOS_PWM_OUTPUT_STATE_LOW : EMIOS_PWM_OUTPUT_STATE_HIGH;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetOutputState
|
|
* Description : Set the state of output pin
|
|
*
|
|
*
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_SetOutputState(uint8 instance,
|
|
uint8 channel,
|
|
Emios_Pwm_Ip_OutputStateType outputState)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_24();
|
|
/* Set output pin polarity */
|
|
if (EMIOS_PWM_OUTPUT_STATE_LOW == outputState)
|
|
{
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, channel, (Emios_Pwm_Ip_PolarityType)EMIOS_PWM_ACTIVE_LOW);
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, channel, (Emios_Pwm_Ip_PolarityType)EMIOS_PWM_ACTIVE_HIGH);
|
|
}
|
|
/* Enter GPIO output mode */
|
|
Emios_Pwm_Ip_SetPwmMode(base, channel, (Emios_Pwm_Ip_PwmModeType)EMIOS_PWM_MODE_GPO);
|
|
/* Disable channel interrupts */
|
|
Emios_Pwm_Ip_SetInterruptRequest(base, channel, (boolean)FALSE);
|
|
/* Clear pending interrupt flag for the channel */
|
|
Emios_Pwm_Ip_ClearFlagEvent(base, channel);
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_24();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetOutputToNormal
|
|
* Description : Set the polarity and mode for current channel as normal
|
|
*
|
|
*
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_SetOutputToNormal(uint8 instance,
|
|
uint8 channel,
|
|
uint16 dutyPercent,
|
|
Emios_Pwm_Ip_PolarityType polarity,
|
|
Emios_Pwm_Ip_PwmModeType mode)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_25();
|
|
if (EMIOS_PWM_MODE_GPO == Emios_Pwm_Ip_GetPwmMode(base, channel))
|
|
{
|
|
|
|
|
|
if ((mode == EMIOS_PWM_MODE_OPWFMB_FLAG) || (mode == EMIOS_PWM_MODE_OPWFMB_FLAG_BOTH))
|
|
{
|
|
Emios_Pwm_Ip_SetPwmMode(base, channel, mode);
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, channel,(polarity == EMIOS_PWM_ACTIVE_HIGH) ? EMIOS_PWM_ACTIVE_LOW : EMIOS_PWM_ACTIVE_HIGH );
|
|
}
|
|
else if((mode == EMIOS_PWM_MODE_OPWMB_FLAG) || (mode == EMIOS_PWM_MODE_OPWMB_FLAG_BOTH))
|
|
{
|
|
Emios_Pwm_Ip_SetPwmMode(base, channel, mode);
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, channel, polarity);
|
|
}
|
|
else
|
|
{
|
|
/* To avoid spike pulse
|
|
If duty cycle = 100%, when enter mode, EDPOL bit get complement of polarity
|
|
after that, EDPOL bit is restored valid value */
|
|
if(dutyPercent == 0x8000U)
|
|
{
|
|
Emios_Pwm_Ip_SetPwmModePol(base, channel,mode, (polarity == EMIOS_PWM_ACTIVE_HIGH) ? EMIOS_PWM_ACTIVE_LOW : EMIOS_PWM_ACTIVE_HIGH);
|
|
Emios_Pwm_Ip_SetEdgePolarity(base, channel, polarity);
|
|
}
|
|
else
|
|
{
|
|
Emios_Pwm_Ip_SetPwmModePol(base, channel,mode, polarity);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*Do Nothing*/
|
|
(void)polarity;
|
|
(void)mode;
|
|
}
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_25();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_GetChannelMode
|
|
* Description : Get mode of operation of the Unified Channel
|
|
*
|
|
*END**************************************************************************/
|
|
Emios_Pwm_Ip_PwmModeType Emios_Pwm_Ip_GetChannelMode(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
Emios_Pwm_Ip_PwmModeType channelMode = Emios_Pwm_Ip_GetPwmMode(base, channel);
|
|
|
|
return channelMode;
|
|
}
|
|
|
|
/**
|
|
* @brief Get master bus channel
|
|
*
|
|
* @param[in] instance The eMIOS group id
|
|
* @param[in] channel The channel in this eMIOS group
|
|
* @return Emios_Pwm_Ip_PwmModeType
|
|
*/
|
|
uint8 Emios_Pwm_Ip_GetMasterBusChannel(uint8 instance,
|
|
uint8 channel)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
const Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
uint8 channelMaster = channel;
|
|
|
|
Emios_Pwm_Ip_CounterBusSourceType counterBus = Emios_Pwm_Ip_GetCounterBus(base, channel);
|
|
|
|
switch (counterBus)
|
|
{
|
|
case EMIOS_PWM_BUS_A:
|
|
channelMaster = 23U;
|
|
break;
|
|
case EMIOS_PWM_BUS_F:
|
|
channelMaster = 22U;
|
|
break;
|
|
case EMIOS_PWM_BUS_BCDE:
|
|
channelMaster = (uint8)((channel >> 3U) * 8U);
|
|
break;
|
|
default:
|
|
/* Internal bus is used */
|
|
channelMaster = channel;
|
|
break;
|
|
}
|
|
return channelMaster;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetPreEnableClock
|
|
* Description : Set Prescaler Enable bit.
|
|
*
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_SetPreEnableClock(uint8 instance,
|
|
uint8 channel,
|
|
boolean value)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_26();
|
|
/* Set Prescaler Enable bit. */
|
|
Emios_Pwm_Ip_SetPrescalerEnable(base, channel, value);
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_26();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetBusSelected
|
|
* Description : Set Bus Select bits.
|
|
*
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_SetBusSelected(uint8 instance,
|
|
uint8 channel,
|
|
Emios_Pwm_Ip_CounterBusSourceType value)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_27();
|
|
/* Set Bus Select bits.*/
|
|
Emios_Pwm_Ip_SetCounterBus(base, channel, value);
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_27();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SetClockPs
|
|
* Description : This function set the value of the prescaler on eMios channels
|
|
*
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_SetClockPs(uint8 instance,
|
|
uint8 channel,
|
|
Emios_Pwm_Ip_InternalClkPsType value)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
DevAssert(EMIOS_PWM_CHANNEL_COUNT > channel);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_28();
|
|
/* Stop eMios channel - this will stop the internal counter */
|
|
Emios_Pwm_Ip_SetPrescalerEnable(base, channel, FALSE);
|
|
/*Set Extended Prescaler bits */
|
|
Emios_Pwm_Ip_SetExtendedPrescaler(base, channel, value);
|
|
/* Re-start eMios channel */
|
|
Emios_Pwm_Ip_SetPrescalerEnable(base, channel, TRUE);
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_28();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_ComparatorTransferEnable
|
|
* Description : The function shall enable the output update for the corresponding channel.
|
|
*
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_ComparatorTransferEnable(uint8 instance, uint32 channelMask)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
#endif
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_29();
|
|
/* Enable the output update for the corresponding channel.*/
|
|
Emios_Mcl_Ip_ComparatorTransferEnable(instance, channelMask);
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_29();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_ComparatorTransferDisable
|
|
* Description : The function shall disable the output update for the corresponding channel.
|
|
*
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_ComparatorTransferDisable(uint8 instance, uint32 channelMask)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
#endif
|
|
|
|
SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_30();
|
|
/* Disable the output update for the corresponding channel.*/
|
|
Emios_Mcl_Ip_ComparatorTransferDisable(instance, channelMask);
|
|
SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_30();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Emios_Pwm_Ip_SyncUpdate
|
|
* Description : This function updates the duty cycle and-or period for the specified PWM channel.
|
|
* The value written does not take effect until calling SyncUpdate API.
|
|
*
|
|
*END**************************************************************************/
|
|
void Emios_Pwm_Ip_SyncUpdate(uint8 instance)
|
|
{
|
|
#if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(EMIOS_PWM_INSTANCE_COUNT > instance);
|
|
#endif
|
|
Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[instance];
|
|
|
|
/* Read OUDIS register */
|
|
uint32 oudisRegVal = (uint32)Emios_Pwm_Ip_GetOutputUpdateInstance(base);
|
|
/* the mask of channels */
|
|
uint32 channelMask = (uint32)0U;
|
|
/* Store the mode of channel */
|
|
Emios_Pwm_Ip_PwmModeType chMode;
|
|
|
|
uint8 oudisDisable = 0U;
|
|
uint8 channelId;
|
|
/* Loop all channels available on each Emios instance */
|
|
for (channelId = 0U; channelId < EMIOS_PWM_CHANNEL_COUNT; channelId++)
|
|
{
|
|
oudisDisable = (uint8)((oudisRegVal & (uint32)((uint32)1U << channelId)) >> channelId);
|
|
|
|
if (((uint8)0U != Emios_Pwm_Ip_aCheckState[instance][channelId]) && ((uint8)1U == oudisDisable))
|
|
{
|
|
chMode = Emios_Pwm_Ip_GetPwmMode(base, channelId);
|
|
/* This statement is required to avoid limitation of 0% duty cycle (if call 100% to 0%) */
|
|
if(1U == Emios_Pwm_Ip_GetUCRegA(base, channelId))
|
|
{
|
|
if((chMode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH))
|
|
{
|
|
/* Enable the output update for the corresponding channel.*/
|
|
Emios_Mcl_Ip_ComparatorTransferEnable(instance, (uint32)((uint32)1U << channelId));
|
|
|
|
Emios_Pwm_Ip_SetForceMatchB(base, channelId, TRUE);
|
|
}
|
|
else if ((chMode == EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG) ||
|
|
(chMode == EMIOS_PWM_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH))
|
|
{
|
|
/* Enable the output update for the corresponding channel.*/
|
|
Emios_Mcl_Ip_ComparatorTransferEnable(instance, (uint32)((uint32)1U << channelId));
|
|
|
|
Emios_Pwm_Ip_SetForceMatchA(base, channelId, TRUE);
|
|
}
|
|
else
|
|
{
|
|
/* Do Nothing */
|
|
}
|
|
}
|
|
|
|
/* Update OUDIS register value for synchronization */
|
|
channelMask |= (uint32)((uint32)1U << channelId);
|
|
}
|
|
}
|
|
/* Write OUDIS register */
|
|
Emios_Mcl_Ip_ComparatorTransferEnable(instance, channelMask);
|
|
}
|
|
|
|
#define PWM_STOP_SEC_CODE
|
|
#include "Pwm_MemMap.h"
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
/** @} */
|