/**
  ******************************************************************************
  * @file    x_nucleo_ihm05a1_stm32l0xx.c
  * @author  IPC Rennes
  * @version V1.5.0
  * @date    June 1st, 2018
  * @brief   BSP driver for x-nucleo-ihm05a1 Nucleo extension board 
  *  (based on L6208)
  ******************************************************************************
* @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2018 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */ 
  
/* Includes ------------------------------------------------------------------*/
#include "x_nucleo_ihm05a1_stm32l1xx.h"
#include "motor.h"

/** @addtogroup BSP
  * @{
  */ 

/** @defgroup X_NUCLEO_IHM05A1_STM32L0XX  NUCLEO IHM05A1 STM32L0XX
  * @{
  */   
    
/* Private constants ---------------------------------------------------------*/    

/** @defgroup IHM05A1_Private_Constants IHM05A1 Private Constants
  * @{
  */   
/// Tick frequency (Hz)
#define TIMER_TICK_FREQUENCY                                     (10000)
    
/// Tick Timer Prescaler
#define TIMER_TICK_PRESCALER                                     (64)       

/// MCU wait time after power bridges are enabled
#define BRIDGE_TURN_ON_DELAY                                     (10)

/**
  * @}
  */ 

/* Private variables ---------------------------------------------------------*/

/** @defgroup IHM05A1_Board_Private_Variables IHM05A1 Board Private Variables
  * @{
  */       
/// L6208 timer handler for VREFA PWM
TIM_HandleTypeDef hTimVrefaPwm;

/// L6208 timer handler for VREFB PWM
TIM_HandleTypeDef hTimVrefbPwm;

/// L6208 timer handler for the tick
TIM_HandleTypeDef hTimTick;
/**
  * @}
  */ 

/** @defgroup IHM05A1_Board_Private_Function_Prototypes IHM05A1 Board Private Function Prototypes
  * @{
  */   
void L6208_Board_CLOCK_PIN_Reset(void);                       //Reset the clock pin
void L6208_Board_CLOCK_PIN_Set(void);                         //Set the clock pin
void L6208_Board_CONTROL_PIN_Reset(void);                     //Reset the control pin
void L6208_Board_CONTROL_PIN_Set(void);                       //Set the control pin
void L6208_Board_Delay(uint32_t delay);                       //Delay of the requested number of milliseconds
void L6208_Board_DIR_PIN_Reset(void);                         //Reset the dir pin
void L6208_Board_DIR_PIN_Set(void);                           //Set the dir pin
void L6208_Board_Disable(void);                               //Disable the power bridges (leave the output bridges HiZ)
void L6208_Board_DisableIrq(void);                            //Disable Irq
void L6208_Board_Enable(void);                                //Enable the power bridges (leave the output bridges HiZ)
void L6208_Board_EnableIrq(void);                             //Disable Irq
uint32_t L6208_Board_FLAG_PIN_GetState(void);                 //Returns the EN pin state
void L6208_Board_GpioInit(void);                              //Initialise GPIOs used for L6208
void L6208_Board_HALF_FULL_PIN_Reset(void);                   //Reset the half full pin
void L6208_Board_HALF_FULL_PIN_Set(void);                     //Set the half full pin
bool L6208_Board_VrefPwmInit(uint8_t bridgeId, uint32_t pwmFreq); //Initialize the VREFA or VREFB PWM
void L6208_Board_ReleaseReset(void);                          //Release the reset pin  
void L6208_Board_Reset(void);                                 //Reset the reset pin
uint32_t L6208_Board_TickGetFreq(void);                       //Get the tick frequency in Hz
void L6208_Board_TickInit(void);                              //Initialize the tick
void L6208_Board_TickStart(void);                             //Start the timer for the tick by using the set tick frequency
void L6208_Board_TickStop(void);                              //Stop the timer for the tick
bool L6208_Board_VrefPwmFreqCheck(uint32_t newFreq);          //Check that the new VREFA and VREFB PWM frequency is nor too low nor too high
uint32_t L6208_Board_VrefPwmGetPeriod(void);                  //Get current VREF PWM period duration
bool L6208_Board_VrefPwmSetDutyCycle(uint8_t bridgeId,\
       uint16_t value,\
       bool valueIsPwmDutyCycle);                             //Set duty cycle of VREFA or VREFB PWM
