158 lines
5.5 KiB
C
158 lines
5.5 KiB
C
//
|
||
// Created by cfif on 07.09.22.
|
||
//
|
||
#include "PwmFlagchip.h"
|
||
|
||
void Get_Set_Tpu_PwmCallback(tPwmFlagchip *env) {
|
||
|
||
// Обновляем только если есть запрос и канал не отключен
|
||
if (env->updatePending) {
|
||
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->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) {
|
||
// Отключаем канал ШИМ
|
||
TPU_StopChannel(env->TPU_PWM_CHANNEL);
|
||
return;
|
||
}
|
||
|
||
// Для всех ненулевых значений (1-100)
|
||
// Принудительно ограничиваем до 95% максимум
|
||
if (percent > 95) {
|
||
percent = 95;
|
||
}
|
||
|
||
// Минимальное значение - 1% (не ниже)
|
||
if (percent < 1) {
|
||
percent = 1; // Минимальный рабочий процент
|
||
}
|
||
|
||
TPU_StartChannel();
|
||
|
||
// Если был отключен, включаем заново
|
||
TPU_StartChannelSpecific(env->TPU_PWM_CHANNEL);
|
||
|
||
// Для 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;
|
||
} |