Pwm_Flagchip_FC7240/Src/PwmFlagchip.c

164 lines
5.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by cfif on 07.09.22.
//
#include "PwmFlagchip.h"
void Get_Set_Tpu_PwmCallback(tPwmFlagchip *env) {
// Обновляем только если есть запрос и канал не отключен
if ((env->updatePending) && (!env->isDisabled)) {
env->etpu_pwmconfig_tbl.u32ActiveTime = env->pendingActiveTime;
env->updatePending = false;
}
TPU_PwmServiceReq(env->TPU_PWM_CHANNEL, env->etpu_pwmconfig_tbl.u32ActiveTime,
env->etpu_pwmconfig_tbl.u32PeriodTime);
}
// Функция для полной остановки ШИМ на канале
static void TPU_StopChannel(uint8_t channel) {
TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS;
// Отключаем выход буфера канала
TPU_E_HWA_EnableChOutputBuf(pTPUE, channel, (bool)false);
// Опционально: устанавливаем выход в безопасное состояние
// (нужно определить, какое состояние безопасно для вашей системы)
}
// Функция для запуска конкретного канала
static void TPU_StartChannelSpecific(uint8_t channel) {
TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS;
// Включаем выход буфера канала
TPU_E_HWA_EnableChOutputBuf(pTPUE, channel, (bool)true);
}
void PWM_Initial(
tPwmFlagchip *env,
bool isDeInit,
uint32_t PeriodTime,
uint32_t ActiveTime,
uint8_t TPU_PWM_CHANNEL,
uint8 TPU_PRIORITY,
TPU_EventCallbackType Bsp_Tpu_PwmCallback,
TPU_TCR1OverflowCallbackType Bsp_Tpu_OverflowCallBack) {
env->etpu_pwmconfig_tbl.eTBS1 = TPUE_EQUAL_ONLY_CAPBASE_TCR1_MATCHBASE_TCR1;
env->etpu_pwmconfig_tbl.eTBS2 = TPUE_EQUAL_ONLY_CAPBASE_TCR1_MATCHBASE_TCR1;
env->etpu_pwmconfig_tbl.bPwmUseTCR1 = (bool) true;
env->etpu_pwmconfig_tbl.bPwmUseTCR2 = (bool) false;
env->etpu_pwmconfig_tbl.u32ActiveTime = ActiveTime;
env->etpu_pwmconfig_tbl.u32PeriodTime = PeriodTime;
env->etpu_pwmconfig_tbl.bActiveHigh = (bool) false;
env->etpu_Int_config_tbl.bEventIntEn = (bool) true;
env->etpu_Int_config_tbl.bTCR1OverFlowEventIntEn = (bool) true;
env->etpu_Int_config_tbl.bTCR2OverFlowEventIntEn = (bool) false;
env->etpu_Int_config_tbl.pEventNotify = Bsp_Tpu_PwmCallback;
env->etpu_Int_config_tbl.pHSANotify = NULL;
env->etpu_Int_config_tbl.pTCR1OverflowNotify = Bsp_Tpu_OverflowCallBack;
env->etpu_Int_config_tbl.pTCR2OverflowNotify = NULL;
env->etpu_Int_config_tbl.eChTrigType = TPUH_ANY_EVENT_GATED_BY_MSRTSR;
env->TPU_PWM_CHANNEL = TPU_PWM_CHANNEL;
env->isDisabled = false;
env->updatePending = false;
env->pendingActiveTime = 0;
if (isDeInit) {
TPU_DeInit();
}
TPU_Init();
TPU_PwmModeInit(TPU_PWM_CHANNEL, &env->etpu_pwmconfig_tbl);
TPU_InitChannelInterrupt(TPU_PWM_CHANNEL, &env->etpu_Int_config_tbl);
TPU_StopChannel(env->TPU_PWM_CHANNEL);
if (TPU_PWM_CHANNEL <= 7) {
NVIC_SetPriority(TPU0_CH0_7_IRQn, TPU_PRIORITY);
NVIC_EnableIRQ(TPU0_CH0_7_IRQn);
} else if (TPU_PWM_CHANNEL <= 15) {
NVIC_SetPriority(TPU0_CH8_15_IRQn, TPU_PRIORITY);
NVIC_EnableIRQ(TPU0_CH8_15_IRQn);
} else if (TPU_PWM_CHANNEL <= 23) {
NVIC_SetPriority(TPU0_CH16_23_IRQn, TPU_PRIORITY);
NVIC_EnableIRQ(TPU0_CH16_23_IRQn);
} else if (TPU_PWM_CHANNEL <= 31) {
NVIC_SetPriority(TPU0_CH24_31_IRQn, TPU_PRIORITY);
NVIC_EnableIRQ(TPU0_CH24_31_IRQn);
}
}
static void vPwmAllRun(tPwmFlagchip *env) {
TPU_StartChannel();
}
static void setActivePercent(tPwmFlagchip *env, uint8_t percent) {
uint8_t final_percent;
// Обработка отключения (0%)
if (percent == 0) {
// Если канал уже отключен, ничего не делаем
if (!env->isDisabled) {
// Отключаем канал ШИМ
TPU_StopChannel(env->TPU_PWM_CHANNEL);
env->isDisabled = true;
}
return;
}
// Для всех ненулевых значений (1-100)
// Принудительно ограничиваем до 95% максимум
if (percent > 95) {
percent = 95;
}
// Минимальное значение - 1% (не ниже)
if (percent < 1) {
percent = 1; // Минимальный рабочий процент
}
// Если был отключен, включаем заново
if (env->isDisabled) {
TPU_StartChannelSpecific(env->TPU_PWM_CHANNEL);
env->isDisabled = false;
}
// Для active LOW (bActiveHigh = false) нужна инверсия
// 10% → 90%, 20% → 80% и т.д.
if (env->etpu_pwmconfig_tbl.bActiveHigh == false) {
final_percent = 100 - percent;
} else {
final_percent = percent;
}
// Расчет времени активности в тактах
uint32_t activeTime = env->etpu_pwmconfig_tbl.u32PeriodTime * final_percent / 100;
// Защита от выхода за пределы
if (activeTime == 0) {
activeTime = 1; // Минимальное значение, чтобы не остановить счетчик
}
if (activeTime >= env->etpu_pwmconfig_tbl.u32PeriodTime) {
activeTime = env->etpu_pwmconfig_tbl.u32PeriodTime - 1;
}
// Не обновляем напрямую, а ставим флаг
env->pendingActiveTime = activeTime;
env->updatePending = true;
}
tPwmIO vPwmGetIo(tPwmFlagchip *env) {
tPwmIO io = {
.env = env,
.run = (PwmIOTransaction) vPwmAllRun,
.setActivePercent = (PwmIOTransactionSetActivePercent) setActivePercent
};
return io;
}