bool L6208_Board_VrefPwmStart(uint8_t bridgeId,\
       uint32_t pwmFreq);                                     //Start the timer for the VREFA or VREFB PWM
bool L6208_Board_VrefPwmStop(uint8_t bridgeId);               //Stop the timer for the VREFA or VREFB PWM

/**
  * @}
  */

/** @defgroup IHM05A1_Board_Private_Functions IHM05A1 Board Private Functions
  * @{
  */   

/******************************************************//**
 * @brief This function provides an accurate delay in milliseconds
 * @param[in] delay  time length in milliseconds
 * @retval None
 **********************************************************/
void L6208_Board_Delay(uint32_t delay)
{
  HAL_Delay(delay);
}

/******************************************************//**
 * @brief This function disable the interruptions
 * @retval None
 **********************************************************/
void L6208_Board_DisableIrq(void)
{
  //__disable_irq();
}

/******************************************************//**
 * @brief This function enable the interruptions
 * @retval None
 **********************************************************/
void L6208_Board_EnableIrq(void)
{
  //__enable_irq();
}

/******************************************************//**
 * @brief Start the L6208 library
 * @retval None
 **********************************************************/
void L6208_Board_GpioInit(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  
  /* GPIO Ports Clock Enable */
  __GPIOC_CLK_ENABLE();
  __GPIOA_CLK_ENABLE();
  __GPIOB_CLK_ENABLE();

  /* Configure L6208 - EN pin -------------------------------*/
  /* When this pin is set low, it is configured just before as                */
  /* GPIO_MODE_OUTPUT_PP with GPIO_NOPULL                                     */
  /* When this pin is set high, it is just after configured for OCD and OVT   */
  /* as GPIO_MODE_IT_FALLING with GPIO_PULLUP                                 */
  L6208_Board_Disable();
  
  /* Set Priority of External Line Interrupt used for the OCD OVT interrupt*/ 
  HAL_NVIC_SetPriority(FLAG_EXTI_LINE_IRQn, BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PRIORITY, 0);
    
  /* Enable the External Line Interrupt used for the OCD OVT interrupt*/
  HAL_NVIC_EnableIRQ(FLAG_EXTI_LINE_IRQn);  
 
  /* Configure L6208 - CW/CCW pin ----------------------------*/
  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_PORT, &GPIO_InitStruct);
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_PIN, GPIO_PIN_RESET);
  
  /* Configure L6208 - HALF/FULL pin -------------------------------------------*/
  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_HALF_FULL_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_HALF_FULL_PORT, &GPIO_InitStruct);
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_HALF_FULL_PORT, BSP_MOTOR_CONTROL_BOARD_HALF_FULL_PIN, GPIO_PIN_RESET); 
  
  /* Configure L6208 - CONTROL pin -------------------------------------------*/
  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_CONTROL_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_CONTROL_PORT, &GPIO_InitStruct);
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CONTROL_PORT, BSP_MOTOR_CONTROL_BOARD_CONTROL_PIN, GPIO_PIN_RESET);
 
  /* Configure L6208 - CLOCK pin -------------------------------------------*/
  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_CLOCK_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_CLOCK_PORT, &GPIO_InitStruct);
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CLOCK_PORT, BSP_MOTOR_CONTROL_BOARD_CLOCK_PIN, GPIO_PIN_RESET);
  
  /* Configure L6208 - STBY/RESET pin -------------------------------------*/
  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_RESET_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, &GPIO_InitStruct);
  L6208_Board_ReleaseReset();
}

/******************************************************//**
 * @brief Initialize the tick
 * @retval None
 **********************************************************/
