X-CUBE-SPN1-20150128 example source code for one motor compiled under mbed. Tested OK on Nucleo F401. l6474.cpp is modified from original with defines in l6474_target_config.h to select the original behaviour (motor de-energised when halted), or new mode to continue powering with a (reduced) current in the coils (braking/position hold capability). On F401 avoid using mbed's InterruptIn on pins 10-15 (any port). Beware of other conflicts! L0 & F0 are included but untested.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f4xx_nucleo_ihm01a1.cpp Source File

stm32f4xx_nucleo_ihm01a1.cpp

00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_nucleo_ihm01a1.c
00004   * @author  IPC Rennes
00005   * @version V1.5.0
00006   * @date    November 12, 2014
00007   * @brief   BSP driver for x-nucleo-ihm01a1 Nucleo extension board 
00008   *  (based on L6474)
00009   ******************************************************************************
00010 * @attention
00011   *
00012   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
00013   *
00014   * Redistribution and use in source and binary forms, with or without modification,
00015   * are permitted provided that the following conditions are met:
00016   *   1. Redistributions of source code must retain the above copyright notice,
00017   *      this list of conditions and the following disclaimer.
00018   *   2. Redistributions in binary form must reproduce the above copyright notice,
00019   *      this list of conditions and the following disclaimer in the documentation
00020   *      and/or other materials provided with the distribution.
00021   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00022   *      may be used to endorse or promote products derived from this software
00023   *      without specific prior written permission.
00024   *
00025   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00026   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00028   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00029   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00031   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00033   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035   *
00036   ******************************************************************************
00037   */ 
00038 #ifdef TARGET_STM32F4  
00039 /* Includes ------------------------------------------------------------------*/
00040 #include "mbed.h"
00041 #include "stm32f4xx_nucleo_ihm01a1.h"
00042 
00043 /** @addtogroup BSP
00044   * @{
00045   */ 
00046 
00047 /** @defgroup STM32F4XX_NUCLEO_IHM01A1
00048   * @{
00049   */   
00050     
00051 /* Private constants ---------------------------------------------------------*/    
00052 
00053 /** @defgroup IHM01A1_Private_Constants
00054   * @{
00055   */   
00056     
00057 /// Timer Prescaler
00058 #define TIMER_PRESCALER (1024)
00059 
00060 /// SPI Maximum Timeout values for flags waiting loops
00061 #define SPIx_TIMEOUT_MAX                      ((uint32_t)0x1000)
00062 
00063 /**
00064   * @}
00065   */ 
00066 
00067 /* Private variables ---------------------------------------------------------*/
00068 
00069 /** @defgroup IHM01A1_Board_Private_Variables
00070   * @{
00071   */       
00072 /// SPI handler declaration
00073 static SPI_HandleTypeDef SpiHandle;
00074 /// Timer handler for PWM1
00075 TIM_HandleTypeDef hTimPwm1;
00076 /// Timer handler for PWM2
00077 TIM_HandleTypeDef hTimPwm2;
00078 /// Timer handler for PWM3
00079 TIM_HandleTypeDef hTimPwm3;
00080 /**
00081   * @}
00082   */ 
00083 
00084 /** @defgroup IHM01A1_Board_Private_Function_Prototypes
00085   * @{
00086   */   
00087    
00088 //mbed moved to header file
00089 
00090 /**
00091   * @}
00092   */
00093 
00094 
00095 /** @defgroup  IHM01A1_Board_Private_Functions
00096   * @{
00097   */   
00098 
00099 /******************************************************//**
00100  * @brief This function provides an accurate delay in milliseconds
00101  * @param[in] delay  time length in milliseconds
00102  * @retval None
00103  **********************************************************/
00104 void BSP_MotorControlBoard_Delay(uint32_t delay)
00105 {
00106   HAL_Delay(delay);
00107 }
00108 
00109 /******************************************************//**
00110  * @brief This function disable the interruptions
00111  * @param None
00112  * @retval None
00113  **********************************************************/
00114 void BSP_MotorControlBoard_DisableIrq(void)
00115 {
00116   __disable_irq();
00117 }
00118 
00119 /******************************************************//**
00120  * @brief This function enable the interruptions
00121  * @param None
00122  * @retval None
00123  **********************************************************/
00124 void BSP_MotorControlBoard_EnableIrq(void)
00125 {
00126   __enable_irq();
00127 }
00128 
00129 /******************************************************//**
00130  * @brief  Initiliases the GPIOs used by the L6474s
00131  * @param[in] nbDevices number of L6474 devices
00132  * @retval None
00133   **********************************************************/
00134 void BSP_MotorControlBoard_GpioInit(uint8_t nbDevices)
00135 {
00136    GPIO_InitTypeDef GPIO_InitStruct;
00137   
00138   /* GPIO Ports Clock Enable */
00139   __GPIOC_CLK_ENABLE();
00140   __GPIOA_CLK_ENABLE();
00141   __GPIOB_CLK_ENABLE();
00142 
00143   /* Configure L6474 - DIR pin for device 1 -------------------------------*/
00144   GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN;
00145   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00146   GPIO_InitStruct.Pull = GPIO_NOPULL;
00147   GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00148   HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT, &GPIO_InitStruct);
00149   
00150   /* Configure L6474 - Flag pin -------------------------------------------*/
00151   GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_FLAG_PIN;
00152   GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
00153   GPIO_InitStruct.Pull = GPIO_PULLUP;
00154   GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00155   HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_FLAG_PORT, &GPIO_InitStruct);
00156   
00157  /* Set Priority of External Line Interrupt used for the Flag interrupt*/ 
00158   HAL_NVIC_SetPriority(EXTI_MCU_LINE_IRQn, 5, 0);
00159     
00160   /* Enable the External Line Interrupt used for the Flag interrupt*/
00161   HAL_NVIC_EnableIRQ(EXTI_MCU_LINE_IRQn);    
00162 
00163   /* Configure L6474 - CS pin ---------------------------------------------*/
00164   GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_CS_PIN;
00165   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00166   GPIO_InitStruct.Pull = GPIO_NOPULL;
00167   GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00168   HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_CS_PORT, &GPIO_InitStruct);
00169   HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_SET); 
00170   
00171   /* Configure L6474 - STBY/RESET pin -------------------------------------*/
00172   GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_RESET_PIN;
00173   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00174   GPIO_InitStruct.Pull = GPIO_NOPULL;
00175   GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00176   HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, &GPIO_InitStruct);
00177   BSP_MotorControlBoard_Reset();  
00178 
00179   if (nbDevices > 1) 
00180   {
00181     /* Configure L6474 - DIR pin for device  2 ----------------------------*/
00182     GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN;
00183     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00184     GPIO_InitStruct.Pull = GPIO_NOPULL;
00185     GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00186     HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT, &GPIO_InitStruct);    
00187   }
00188   if (nbDevices > 2) 
00189   {
00190     /* Configure L6474 - DIR pin for device  3 ----------------------------*/
00191     GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN;
00192     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00193     GPIO_InitStruct.Pull = GPIO_NOPULL;
00194     GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00195     HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT, &GPIO_InitStruct);    
00196   }  
00197 }
00198 
00199 /******************************************************//**
00200  * @brief  Sets the frequency of PWM1 used by device 0
00201  * @param[in] newFreq in Hz
00202  * @retval None
00203  * @note The frequency is directly the current speed of the device
00204  **********************************************************/
00205 void BSP_MotorControlBoard_Pwm1SetFreq(uint16_t newFreq)
00206 {
00207   uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
00208   uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM1_FREQ_RESCALER * (uint32_t)newFreq)) - 1;
00209   
00210   __HAL_TIM_SetAutoreload(&hTimPwm1, period);
00211   __HAL_TIM_SetCompare(&hTimPwm1, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1, period >> 1);
00212   HAL_TIM_PWM_Start_IT(&hTimPwm1, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1);  
00213 }
00214 
00215 /******************************************************//**
00216  * @brief  Sets the frequency of PWM2 used by device 1
00217  * @param[in] newFreq in Hz
00218  * @retval None
00219  * @note The frequency is directly the current speed of the device
00220  **********************************************************/
00221 void BSP_MotorControlBoard_Pwm2SetFreq(uint16_t newFreq)
00222 {
00223   uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
00224   uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM2_FREQ_RESCALER  * (uint32_t)newFreq)) - 1;
00225   
00226   __HAL_TIM_SetAutoreload(&hTimPwm2, period);
00227   __HAL_TIM_SetCompare(&hTimPwm2, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2, period >> 1);
00228   HAL_TIM_PWM_Start_IT(&hTimPwm2, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2);
00229 }
00230 /******************************************************//**
00231  * @brief  Sets the frequency of PWM3 used by device 2
00232  * @param[in] newFreq in Hz
00233  * @retval None
00234  * @note The frequency is directly the current speed of the device
00235  **********************************************************/
00236 void BSP_MotorControlBoard_Pwm3SetFreq(uint16_t newFreq)
00237 {
00238   uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
00239   /* Double the frequency as the SW is generated by SW */
00240   uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM3_FREQ_RESCALER * (uint32_t)newFreq)) - 1;
00241   
00242   __HAL_TIM_SetAutoreload(&hTimPwm3, period);
00243   __HAL_TIM_SetCompare(&hTimPwm3, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3, period >> 1);
00244   HAL_TIM_PWM_Start_IT(&hTimPwm3, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3);  
00245 }
00246 
00247 /******************************************************//**
00248  * @brief  Initialises the PWM uses by the specified device
00249  * @param[in] deviceId (from 0 to 2)
00250  * @retval None
00251  * @note Device 0 uses PWM1 based on timer 1 
00252  * Device 1 uses PWM 2 based on timer 2
00253  * Device 2 uses PWM3 based timer 0
00254  **********************************************************/
00255 void BSP_MotorControlBoard_PwmInit(uint8_t deviceId)
00256 {
00257   TIM_OC_InitTypeDef sConfigOC;
00258   TIM_MasterConfigTypeDef sMasterConfig;
00259   TIM_HandleTypeDef *pHTim;
00260   uint32_t  channel;
00261 
00262   switch (deviceId)
00263   {
00264 
00265   case 0:
00266   default:
00267       pHTim = &hTimPwm1;
00268       pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1;
00269       channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1;
00270 
00271       break;
00272     case  1:
00273       pHTim = &hTimPwm2;
00274       pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2;
00275       channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2;
00276       break;
00277 
00278 
00279     case 2:
00280       pHTim = &hTimPwm3;
00281       pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3;
00282       channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3;
00283       break;
00284   }
00285   pHTim->Init.Prescaler = TIMER_PRESCALER -1;
00286   pHTim->Init.CounterMode = TIM_COUNTERMODE_UP;
00287   pHTim->Init.Period = 0;
00288   pHTim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
00289   HAL_TIM_PWM_Init(pHTim);
00290   
00291   sConfigOC.OCMode = TIM_OCMODE_PWM1;
00292   sConfigOC.Pulse = 0;
00293   sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
00294   sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
00295   HAL_TIM_PWM_ConfigChannel(pHTim, &sConfigOC, channel);
00296   
00297   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
00298   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
00299   HAL_TIMEx_MasterConfigSynchronization(pHTim, &sMasterConfig);
00300 }
00301 
00302 /******************************************************//**
00303  * @brief  Stops the PWM uses by the specified device
00304  * @param[in] deviceId (from 0 to 2)
00305  * @retval None
00306  **********************************************************/
00307 void BSP_MotorControlBoard_PwmStop(uint8_t deviceId)
00308 {
00309   switch (deviceId)
00310   {
00311     case 0:
00312        HAL_TIM_PWM_Stop(&hTimPwm1,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1);
00313     
00314       break;
00315     case  1:
00316       HAL_TIM_PWM_Stop(&hTimPwm2,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2);
00317       
00318       break;
00319     case 2:
00320        HAL_TIM_PWM_Stop(&hTimPwm3,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3);
00321       
00322       break;
00323     default:
00324       break;//ignore error
00325   }
00326 }
00327 
00328 /******************************************************//**
00329  * @brief  Releases the L6474 reset (pin set to High) of all devices
00330  * @param  None
00331  * @retval None
00332  **********************************************************/
00333 void BSP_MotorControlBoard_ReleaseReset(void)
00334 { 
00335   HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_SET); 
00336 }
00337 
00338 /******************************************************//**
00339  * @brief  Resets the L6474 (reset pin set to low) of all devices
00340  * @param  None
00341  * @retval None
00342  **********************************************************/
00343 void BSP_MotorControlBoard_Reset(void)
00344 {
00345   HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_RESET); 
00346 }
00347 
00348 /******************************************************//**
00349  * @brief  Set the GPIO used for the direction
00350  * @param[in] deviceId (from 0 to 2)
00351  * @param[in] gpioState state of the direction gpio (0 to reset, 1 to set)
00352  * @retval None
00353  **********************************************************/
00354 void BSP_MotorControlBoard_SetDirectionGpio(uint8_t deviceId, uint8_t gpioState)
00355 {
00356   switch (deviceId)
00357   {
00358     case 2:
00359       HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN, (GPIO_PinState)gpioState); 
00360       break;
00361     case 1:
00362       HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN, (GPIO_PinState)gpioState); 
00363       break;
00364     case 0:
00365       HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN, (GPIO_PinState)gpioState); 
00366       break;
00367     default:
00368       ;
00369   }
00370 }
00371 
00372 /******************************************************//**
00373  * @brief  Initialise the SPI used by L6474
00374  * @param None
00375  * @retval HAL_OK if SPI transaction is OK, HAL_KO else
00376  **********************************************************/
00377 uint8_t BSP_MotorControlBoard_SpiInit(void)
00378 {
00379   HAL_StatusTypeDef status;
00380   
00381   /* Initialises the SPI  --------------------------------------------------*/
00382   SpiHandle.Instance               = SPIx;
00383   SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; 
00384   SpiHandle.Init.Direction         = SPI_DIRECTION_2LINES;
00385   SpiHandle.Init.CLKPhase          = SPI_PHASE_2EDGE;    
00386   SpiHandle.Init.CLKPolarity       = SPI_POLARITY_HIGH;
00387   SpiHandle.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLED;
00388   SpiHandle.Init.CRCPolynomial     = 7;
00389   SpiHandle.Init.DataSize          = SPI_DATASIZE_8BIT;
00390   SpiHandle.Init.FirstBit          = SPI_FIRSTBIT_MSB;
00391   SpiHandle.Init.NSS               = SPI_NSS_SOFT;
00392   SpiHandle.Init.TIMode            = SPI_TIMODE_DISABLED;
00393   
00394   SpiHandle.Init.Mode = SPI_MODE_MASTER;
00395   
00396   status = HAL_SPI_Init(&SpiHandle);
00397   
00398   return (uint8_t) status;
00399 }
00400 /******************************************************//**
00401  * @brief  Write and read SPI byte to the L6474
00402  * @param[in] pByteToTransmit pointer to the byte to transmit
00403  * @param[in] pReceivedByte pointer to the received byte
00404  * @param[in] nbDevices Number of device in the SPI chain
00405  * @retval HAL_OK if SPI transaction is OK, HAL_KO else 
00406  **********************************************************/
00407 uint8_t BSP_MotorControlBoard_SpiWriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte, uint8_t nbDevices)
00408 {
00409   HAL_StatusTypeDef status;
00410   uint32_t i;
00411   HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_RESET); 
00412   for (i = 0; i < nbDevices; i++)
00413   {
00414     status = HAL_SPI_TransmitReceive(&SpiHandle, pByteToTransmit, pReceivedByte, 1, SPIx_TIMEOUT_MAX);
00415     if (status != HAL_OK)
00416     {
00417       break;
00418     }
00419     pByteToTransmit++;
00420     pReceivedByte++;
00421   }
00422   HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_SET); 
00423   
00424   return (uint8_t) status;  
00425 }
00426 
00427 /**
00428   * @}
00429   */
00430 
00431 /**
00432   * @}
00433   */    
00434 
00435 /**
00436   * @}
00437   */ 
00438 #endif    
00439 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/