#include "bsp_motor.h"

#include <stdint.h>
#include <stdio.h>

#include "stm32f10x.h"                  // Device header
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_tim.h"
// /* A IN1 */
// #define A_IN1_GPIO_PORT	(GPIOA)
// #define A_IN1_GPIO_PIN	(GPIO_Pin_4)
// /* A IN2 */
// #define A_IN2_GPIO_PORT	(GPIOA)
// #define A_IN2_GPIO_PIN	(GPIO_Pin_5)
// /* B IN1 */
// #define B_IN1_GPIO_PORT	(GPIOA)
// #define B_IN1_GPIO_PIN	(GPIO_Pin_1)
// /* B IN2 */
// #define B_IN2_GPIO_PORT	(GPIOA)
// #define B_IN2_GPIO_PIN	(GPIO_Pin_8)

/* 电机驱动PWM定时器 */
#define TIM_MOTOR                       TIM4
#define TIM_MOTOR_IRQn	                TIM4_IRQn
#define	TIM_MOTOR_PERIPH_RCC	        RCC_APB1Periph_TIM4
/* PWMA */
#define TIM_MOTOR_PWMA_GPIO_RCC          RCC_APB2Periph_GPIOB
#define TIM_MOTOR_PWMA_GPIO_PORT         GPIOB
#define TIM_MOTOR_PWMA_GPIO_PIN          GPIO_Pin_8
/* PWMB */
#define TIM_MOTOR_PWMB_GPIO_RCC          RCC_APB2Periph_GPIOB
#define TIM_MOTOR_PWMB_GPIO_PORT         GPIOB
#define TIM_MOTOR_PWMB_GPIO_PIN          GPIO_Pin_9


/*************************************************************************************
 * @brief    对外输出至电机驱动板IN接口的GPIO初始化
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_InitGPIO_MotorOut(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	// 时钟初始化
	if(A_IN1_GPIO_PORT == GPIOA || A_IN2_GPIO_PORT == GPIOA || B_IN1_GPIO_PORT == GPIOA || B_IN2_GPIO_PORT == GPIOA)
	{
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	}
	if(A_IN1_GPIO_PORT == GPIOB || A_IN2_GPIO_PORT == GPIOB || B_IN1_GPIO_PORT == GPIOB || B_IN2_GPIO_PORT == GPIOB)
	{
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	}
	if(A_IN1_GPIO_PORT == GPIOC || A_IN2_GPIO_PORT == GPIOC || B_IN1_GPIO_PORT == GPIOC || B_IN2_GPIO_PORT == GPIOC)
	{
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	}
	
	
	/* AIN1 初始化 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = A_IN1_GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(A_IN1_GPIO_PORT, &GPIO_InitStructure);
	/* AIN2 初始化 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = A_IN2_GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(A_IN2_GPIO_PORT, &GPIO_InitStructure);
	/* BIN1 初始化 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = B_IN1_GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(B_IN1_GPIO_PORT, &GPIO_InitStructure);
	/* BIN2 初始化 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = B_IN2_GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(B_IN2_GPIO_PORT, &GPIO_InitStructure);

}


/*************************************************************************************
 * @brief    初始化驱动电机的定时器
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
 void bsp_InitMotorTimer(void)
 {
	 GPIO_InitTypeDef GPIO_InitStructure;
	 TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	 NVIC_InitTypeDef NVIC_InitStructure;
	 TIM_OCInitTypeDef TIM_OCInitStructure;
	 /* 1. 使能TIM时钟 */
	 RCC_APB1PeriphClockCmd(TIM_MOTOR_PERIPH_RCC, ENABLE);
	 /* 2. 使能对应的GPIO引脚  */
	 /* PWMA */
	 GPIO_Init(TIM_MOTOR_PWMA_GPIO_PORT, &GPIO_InitStructure);              //初始化 
	 RCC_APB2PeriphClockCmd(TIM_MOTOR_PWMA_GPIO_RCC, ENABLE); //使能 PA 端口时钟
	 GPIO_InitStructure.GPIO_Pin = TIM_MOTOR_PWMA_GPIO_PIN;           
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    
	 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //IO 口速度为 50MHz
	 GPIO_Init(TIM_MOTOR_PWMA_GPIO_PORT, &GPIO_InitStructure);             

	  /* PWMB */
	 GPIO_Init(TIM_MOTOR_PWMB_GPIO_PORT, &GPIO_InitStructure);              //初始化 
	 RCC_APB2PeriphClockCmd(TIM_MOTOR_PWMB_GPIO_RCC, ENABLE); //使能 PA 端口时钟
	 GPIO_InitStructure.GPIO_Pin = TIM_MOTOR_PWMB_GPIO_PIN;           
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    
	 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //IO 口速度为 50MHz
	 GPIO_Init(TIM_MOTOR_PWMB_GPIO_PORT, &GPIO_InitStructure);      
	 /* 3. Configures the TIMx internal Clock */
	 TIM_InternalClockConfig(TIM_MOTOR);
	 /* 4. 定义时基单元 */
	 TIM_TimeBaseStructure.TIM_Period = (100u - 1);     // 周期   ARR自动重装器的值
	 TIM_TimeBaseStructure.TIM_Prescaler = 36 - 1;	       // PSC预分频器的值
	 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
	 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数器模式
	 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;    // 重复计数器的值，高级定时器才有
	 TIM_TimeBaseInit(TIM_MOTOR, &TIM_TimeBaseStructure);
	 /* 5. 输出比较 */
	 TIM_OCStructInit(&TIM_OCInitStructure);
	 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;	// PWM模式1（CNT<CCR时高电平）
	 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;	// 高电平有效
	 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	// 使能输出
	 TIM_OCInitStructure.TIM_Pulse = 0;		//CCR	占空比
	 // 应用至TIM2_CHx[1,7](@ref)
	 /* PWMA */
	 TIM_OC3Init(TIM_MOTOR, &TIM_OCInitStructure);
	 /* PWMB */
	 TIM_OC4Init(TIM_MOTOR, &TIM_OCInitStructure);

	 TIM_ARRPreloadConfig(TIM_MOTOR, ENABLE);
	 /* 6. TIMx enable counter */
	 TIM_Cmd(TIM_MOTOR, ENABLE);
 }