void L6208_Board_TickInit(void)
{
  static TIM_OC_InitTypeDef sConfigOC;
  static TIM_MasterConfigTypeDef sMasterConfig;
  static TIM_ClockConfigTypeDef sClockSourceConfig;

  hTimTick.Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_TICK;
  hTimTick.Init.Period = (HAL_RCC_GetSysClockFreq() / (TIMER_TICK_PRESCALER * TIMER_TICK_FREQUENCY)) - 1;
  hTimTick.Init.Prescaler = TIMER_TICK_PRESCALER -1;
  hTimTick.Init.ClockDivision = 0;
  hTimTick.Init.CounterMode = TIM_COUNTERMODE_UP;
  HAL_TIM_PWM_Init(&hTimTick);
  
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  HAL_TIM_ConfigClockSource(&hTimTick, &sClockSourceConfig);
  
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  HAL_TIM_PWM_ConfigChannel(&hTimTick, &sConfigOC, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_TICK);
  
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&hTimTick, &sMasterConfig); 
}

/******************************************************//**
 * @brief Start the timer for the tick by using the set tick frequency
 * @retval None
 **********************************************************/
void L6208_Board_TickStart(void)
{
  uint32_t period = (HAL_RCC_GetSysClockFreq() / (TIMER_TICK_PRESCALER * TIMER_TICK_FREQUENCY)) - 1;
  
  __HAL_TIM_SetAutoreload(&hTimTick, period);
  __HAL_TIM_SetCompare(&hTimTick, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_TICK, period >> 1);
  HAL_TIM_PWM_Start_IT(&hTimTick, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_TICK);  
}

/******************************************************//**
 * @brief  Stop the timer for the tick
 * @retval None
 **********************************************************/
void L6208_Board_TickStop(void)
{
  HAL_TIM_PWM_Stop_IT(&hTimTick, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_TICK);
}

/******************************************************//**
 * @brief  Get the tick timer frequency in Hz
 * @retval The tick timer frequency in Hz
 **********************************************************/
uint32_t L6208_Board_TickGetFreq(void)
{
  return TIMER_TICK_FREQUENCY;
}

/******************************************************//**
 * @brief Check that the frequency for the VREFA and VREFB PWM
 * is high enough to prevent overflow in the computation of the
 * micro stepping waveform sample for a maximum torque. 
 * @param[in] newFreq frequency in Hz of the PWM used to generate
 * the reference voltage for the bridge
 * @retval FALSE if frequency is too low or too high, else TRUE
 **********************************************************/
bool L6208_Board_VrefPwmFreqCheck(uint32_t newFreq)
{
  if (newFreq<=(HAL_RCC_GetSysClockFreq()>>16))
  {
    return FALSE;
  }
  else
  {
    return TRUE;
  }
}
/******************************************************//**
 * @brief  Initialize the VREFA or VREFB PWM
 * @param[in] bridgeId
 *            0 for BRIDGE_A
 *            1 for BRIDGE_B
 * @param[in] pwmFreq frequency in Hz of the PWM used to generate the reference
 * voltage for the bridge
 * @retval FALSE if wrong timer handle is used, else TRUE
 * @note None
 **********************************************************/
bool L6208_Board_VrefPwmInit(uint8_t bridgeId, uint32_t pwmFreq)
{
  static TIM_OC_InitTypeDef sConfigOC;
  static TIM_MasterConfigTypeDef sMasterConfig;
  static TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_HandleTypeDef *pHTim = NULL;
  uint32_t channel;
  
  if (bridgeId == 0)
  {
    pHTim = &hTimVrefaPwm;
    pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_VREFA_PWM;
    pHTim->Init.Prescaler = 0;
    pHTim->Init.Period = (HAL_RCC_GetSysClockFreq() / pwmFreq) - 1;
    channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_VREFA_PWM;
  } 
  else if (bridgeId == 1)
  {
    pHTim = &hTimVrefbPwm;
    pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_VREFB_PWM;
    pHTim->Init.Prescaler = 0;
    pHTim->Init.Period = (HAL_RCC_GetSysClockFreq() / pwmFreq) - 1;
    channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_VREFB_PWM;
  }
  else
  {
    return FALSE;
  }

  pHTim->Init.CounterMode = TIM_COUNTERMODE_UP;
  pHTim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_PWM_Init(pHTim);  

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  HAL_TIM_ConfigClockSource(pHTim, &sClockSourceConfig); 
  
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  HAL_TIM_PWM_ConfigChannel(pHTim, &sConfigOC, channel);

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(pHTim, &sMasterConfig);
  
  return TRUE;
}

