//------------------------------------------------------------------------------
// 模块名称：步进电机脉冲驱动模块
// 文件名称：bsp_step_moto
// 版本名称：V1.0
// 文件说明：控制电机转动脉冲输出文件
// 日期时间：2018年8月23日20点37分
// 文件作者：Jackie Chan
// 修改记录：
//    版本号  日期        作者  说明
//    V1.0    2018.08.23  J.C   正式发布
//
// 公司名称：多场低温科技有限公司
//
//------------------------------------------------------------------------------

#include "bsp.h"

// 定义GPIO端口
#define GPIO_PORT_STEP GPIOC // 脉冲输入，内部下拉，上升沿触发
#define GPIO_PIN_STEP GPIO_Pin_7
#define MOTO_STEP_0() GPIO_PORT_STEP->BRR = GPIO_PIN_STEP
#define MOTO_STEP_1() GPIO_PORT_STEP->BSRR = GPIO_PIN_STEP

// PA6 零位信号输出引脚
#define GPIO_PORT_ZERO_SIG GPIOA
#define GPIO_PIN_ZERO_SIG GPIO_Pin_6
#define ZERO_SIG_TOGGLE() (GPIO_PORT_ZERO_SIG->ODR ^= GPIO_PIN_ZERO_SIG)

extern DIGITIAL_TUBE_T g_tTube;
MOTO_T g_tMoto;

//------------------------------------------------------------------------------
//  函 数 名: bsp_InitStepMoto
//  功能说明: 配置步进电器驱动IO
//  形    参: 无
//  返 回 值: 无
//------------------------------------------------------------------------------
void bsp_InitStepMoto(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  // 初始化 PA6 为零位信号输出引脚
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_PIN_ZERO_SIG;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIO_PORT_ZERO_SIG, &GPIO_InitStructure);
  GPIO_PORT_ZERO_SIG->BRR = GPIO_PIN_ZERO_SIG; // 默认输出低电平

  g_tMoto.Dir = 0;
  g_tMoto.StepFreq = 0;
  g_tMoto.StepCount = 0;
  g_tMoto.Running = 0;
  g_tMoto.Pos = 0;
  g_tMoto.pv_pulse = 0;
  g_tMoto.sv_pulse = 0;
  g_tMoto.prev_pv_pulse = 0;
}

//------------------------------------------------------------------------------
//  函 数 名: MOTO_StartWork
//  功能说明: 控制电机开始旋转
//  形    参: _speed 旋转速度. 换相的频率。Hz
//     _dir    旋转方向 0 表示正转， 1表示反转
//     _step   旋转步数 0 表示一直旋转
//  返 回 值: 无
//------------------------------------------------------------------------------
void MOTO_Start(uint32_t _speed, uint8_t _dir, int32_t _stpes)
{
  bsp_drv8880_enable_config(ENABLE);
  g_tMoto.Dir = _dir;
  g_tMoto.StepFreq = _speed;
  g_tMoto.StepCount = _stpes;
  g_tMoto.AllStep = _stpes;
  g_tMoto.CurrentStep = 0;
  g_tMoto.Running = 1;

  // void bsp_SetTIMforInt(TIM_TypeDef* TIMx, uint32_t _ulFreq, uint8_t _PreemptionPriority, uint8_t _SubPriority)
  // bsp_SetTIMforInt(TIM6, _speed*2, 2, 2);
  switch (_dir)
  {
  case 1:
    bsp_drv8880_config_dir(DIR_CW);
    break;
  case 0:
    bsp_drv8880_config_dir(DIR_CCW);
    break;
  default:
    break;
  }
  bsp_SetTIMforInt(TIM6, _speed * 2, 0, 0);
}

//------------------------------------------------------------------------------
// 函 数 名: MOTO_ShangeSpeed
// 功能说明: 控制电机的步进速度
// 形    参: _speed 旋转速度. 换相的频率。Hz
// 		 _dir    旋转方向 0 表示正转， 1表示反转
// 		 _step   旋转步数 0 表示一直旋转
// 返 回 值: 无
//------------------------------------------------------------------------------
void MOTO_ShangeSpeed(uint32_t _speed)
{
  g_tMoto.StepFreq = _speed;

  if (g_tMoto.Running == 1)
  {
    // void bsp_SetTIMforInt(TIM_TypeDef* TIMx, uint32_t _ulFreq, uint8_t _PreemptionPriority, uint8_t _SubPriority)
    bsp_SetTIMforInt(TIM6, _speed, 2, 2);
  }
}

