note: - модбас не моделируется, в s-function просто передаются константы режимов. - лишние файлы убраны в outdate. - два канала одной фазы переключаются немного криво: на один такт симуляции проскакивает высокий уровень предыдущего канала и только потом включается текущий канал
		
			
				
	
	
		
			856 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			856 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "pwm.h"
 | 
						||
//#include "rng.h"
 | 
						||
 | 
						||
PWM_HandleTypeDef hpwm1;
 | 
						||
PWM_SlaveHandleTypeDef hpwm2;
 | 
						||
PWM_SlaveHandleTypeDef hpwm3;
 | 
						||
 | 
						||
uint32_t sin_table[SIN_TABLE_SIZE_MAX];
 | 
						||
unsigned 				ActiveChannelSHDW_Master;
 | 
						||
float 					DeadTimeCnt_Master;
 | 
						||
 | 
						||
unsigned 				ActiveChannelSHDW_Slave2;
 | 
						||
float 					DeadTimeCnt_Slave2;
 | 
						||
 | 
						||
unsigned 				ActiveChannelSHDW_Slave3;
 | 
						||
float 					DeadTimeCnt_Slave3;
 | 
						||
/** 
 | 
						||
	* @brief 	First set up of PWM.
 | 
						||
	* @note 	Первый инит ШИМ. Заполняет структуры и инициализирует таймер для генерации синуоидального ШИМ.
 | 
						||
	* 				Скважность ШИМ меняется по закону синусоиды, каждый канал генерирует свой полупериод синуса (от -1 до 0 И от 0 до 1)
 | 
						||
	* 				ШИМ генерируется на одном канале.
 | 
						||
	* @note		This called from main
 | 
						||
	*/
 | 
						||
