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 stm32f0xx_nucleo_ihm01a1.cpp Source File

stm32f0xx_nucleo_ihm01a1.cpp

00001 /**
00002   ******************************************************************************
00003   * @file    stm32f0xx_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_STM32F0  
00039 /* Includes ------------------------------------------------------------------*/
00040 #include "mbed.h"
00041 #include "stm32f0xx_nucleo_ihm01a1.h"
00042 
00043 /** @addtogroup BSP
00044   * @{
00045   */ 
00046 
00047 /** @defgroup  STM32F0XX_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 /// imer handler for PWM2
00077 TIM_HandleTypeDef hTimPwm2;
00078 /// Timer handler for PWM3
00079 TIM_HandleTypeDef hTimPwm3;
00080 /**
00081   * @}
00082   */ 
00083 
00084 
00085 /**
00086   * @}
00087   */
00088 
00089 
00090 /** @defgroup  IHM01A1_Board_Private_Functions
00091   * @{
00092   */   
00093 
00094 /******************************************************//**
00095  * @brief This function provides an accurate delay in milliseconds
00096  * @param[in] delay  time length in milliseconds
00097   * @retval None
00098  **********************************************************/
00099 void BSP_MotorControlBoard_Delay(uint32_t delay)
00100 {
00101   HAL_Delay(delay);
00102 }
00103 
00104 /******************************************************//**
00105  * @brief This function disable the interruptions
00106  * @param None
00107  * @retval None
00108  **********************************************************/
00109 void BSP_MotorControlBoard_DisableIrq(void)
00110 {
00111   __disable_irq();
00112 }
00113 
00114 /******************************************************//**
00115  * @brief This function enable the interruptions
00116  * @param None
00117  * @retval None
00118  **********************************************************/
00119 void BSP_MotorControlBoard_EnableIrq(void)
00120 {
00121   __enable_irq();
00122 }
00123 
00124 /******************************************************//**
00125  * @brief  Initiliases the GPIOs used by the L6474s
00126  * @param[in] nbDevices number of L6474 devices
00127  * @retval None
00128   **********************************************************/
00129 void BSP_MotorControlBoard_GpioInit(uint8_t nbDevices)
00130 {
00131    GPIO_InitTypeDef GPIO_InitStruct;
00132   
00133   /* GPIO Ports Clock Enable */
00134   __GPIOC_CLK_ENABLE();
00135   __GPIOA_CLK_ENABLE();
00136   __GPIOB_CLK_ENABLE();
00137 
00138   /* Configure L6474  - DIR pin for device 1 -------------------------------*/
00139   GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN;
00140   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00141   GPIO_InitStruct.Pull = GPIO_NOPULL;
00142   GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00143   HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT, &GPIO_InitStruct);
00144   
00145   /* Configure L6474 - Flag pin -------------------------------------------*/
00146   GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_FLAG_PIN;
00147   GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
00148   GPIO_InitStruct.Pull = GPIO_PULLUP;
00149   GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00150   HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_FLAG_PORT, &GPIO_InitStruct);
00151   
00152  /* Set Priority of External Line Interrupt used for the Flag interrupt*/ 
00153   HAL_NVIC_SetPriority(EXTI_MCU_LINE_IRQn, 5, 0);
00154     
00155   /* Enable the External Line Interrupt used for the Flag interrupt*/
00156   HAL_NVIC_EnableIRQ(EXTI_MCU_LINE_IRQn);    
00157 
00158   /* Configure L6474 - CS pin ---------------------------------------------*/
00159   GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_CS_PIN;
00160   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00161   GPIO_InitStruct.Pull = GPIO_NOPULL;
00162   GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00163   HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_CS_PORT, &GPIO_InitStruct);
00164   HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_SET); 
00165   
00166   /* Configure L6474 - STBY/RESET pin -------------------------------------*/
00167   GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_RESET_PIN;
00168   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00169   GPIO_InitStruct.Pull = GPIO_NOPULL;
00170   GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00171   HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, &GPIO_InitStruct);
00172   BSP_MotorControlBoard_Reset();  
00173 
00174   if (nbDevices > 1) 
00175   {
00176     /* Configure L6474 - DIR pin for device  2 ----------------------------*/
00177     GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN;
00178     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00179     GPIO_InitStruct.Pull = GPIO_NOPULL;
00180     GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00181     HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT, &GPIO_InitStruct);    
00182   }
00183   if (nbDevices > 2) 
00184   {
00185     /* Configure L6474 - DIR pin for device  3 ----------------------------*/
00186     GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN;
00187     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00188     GPIO_InitStruct.Pull = GPIO_NOPULL;
00189     GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
00190     HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT, &GPIO_InitStruct);    
00191   }  
00192 }
00193 
00194 /******************************************************//**
00195  * @brief  Sets the frequency of PWM1 used by device 0
00196  * @param[in] newFreq in Hz
00197  * @retval None
00198  * @note The frequency is directly the current speed of the device
00199  **********************************************************/
00200 void BSP_MotorControlBoard_Pwm1SetFreq(uint16_t newFreq)
00201 {
00202   uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
00203   uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM1_FREQ_RESCALER * (uint32_t)newFreq)) - 1;
00204   
00205   __HAL_TIM_SetAutoreload(&hTimPwm1, period);
00206   __HAL_TIM_SetCompare(&hTimPwm1, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1, period >> 1);
00207   HAL_TIM_PWM_Start_IT(&hTimPwm1, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1);  
00208 }
00209 
00210 /******************************************************//**
00211  * @brief  Sets the frequency of PWM2 used by device 1
00212  * @param[in] newFreq in Hz
00213  * @retval None
00214  * @note The frequency is directly the current speed of the device
00215  **********************************************************/
00216 void BSP_MotorControlBoard_Pwm2SetFreq(uint16_t newFreq)
00217 {
00218   uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
00219   uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM2_FREQ_RESCALER  * (uint32_t)newFreq)) - 1;
00220   
00221   __HAL_TIM_SetAutoreload(&hTimPwm2, period);
00222   __HAL_TIM_SetCompare(&hTimPwm2, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2, period >> 1);
00223   HAL_TIM_PWM_Start_IT(&hTimPwm2, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2);
00224 }
00225 /******************************************************//**
00226  * @brief  Sets the frequency of PWM3 used by device 2
00227  * @param[in] newFreq in Hz
00228  * @retval None
00229  * @note The frequency is directly the current speed of the device
00230  **********************************************************/
00231 void BSP_MotorControlBoard_Pwm3SetFreq(uint16_t newFreq)
00232 {
00233   uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
00234   /* Double the frequency as the SW is generated by SW */
00235   uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM3_FREQ_RESCALER * (uint32_t)newFreq)) - 1;
00236   
00237   __HAL_TIM_SetAutoreload(&hTimPwm3, period);
00238   __HAL_TIM_SetCompare(&hTimPwm3, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3, period >> 1);
00239   HAL_TIM_PWM_Start_IT(&hTimPwm3, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3);  
00240 }
00241 
00242 /******************************************************//**
00243  * @brief  Initialises the PWM uses by the specified device
00244  * @param[in] deviceId (from 0 to 2)
00245  * @retval None
00246  * @note Device 0 uses PWM1 based on timer 1 
00247  * Device 1 uses PWM 2 based on timer 2
00248  * Device 2 uses PWM3 based timer 0
00249  **********************************************************/
00250 void BSP_MotorControlBoard_PwmInit(uint8_t deviceId)
00251 {
00252   TIM_OC_InitTypeDef sConfigOC;
00253   TIM_MasterConfigTypeDef sMasterConfig;
00254   TIM_HandleTypeDef *pHTim;
00255   uint32_t  channel;
00256 
00257   switch (deviceId)
00258   {
00259 
00260   case 0:
00261   default:
00262       pHTim = &hTimPwm1;
00263       pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1;
00264       channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1;
00265 
00266       break;
00267     case  1:
00268       pHTim = &hTimPwm2;
00269       pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2;
00270       channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2;
00271       break;
00272 
00273 
00274     case 2:
00275       pHTim = &hTimPwm3;
00276       pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3;
00277       channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3;
00278       break;
00279   }
00280   pHTim->Init.Prescaler = TIMER_PRESCALER -1;
00281   pHTim->Init.CounterMode = TIM_COUNTERMODE_UP;
00282   pHTim->Init.Period = 0;
00283   pHTim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
00284   HAL_TIM_PWM_Init(pHTim);
00285   
00286   sConfigOC.OCMode = TIM_OCMODE_PWM1;
00287   sConfigOC.Pulse = 0;
00288   sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
00289   sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
00290   HAL_TIM_PWM_ConfigChannel(pHTim, &sConfigOC, channel);
00291   
00292   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
00293   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
00294   HAL_TIMEx_MasterConfigSynchronization(pHTim, &sMasterConfig);
00295 }
00296 
00297 /******************************************************//**
00298  * @brief  Stops the PWM uses by the specified device
00299  * @param[in] deviceId (from 0 to 2)
00300  * @retval None
00301  **********************************************************/
00302 void BSP_MotorControlBoard_PwmStop(uint8_t deviceId)
00303 {
00304   switch (deviceId)
00305   {
00306     case 0:
00307        HAL_TIM_PWM_Stop(&hTimPwm1,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1);
00308     
00309       break;
00310     case  1:
00311       HAL_TIM_PWM_Stop(&hTimPwm2,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2);
00312       
00313       break;
00314     case 2:
00315        HAL_TIM_PWM_Stop(&hTimPwm3,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3);
00316       
00317       break;
00318     default:
00319       break;//ignore error
00320   }
00321 }
00322 
00323 /******************************************************//**
00324  * @brief  Releases the L6474 reset (pin set to High) of all devices
00325  * @param  None
00326  * @retval None
00327  **********************************************************/
00328 void BSP_MotorControlBoard_ReleaseReset(void)
00329 { 
00330   HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_SET); 
00331 }
00332 
00333 /******************************************************//**
00334  * @brief  Resets the L6474 (reset pin set to low) of all devices
00335  * @param  None
00336  * @retval None
00337  **********************************************************/
00338 void BSP_MotorControlBoard_Reset(void)
00339 {
00340   HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_RESET); 
00341 }
00342 
00343 /******************************************************//**
00344  * @brief  Set the GPIO used for the direction
00345  * @param[in] deviceId (from 0 to 2)
00346  * @param[in] gpioState state of the direction gpio (0 to reset, 1 to set)
00347  * @retval None
00348  **********************************************************/
00349 void BSP_MotorControlBoard_SetDirectionGpio(uint8_t deviceId, uint8_t gpioState)
00350 {
00351   switch (deviceId)
00352   {
00353     case 2:
00354       HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN, (GPIO_PinState)gpioState); 
00355       break;
00356     case 1:
00357       HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN, (GPIO_PinState)gpioState); 
00358       break;
00359     case 0:
00360       HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN, (GPIO_PinState)gpioState); 
00361       break;
00362     default:
00363       ;
00364   }
00365 }
00366 
00367 /******************************************************//**
00368  * @brief  Initialise the SPI used by L6474
00369  * @param None
00370  * @retval HAL_OK if SPI transaction is OK, HAL_KO else
00371  **********************************************************/
00372 uint8_t BSP_MotorControlBoard_SpiInit(void)
00373 {
00374   HAL_StatusTypeDef status;
00375   
00376   /* Initialises the SPI  --------------------------------------------------*/
00377   SpiHandle.Instance               = SPIx;
00378   SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; 
00379   SpiHandle.Init.Direction         = SPI_DIRECTION_2LINES;
00380   SpiHandle.Init.CLKPhase          = SPI_PHASE_2EDGE;    
00381   SpiHandle.Init.CLKPolarity       = SPI_POLARITY_HIGH;
00382   SpiHandle.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLED;
00383   SpiHandle.Init.CRCPolynomial     = 7;
00384   SpiHandle.Init.DataSize          = SPI_DATASIZE_8BIT;
00385   SpiHandle.Init.FirstBit          = SPI_FIRSTBIT_MSB;
00386   SpiHandle.Init.NSS               = SPI_NSS_SOFT;
00387   SpiHandle.Init.TIMode            = SPI_TIMODE_DISABLED;
00388   
00389   SpiHandle.Init.Mode = SPI_MODE_MASTER;
00390   
00391   status = HAL_SPI_Init(&SpiHandle);
00392   
00393   return (uint8_t) status;
00394 }
00395 /******************************************************//**
00396  * @brief  Write and read SPI byte to the L6474
00397  * @param[in] pByteToTransmit pointer to the byte to transmit
00398  * @param[in] pReceivedByte pointer to the received byte
00399  * @param[in] nbDevices Number of device in the SPI chain
00400  * @retval HAL_OK if SPI transaction is OK, HAL_KO else 
00401  **********************************************************/
00402 uint8_t BSP_MotorControlBoard_SpiWriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte, uint8_t nbDevices)
00403 {
00404   HAL_StatusTypeDef status;
00405   uint32_t i;
00406   HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_RESET); 
00407   for (i = 0; i < nbDevices; i++)
00408   {
00409     status = HAL_SPI_TransmitReceive(&SpiHandle, pByteToTransmit, pReceivedByte, 1, SPIx_TIMEOUT_MAX);
00410     if (status != HAL_OK)
00411     {
00412       break;
00413     }
00414     pByteToTransmit++;
00415     pReceivedByte++;
00416   }
00417   HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_SET); 
00418   
00419   return (uint8_t) status;  
00420 }
00421 
00422 /**
00423   * @}
00424   */
00425 
00426 /**
00427   * @}
00428   */    
00429 
00430 /**
00431   * @}
00432   */ 
00433 #endif    
00434 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/