/******************************************************//**
 * @brief Set duty cycle of VREFA or VREFB PWM
 * @param[in] bridgeId
 *            0 for BRIDGE_A
 *            1 for BRIDGE_B
 * @param[in] value pulse length or PWM duty cycle: 0 - 100 %
 * @param[in] valueIsPwmDutyCycle must be TRUE if value is a PWM duty cycle
 * @retval FALSE if wrong timer handle is used, else TRUE
 **********************************************************/
bool L6208_Board_VrefPwmSetDutyCycle(uint8_t bridgeId, uint16_t value, bool valueIsPwmDutyCycle)
{
  TIM_HandleTypeDef *pHTim = NULL;
  uint32_t channel;
  
  if (bridgeId == 0)
  {
    pHTim = &hTimVrefaPwm;
    channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_VREFA_PWM;
  } 
  else if (bridgeId == 1)
  {
    pHTim = &hTimVrefbPwm;
    channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_VREFB_PWM;
  }
  else
  {
    return 0;
  }
  // PWM or OC Channel pulse length
  if(valueIsPwmDutyCycle)
  {
    if (value > 100) value = 100;
    value = (uint16_t)(((uint32_t)pHTim->Init.Period * (uint32_t)value) / 100);    
  }
  __HAL_TIM_SetCompare(pHTim, channel, value);
  
  return 1;
}

/******************************************************//**
 * @brief Start the timer for the VREFA or VREFB PWM
 * @param[in] bridgeId
 *            0 for BRIDGE_A
 *            1 for BRIDGE_B
 * @param[in] pwmFreq frequency in Hz of the PWM used to generate the reference
 * voltage for the bridge
 * @retval FALSE if wrong timer handle is used, else TRUE
 **********************************************************/
bool L6208_Board_VrefPwmStart(uint8_t bridgeId, uint32_t pwmFreq)
{
  TIM_HandleTypeDef *pHTim = NULL;
  uint32_t period;
  uint32_t channel;

  if (bridgeId == 0)
  {
    pHTim = &hTimVrefaPwm;
    period = (HAL_RCC_GetSysClockFreq() / pwmFreq) - 1;
    channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_VREFA_PWM;
  } 
  else if (bridgeId == 1)
  {
    pHTim = &hTimVrefbPwm;
    period = (HAL_RCC_GetSysClockFreq() / pwmFreq) - 1;
    channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_VREFB_PWM;
  }
  else
  {
    return FALSE;
  }
  __HAL_TIM_SetAutoreload(pHTim, period);
  HAL_TIM_PWM_Start(pHTim, channel);
  
  return TRUE;
}

/******************************************************//**
 * @brief Stop the VREFA or VREFB PWM
 * @param[in] bridgeId
 *            0 for BRIDGE_A
 *            1 for BRIDGE_B
 * @retval None
 **********************************************************/
bool L6208_Board_VrefPwmStop(uint8_t bridgeId)
{
  TIM_HandleTypeDef *pHTim = NULL;
  uint32_t channel;
  if (bridgeId == 0)
  {
    pHTim = &hTimVrefaPwm;
    channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_VREFA_PWM;
  } 
  else if (bridgeId == 1)
  {
    pHTim = &hTimVrefbPwm;
    channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_VREFB_PWM;
  }
  else
  {
    return FALSE;
  }
  HAL_TIM_PWM_Stop(pHTim, channel);
  
  return TRUE;
}

/******************************************************//**
 * @brief Get current VREF PWM period duration
 * @retval the current VREF PWM period duration
 * @note hTimVrefbPwm.Init.Period is the same as hTimVrefaPwm.Init.Period
 **********************************************************/
uint32_t L6208_Board_VrefPwmGetPeriod(void)
{
  return ((uint32_t)hTimVrefaPwm.Init.Period);
}

/******************************************************//**
 * @brief  Releases the L6208 reset (pin set to High) of all devices
 * @retval None
 **********************************************************/
void L6208_Board_ReleaseReset(void)
{ 
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_SET); 
}

/******************************************************//**
 * @brief  Resets the L6208 (reset pin set to low) of all devices
 * @retval None
 **********************************************************/
void L6208_Board_Reset(void)
{
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_RESET); 
}