void PWM_Sine_FirstInit(void)
 | 
						||
{
 | 
						||
	hpwm1.pDuty_Table_Origin = SIN_TABLE_ORIGIN;
 | 
						||
	
 | 
						||
	//---------PWM TIMER1 INIT------------
 | 
						||
	// channels settings
 | 
						||
	hpwm1.sConfigOC.OCMode = TIM_OCMODE_PWM1;
 | 
						||
  hpwm1.sConfigOC.Pulse = 0;
 | 
						||
  hpwm1.sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
 | 
						||
  hpwm1.sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
 | 
						||
	
 | 
						||
	// tim1 settings
 | 
						||
	hpwm1.stim.htim.Instance = TIMER_PWM1_INSTANCE;
 | 
						||
	hpwm1.stim.sTimMode = TIM_IT_MODE;
 | 
						||
	hpwm1.stim.sTimFreqHz = HZ_TIMER_PWM;
 | 
						||
	hpwm1.stim.sTickBaseMHz = 	PROJSET.TIM_PWM_TICKBASE;
 | 
						||
	hpwm1.stim.sTimAHBFreqMHz = PROJSET.TIM_PWM_AHB_FREQ;
 | 
						||
	hpwm1.GPIOx = 							TIMER_PWM1_GPIOx;
 | 
						||
	hpwm1.GPIO_PIN_X1 = 				PROJSET.TIM_PWM1_GPIO_PIN_X1;
 | 
						||
	hpwm1.GPIO_PIN_X2 = 				PROJSET.TIM_PWM1_GPIO_PIN_X2;
 | 
						||
	hpwm1.PWM_Channel1 = 				PROJSET.TIM_PWM1_TIM_CHANNEL1;
 | 
						||
	hpwm1.PWM_Channel2 = 				PROJSET.TIM_PWM1_TIM_CHANNEL2;
 | 
						||
	hpwm1.hpwm2 = (void *)&hpwm2;
 | 
						||
	hpwm1.hpwm3 = (void *)&hpwm3;
 | 
						||
	
 | 
						||
	TIM_Base_Init(&hpwm1.stim);
 | 
						||
	TIM_Output_PWM_Init(&hpwm1.stim.htim, &hpwm1.sConfigOC, hpwm1.PWM_Channel1, hpwm1.GPIOx, hpwm1.GPIO_PIN_X1);
 | 
						||
	TIM_Output_PWM_Init(&hpwm1.stim.htim, &hpwm1.sConfigOC, hpwm1.PWM_Channel2, hpwm1.GPIOx, hpwm1.GPIO_PIN_X2);
 | 
						||
	
 | 
						||
	
 | 
						||
	// PWM SLAVES INIT
 | 
						||
	hpwm2.hMasterPWM = &hpwm1;
 | 
						||
	hpwm2.stim = hpwm1.stim;
 | 
						||
	hpwm2.stim.htim.Instance = 	(TIM_TypeDef *)PROJSET.TIM_PWM2_INSTANCE;
 | 
						||
	hpwm2.GPIOx = 							(GPIO_TypeDef *)PROJSET.TIM_PWM2_GPIOx;
 | 
						||
	hpwm2.GPIO_PIN_X1 = 				PROJSET.TIM_PWM2_GPIO_PIN_X1;
 | 
						||
	hpwm2.GPIO_PIN_X2 = 				PROJSET.TIM_PWM2_GPIO_PIN_X2;
 | 
						||
	hpwm2.PWM_Channel1 = 				PROJSET.TIM_PWM2_TIM_CHANNEL1;
 | 
						||
	hpwm2.PWM_Channel2 = 				PROJSET.TIM_PWM2_TIM_CHANNEL2;
 | 
						||
	hpwm2.Duty_Shift_Ratio = (float)2/3;
 | 
						||
	
 | 
						||
	hpwm3.hMasterPWM = &hpwm1;
 | 
						||
	hpwm3.stim = hpwm1.stim;
 | 
						||
	hpwm3.stim.htim.Instance = 	(TIM_TypeDef *)PROJSET.TIM_PWM3_INSTANCE;
 | 
						||
	hpwm3.GPIOx = 							(GPIO_TypeDef *)PROJSET.TIM_PWM3_GPIOx;
 | 
						||
	hpwm3.GPIO_PIN_X1 = 				PROJSET.TIM_PWM3_GPIO_PIN_X1;
 | 
						||
	hpwm3.GPIO_PIN_X2 = 				PROJSET.TIM_PWM3_GPIO_PIN_X2;
 | 
						||
	hpwm3.PWM_Channel1 = 				PROJSET.TIM_PWM3_TIM_CHANNEL1;
 | 
						||
	hpwm3.PWM_Channel2 = 				PROJSET.TIM_PWM3_TIM_CHANNEL2;
 | 
						||
	hpwm3.Duty_Shift_Ratio = (float)-2/3;
 | 
						||
	
 | 
						||
	PWM_SlavePhase_Init(&hpwm2);
 | 
						||
	PWM_SlavePhase_Init(&hpwm3);
 | 
						||
	
 | 
						||
	//----------TIMERS START-------------
 | 
						||
	HAL_TIM_Base_Start_IT(&hpwm1.stim.htim); // timer for PWM
 | 
						||
	HAL_TIM_PWM_Start(&hpwm1.stim.htim, hpwm1.PWM_Channel1); // PWM channel 1
 | 
						||
	HAL_TIM_PWM_Start(&hpwm1.stim.htim, hpwm1.PWM_Channel2); // PWM channel 2
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	PWM Handler.
 | 
						||
	* @param	hpwm - указатель на хендл ШИМ.
 | 
						||
	* @note 	Управляет скважностью ШИМ.
 | 
						||
	* @note		This called from TIM_PWM_Handler
 | 
						||
	*/
 | 
						||
void PWM_Handler(PWM_HandleTypeDef *hpwm)
 | 
						||
{	
 | 
						||
	//------------SINUS MODE-------------
 | 
						||
	if(PWM_Get_Mode(&hpwm1,PWM_DC_MODE) == 0)
 | 
						||
	{
 | 
						||
		if(hpwm->PWM_Value != 0) // if there some frequency
 | 
						||
		{
 | 
						||
			unsigned sin_ind = PWM_Get_Duty_Table_Ind(hpwm, hpwm->stim.sTimFreqHz);
 | 
						||
			// overflow check
 | 
						||
			if(sin_ind >= hpwm->Duty_Table_Size)
 | 
						||
				sin_ind -= hpwm->Duty_Table_Size;
 | 
						||
			if(sin_ind >= hpwm->Duty_Table_Size) // if its still overflow reset it
 | 
						||
				sin_ind = 0;
 | 
						||
			
 | 
						||
			// if unsigned sine enabled
 | 
						||
			if(PWM_Get_Mode(hpwm, PWM_CH_MODE) == 0) 
 | 
						||
			{
 | 
						||
				// set pwm duty
 | 
						||
				PWM_Set_Duty_From_Table(hpwm, sin_ind);						// set first channel
 | 
						||
				PWM_SlavePhase_Set_DutyTable_Unsigned(PWM_Set_pSlaveHandle(hpwm,hpwm2), sin_ind);
 | 
						||
				PWM_SlavePhase_Set_DutyTable_Unsigned(PWM_Set_pSlaveHandle(hpwm,hpwm3), sin_ind);
 | 
						||
			}	
 | 
						||
			// if signed sine enabled
 | 
						||
			else
 | 
						||
			{
 | 
						||
				int Duty = PWM_Get_Table_Element_Signed(hpwm, sin_ind);	
 | 
						||
				
 | 
						||
				if(Duty >= 0)	
 | 
						||
				{					
 | 
						||
					PWM_Set_Compare1(hpwm, Duty);	// set first channel
 | 
						||
					PWM_Set_Compare2(hpwm, 0);		// reset second channel
 | 
						||
				}
 | 
						||
				else																			// если это вторая полуволна
 | 
						||
				{
 | 
						||
					PWM_Set_Compare1(hpwm, 0);		// reset first channel
 | 
						||
					PWM_Set_Compare2(hpwm, -Duty);	// set second channel
 | 
						||
				}
 | 
						||
				
 | 
						||
				PWM_SlavePhase_Set_DutyTable_Signed(PWM_Set_pSlaveHandle(hpwm,hpwm2), sin_ind);
 | 
						||
				PWM_SlavePhase_Set_DutyTable_Signed(PWM_Set_pSlaveHandle(hpwm,hpwm3), sin_ind);
 | 
						||
			}
 | 
						||
		}
 | 
						||
		else // if freq = 0 reset all channels
 | 
						||
		{		
 | 
						||
			PWM_Set_Compare1(hpwm, 0);	// reset first channel
 | 
						||
			PWM_Set_Compare2(hpwm, 0);	// reset second channel
 | 
						||
			PWM_Set_Compare1(PWM_Set_pSlaveHandle(hpwm,hpwm2), 0);	// reset first channel
 | 
						||
			PWM_Set_Compare2(PWM_Set_pSlaveHandle(hpwm,hpwm2), 0);	// reset second channel
 | 
						||
			PWM_Set_Compare1(PWM_Set_pSlaveHandle(hpwm,hpwm3), 0);	// reset first channel
 | 
						||
			PWM_Set_Compare2(PWM_Set_pSlaveHandle(hpwm,hpwm3), 0);	// reset second channel
 | 
						||
		}
 | 
						||
			
 | 
						||
	}
 | 
						||
	//-----------PWM DC MODE-------------
 | 
						||
	else
 | 
						||
	{		
 | 
						||
		PWM_Set_Compare1(PWM_Set_pSlaveHandle(hpwm,hpwm2), 0);	// reset first channel
 | 
						||
		PWM_Set_Compare2(PWM_Set_pSlaveHandle(hpwm,hpwm2), 0);	// reset second channel
 | 
						||
		PWM_Set_Compare1(PWM_Set_pSlaveHandle(hpwm,hpwm3), 0);	// reset first channel
 | 
						||
		PWM_Set_Compare2(PWM_Set_pSlaveHandle(hpwm,hpwm3), 0);	// reset second channel
 | 
						||
//		uint32_t pwm_rng = 0;
 | 
						||
//		HAL_RNG_GenerateRandomNumber(&hrng, &pwm_rng);
 | 
						||
//		pwm_rng = ((pwm_rng&0xFFFF)/(0xFFFF/PWM_Get_Autoreload(hpwm)))/((float)100/hpwm->PWM_Value);
 | 
						||
//		if (pwm_rng < PWM_Calc_Min_Duty(hpwm)) 
 | 
						||
//			pwm_rng = PWM_Calc_Min_Duty(hpwm);
 | 
						||
		// if second channel enabled
 | 
						||
		if(PWM_Get_Mode(hpwm, PWM_CH_MODE)) 
 | 
						||
		{
 | 
						||
			PWM_Set_Compare1(hpwm, 0); 					// reset first channel
 | 
						||
			PWM_Set_Duty_From_Percent(hpwm, hpwm->PWM_Channel2); 	// set second channel
 | 
						||
//			__HAL_TIM_SET_COMPARE(&(hpwm->stim.htim), TIM_CHANNEL_2, pwm_rng); 	// set second channel
 | 
						||
		}
 | 
						||
		// if first channel enabled
 | 
						||
		else 
 | 
						||
		{
 | 
						||
//			__HAL_TIM_SET_COMPARE(&(hpwm->stim.htim), TIM_CHANNEL_1, pwm_rng); 	// set second channel
 | 
						||
			PWM_Set_Duty_From_Percent(hpwm, hpwm->PWM_Channel1); 	// set first channel
 | 
						||
			PWM_Set_Compare2(hpwm, 0); 														// reset second channel
 | 
						||
		}
 | 
						||
	}
 | 
						||
	
 | 
						||
	//-----CHECK CHANNELS FOR ERRORS-----
 | 
						||
	uint16_t min_duty = PWM_Calc_Min_Duty(hpwm);
 | 
						||
	// IF FIRST CHANNEL IS ACRIVE
 | 
						||
	if(PWM_Get_Compare1(hpwm) != 0)
 | 
						||
	{
 | 
						||
		// Duty shoud be bigger or equeal than min duration
 | 
						||
		if (PWM_Get_Compare1(hpwm)<min_duty)
 | 
						||
			PWM_Set_Compare1(hpwm, min_duty);		
 | 
						||
		// Duty shoud be less or equeal than ARR-min duration
 | 
						||
		if (PWM_Get_Compare1(hpwm)>PWM_Get_Autoreload(hpwm)-min_duty)
 | 
						||
			PWM_Set_Compare1(hpwm, PWM_Get_Autoreload(hpwm)-min_duty);
 | 
						||
	}
 | 
						||
	// IF SECOND CHANNEL IS ACRIVE
 | 
						||
	else if(PWM_Get_Compare2(hpwm) != 0)
 | 
						||
	{
 | 
						||
	// Duty shoud be bigger or equeal than min duration
 | 
						||
	if (PWM_Get_Compare2(hpwm)<min_duty)
 | 
						||
		PWM_Set_Compare2(hpwm, min_duty);
 | 
						||
	// Duty shoud be less or equeal than ARR
 | 
						||
	if (PWM_Get_Compare2(hpwm)>PWM_Get_Autoreload(hpwm)-min_duty)
 | 
						||
		PWM_Set_Compare2(hpwm, PWM_Get_Autoreload(hpwm)-min_duty);
 | 
						||
	}	
 | 
						||
	// IF BOTH CHANNEL IS ACRIVE
 | 
						||
	if((PWM_Get_Compare1(hpwm) != 0) && (PWM_Get_Compare2(hpwm) != 0))
 | 
						||
	{
 | 
						||
		// Only one channel shoud be active so disable all
 | 
						||
		PWM_Set_Compare1(hpwm, 0);
 | 
						||
		PWM_Set_Compare2(hpwm, 0);
 | 
						||
	}
 | 
						||
	PWM_SlavePhase_Check_Channels(PWM_Set_pSlaveHandle(hpwm,hpwm2));
 | 
						||
	PWM_SlavePhase_Check_Channels(PWM_Set_pSlaveHandle(hpwm,hpwm3));
 | 
						||
	
 | 
						||
	if(hpwm->PWM_DeadTime)
 | 
						||
	{
 | 
						||
		PWM_CreateDeadTime(hpwm, &DeadTimeCnt_Master, &ActiveChannelSHDW_Master);
 | 
						||
		PWM_SlavePhase_CreateDeadTime(PWM_Set_pSlaveHandle(hpwm,hpwm2), &DeadTimeCnt_Slave2, &ActiveChannelSHDW_Slave2);
 | 
						||
		PWM_SlavePhase_CreateDeadTime(PWM_Set_pSlaveHandle(hpwm,hpwm3), &DeadTimeCnt_Slave3, &ActiveChannelSHDW_Slave3);
 | 
						||
	}
 | 
						||
 | 
						||
		
 | 
						||
}
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	Update PWM parameters.
 | 
						||
	* @note 	Проверка надо ли обновлять параметры ШИМ, и если надо - обновляет их.
 | 
						||
	* @note		This called from TIM_CTRL_Handler
 | 
						||
	*/
 | 
						||
void Update_Params_For_PWM(PWM_HandleTypeDef *hpwm)
 | 
						||
{
 | 
						||
	unsigned UpdateModeParams = 0;
 | 
						||
	unsigned UpdateLog = 0;
 | 
						||
		
 | 
						||
	// READ	PWM_DC_MODE
 | 
						||
	if(PWM_Get_Mode(hpwm, PWM_DC_MODE) != (MB_Read_Coil_Local(&coils_regs[0], COIL_PWM_DC_MODE) << PWM_DC_MODE_Pos))
 | 
						||
	{	
 | 
						||
		if(MB_Read_Coil_Local(&coils_regs[0], COIL_PWM_DC_MODE))
 | 
						||
		{
 | 
						||
			hpwm->sPWM_Mode |= PWM_DC_MODE;
 | 
						||
		}
 | 
						||
		else
 | 
						||
		{
 | 
						||
			hpwm->sPWM_Mode &= ~PWM_DC_MODE;
 | 
						||
		}		
 | 
						||
		// update mode params
 | 
						||
		UpdateModeParams = 1;
 | 
						||
		// update logs params
 | 
						||
		UpdateLog = 1;
 | 
						||
	}
 | 
						||
	
 | 
						||
	// READ	PWM_CH_MODE
 | 
						||
	if(PWM_Get_Mode(hpwm, PWM_CH_MODE) != (MB_Read_Coil_Local(&coils_regs[0], COIL_PWM_CH_MODE) << PWM_CH_MODE_Pos))
 | 
						||
	{	
 | 
						||
		if(MB_Read_Coil_Local(&coils_regs[0], COIL_PWM_CH_MODE))
 | 
						||
		{
 | 
						||
			hpwm->sPWM_Mode |= PWM_CH_MODE;
 | 
						||
		}
 | 
						||
		else
 | 
						||
		{
 | 
						||
			hpwm->sPWM_Mode &= ~PWM_CH_MODE;
 | 
						||
		}		
 | 
						||
		// update mode params
 | 
						||
		UpdateModeParams = 1;
 | 
						||
		// update logs params
 | 
						||
		UpdateLog = 1;
 | 
						||
	}
 | 
						||
	
 | 
						||
		
 | 
						||
	// READ	PWM_CH_MODE
 | 
						||
	if(PWM_Get_Mode(hpwm, PWM_PHASE_MODE) != (MB_Read_Coil_Local(&coils_regs[0], COIL_PWM_PHASE_MODE) << PWM_PHASE_MODE_Pos))
 | 
						||
	{	
 | 
						||
		if(MB_Read_Coil_Local(&coils_regs[0], COIL_PWM_PHASE_MODE))
 | 
						||
		{
 | 
						||
			hpwm->sPWM_Mode |= PWM_PHASE_MODE;
 | 
						||
		}
 | 
						||
		else
 | 
						||
		{
 | 
						||
			hpwm->sPWM_Mode &= ~PWM_PHASE_MODE;
 | 
						||
		}		
 | 
						||
		// update mode params
 | 
						||
		UpdateModeParams = 1;
 | 
						||
		// update logs params
 | 
						||
		UpdateLog = 1;
 | 
						||
	}
 | 
						||
	
 | 
						||
	
 | 
						||
	
 | 
						||
	// READ	PWM_VALUE
 | 
						||
	if(hpwm->PWM_Value != int_to_percent(pwm_ctrl[R_PWM_CTRL_PWM_VALUE]))
 | 
						||
	{	
 | 
						||
		hpwm->PWM_Value = int_to_percent(pwm_ctrl[R_PWM_CTRL_PWM_VALUE]);
 | 
						||
		// update logs params
 | 
						||
		UpdateLog = 1;
 | 
						||
	}
 | 
						||
	
 | 
						||
	// READ	TABLE_SIZE
 | 
						||
	if(hpwm->Duty_Table_Size != pwm_ctrl[R_PWM_CTRL_SIN_TABLE_SIZE])
 | 
						||
	{
 | 
						||
		hpwm->Duty_Table_Size = PWM_Fill_Sine_Table(&hpwm1, pwm_ctrl[R_PWM_CTRL_SIN_TABLE_SIZE]);
 | 
						||
		pwm_ctrl[R_PWM_CTRL_SIN_TABLE_SIZE] = hpwm->Duty_Table_Size;
 | 
						||
	}	
 | 
						||
	
 | 
						||
	// READ MIN PULSE DURATION
 | 
						||
	if(hpwm->PWM_MinPulseDur != pwm_ctrl[R_PWM_CTRL_MIN_PULSE_DUR])
 | 
						||
	{
 | 
						||
		hpwm->PWM_MinPulseDur = pwm_ctrl[R_PWM_CTRL_MIN_PULSE_DUR];	
 | 
						||
		// update mode params
 | 
						||
		UpdateModeParams = 1;
 | 
						||
		// update logs params
 | 
						||
		UpdateLog = 1;
 | 
						||
	}
 | 
						||
	
 | 
						||
	// READ DEAD TIME
 | 
						||
	if(hpwm->PWM_DeadTime != pwm_ctrl[R_PWM_CTRL_DEAD_TIME])
 | 
						||
	{
 | 
						||
		hpwm->PWM_DeadTime = pwm_ctrl[R_PWM_CTRL_DEAD_TIME];
 | 
						||
	}
 | 
						||
	
 | 
						||
	
 | 
						||
	
 | 
						||
	// UPDATE PWM PARAMS
 | 
						||
	if(UpdateModeParams)
 | 
						||
	{			
 | 
						||
		// UPDATE DUTY TABLE SCALE
 | 
						||
		PWM_Update_DutyTableScale(hpwm);
 | 
						||
		
 | 
						||
		
 | 
						||
		// update logs params
 | 
						||
		UpdateLog = 1;
 | 
						||
	}
 | 
						||
	
 | 
						||
	// UPDATE LOG PARAMS
 | 
						||
	if(UpdateLog)
 | 
						||
	{
 | 
						||
		// set logs params
 | 
						||
		Set_Log_Params();	
 | 
						||
	}	
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	reInitialization of PWM TIM.
 | 
						||
	* @param	hpwm - указатель на хендл ШИМ.
 | 
						||
	* @note 	Перенастраивает таймер согласно принятным настройкам в pwm_ctrl
 | 
						||
	* 				ШИМ генерируется на одном канале.
 | 
						||
	*/
 | 
						||
void PWM_Sine_ReInit(PWM_HandleTypeDef *hpwm)
 | 
						||
{
 | 
						||
	Trace_PWM_reInit_Enter();
 | 
						||
	TIM_Base_MspDeInit(&hpwm->stim.htim);
 | 
						||
	hpwm1.stim.sTickBaseMHz = TIMER_PWM_TICKBASE;
 | 
						||
	TIM_Base_Init(&hpwm->stim);
 | 
						||
	TIM_Output_PWM_Init(&hpwm->stim.htim, &hpwm->sConfigOC, hpwm->PWM_Channel1, hpwm->GPIOx, hpwm->GPIO_PIN_X1);
 | 
						||
	TIM_Output_PWM_Init(&hpwm->stim.htim, &hpwm->sConfigOC, hpwm->PWM_Channel2, hpwm->GPIOx, hpwm->GPIO_PIN_X2);
 | 
						||
	
 | 
						||
 | 
						||
	
 | 
						||
	PWM_Update_DutyTableScale(hpwm);
 | 
						||
	
 | 
						||
	
 | 
						||
	//----------TIMERS START-------------
 | 
						||
	HAL_TIM_Base_Start_IT(&hpwm1.stim.htim); // timer for PWM
 | 
						||
	HAL_TIM_PWM_Start(&hpwm1.stim.htim, hpwm->PWM_Channel1); // PWM channel 1
 | 
						||
	HAL_TIM_PWM_Start(&hpwm1.stim.htim, hpwm->PWM_Channel2); // PWM channel 2
 | 
						||
	
 | 
						||
	Trace_PWM_reInit_Exit();
 | 
						||
}
 | 
						||
/** 
 | 
						||
	* @brief 	Getting ind for Duty Table.
 | 
						||
	* @param	hpwm - указатель на хендл ШИМ.
 | 
						||
	* @param	FreqTIM - частота таймера ШИМ.
 | 
						||
	* @note 	Рассчитывает индекс для таблицы скважностей.
 | 
						||
	*					PWM_Value в hpwm - частота с которой эта таблица должна выводиться на ШИМ
 | 
						||
	* @note		This called from TIM_PWM_Handler
 | 
						||
	*/
 | 
						||
uint32_t PWM_Get_Duty_Table_Ind(PWM_HandleTypeDef *hpwm, float FreqTIM)
 | 
						||
{
 | 
						||
	float sine_ind_step;
 | 
						||
	uint32_t sine_ind;
 | 
						||
	// calc ind for sin table
 | 
						||
	sine_ind_step = hpwm->Duty_Table_Size/(FreqTIM/hpwm->PWM_Value);
 | 
						||
	hpwm->Duty_Table_Ind += sine_ind_step;
 | 
						||
	if(hpwm->Duty_Table_Ind >= hpwm->Duty_Table_Size)
 | 
						||
		hpwm->Duty_Table_Ind -= hpwm->Duty_Table_Size;
 | 
						||
	
 | 
						||
	// if its too big (e.g. inf)
 | 
						||
	if(hpwm->Duty_Table_Ind >= 0xFFFF)
 | 
						||
		hpwm->Duty_Table_Ind = 0;
 | 
						||
	
 | 
						||
	return hpwm->Duty_Table_Ind;
 | 
						||
 | 
						||
}
 | 
						||
 | 
						||
	
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	Create Dead Time when switches channels.
 | 
						||
	* @param	hpwm - указатель на хендл ШИМ.
 | 
						||
	*/
 | 
						||
void PWM_CreateDeadTime(PWM_HandleTypeDef *hpwm, float *LocalDeadTimeCnt, unsigned *LocalActiveChannel)
 | 
						||
{	
 | 
						||
	// get current active channel
 | 
						||
	hpwm->fActiveChannel = (PWM_Get_Compare2(hpwm) != 0); // if channel two is active - write 1, otherwise - 0
 | 
						||
	// when channels are swithed and no dead time currently active
 | 
						||
	if(*LocalActiveChannel != hpwm->fActiveChannel)
 | 
						||
	{	// update active channel
 | 
						||
		*LocalActiveChannel = hpwm->fActiveChannel; 
 | 
						||
		// set deadtime
 | 
						||
		*LocalDeadTimeCnt = hpwm->PWM_DeadTime;
 | 
						||
		Trace_PWM_DeadTime_Enter();
 | 
						||
	}	
 | 
						||
	// decrement dead time
 | 
						||
	*LocalDeadTimeCnt -= (PWM_Get_Autoreload(hpwm)+1)*hpwm->stim.sTickBaseMHz;
 | 
						||
	if(*LocalDeadTimeCnt > 0) // if dead time is still active
 | 
						||
	{ // reset all channels 
 | 
						||
		// reset channels
 | 
						||
		PWM_Set_Compare1(hpwm, 0);
 | 
						||
		PWM_Set_Compare2(hpwm, 0);
 | 
						||
	}
 | 
						||
	else // if dead time is done
 | 
						||
	{ // set it to zero
 | 
						||
		*LocalDeadTimeCnt = 0;		
 | 
						||
		Trace_PWM_DeadTime_Exit();
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	Filling table with one period of sinus values.
 | 
						||
	* @param	hpwm - указатель на хендл ШИМ.
 | 
						||
	* @param	table_size - размер таблицы.
 | 
						||
	* @note 	Формирует таблицу синусов размером table_size.
 | 
						||
	*/
 | 
						||
uint32_t PWM_Fill_Sine_Table(PWM_HandleTypeDef *hpwm, uint32_t table_size)
 | 
						||
{
 | 
						||
	if((hpwm == NULL) || (hpwm->pDuty_Table_Origin == NULL)  || (table_size == 0))
 | 
						||
	{
 | 
						||
		return 0;
 | 
						||
	}
 | 
						||
	if (table_size > SIN_TABLE_SIZE_MAX)
 | 
						||
		table_size = SIN_TABLE_SIZE_MAX;
 | 
						||
	
 | 
						||
	
 | 
						||
	hpwm->Duty_Table_Size = table_size;
 | 
						||
	float pi_step = 2*M_PI/(hpwm->Duty_Table_Size);
 | 
						||
	float pi_val = 0;
 | 
						||
	float sin_koef = 0;
 | 
						||
	uint32_t sin_val = 0;
 | 
						||
 | 
						||
	// fill table with sinus
 | 
						||
	for(int i = 0; i < hpwm->Duty_Table_Size; i++)
 | 
						||
	{			
 | 
						||
		// rotate pi
 | 
						||
		pi_val += pi_step;	
 | 
						||
		// calc sin value
 | 
						||
		sin_koef = (float)0xFFFF;
 | 
						||
		sin_val = (sin(pi_val)+1)*sin_koef/2;
 | 
						||
		sin_table[i] = sin_val;	
 | 
						||
	}	
 | 
						||
	// fill rest of table with zeros
 | 
						||
	for(int i = hpwm->Duty_Table_Size; i < SIN_TABLE_SIZE_MAX; i++)
 | 
						||
		sin_table[i] = 0;	
 | 
						||
	
 | 
						||
	// if second channel is enabled
 | 
						||
	PWM_Update_DutyTableScale(hpwm);
 | 
						||
	
 | 
						||
	return hpwm->Duty_Table_Size;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	Calc and update new Duty Table Scale.
 | 
						||
	* @param	hpwm - указатель на хендл ШИМ.
 | 
						||
	* @note 	Используется, когда изменяется значение регистра ARR.
 | 
						||
	*/
 | 
						||
void PWM_Update_DutyTableScale(PWM_HandleTypeDef *hpwm)
 | 
						||
{
 | 
						||
			// UPDATE DUTY TABLE SCALE
 | 
						||
		if(PWM_Get_Mode(hpwm, PWM_CH_MODE)) // if second channel is enabled
 | 
						||
		{
 | 
						||
			hpwm->Duty_Table_Scale = PWM_Calc_Duty_Scale(&hpwm1, 0x8000);
 | 
						||
		}
 | 
						||
		else
 | 
						||
		{
 | 
						||
			hpwm->Duty_Table_Scale = PWM_Calc_Duty_Scale(&hpwm1, 0xFFFF);
 | 
						||
		}	
 | 
						||
	// for case if min pulse dur is too big and scale is negative
 | 
						||
		if (hpwm->Duty_Table_Scale < 0)
 | 
						||
			hpwm->Duty_Table_Scale = 1;
 | 
						||
}
 | 
						||
 | 
						||
//-------------------------------------------------------------------
 | 
						||
//-----------------------THREEPHASE FUNCTIONS------------------------
 | 
						||
/** 
 | 
						||
	* @brief 	Initialization of Slave PWM TIM.
 | 
						||
	* @param	hspwm - указатель на хендл слейв ШИМ.
 | 
						||
	* @note		Вызывает функции инициализации и включения слейв ШИМ.
 | 
						||
	*/
 | 
						||
void PWM_SlavePhase_Init(PWM_SlaveHandleTypeDef *hspwm)
 | 
						||
{	
 | 
						||
	TIM_Base_Init(&hspwm->stim);
 | 
						||
	TIM_Output_PWM_Init(&hspwm->stim.htim, &hspwm->hMasterPWM->sConfigOC, hspwm->PWM_Channel1, hspwm->GPIOx, hspwm->GPIO_PIN_X1);
 | 
						||
	TIM_Output_PWM_Init(&hspwm->stim.htim, &hspwm->hMasterPWM->sConfigOC, hspwm->PWM_Channel2, hspwm->GPIOx, hspwm->GPIO_PIN_X2);
 | 
						||
	
 | 
						||
	// if three phase enables
 | 
						||
	//----------TIMERS START-------------
 | 
						||
	HAL_TIM_Base_Start(&hspwm->stim.htim);
 | 
						||
	HAL_TIM_PWM_Start(&hspwm->stim.htim, hspwm->PWM_Channel1); // PWM channel 1
 | 
						||
	HAL_TIM_PWM_Start(&hspwm->stim.htim, hspwm->PWM_Channel2); // PWM channel 2
 | 
						||
	
 | 
						||
	if(PWM_Get_Mode(hspwm->hMasterPWM, PWM_PHASE_MODE) == 0) // if three phase disabled
 | 
						||
	{
 | 
						||
		PWM_Set_Compare1(hspwm, 0);	// reset first channel
 | 
						||
		PWM_Set_Compare2(hspwm, 0);	// reset second channel
 | 
						||
	}
 | 
						||
}
 | 
						||
/** 
 | 
						||
	* @brief 	reInitialization of Slave PWM TIM.
 | 
						||
	* @param	hspwm - указатель на хендл слейв ШИМ.
 | 
						||
	* @note 	Перенастраивает таймер согласно принятным настройкам в pwm_ctrl.
 | 
						||
	*/
 | 
						||
void PWM_SlavePhase_reInit(PWM_SlaveHandleTypeDef *hspwm)
 | 
						||
{	
 | 
						||
	PWM_Slave_CopyTimSetting(hspwm, sTimFreqHz);
 | 
						||
	TIM_Base_MspDeInit(&hspwm->stim.htim);
 | 
						||
	
 | 
						||
	PWM_SlavePhase_Init(hspwm);
 | 
						||
}
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	Set Duty from table on Slave PWM at one channel by sin_ind of the Master PWM.
 | 
						||
	* @param	hspwm 		- указатель на хендл слейв ШИМ.
 | 
						||
	* @param	sin_ind 	- индекс таблицы для Мастер ШИМ.
 | 
						||
	* @note		Индекс для свейл ШИМ расчитывается в самой функции.
 | 
						||
	*/
 | 
						||
void PWM_SlavePhase_Set_DutyTable_Unsigned(PWM_SlaveHandleTypeDef *hspwm, uint16_t sin_ind)
 | 
						||
{
 | 
						||
	// if three phase enables
 | 
						||
	if (PWM_Get_Mode(hspwm->hMasterPWM, PWM_PHASE_MODE))
 | 
						||
	{
 | 
						||
		if(hspwm->Duty_Shift_Ratio > 0)
 | 
						||
			sin_ind += hspwm->hMasterPWM->Duty_Table_Size*hspwm->Duty_Shift_Ratio;
 | 
						||
		else
 | 
						||
			sin_ind += hspwm->hMasterPWM->Duty_Table_Size*(1+hspwm->Duty_Shift_Ratio);
 | 
						||
		
 | 
						||
		// overflow check
 | 
						||
		if(sin_ind > hspwm->hMasterPWM->Duty_Table_Size)
 | 
						||
			sin_ind -= hspwm->hMasterPWM->Duty_Table_Size;
 | 
						||
		
 | 
						||
		PWM_Set_SlaveDuty_From_Table(hspwm, sin_ind);						// set first channel
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	Set Duty from table on Slave PWM at two channel by sin_ind of the Master PWM.
 | 
						||
	* @param	hspwm 		- указатель на хендл слейв ШИМ.
 | 
						||
	* @param	sin_ind 	- индекс таблицы для Мастер ШИМ.
 | 
						||
	* @note		Индекс для свейл ШИМ расчитывается в самой функции.
 | 
						||
	*/
 | 
						||
void PWM_SlavePhase_Set_DutyTable_Signed(PWM_SlaveHandleTypeDef *hspwm, uint16_t sin_ind)
 | 
						||
{
 | 
						||
	int Duty;
 | 
						||
	// if three phase enables
 | 
						||
	if (PWM_Get_Mode(hspwm->hMasterPWM, PWM_PHASE_MODE))
 | 
						||
	{
 | 
						||
		if(hspwm->Duty_Shift_Ratio > 0)
 | 
						||
			sin_ind += hspwm->hMasterPWM->Duty_Table_Size*hspwm->Duty_Shift_Ratio;
 | 
						||
		else
 | 
						||
			sin_ind += hspwm->hMasterPWM->Duty_Table_Size*(1+hspwm->Duty_Shift_Ratio);
 | 
						||
		
 | 
						||
		// overflow check
 | 
						||
		if(sin_ind >= hspwm->hMasterPWM->Duty_Table_Size)
 | 
						||
			sin_ind -= hspwm->hMasterPWM->Duty_Table_Size;
 | 
						||
		
 | 
						||
		Duty = PWM_Get_Table_Element_Signed(hspwm->hMasterPWM, sin_ind);		
 | 
						||
		// если это первая полуволна
 | 
						||
		if(Duty > 0)		
 | 
						||
		{		
 | 
						||
			PWM_Set_Compare1(hspwm, Duty+PWM_Calc_Min_Duty(hspwm->hMasterPWM));	// set first channel
 | 
						||
			PWM_Set_Compare2(hspwm, 0);			// reset second channel
 | 
						||
		}
 | 
						||
		else // если это вторая полуволна
 | 
						||
		{
 | 
						||
			PWM_Set_Compare1(hspwm, 0);			// reset first channel
 | 
						||
			PWM_Set_Compare2(hspwm, (-Duty)+PWM_Calc_Min_Duty(hspwm->hMasterPWM));		// set second channel
 | 
						||
		}
 | 
						||
	//if(hspwm == &hpwm2)
 | 
						||
		//__ASM("");
 | 
						||
	}
 | 
						||
	else // if three phase disabled
 | 
						||
	{
 | 
						||
		PWM_Set_Compare1(hspwm, 0);	// reset first channel
 | 
						||
		PWM_Set_Compare2(hspwm, 0);	// reset second channel
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	Check is all Slave channels works properly.
 | 
						||
	* @param	hspwm - указатель на хендл слейв ШИМ.
 | 
						||
	* @note		Проверка работает ли только один из каналов, и проверка чтобы CCRx <= ARR
 | 
						||
	* @note		В мастере проверка происходит напрямую в PWM_Handler.
 | 
						||
	*/
 | 
						||
void PWM_SlavePhase_Check_Channels(PWM_SlaveHandleTypeDef *hspwm)
 | 
						||
{	
 | 
						||
	// if three phase enables
 | 
						||
	if (PWM_Get_Mode(hspwm->hMasterPWM, PWM_PHASE_MODE))
 | 
						||
	{
 | 
						||
		uint16_t min_duty = PWM_Calc_Min_Duty(hspwm->hMasterPWM);
 | 
						||
		// IF FIRST CHANNEL IS ACRIVE
 | 
						||
		if(PWM_Get_Compare1(hspwm) != 0)
 | 
						||
		{
 | 
						||
			// Duty shoud be bigger or equeal than min duration
 | 
						||
			if (PWM_Get_Compare1(hspwm)<min_duty)
 | 
						||
				PWM_Set_Compare1(hspwm, min_duty);		
 | 
						||
			// Duty shoud be less or equeal than ARR-min duration
 | 
						||
			if (PWM_Get_Compare1(hspwm)>PWM_Get_Autoreload(hspwm)-min_duty)
 | 
						||
				PWM_Set_Compare1(hspwm, PWM_Get_Autoreload(hspwm)-min_duty);
 | 
						||
		}
 | 
						||
		// IF SECOND CHANNEL IS ACRIVE
 | 
						||
		else if(PWM_Get_Compare2(hspwm) != 0)
 | 
						||
		// Duty shoud be bigger or equeal than min duration
 | 
						||
		if (PWM_Get_Compare2(hspwm)<min_duty)
 | 
						||
			PWM_Set_Compare2(hspwm, min_duty);
 | 
						||
		// Duty shoud be less or equeal than ARR
 | 
						||
		if (PWM_Get_Compare2(hspwm)>PWM_Get_Autoreload(hspwm)-min_duty)
 | 
						||
			PWM_Set_Compare2(hspwm, PWM_Get_Autoreload(hspwm)-min_duty);	
 | 
						||
		// IF BOTH CHANNEL IS ACRIVE
 | 
						||
		if((PWM_Get_Compare1(hspwm) != 0) && (PWM_Get_Compare2(hspwm) != 0))
 | 
						||
		{
 | 
						||
			// Only one channel shoud be active so disable all
 | 
						||
			PWM_Set_Compare1(hspwm, 0);
 | 
						||
			PWM_Set_Compare2(hspwm, 0);
 | 
						||
		}
 | 
						||
	}
 | 
						||
	else
 | 
						||
	{
 | 
						||
		// reset channels
 | 
						||
		PWM_Set_Compare1(hspwm, 0);	// reset first channel
 | 
						||
		PWM_Set_Compare2(hspwm, 0);	// reset second channel
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	Create Dead Time for Slave PWM when switches channels.
 | 
						||
	* @param	hspwm 							- указатель на хендл слейв ШИМ.
 | 
						||
	* @param	LocalDeadTimeCnt 		- указатель на переменную для отсчитывания дедтайма.
 | 
						||
	* @param	LocalActiveChannel 	- указатель на переменную для отслеживания смены канала.
 | 
						||
	* @note		Аналог функции PWM_CreateDeadTime но для слейв ШИМов.
 | 
						||
	*/
 | 
						||
void PWM_SlavePhase_CreateDeadTime(PWM_SlaveHandleTypeDef *hspwm, float *LocalDeadTimeCnt, unsigned *LocalActiveChannel)
 | 
						||
{
 | 
						||
	// get current active channel
 | 
						||
	hspwm->fActiveChannel = (PWM_Get_Compare2(hspwm) != 0); // if channel two is active - write 1, otherwise - 0
 | 
						||
	// when channels are swithed and no dead time currently active
 | 
						||
	if(*LocalActiveChannel != hspwm->fActiveChannel)
 | 
						||
	{	// update active channel
 | 
						||
		*LocalActiveChannel = hspwm->fActiveChannel; 
 | 
						||
		// set deadtime
 | 
						||
		*LocalDeadTimeCnt = hspwm->hMasterPWM->PWM_DeadTime;
 | 
						||
		Trace_PWM_DeadTime_Enter();
 | 
						||
	}	
 | 
						||
	// decrement dead time
 | 
						||
	*LocalDeadTimeCnt -= (PWM_Get_Autoreload(hspwm)+1)*hspwm->hMasterPWM->stim.sTickBaseMHz;
 | 
						||
	if(*LocalDeadTimeCnt > 0) // if dead time is still active
 | 
						||
	{ // reset all channels 
 | 
						||
		// reset channels
 | 
						||
		PWM_Set_Compare1(hspwm, 0);
 | 
						||
		PWM_Set_Compare2(hspwm, 0);
 | 
						||
	}
 | 
						||
	else // if dead time is done
 | 
						||
	{ // set it to zero
 | 
						||
		*LocalDeadTimeCnt = 0;		
 | 
						||
		Trace_PWM_DeadTime_Exit();
 | 
						||
	}
 | 
						||
}
 | 
						||
//-------------------------------------------------------------------
 | 
						||
//------------------------HANDLERS FUNCTIONS-------------------------
 | 
						||
//---------------PWM TIMER-----------------
 | 
						||
#if (PWM_MASTER_TIM_NUMB == 1) || (PWM_MASTER_TIM_NUMB == 10) // choose handler for TIM
 | 
						||
void TIM1_UP_TIM10_IRQHandler(void)
 | 
						||
#elif (PWM_MASTER_TIM_NUMB == 2)
 | 
						||
void TIM2_IRQHandler(void)
 | 
						||
#elif (PWM_MASTER_TIM_NUMB == 3)
 | 
						||
void TIM3_IRQHandler(void)
 | 
						||
#elif (PWM_MASTER_TIM_NUMB == 4)
 | 
						||
void TIM4_IRQHandler(void)
 | 
						||
#elif (PWM_MASTER_TIM_NUMB == 5)
 | 
						||
void TIM5_IRQHandler(void)
 | 
						||
#elif (PWM_MASTER_TIM_NUMB == 6)
 | 
						||
void TIM6_DAC_IRQHandler(void)
 | 
						||
#elif (PWM_MASTER_TIM_NUMB == 7)
 | 
						||
void TIM7_IRQHandler(void)
 | 
						||
#elif (PWM_MASTER_TIM_NUMB == 8) || (PWM_MASTER_TIM_NUMB == 13)
 | 
						||
void TIM8_UP_TIM13_IRQHandler(void)
 | 
						||
#elif (PWM_MASTER_TIM_NUMB == 1) || (PWM_MASTER_TIM_NUMB == 9)
 | 
						||
void TIM1_BRK_TIM9_IRQHandler(void)
 | 
						||
#elif (PWM_MASTER_TIM_NUMB == 1) || (PWM_MASTER_TIM_NUMB == 11)
 | 
						||
void TIM1_TRG_COM_TIM11_IRQHandler(void)
 | 
						||
#elif (PWM_MASTER_TIM_NUMB == 8) || (PWM_MASTER_TIM_NUMB == 12)
 | 
						||
void TIM8_BRK_TIM12_IRQHandler(void)
 | 
						||
#elif (PWM_MASTER_TIM_NUMB == 8) || (PWM_MASTER_TIM_NUMB == 14)
 | 
						||
void TIM8_TRG_COM_TIM14_IRQHandler(void)
 | 
						||
#endif
 | 
						||
{
 | 
						||
	Trace_PWM_TIM_Enter();
 | 
						||
  HAL_TIM_IRQHandler(&hpwm1.stim.htim);
 | 
						||
	PWM_Handler(&hpwm1);
 | 
						||
	
 | 
						||
	Trace_PWM_TIM_Exit();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//-------------------------------------------------------------------
 | 
						||
//-------------------------------------------------------------------
 | 
						||
//-----------------------------OUTDATE-------------------------------
 | 
						||
#ifdef OUTDATE
 | 
						||
/** 
 | 
						||
	* @brief 	First set up of PWM Single Channel.
 | 
						||
	* @note 	Первый инит ШИМ. Заполняет структуры и инициализирует таймер для генерации синуоидального ШИМ.
 | 
						||
	* 				Скважность ШИМ меняется по закону синусоиды, сдвинутой в положительную область (от 0 до 2)
 | 
						||
	* 				ШИМ генерируется на одном канале.
 | 
						||
	* @note		This called from main
 | 
						||
	*/
 | 
						||
void PWM_SineSingChannel_FirstInit(void)
 | 
						||
{
 | 
						||
	hpwm1.pDuty_Table_Origin = SIN_TABLE_ORIGIN;
 | 
						||
	
 | 
						||
	//---------PWM TIMER1 INIT------------
 | 
						||
	// channel settings
 | 
						||
	hpwm1.sConfigOC.OCMode = TIM_OCMODE_PWM1;
 | 
						||
  hpwm1.sConfigOC.Pulse = 0;
 | 
						||
  hpwm1.sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
 | 
						||
  hpwm1.sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
 | 
						||
	
 | 
						||
	// tim1 settings
 | 
						||
	hpwm1.stim.htim.Instance = TIMER_PWM1_INSTANCE;
 | 
						||
	hpwm1.stim.sTimMode = TIM_IT_MODE;
 | 
						||
	hpwm1.stim.sTickBaseMHz = TIM_TickBase_1US;
 | 
						||
	hpwm1.stim.sTimAHBFreqMHz = 72;
 | 
						||
	hpwm1.stim.sTimFreqHz = HZ_TIMER_PWM;
 | 
						||
	hpwm1.GPIOx = GPIOD;
 | 
						||
	hpwm1.GPIO_PIN_X1 = GPIO_PIN_12;
 | 
						||
	
 | 
						||
	TIM_Base_Init(&hpwm1.stim);
 | 
						||
	TIM_Output_PWM_Init(&hpwm1.stim.htim, &hpwm1.sConfigOC, hpwm->PWM_Channel1, hpwm1.GPIOx, hpwm1.GPIO_PIN_X1);
 | 
						||
		
 | 
						||
	
 | 
						||
 | 
						||
	
 | 
						||
	//----------TIMERS START-------------
 | 
						||
	HAL_TIM_PWM_Start_IT(&hpwm1.stim.htim, hpwm->PWM_Channel1); // timer for PWM
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
#ifdef SINE_THREE_PHASE_PWM_ENABLE
 | 
						||
	
 | 
						||
	//---------PWM TIMER2 INIT------------
 | 
						||
	// tim2 settings
 | 
						||
	hpwm2 = hpwm1;
 | 
						||
	hpwm2.stim.htim.Instance = TIM5;
 | 
						||
	hpwm2.GPIOx = GPIOA;
 | 
						||
	hpwm2.GPIO_PIN_X = GPIO_PIN_0;
 | 
						||
	
 | 
						||
	TIM_Base_Init(&hpwm2.stim);
 | 
						||
	TIM_Output_PWM_Init(&hpwm2.stim.htim, &hpwm2.sConfigOC, TIM_CHANNEL_1, hpwm2.GPIOx, hpwm2.GPIO_PIN_X);
 | 
						||
	
 | 
						||
	//---------PWM TIMER3 INIT------------
 | 
						||
	// tim3 settings
 | 
						||
	hpwm3 = hpwm2;
 | 
						||
	hpwm3.stim.htim.Instance = TIM8;
 | 
						||
	hpwm3.GPIOx = GPIOC;
 | 
						||
	hpwm3.GPIO_PIN_X = GPIO_PIN_6;
 | 
						||
	
 | 
						||
	TIM_Base_Init(&hpwm3.stim);
 | 
						||
	TIM_Output_PWM_Init(&hpwm3.stim.htim, &hpwm3.sConfigOC, TIM_CHANNEL_1, hpwm3.GPIOx, hpwm3.GPIO_PIN_X);	
 | 
						||
	
 | 
						||
	HAL_TIM_PWM_Start(&hpwm2.stim.htim, TIM_CHANNEL_1); // timer for PWM
 | 
						||
	HAL_TIM_PWM_Start(&hpwm3.stim.htim, TIM_CHANNEL_1); // timer for PWM
 | 
						||
#endif // SINE_THREE_PHASE_PWM_ENABLE
 | 
						||
 | 
						||
void PWM_Threephase_Init(void)
 | 
						||
{
 | 
						||
#ifdef INTERNAL_THREE_PHASE_PWM_ENABLE
 | 
						||
  TIM_OC_InitTypeDef sPWMConfigOC = {0};
 | 
						||
  TIM_OC_InitTypeDef sOCConfigOC = {0};
 | 
						||
	int us100Time = 10000/TIM_CTRL.sTimFreqHz;								// 1/TIM_CTRL.sTimFreqHz * 10^6 - Sample time in us
 | 
						||
	
 | 
						||
	// PWM CHANNEL SETTINGS		
 | 
						||
	sPWMConfigOC.OCMode = TIM_OCMODE_PWM1;
 | 
						||
  sPWMConfigOC.Pulse = us100Time/2;
 | 
						||
  sPWMConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
 | 
						||
  sPWMConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
 | 
						||
		
 | 
						||
	// CC CHANNEL SETTINGS
 | 
						||
  sOCConfigOC.OCMode = TIM_OCMODE_ACTIVE;
 | 
						||
  sOCConfigOC.Pulse = (2*us100Time-1) / 3;
 | 
						||
  sOCConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;	
 | 
						||
	
 | 
						||
	
 | 
						||
	// TIMER1 PWM MASTER INIT
 | 
						||
	TIM_3PWM1.htim = &tim_3pwm1;
 | 
						||
	TIM_3PWM1.htim->Instance = TIM1;
 | 
						||
	TIM_3PWM1.htim->Init.Prescaler = 7200-1;		// 1 us
 | 
						||
	TIM_3PWM1.htim->Init.Period = us100Time-1;	// period in us = Sample time in us
 | 
						||
	
 | 
						||
  TIM_3PWM1.sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC2REF;
 | 
						||
  TIM_3PWM1.sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 | 
						||
	
 | 
						||
  TIM_3PWM1.sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
 | 
						||
	
 | 
						||
	TIM_Base_Init(&TIM_3PWM1);
 | 
						||
	TIM_Output_PWM_Init(TIM_3PWM1.htim, &sPWMConfigOC, TIM_CHANNEL_1, GPIOE, GPIO_PIN_9);
 | 
						||
	HAL_TIM_OC_ConfigChannel(TIM_3PWM1.htim, &sOCConfigOC, TIM_CHANNEL_2);
 | 
						||
 | 
						||
	
 | 
						||
	// TIMER2 PWM SLAVE INIT
 | 
						||
	TIM_3PWM2 = TIM_3PWM1;
 | 
						||
	TIM_3PWM2.htim = &tim_3pwm2;
 | 
						||
	*TIM_3PWM2.htim = *TIM_3PWM1.htim;
 | 
						||
	TIM_3PWM2.htim->Instance = TIM2;
 | 
						||
	TIM_3PWM1.TIM_MODE = TIM_DEFAULT;
 | 
						||
	
 | 
						||
  TIM_3PWM2.sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
 | 
						||
  TIM_3PWM2.sSlaveConfig.InputTrigger = TIM_TS_ITR0;
 | 
						||
	
 | 
						||
	TIM_Base_Init(&TIM_3PWM2);
 | 
						||
	TIM_Output_PWM_Init(TIM_3PWM2.htim, &sPWMConfigOC, TIM_CHANNEL_1, GPIOA, GPIO_PIN_5);
 | 
						||
	HAL_TIM_OC_ConfigChannel(TIM_3PWM2.htim, &sOCConfigOC, TIM_CHANNEL_2);
 | 
						||
	
 | 
						||
	
 | 
						||
		
 | 
						||
	// TIMER3 PWM SLAVE INIT
 | 
						||
	TIM_3PWM3 = TIM_3PWM2;
 | 
						||
	TIM_3PWM3.htim = &tim_3pwm3;
 | 
						||
	*TIM_3PWM3.htim = *TIM_3PWM2.htim;
 | 
						||
	TIM_3PWM3.htim->Instance = TIM3;
 | 
						||
  TIM_3PWM3.sSlaveConfig.InputTrigger = TIM_TS_ITR1;
 | 
						||
	
 | 
						||
	TIM_Base_Init(&TIM_3PWM3);
 | 
						||
	TIM_Output_PWM_Init(TIM_3PWM3.htim, &sPWMConfigOC, TIM_CHANNEL_1, GPIOA, GPIO_PIN_6);
 | 
						||
	
 | 
						||
	hpwm1.Duty_Table_Size = PWM_Fill_Sine_Table(&sin_table, SIN_TABLE_SIZE_MAX);
 | 
						||
	
 | 
						||
	// TIMERS START	
 | 
						||
	HAL_TIM_OC_Start(TIM_3PWM3.htim, TIM_CHANNEL_2);
 | 
						||
	HAL_TIM_PWM_Start(TIM_3PWM3.htim, TIM_CHANNEL_1);
 | 
						||
	
 | 
						||
	HAL_TIM_PWM_Start(TIM_3PWM2.htim, TIM_CHANNEL_1);
 | 
						||
	HAL_TIM_OC_Start(TIM_3PWM2.htim, TIM_CHANNEL_2);
 | 
						||
	
 | 
						||
	HAL_TIM_OC_Start(TIM_3PWM1.htim, TIM_CHANNEL_2);
 | 
						||
	HAL_TIM_PWM_Start(TIM_3PWM1.htim, TIM_CHANNEL_1);
 | 
						||
#endif // INTERNAL_THREE_PHASE_PWM_ENABLE
 | 
						||
 | 
						||
}
 | 
						||
#endif
 |