void MOTO_ZorePos(void)
{
  MOTO_Stop();
  g_tMoto.sv_pulse = 0;
  g_tMoto.pv_pulse = 0;
  g_tMoto.prev_pv_pulse = 0;
  GPIO_PORT_ZERO_SIG->BRR = GPIO_PIN_ZERO_SIG; // 归零时 PA6 输出低
  BEEP_Start(1500, 5, 5, 3);
}

//------------------------------------------------------------------------------
// 函 数 名: MOTO_Stop
// 功能说明: 控制电机停止运行。
// 形    参: 无
// 返 回 值: 无
//------------------------------------------------------------------------------
void MOTO_Stop(void)
{
  // void bsp_SetTIMforInt(TIM_TypeDef* TIMx, uint32_t _ulFreq, uint8_t _PreemptionPriority, uint8_t _SubPriority)
  bsp_SetTIMforInt(TIM6, 0, 0, 0);
  g_tMoto.Running = 0;

  MOTO_STEP_0();
  // bsp_drv8880_enable_config(DISABLE);
  if (g_tTube.state == SEARCH)
  {
    g_tTube.state = IDLE;
  }
}

//------------------------------------------------------------------------------
// 函 数 名: MOTO_Pause
// 功能说明: 控制电机暂停旋转。
// 形    参: 无
// 返 回 值: 无
//------------------------------------------------------------------------------
void MOTO_Pause(void)
{
  // void bsp_SetTIMforInt(TIM_TypeDef* TIMx, uint32_t _ulFreq, uint8_t _PreemptionPriority, uint8_t _SubPriority)
  bsp_SetTIMforInt(TIM6, 0, 0, 0);
  g_tMoto.Running = 0;
  MOTO_STEP_0();
  // bsp_drv8880_enable_config(DISABLE);
}

//------------------------------------------------------------------------------
// 函 数 名: MOTO_RoudToStep
// 功能说明: 圈数换算为步数。28BYJ48 电机步距角度 = 5.625/64度.
// 形    参: 无
// 返 回 值: 无
//------------------------------------------------------------------------------
uint32_t MOTO_RoudToStep(void)
{
  uint32_t steps;

  /* 28BYJ48 电机步距角度 = 5.625/64度.
    一圈 360度；
    step = 360 / (5.625 / 64)
  */
  steps = (360 * 64 * 1000 / 4) / 5625; // 4096步

  return steps;
}

//------------------------------------------------------------------------------
// 函 数 名: MOTO_ISR
// 功能说明: 中断服务程序
// 形    参: 无
// 返 回 值: 无
//------------------------------------------------------------------------------
void MOTO_ISR(void)
{
  if (g_tMoto.Running == 0)
  {
    return;
  }
  // BEEP_KeyTone();

  // g_tMoto.Pos = 0;
  switch (g_tMoto.Pos)
  {
  case 0:
  {
    g_tMoto.Pos = 1;
    MOTO_STEP_1();
    g_tMoto.prev_pv_pulse = g_tMoto.pv_pulse;
    if (g_tMoto.pv_pulse < g_tMoto.sv_pulse)
    {
      g_tMoto.pv_pulse++;
    }
    else if (g_tMoto.pv_pulse > g_tMoto.sv_pulse)
    {
      g_tMoto.pv_pulse--;
    }
    // 检测过零点：pv_pulse 每跨越一个 STEP_PER_LAP（即每转一圈）翻转PA6
    if ((g_tMoto.prev_pv_pulse / STEP_PER_LAP) != (g_tMoto.pv_pulse / STEP_PER_LAP))
    {
      ZERO_SIG_TOGGLE();
    }
    break;
  }

  case 1:
  {
    g_tMoto.Pos = 0;
    MOTO_STEP_0();
    g_tMoto.CurrentStep++;
    if (g_tMoto.pv_pulse == g_tMoto.sv_pulse)
    {
      MOTO_Stop();
      TIM_ClearITPendingBit(TIM6, TIM_IT_Update); /* 清除中断标志位 */
    }
    break;
  }
  default:
    break;
  }
}

//------------------------------------------------------------------------------
// 函 数 名: TIM6_IRQHandler
// 功能说明: 外部中断服务程序.
// 形    参：无
// 返 回 值: 无
//------------------------------------------------------------------------------
#ifndef TIM6_ISR_MOVE_OUT /* bsp.h 中定义此行，表示本函数移到 stam32fxxx_it.c。 避免重复定义 */
void TIM6_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
  {
    MOTO_ISR(); /* 中断服务程序 */

    TIM_ClearITPendingBit(TIM6, TIM_IT_Update); /* 清除中断标志位 */
  }
}
#endif

//-------------------------------- End of file ---------------------------------
