/*
 * pwm.c
 *
 *  Created on: Dec 6, 2025
 *      Author: user
 */


#include "stm32f1xx_hal.h"
#include "main.h"
#include "pwm.h"

extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim3;
extern TIM_HandleTypeDef htim4;
extern volatile uint8_t rtramp[4];
extern uint8_t mrampstart[4];
bool IsPwmRunning(TIM_HandleTypeDef *htim, uint32_t Channel)
{
    HAL_TIM_ChannelStateTypeDef chState = HAL_TIM_GetChannelState(htim, Channel);

    return (chState == HAL_TIM_CHANNEL_STATE_BUSY);
}

void StopMot(TIM_HandleTypeDef *htim,uint32_t Channel){
	HAL_TIM_PWM_Stop(htim, Channel);
}

void StartMot(TIM_HandleTypeDef *htim,uint32_t Channel,uint16_t pwmval){
	__HAL_TIM_SET_COMPARE(htim, Channel, pwmval);
	HAL_TIM_PWM_Start(htim, Channel);
}

void SetMotPwm(TIM_HandleTypeDef *htim,uint32_t Channel,uint16_t pwmval){
	__HAL_TIM_SET_COMPARE(htim, Channel, pwmval);
}

void SetMot(uint8_t mot,uint8_t dir,uint16_t pwmval){
	switch(mot){
	case 1:
		if(dir==FW){
			if(pwmval==0){
				StopMot(timMot1,FWMot1);
				HAL_GPIO_WritePin(INH1_GPIO_Port, INH1_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot1, FWMot1)){
				SetMotPwm(timMot1,FWMot1,pwmval);
			}else{
				HAL_GPIO_WritePin(INH1_GPIO_Port, INH1_Pin, GPIO_PIN_SET);
				StartMot(timMot1,FWMot1,pwmval);
			}
		}else{
			if(pwmval==0){
				StopMot(timMot1,BWMot1);
				HAL_GPIO_WritePin(INH1_GPIO_Port, INH1_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot1, BWMot1)){
				SetMotPwm(timMot1,BWMot1,pwmval);
			}else{
				HAL_GPIO_WritePin(INH1_GPIO_Port, INH1_Pin, GPIO_PIN_SET);
				StartMot(timMot1,BWMot1,pwmval);

			}
		}
		break;
	case 2:
		if(dir==FW){
			if(pwmval==0){
				StopMot(timMot2,FWMot2);
				HAL_GPIO_WritePin(INH2_GPIO_Port, INH2_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot2, FWMot2)){
				SetMotPwm(timMot2,FWMot2,pwmval);
			}else{
				HAL_GPIO_WritePin(INH2_GPIO_Port, INH2_Pin, GPIO_PIN_SET);
				StartMot(timMot2,FWMot2,pwmval);
			}
		}else{
			if(pwmval==0){
				StopMot(timMot2,BWMot2);
				HAL_GPIO_WritePin(INH2_GPIO_Port, INH2_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot2, BWMot2)){
				SetMotPwm(timMot2,BWMot2,pwmval);
			}else{
				HAL_GPIO_WritePin(INH2_GPIO_Port, INH2_Pin, GPIO_PIN_SET);
				StartMot(timMot2,BWMot2,pwmval);
			}
		}
		break;
	case 3:
		if(dir==FW){
			if(pwmval==0){
				StopMot(timMot3,FWMot3);
				HAL_GPIO_WritePin(INH3_GPIO_Port, INH3_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot3, FWMot3)){
				SetMotPwm(timMot3,FWMot3,pwmval);
			}else{
				HAL_GPIO_WritePin(INH3_GPIO_Port, INH3_Pin, GPIO_PIN_SET);
				StartMot(timMot3,FWMot3,pwmval);
			}
		}else{
			if(pwmval==0){
				StopMot(timMot3,BWMot3);
				HAL_GPIO_WritePin(INH3_GPIO_Port, INH3_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot3, BWMot3)){
				SetMotPwm(timMot3,BWMot3,pwmval);
			}else{
				HAL_GPIO_WritePin(INH3_GPIO_Port, INH3_Pin, GPIO_PIN_SET);
				StartMot(timMot3,BWMot3,pwmval);
			}
		}
		break;
	case 4:
		if(dir==FW){
			if(pwmval==0){
				StopMot(timMot4,FWMot4);
				HAL_GPIO_WritePin(INH4_GPIO_Port, INH4_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot4, FWMot4)){
				SetMotPwm(timMot4,FWMot4,pwmval);
			}else{
				HAL_GPIO_WritePin(INH4_GPIO_Port, INH4_Pin, GPIO_PIN_SET);
				StartMot(timMot4,FWMot4,pwmval);
			}
		}else{
			if(pwmval==0){
				StopMot(timMot4,BWMot4);
				HAL_GPIO_WritePin(INH4_GPIO_Port, INH4_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot4, BWMot4)){
				SetMotPwm(timMot4,BWMot4,pwmval);
			}else{
				HAL_GPIO_WritePin(INH4_GPIO_Port, INH4_Pin, GPIO_PIN_SET);
				StartMot(timMot4,BWMot4,pwmval);
			}
		}
		break;
	default:
		break;
	}

}