/******************************************************//**
 * @brief  Set the L6208 CONTROL pin
 * @retval None
 **********************************************************/
void L6208_Board_CONTROL_PIN_Set(void)
{ 
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CONTROL_PORT, BSP_MOTOR_CONTROL_BOARD_CONTROL_PIN, GPIO_PIN_SET); 
}

/******************************************************//**
 * @brief  Reset the L6208 CONTROL pin
 * @retval None
 **********************************************************/
void L6208_Board_CONTROL_PIN_Reset(void)
{
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CONTROL_PORT, BSP_MOTOR_CONTROL_BOARD_CONTROL_PIN, GPIO_PIN_RESET); 
}

/******************************************************//**
 * @brief  Set the L6208 CLOCK pin
 * @retval None
 **********************************************************/
void L6208_Board_CLOCK_PIN_Set(void)
{ 
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CLOCK_PORT, BSP_MOTOR_CONTROL_BOARD_CLOCK_PIN, GPIO_PIN_SET); 
}

/******************************************************//**
 * @brief  Reset the L6208 CLOCK pin
 * @retval None
 **********************************************************/
void L6208_Board_CLOCK_PIN_Reset(void)
{
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CLOCK_PORT, BSP_MOTOR_CONTROL_BOARD_CLOCK_PIN, GPIO_PIN_RESET); 
}

/******************************************************//**
 * @brief  Set the L6208 HALF_FULL pin
 * @retval None
 **********************************************************/
void L6208_Board_HALF_FULL_PIN_Set(void)
{ 
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_HALF_FULL_PORT, BSP_MOTOR_CONTROL_BOARD_HALF_FULL_PIN, GPIO_PIN_SET); 
}

/******************************************************//**
 * @brief  Reset the L6208 HALF_FULL pin
 * @retval None
 **********************************************************/
void L6208_Board_HALF_FULL_PIN_Reset(void)
{
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_HALF_FULL_PORT, BSP_MOTOR_CONTROL_BOARD_HALF_FULL_PIN, GPIO_PIN_RESET); 
}

/******************************************************//**
 * @brief  Set the L6208 DIR pin
 * @retval None
 **********************************************************/
void L6208_Board_DIR_PIN_Set(void)
{ 
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_PIN, GPIO_PIN_SET); 
}

/******************************************************//**
 * @brief  Reset the L6208 DIR pin
 * @retval None
 **********************************************************/
void L6208_Board_DIR_PIN_Reset(void)
{
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_PIN, GPIO_PIN_RESET); 
}

/******************************************************//**
 * @brief  Returns the FLAG pin state.
 * @retval The FLAG pin value.
 **********************************************************/
uint32_t L6208_Board_FLAG_PIN_GetState(void)
{
  return HAL_GPIO_ReadPin(BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PORT, BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PIN);
}

/******************************************************//**
 * @brief Disable the power bridges (leave the output bridges HiZ)
 * @retval None
 **********************************************************/
void L6208_Board_Disable(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  
  /* Configure the GPIO connected to EN pin as an output */
  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PORT, &GPIO_InitStruct);
  __disable_irq();
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PORT, BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PIN, GPIO_PIN_RESET);  
  __HAL_GPIO_EXTI_CLEAR_IT(BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PIN);
  __enable_irq();
}

/******************************************************//**
 * @brief Enable the power bridges (leave the output bridges HiZ)
 * @retval None
 **********************************************************/
void L6208_Board_Enable(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  
  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PORT, BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PIN, GPIO_PIN_SET);
  HAL_Delay(BRIDGE_TURN_ON_DELAY);
  /* Configure the GPIO connected to EN pin to take interrupt */
  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PORT, &GPIO_InitStruct);
  __HAL_GPIO_EXTI_CLEAR_IT(BSP_MOTOR_CONTROL_BOARD_EN_AND_FLAG_PIN);
  HAL_NVIC_ClearPendingIRQ(FLAG_EXTI_LINE_IRQn);
  HAL_NVIC_EnableIRQ(FLAG_EXTI_LINE_IRQn);  
}

/**
  * @}
  */

/**
  * @}
  */    

/**
  * @}
  */ 
    
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
