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.
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>© 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****/
Generated on Tue Jul 12 2022 22:53:31 by 1.7.2