void SetMotPerc(uint8_t mot,uint8_t dir,uint8_t perc){
	uint16_t pwmval;
	uint32_t tempval;
	tempval=perc;
	tempval*=16384;
	tempval/=100;
	pwmval=(uint16_t)tempval;
	switch(mot){
	case 1:
		if(dir==FW){
			if(pwmval==0){
				StopMot(timMot1,FWMot1);
				HAL_GPIO_WritePin(INH1_GPIO_Port, INH1_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot1, FWMot1)){
				SetMotPwm(timMot1,FWMot1,pwmval);
			}else{
				HAL_GPIO_WritePin(INH1_GPIO_Port, INH1_Pin, GPIO_PIN_SET);
				StartMot(timMot1,FWMot1,pwmval);
			}
		}else{
			if(pwmval==0){
				StopMot(timMot1,BWMot1);
				HAL_GPIO_WritePin(INH1_GPIO_Port, INH1_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot1, BWMot1)){
				SetMotPwm(timMot1,BWMot1,pwmval);
			}else{
				HAL_GPIO_WritePin(INH1_GPIO_Port, INH1_Pin, GPIO_PIN_SET);
				StartMot(timMot1,BWMot1,pwmval);

			}
		}
		break;
	case 2:
		if(dir==FW){
			if(pwmval==0){
				StopMot(timMot2,FWMot2);
				HAL_GPIO_WritePin(INH2_GPIO_Port, INH2_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot2, FWMot2)){
				SetMotPwm(timMot2,FWMot2,pwmval);
			}else{
				HAL_GPIO_WritePin(INH2_GPIO_Port, INH2_Pin, GPIO_PIN_SET);
				StartMot(timMot2,FWMot2,pwmval);
			}
		}else{
			if(pwmval==0){
				StopMot(timMot2,BWMot2);
				HAL_GPIO_WritePin(INH2_GPIO_Port, INH2_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot2, BWMot2)){
				SetMotPwm(timMot2,BWMot2,pwmval);
			}else{
				HAL_GPIO_WritePin(INH2_GPIO_Port, INH2_Pin, GPIO_PIN_SET);
				StartMot(timMot2,BWMot2,pwmval);
			}
		}
		break;
	case 3:
		if(dir==FW){
			if(pwmval==0){
				StopMot(timMot3,FWMot3);
				HAL_GPIO_WritePin(INH3_GPIO_Port, INH3_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot3, FWMot3)){
				SetMotPwm(timMot3,FWMot3,pwmval);
			}else{
				HAL_GPIO_WritePin(INH3_GPIO_Port, INH3_Pin, GPIO_PIN_SET);
				StartMot(timMot3,FWMot3,pwmval);
			}
		}else{
			if(pwmval==0){
				StopMot(timMot3,BWMot3);
				HAL_GPIO_WritePin(INH3_GPIO_Port, INH3_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot3, BWMot3)){
				SetMotPwm(timMot3,BWMot3,pwmval);
			}else{
				HAL_GPIO_WritePin(INH3_GPIO_Port, INH3_Pin, GPIO_PIN_SET);
				StartMot(timMot3,BWMot3,pwmval);
			}
		}
		break;
	case 4:
		if(dir==FW){
			if(pwmval==0){
				StopMot(timMot4,FWMot4);
				HAL_GPIO_WritePin(INH4_GPIO_Port, INH4_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot4, FWMot4)){
				SetMotPwm(timMot4,FWMot4,pwmval);
			}else{
				HAL_GPIO_WritePin(INH4_GPIO_Port, INH4_Pin, GPIO_PIN_SET);
				StartMot(timMot4,FWMot4,pwmval);
			}
		}else{
			if(pwmval==0){
				StopMot(timMot4,BWMot4);
				HAL_GPIO_WritePin(INH4_GPIO_Port, INH4_Pin, GPIO_PIN_RESET);
			}else if(IsPwmRunning(timMot4, BWMot4)){
				SetMotPwm(timMot4,BWMot4,pwmval);
			}else{
				HAL_GPIO_WritePin(INH4_GPIO_Port, INH4_Pin, GPIO_PIN_SET);
				StartMot(timMot4,BWMot4,pwmval);
			}
		}
		break;
	default:
		break;
	}

}

uint8_t ramp(uint8_t mot,uint8_t dir,uint8_t percStart,uint8_t percEnd,uint8_t tr,uint8_t mode){
	static uint8_t memrtramp[4];
	uint16_t delta;
	switch(mode){
	case RAMPINIT:
		memrtramp[mot-1]=percStart=tr;
		SetMotPerc(mot,dir,mrampstart[mot-1]);
		return DONE;
	case RAMPRUN:
		if(memrtramp[mot-1]!=rtramp[mot-1]){
			memrtramp[mot-1]=rtramp[mot-1];
			if(rtramp[mot-1]){
				if(mrampstart[mot-1]>percEnd){
					delta=mrampstart[mot-1]-percEnd;
					delta=delta*(uint16_t)(tr-rtramp[mot-1]);
					delta=delta/tr;
					SetMotPerc(mot,dir,mrampstart[mot-1]-delta);
					return RUNNING;
				}else if(mrampstart[mot-1]<percEnd){
					delta=percEnd-mrampstart[mot-1];
					delta=delta*(uint16_t)(tr-rtramp[mot-1]);
					delta=delta/tr;
					SetMotPerc(mot,dir,mrampstart[mot-1]+delta);
					return RUNNING;
				}else{
					SetMotPerc(mot,dir,percEnd);
					return DONE;
				}
			}else{
				SetMotPerc(mot,dir,percEnd);
				return DONE;
			}
		}else return RUNNING;
		break;
	}
	return DONE;
}
