MXC-A36_2024.04.18/fr3092_mcu/components/drivers/peripheral/Src/driver_pwm.c

307 lines
9.1 KiB
C
Raw Normal View History

2024-04-17 19:45:26 +08:00
/*
******************************************************************************
* @file driver_pwm.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief SPI module driver.
* This file provides firmware functions to manage the
* Pulse-Width Modulatio (PWM) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn pwm_config
*
* @brief PWM mode. Config channel paramter.
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fu16_channel: Select output channel.(1bit ~ 1channel)
* fstr_Config: Config paramter.
*/
void pwm_config(struct_PWM_t *PWMx, uint16_t fu16_channel, struct_PWM_Config_t fstr_Config)
{
uint32_t lu32_Position = 0;
uint32_t lu32_Current_Channel;
PWMx->OutputSelect &= ~fu16_channel;
/* Configure Select channel */
while (fu16_channel >> lu32_Position != 0)
{
/* Get current pin position */
lu32_Current_Channel = fu16_channel & (1uL << lu32_Position);
if (lu32_Current_Channel)
{
/* stop sync update */
PWMx->Update.PWM_Update &= ~lu32_Current_Channel;
PWMx->Edge[lu32_Position].Posedge = fstr_Config.Posedge;
PWMx->Edge[lu32_Position].Negedeg = fstr_Config.Negedge;
PWMx->Frequency[lu32_Position].Prescale = fstr_Config.Prescale - 1;
PWMx->Frequency[lu32_Position].Period = fstr_Config.Period - 1;
}
lu32_Position++;
}
}
/************************************************************************************
* @fn pwm_complementary_config
*
* @brief Complementary outputs with dead-time insertion
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fu16_MainChannel: Select main output channel.(1bit ~ 1channel)
* @param ComplementaryChannel: Select complementary output channel.(1bit ~ 1channel)
* fstr_Config: Config paramter.
*/
bool pwm_complementary_config(struct_PWM_t *PWMx, uint16_t fu16_MainChannel, uint16_t ComplementaryChannel, struct_PWM_Complementary_Config_t fstr_Config)
{
struct_PWM_Config_t PWM_Config;
PWM_Config.Prescale = fstr_Config.Prescale;
PWM_Config.Period = fstr_Config.Period;
if (fstr_Config.MianDeadTime != 0)
{
if (fstr_Config.MianDeadTime - 1 >= PWM_Config.Period - 1 - fstr_Config.DutyCycle - fstr_Config.MianDeadTime)
return false;
PWM_Config.Posedge = fstr_Config.MianDeadTime - 1;
PWM_Config.Negedge = PWM_Config.Period - 1 - fstr_Config.DutyCycle - fstr_Config.MianDeadTime;
}
else
{
/* Error check */
if (fstr_Config.DutyCycle >= PWM_Config.Period)
return false;
if (fstr_Config.DutyCycle == 0)
return false;
PWM_Config.Posedge = PWM_Config.Period - 1;
PWM_Config.Negedge = PWM_Config.Period - 1 - fstr_Config.DutyCycle;
}
pwm_config(PWMx, fu16_MainChannel, PWM_Config);
if (fstr_Config.CompDeadTime != 0)
{
if (PWM_Config.Period - 1 - fstr_Config.DutyCycle + fstr_Config.MianDeadTime >= PWM_Config.Period - 1 - fstr_Config.CompDeadTime)
return false;
PWM_Config.Posedge = PWM_Config.Period - 1 - fstr_Config.DutyCycle + fstr_Config.MianDeadTime;
PWM_Config.Negedge = PWM_Config.Period - 1 - fstr_Config.CompDeadTime;
}
else
{
/* Error check */
if (fstr_Config.DutyCycle >= PWM_Config.Period)
return false;
if (fstr_Config.DutyCycle == 0)
return false;
PWM_Config.Posedge = PWM_Config.Period - 1 - fstr_Config.DutyCycle;
PWM_Config.Negedge = PWM_Config.Period - 1;
}
pwm_config(PWMx, ComplementaryChannel, PWM_Config);
return true;
}
/************************************************************************************
* @fn pwm_output_enable
*
* @brief PWM_DAC mode. output enable.
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fu16_channel: Select output channel.(1bit ~ 1channel)
*/
void pwm_output_enable(struct_PWM_t *PWMx, uint16_t fu16_channel)
{
PWMx->Update.PWM_Update |= fu16_channel;
PWMx->CNT_EN |= fu16_channel;
PWMx->ChannelEN |= fu16_channel;
}
/************************************************************************************
* @fn pwm_output_disable
*
* @brief PWM_DAC mode. output disable.
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fu8_channel: Select output channel.(1bit ~ 1channel)
*/
void pwm_output_disable(struct_PWM_t *PWMx, uint16_t fu16_channel)
{
/* stop sync update */
PWMx->Update.PWM_Update &= ~fu16_channel;
PWMx->ChannelEN &= ~fu16_channel;
PWMx->CNT_EN &= ~fu16_channel;
}
/************************************************************************************
* @fn pwm_output_status
*
* @brief PWM_DAC mode. output inverter disable.
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fe_channel: Select output channel.(1bit ~ 1channel)
*
* @return true : PWM runing.
* false: PWM stop.
*/
bool pwm_output_status(struct_PWM_t *PWMx, enum_PWMChannel_t fe_channel)
{
if (PWMx->Update.PWM_Status & fe_channel)
{
return true;
}
else
{
return false;
}
}
/************************************************************************************
* @fn pwm_output_updata
*
* @brief channel Posedge/Negedeg/Prescale/Period updata
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fu16_channel: Select output channel.(1bit ~ 1channel)
*/
void pwm_output_updata(struct_PWM_t *PWMx, uint16_t fu16_channel)
{
/* start sync update */
PWMx->Update.PWM_Update |= fu16_channel;
}
/************************************************************************************
* @fn pwm_capture_config
*
* @brief Capture mode. Config channel paramter.
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fu16_channel: Select capture channel(1bit ~ 1channel).
* fstr_Config: Config paramter.
*/
void pwm_capture_config(struct_PWM_t *PWMx, uint16_t fu16_channel, struct_Capture_Config_t fstr_Config)
{
uint32_t lu32_Position = 0;
uint32_t lu32_Current_Channel;
/* Set Capture Prescale */
PWMx->CapturePrescale = 0x10 | fstr_Config.CapturePrescale;
/* Configure Select channel */
while (fu16_channel >> lu32_Position != 0)
{
/* Get current pin position */
lu32_Current_Channel = fu16_channel & (1uL << lu32_Position);
if (lu32_Current_Channel)
{
/* Set Capture mode */
if (fstr_Config.CaptureMode == MODE_LOOP)
{
PWMx->CaptureCtrl.Capture_Mode &= ~lu32_Current_Channel;
}
else
{
PWMx->CaptureCtrl.Capture_Mode |= lu32_Current_Channel;
}
}
lu32_Position++;
}
}
/************************************************************************************
* @fn pwm_capture_enable
*
* @brief capture enable.
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fu16_channel: Select capture channel.(1bit ~ 1channel)
*/
void pwm_capture_enable(struct_PWM_t *PWMx, uint16_t fu16_channel)
{
PWMx->CaptureCtrl.Capture_EN |= fu16_channel;
}
/************************************************************************************
* @fn pwm_capture_disable
*
* @brief pwm_capture_disable.
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fu16_channel: Select capture channel.(1bit ~ 1channel)
*/
void pwm_capture_disable(struct_PWM_t *PWMx, uint16_t fu16_channel)
{
PWMx->CaptureCtrl.Capture_EN &= ~fu16_channel;
}
/************************************************************************************
* @fn pwm_capture_status
*
* @brief get pwm_capture_status.
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fe_channel: Select capture channel.(1bit ~ 1channel)
* @return true : capture result value ready.
* false: capture result value not ready.
*/
bool pwm_capture_status(struct_PWM_t *PWMx, enum_PWMChannel_t fe_channel)
{
return (PWMx->CaptureStatus & fe_channel) ? true : false;
}
/************************************************************************************
* @fn pwm_capture_status_clear
*
* @brief capture status claear.
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fe_channel: Select capture channel.(1bit ~ 1channel)
*/
void pwm_capture_status_clear(struct_PWM_t *PWMx,enum_PWMChannel_t fe_channel)
{
PWMx->CaptureStatus |= fe_channel;
}
/************************************************************************************
* @fn pwm_capture_value
*
* @brief get pwm_capture_value.
*
* @param PWMx: PWM0<EFBFBD><EFBFBD>PWM1.
* fe_channel: Select capture channel.(1bit ~ 1channel)
*/
uint32_t pwm_capture_value(struct_PWM_t *PWMx, enum_PWMChannel_t fe_channel)
{
uint8_t i;
for (i = 0; i < 16; i++)
{
if (fe_channel & 1 << i)
break;
}
return PWMx->CaptureValue[i];
}