/*************************************************************************************
 * @brief    初始化电机驱动器
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_InitMotor(void)
{
	bsp_InitGPIO_MotorOut();

	bsp_InitMotorTimer();
}
/*************************************************************************************
 * @brief    A IN1 开
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_AIN1_ON(void)
{
	GPIO_SetBits(A_IN1_GPIO_PORT, A_IN1_GPIO_PIN);
}
/*************************************************************************************
 * @brief    A IN1 关
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_AIN1_OFF(void)
{
	GPIO_ResetBits(A_IN1_GPIO_PORT, A_IN1_GPIO_PIN);
}
/*************************************************************************************
 * @brief    A IN2 开
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_AIN2_ON(void)
{
	GPIO_SetBits(A_IN2_GPIO_PORT, A_IN2_GPIO_PIN);
}
/*************************************************************************************
 * @brief    A IN2 关
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_AIN2_OFF(void)
{
	GPIO_ResetBits(A_IN2_GPIO_PORT, A_IN2_GPIO_PIN);
}
/*************************************************************************************
 * @brief    B IN1 开
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_BIN1_ON(void)
{
	GPIO_SetBits(B_IN1_GPIO_PORT, B_IN1_GPIO_PIN);
}
/*************************************************************************************
 * @brief    B IN1 关
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_BIN1_OFF(void)
{
	GPIO_ResetBits(B_IN1_GPIO_PORT, B_IN1_GPIO_PIN);
}
/*************************************************************************************
 * @brief    B IN2 开
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_BIN2_ON(void)
{
	GPIO_SetBits(B_IN2_GPIO_PORT, B_IN2_GPIO_PIN);
}
/*************************************************************************************
 * @brief    B IN2 关
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_BIN2_OFF(void)
{
	GPIO_ResetBits(B_IN2_GPIO_PORT, B_IN2_GPIO_PIN);
}
/*************************************************************************************
 * @brief    通过修改pwm，来修改左轮电机的速度
 * @param[in/out] Compare【参数注释】
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_changeLeftMotorSpeed(uint16_t Compare)
{
	TIM_SetCompare3(TIM_MOTOR, Compare);
}
/*************************************************************************************
 * @brief    通过修改pwm，来修改右轮电机的速度
 * @param[in/out] Compare【参数注释】
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_changeRightMotorSpeed(uint16_t Compare)
{
	TIM_SetCompare4(TIM_MOTOR, Compare);
}

