Expansion SW library to control a bipolar stepper motor using X-NUCLEO-IHM05A1 expansion board based on L6208.
Dependencies: ST_INTERFACES
Dependents: HelloWorld_IHM05A1 TAU_ROTATING_PLATFORM_IHM05A1 Amaldi_13_Exercise_IHM05A1 Amaldi_13_Exercise_IHM05A1motore ... more
Fork of X-NUCLEO-IHM05A1 by
L6208.cpp
00001 /** 00002 ****************************************************************************** 00003 * @file L6208.cpp 00004 * @author IPC Rennes 00005 * @version V1.1.0 00006 * @date February 11th, 2016 00007 * @brief L6208 product related routines 00008 * @note (C) COPYRIGHT 2016 STMicroelectronics 00009 ****************************************************************************** 00010 * @attention 00011 * 00012 * <h2><center>© COPYRIGHT(c) 2016 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 00039 /* Includes ------------------------------------------------------------------*/ 00040 #include "L6208.h" 00041 00042 /* Definitions ---------------------------------------------------------------*/ 00043 /// Bridge A 00044 #define BRIDGE_A (0) 00045 /// Bridge B 00046 #define BRIDGE_B (1) 00047 00048 /// Bitmaps for system flags 00049 #define EN_A_set 0x00000001 ///< EN_A pin status 00050 #define HiZstop 0x00000002 ///< motor has to be left in HiZ after stopping 00051 #define busy 0x00000004 ///< stepper position command executing flag 00052 #define running 0x00000008 ///< running motor flag 00053 #define velocitymode 0x00000010 ///< velocity controlled stepper motor 00054 #define positionmode 0x00000020 ///< position controlled stepper motor 00055 #define fullstep 0x00000040 ///< full step mode controlled 00056 #define halfstep 0x00000080 ///< half step mode controlled 00057 #define microstep 0x00000100 ///< micro step mode controlled 00058 #define forward 0x00000200 ///< forward running motor 00059 #define dir2change 0x00000400 ///< direction has to be changed while the motor is running 00060 #define fastdecaymode 0x00000800 ///< decay mode is fast 00061 #define wavestep 0x00001000 ///< wave step mode controlled 00062 00063 /* Variables ----------------------------------------------------------------*/ 00064 /* Number of devices. */ 00065 uint8_t L6208::numberOfDevices = 0; 00066 00067 /// RefMicroTable values are 2^L6208_SINE_WAVEFORM_POWER_OF_TWO_MAX_VALUE*|sin(n/16*PI/2)| 00068 /// where n is the index in the table 00069 const uint16_t L6208::RefMicroTable[L6208_USTEPS_PER_QUARTER_PERIOD*3] = 00070 { 00071 0,3212,6393,9512,12540,15447,18205,20788,23170,25330,27246,28899,30274,31357,32138,32610, 00072 32768,32610,32138,31357,30274,28899,27246,25330,23170,20788,18205,15447,12540,9512,6393,3212, 00073 0,3212,6393,9512,12540,15447,18205,20788,23170,25330,27246,28899,30274,31357,32138,32610 00074 }; 00075 00076 /* Methods -------------------------------------------------------------------*/ 00077 /******************************************************//** 00078 * @brief Start the L6208 library 00079 * @param[in] pInit pointer to the initialization data 00080 * @retval COMPONENT_OK in case of success. 00081 **********************************************************/ 00082 status_t L6208::L6208_Init(void* pInit) 00083 { 00084 if (pInit == NULL) 00085 { 00086 /* Set context variables to the predefined values from l6208_target_config.h */ 00087 /* Set GPIO according to these values */ 00088 L6208_SetDeviceParamsToPredefinedValues(); 00089 } 00090 else 00091 { 00092 L6208_SetDeviceParamsToGivenValues((l6208_init_t*) pInit); 00093 } 00094 00095 /* Initialise the PWMs */ 00096 L6208_Board_VrefPwmInit(BRIDGE_A, devicePrm.vrefPwmPeriod); 00097 L6208_Board_VrefPwmInit(BRIDGE_B, devicePrm.vrefPwmPeriod); 00098 00099 /* Initialise the tick */ 00100 L6208_Board_TickInit(); 00101 00102 /* Reset L6208 */ 00103 L6208_ResetDevice(); 00104 00105 /* Align motor mechanical position to driver position */ 00106 L6208_Board_VrefPwmStart(BRIDGE_A, devicePrm.vrefPwmPeriod); 00107 L6208_Board_VrefPwmStart(BRIDGE_B, devicePrm.vrefPwmPeriod); 00108 //L6208_Enable(); 00109 00110 return COMPONENT_OK; 00111 } 00112 00113 /********************************************************** 00114 * @brief Read id 00115 * @param id pointer to the identifier to be read. 00116 * @retval COMPONENT_OK in case of success. 00117 **********************************************************/ 00118 status_t L6208::L6208_ReadID(uint8_t *id) 00119 { 00120 *id = deviceInstance; 00121 00122 return COMPONENT_OK; 00123 } 00124 00125 /********************************************************** 00126 * @brief Attaches a user callback to the error Handler. 00127 * The call back will be then called each time the library 00128 * detects an error 00129 * @param[in] callback Name of the callback to attach 00130 * to the error Hanlder 00131 * @retval None 00132 **********************************************************/ 00133 void L6208::L6208_AttachErrorHandler(void (*callback)(uint16_t error)) 00134 { 00135 errorHandlerCallback = (void (*)(uint16_t error)) callback; 00136 } 00137 00138 /******************************************************//** 00139 * @brief Disable the power bridges (leave the output bridges HiZ) 00140 * @retval None 00141 **********************************************************/ 00142 void L6208::L6208_Disable(void) 00143 { 00144 L6208_Board_Disable(); 00145 L6208_ClearSysFlag(EN_A_set); 00146 } 00147 00148 /******************************************************//** 00149 * @brief Error handler which calls the user callback (if defined) 00150 * @param[in] error Number of the error 00151 * @retval None 00152 **********************************************************/ 00153 void L6208::L6208_ErrorHandler(uint16_t error) 00154 { 00155 if (errorHandlerCallback != 0) 00156 { 00157 errorHandlerCallback(error); 00158 } 00159 else 00160 { 00161 while(1) 00162 { 00163 /* Infinite loop */ 00164 } 00165 } 00166 } 00167 00168 /******************************************************//** 00169 * @brief Enable the power bridges 00170 * @retval None 00171 **********************************************************/ 00172 void L6208::L6208_Enable(void) 00173 { 00174 L6208_Board_Enable(); 00175 L6208_SetSysFlag(EN_A_set); 00176 } 00177 00178 /******************************************************//** 00179 * @brief Get the stepper acceleration rate 00180 * in step/s^2 for full, half and wave modes 00181 * in microsteps/s^2 for microstep modes 00182 * @retval the stepper acceleration rate in step/s^2 or microstep/s^2 00183 * @note 00184 **********************************************************/ 00185 uint16_t L6208::L6208_GetAcceleration(void) 00186 { 00187 return devicePrm.accelerationSps2; 00188 } 00189 00190 /******************************************************//** 00191 * @brief Get the current speed 00192 * in step/s for full, half and wave modes 00193 * in microsteps/s for microstep modes 00194 * @retval return the current speed in step/s or microstep/s 00195 * @note 00196 **********************************************************/ 00197 uint16_t L6208::L6208_GetCurrentSpeed(void) 00198 { 00199 uint64_t tmp64 = (uint64_t) devicePrm.speedSpt * L6208_Board_TickGetFreq(); 00200 00201 devicePrm.speedSps = (uint16_t)(tmp64 >> 23); 00202 if (devicePrm.speedSps & 0x1) 00203 { 00204 devicePrm.speedSps = (devicePrm.speedSps >> 1) + 1; 00205 } 00206 else 00207 { 00208 devicePrm.speedSps = devicePrm.speedSps >> 1; 00209 } 00210 return devicePrm.speedSps; 00211 } 00212 00213 /******************************************************//** 00214 * @brief Get the motor decay mode 00215 * @retval decay mode 00216 **********************************************************/ 00217 motorDecayMode_t L6208::L6208_get_decay_mode(void) 00218 { 00219 if (L6208_IsSysFlag(fastdecaymode)) 00220 { 00221 return (FAST_DECAY); 00222 } 00223 else 00224 { 00225 return (SLOW_DECAY); 00226 } 00227 } 00228 00229 /******************************************************//** 00230 * @brief Get the stepper deceleration rate 00231 * in step/s^2 for full, half and wave modes 00232 * in microsteps/s^2 for microstep modes 00233 * @retval the stepper deceleration rate in step/s^2 or microstep/s^2 00234 * @note 00235 **********************************************************/ 00236 uint16_t L6208::L6208_GetDeceleration(void) 00237 { 00238 return devicePrm.decelerationSps2; 00239 } 00240 00241 /******************************************************//** 00242 * @brief Get the motor current direction 00243 * @retval direction 00244 **********************************************************/ 00245 motorDir_t L6208::L6208_GetDirection(void) 00246 { 00247 if (L6208_IsSysFlag(forward)) 00248 { 00249 return FORWARD; 00250 } 00251 else 00252 { 00253 return BACKWARD; 00254 } 00255 } 00256 00257 /******************************************************//** 00258 * @brief Return the FW version. 00259 * @retval FW version 00260 **********************************************************/ 00261 uint32_t L6208::L6208_GetFwVersion(void) 00262 { 00263 return L6208_FW_VERSION; 00264 } 00265 00266 /******************************************************//** 00267 * @brief Get the mark position (32b signed) 00268 * @retval mark position 00269 **********************************************************/ 00270 int32_t L6208::L6208_GetMark(void) 00271 { 00272 return devicePrm.markPos; 00273 } 00274 00275 /******************************************************//** 00276 * @brief Get the max speed 00277 * in step/s for full, half and wave modes 00278 * in microsteps/s for microstep modes 00279 * @retval return the max speed in step/s or microstep/s 00280 * @note 00281 **********************************************************/ 00282 uint16_t L6208::L6208_GetMaxSpeed(void) 00283 { 00284 return devicePrm.maxSpeedSps; 00285 } 00286 00287 /******************************************************//** 00288 * @brief Get the min speed 00289 * in step/s for full, half and wave modes 00290 * in microsteps/s for microstep modes 00291 * @retval return the min speed in step/s or microstep/s 00292 * @note 00293 **********************************************************/ 00294 uint16_t L6208::L6208_GetMinSpeed(void) 00295 { 00296 return devicePrm.minSpeedSps; 00297 } 00298 00299 /******************************************************//** 00300 * @brief Get the stepper state machine index 00301 * @retval one of the stepper state machine index in the motorState_t enum 00302 **********************************************************/ 00303 motorState_t L6208::L6208_GetMotionState(void) 00304 { 00305 // gets the new stepper state machine index 00306 return devicePrm.motionState; 00307 } 00308 00309 /******************************************************//** 00310 * @brief Get the current position (32b signed) 00311 * @retval current absoulte position 00312 **********************************************************/ 00313 int32_t L6208::L6208_GetPosition(void) 00314 { 00315 return devicePrm.absolutePos; 00316 } 00317 00318 /******************************************************//** 00319 * @brief Get the motor step mode 00320 * @retval step mode 00321 **********************************************************/ 00322 motorStepMode_t L6208::L6208_GetStepMode(void) 00323 { 00324 return devicePrm.stepMode; 00325 } 00326 00327 /******************************************************//** 00328 * @brief Get the selected stop mode 00329 * @retval the selected stop mode 00330 **********************************************************/ 00331 motorStopMode_t L6208::L6208_GetStopMode(void) 00332 { 00333 if (L6208_IsSysFlag(HiZstop) == FALSE) 00334 { 00335 return (HOLD_MODE); 00336 } 00337 else 00338 { 00339 return (HIZ_MODE); 00340 } 00341 } 00342 00343 /******************************************************//** 00344 * @brief Go to the home position 00345 * @retval None 00346 **********************************************************/ 00347 void L6208::L6208_GoHome(void) 00348 { 00349 L6208_GoTo(0); 00350 } 00351 00352 /******************************************************//** 00353 * @brief Go to the Mark position 00354 * @retval None 00355 **********************************************************/ 00356 void L6208::L6208_GoMark(void) 00357 { 00358 L6208_GoTo(devicePrm.markPos); 00359 } 00360 00361 /******************************************************//** 00362 * @brief move the motor to the absolute position using the shortest path 00363 * @param[in] abs_pos 32 bit signed value position 00364 * @retval None 00365 * @note The position is at the resolution corresponding to the 00366 * selected step mode. 00367 * STEP_MODE_FULL or STEP_MODE_WAVE : step 00368 * STEP_MODE_HALF : 1/2 step 00369 * STEP_MODE_1_4 : 1/4 step 00370 * STEP_MODE_1_8 : 1/8 step 00371 * STEP_MODE_1_16 : 1/16 step 00372 **********************************************************/ 00373 void L6208::L6208_GoTo(int32_t abs_pos) 00374 { 00375 uint32_t steps = 0; 00376 00377 if(L6208_IsSysFlag(running)) 00378 { 00379 L6208_HardStop(); 00380 } 00381 00382 if (abs_pos > devicePrm.absolutePos) 00383 { 00384 steps = abs_pos - devicePrm.absolutePos; 00385 if (steps < (L6208_POSITION_RANGE>>1)) 00386 { 00387 L6208_Move(FORWARD, steps); 00388 } 00389 else 00390 { 00391 L6208_Move(BACKWARD, (L6208_POSITION_RANGE - steps)); 00392 } 00393 } 00394 else 00395 { 00396 steps = devicePrm.absolutePos - abs_pos; 00397 if (steps < (L6208_POSITION_RANGE>>1)) 00398 { 00399 L6208_Move(BACKWARD, steps); 00400 } 00401 else 00402 { 00403 L6208_Move(FORWARD, (L6208_POSITION_RANGE - steps)); 00404 } 00405 } 00406 } 00407 00408 /******************************************************//** 00409 * @brief move the motor to the absolute position 00410 * @param[in] direction FORWARD or BACKWARD 00411 * @param[in] abs_pos 32 bit signed value position 00412 * @retval None 00413 * @note The position is at the resolution corresponding to the 00414 * selected step mode. 00415 * STEP_MODE_FULL or STEP_MODE_WAVE : step 00416 * STEP_MODE_HALF : 1/2 step 00417 * STEP_MODE_1_4 : 1/4 step 00418 * STEP_MODE_1_8 : 1/8 step 00419 * STEP_MODE_1_16 : 1/16 step 00420 **********************************************************/ 00421 void L6208::L6208_GoToDir(motorDir_t direction, int32_t abs_pos) 00422 { 00423 uint32_t steps = 0; 00424 00425 if(L6208_IsSysFlag(running)) 00426 { 00427 L6208_HardStop(); 00428 } 00429 00430 if (direction != BACKWARD) 00431 { 00432 if (abs_pos > devicePrm.absolutePos) 00433 { 00434 steps = abs_pos - devicePrm.absolutePos; 00435 } 00436 else 00437 { 00438 steps = L6208_POSITION_RANGE + (abs_pos - devicePrm.absolutePos); 00439 } 00440 } 00441 else 00442 { 00443 if (abs_pos > devicePrm.absolutePos) 00444 { 00445 steps = L6208_POSITION_RANGE + (devicePrm.absolutePos - abs_pos); 00446 } 00447 else 00448 { 00449 steps = devicePrm.absolutePos - abs_pos; 00450 } 00451 } 00452 L6208_Move(direction, steps); 00453 } 00454 00455 /******************************************************//** 00456 * @brief Immediately stop the motor and disables the power bridges 00457 * @retval None 00458 **********************************************************/ 00459 void L6208::L6208_HardHiZ(void) 00460 { 00461 /* Disables power stage */ 00462 L6208_Disable(); 00463 00464 /* Sets inactive state */ 00465 L6208_SetMotionState(INACTIVE); 00466 00467 /* Clears the running motor and the position */ 00468 L6208_ClearSysFlag(running); 00469 00470 /* Disables PWMs */ 00471 L6208_Board_VrefPwmStop(BRIDGE_A); 00472 L6208_Board_VrefPwmStop(BRIDGE_B); 00473 00474 /* Disables tick timer */ 00475 L6208_Board_TickStop(); 00476 } 00477 00478 /******************************************************//** 00479 * @brief Immediately stop the motor and keeps holding torque 00480 * @retval None 00481 **********************************************************/ 00482 void L6208::L6208_HardStop(void) 00483 { 00484 /* Sets inactive state */ 00485 L6208_SetMotionState(INACTIVE); 00486 00487 /* Clears the running motor and the position */ 00488 L6208_ClearSysFlag(running); 00489 L6208_VectorCalc(devicePrm.holdTorque); 00490 00491 /* Disables tick timer */ 00492 L6208_Board_TickStop(); 00493 } 00494 00495 /******************************************************//** 00496 * @brief move the motor by the specified number of steps 00497 * in the specified direction 00498 * @param[in] direction FORWARD or BACKWARD 00499 * @param[in] stepCount 32 bit unsigned step count 00500 * @retval None 00501 * @note The step count resolution is corresponding to the 00502 * selected step mode. 00503 * STEP_MODE_FULL or STEP_MODE_WAVE : step 00504 * STEP_MODE_HALF : 1/2 step 00505 * STEP_MODE_1_4 : 1/4 step 00506 * STEP_MODE_1_8 : 1/8 step 00507 * STEP_MODE_1_16 : 1/16 step 00508 **********************************************************/ 00509 void L6208::L6208_Move(motorDir_t direction, uint32_t stepCount) 00510 { 00511 if(L6208_IsSysFlag(running)) 00512 { 00513 L6208_HardStop(); 00514 } 00515 00516 /* clear the velocity driving mode flag */ 00517 L6208_ClearSysFlag(velocitymode); 00518 00519 /* Set the indexing driving mode flag */ 00520 /* and the user command executing flag */ 00521 L6208_SetSysFlag(positionmode); 00522 00523 /* store relative number of steps to move */ 00524 devicePrm.positionTarget = stepCount; 00525 00526 L6208_SetDirection(direction); 00527 00528 /* Motor activation */ 00529 L6208_StartMovement(); 00530 } 00531 00532 /******************************************************//** 00533 * @brief Release the L6208 reset (Reset pin set to high level) 00534 * @retval None 00535 **********************************************************/ 00536 void L6208::L6208_ReleaseReset(void) 00537 { 00538 L6208_Board_ReleaseReset(); 00539 } 00540 00541 /******************************************************//** 00542 * @brief Reset the L6208 (Reset pin set to low level) 00543 * @retval None 00544 **********************************************************/ 00545 void L6208::L6208_Reset(void) 00546 { 00547 L6208_Board_Reset(); 00548 } 00549 00550 00551 /******************************************************//** 00552 * @brief Call L6208_SetStepMode with current step mode, 00553 * the L6208_SetStepMode function along with setting the step mode resets 00554 * the L6208 device 00555 * @retval None 00556 **********************************************************/ 00557 void L6208::L6208_ResetDevice(void) 00558 { 00559 L6208_SetStepMode(L6208_GetStepMode()); 00560 } 00561 00562 /******************************************************//** 00563 * @brief run the motor in the specified direction 00564 * according to the speed profile defined by the minimum speed, 00565 * maximum speed, and acceleration parameters. 00566 * The device accelerates from the minimum speed up to the maximum 00567 * speed by using the device acceleration. 00568 * @param[in] direction FORWARD or BACKWARD 00569 * @retval None 00570 **********************************************************/ 00571 void L6208::L6208_Run(motorDir_t direction) 00572 { 00573 if(L6208_IsSysFlag(running)) 00574 { 00575 L6208_HardStop(); 00576 } 00577 L6208_SetDirection(direction); 00578 /* Clear the indexing driving mode flag */ 00579 L6208_ClearSysFlag(positionmode); 00580 /* Set the velocity driving mode flag */ 00581 L6208_SetSysFlag(velocitymode); 00582 /* Motor activation */ 00583 L6208_StartMovement(); 00584 } 00585 00586 /******************************************************//** 00587 * @brief Set the stepper acceleration rate 00588 * in step/s^2 and step/tick^2 for full, half and wave modes 00589 * in microsteps/s^2 and microsteps/tick^2 for microstep modes 00590 * @param[in] newAcc new acceleration rate in step/s^2 or microstep/s^2 00591 * @retval TRUE 00592 * @note 00593 **********************************************************/ 00594 bool L6208::L6208_SetAcceleration(uint16_t newAcc) 00595 { 00596 uint16_t newAccSpt2 = L6208_ConvertAcceDecelRateValue(newAcc); 00597 if (newAccSpt2) 00598 { 00599 devicePrm.accelerationSps2 = newAcc; 00600 devicePrm.accelerationSpt2 = newAccSpt2; 00601 } 00602 else 00603 { 00604 L6208_ErrorHandler(L6208_ERROR_SET_ACCELERATION); 00605 } 00606 return TRUE; 00607 } 00608 00609 /******************************************************//** 00610 * @brief Select the motor decay mode 00611 * @param[in] decayMode (SLOW_DECAY or FAST_DECAY) 00612 * @retval None 00613 **********************************************************/ 00614 void L6208::L6208_SetDecayMode(motorDecayMode_t decayMode) 00615 { 00616 if ((decayMode & L6208_FAST_DECAY_MODE_MASK) == L6208_FAST_DECAY_MODE_MASK) 00617 { 00618 L6208_Board_CONTROL_PIN_Set(); 00619 L6208_SetSysFlag(fastdecaymode); 00620 } 00621 else 00622 { 00623 L6208_Board_CONTROL_PIN_Reset(); 00624 L6208_ClearSysFlag(fastdecaymode); 00625 } 00626 } 00627 00628 /******************************************************//** 00629 * @brief Set the stepper deceleration rate 00630 * in step/s^2 and step/tick^2 for full, half and wave modes 00631 * in microsteps/s^2 and microsteps/tick^2 for microstep modes 00632 * @param[in] newDec new deceleration rate in step/s^2 or microstep/s^2 00633 * @retval TRUE 00634 * @note 00635 **********************************************************/ 00636 bool L6208::L6208_SetDeceleration(uint16_t newDec) 00637 { 00638 uint16_t newDecSpt2 = L6208_ConvertAcceDecelRateValue(newDec); 00639 if (newDecSpt2) 00640 { 00641 devicePrm.decelerationSps2 = newDec; 00642 devicePrm.decelerationSpt2 = newDecSpt2; 00643 } 00644 else 00645 { 00646 L6208_ErrorHandler(L6208_ERROR_SET_DECELERATION); 00647 } 00648 return TRUE; 00649 } 00650 00651 /******************************************************//** 00652 * @brief Specify the direction 00653 * @param[in] dir FORWARD or BACKWARD 00654 * @note In velocity mode a direction change forces the device to stop and 00655 * then run in the new direction. In position mode, if the device is 00656 * running, a direction change will generate an error. 00657 * @retval None 00658 **********************************************************/ 00659 void L6208::L6208_SetDirection(motorDir_t dir) 00660 { 00661 L6208_ClearSysFlag(dir2change); 00662 if (dir == FORWARD) 00663 { 00664 if (!L6208_IsSysFlag(forward)) 00665 { 00666 if (L6208_IsSysFlag(running)) 00667 { 00668 /* motor is running */ 00669 if (L6208_IsSysFlag(positionmode)) 00670 { 00671 L6208_ErrorHandler(L6208_ERROR_SET_DIRECTION); 00672 } 00673 else 00674 { 00675 /* set the rotation direction to change flag */ 00676 L6208_SetSysFlag(dir2change); 00677 } 00678 } 00679 else /* the motor is stopped, cw direction selected */ 00680 { 00681 L6208_SetSysFlag(forward); 00682 L6208_Board_DIR_PIN_Set(); 00683 } 00684 } 00685 } 00686 else 00687 { 00688 if (L6208_IsSysFlag(forward)) 00689 { 00690 if (L6208_IsSysFlag(running)) 00691 { 00692 /* motor is running */ 00693 if (L6208_IsSysFlag(positionmode)) 00694 { 00695 L6208_ErrorHandler(L6208_ERROR_SET_DIRECTION); 00696 } 00697 else 00698 { 00699 /* set the rotation direction to change flag */ 00700 L6208_SetSysFlag(dir2change); 00701 } 00702 } 00703 else /* the motor is stopped, ccw direction selected */ 00704 { 00705 L6208_ClearSysFlag(forward); 00706 L6208_Board_DIR_PIN_Reset(); 00707 } 00708 } 00709 } 00710 if(L6208_IsSysFlag(dir2change)) 00711 { 00712 L6208_VectorCalc(devicePrm.decelTorque); 00713 L6208_SetMotionState(DECELERATINGTOSTOP); 00714 } 00715 } 00716 00717 /******************************************************//** 00718 * @brief Set current position to be the home position 00719 * @retval None 00720 **********************************************************/ 00721 void L6208::L6208_SetHome(void) 00722 { 00723 if (!L6208_IsSysFlag(running)) 00724 { 00725 devicePrm.absolutePos = 0; 00726 } 00727 else 00728 { 00729 L6208_ErrorHandler(L6208_ERROR_SET_HOME); 00730 } 00731 } 00732 00733 /******************************************************//** 00734 * @brief Set current position to be the mark position 00735 * @retval None 00736 **********************************************************/ 00737 void L6208::L6208_SetMark(void) 00738 { 00739 devicePrm.markPos = devicePrm.absolutePos; 00740 } 00741 00742 /******************************************************//** 00743 * @brief Set the user selected maximum speed 00744 * in step/s and step/tick for full, half and wave modes 00745 * in microsteps/s and microsteps/tick for microstep modes 00746 * @param[in] newSpeed speed value (step/s or microstep/s) 00747 * @retval TRUE 00748 * @note One microstep is 1/16 step 00749 **********************************************************/ 00750 bool L6208::L6208_SetMaxSpeed(uint16_t newSpeed) 00751 { 00752 if (L6208_SetSpeed(newSpeed, &devicePrm.maxSpeedSpt)) 00753 { 00754 devicePrm.maxSpeedSps = newSpeed; 00755 } 00756 else 00757 { 00758 L6208_ErrorHandler(L6208_ERROR_SET_MAX_SPEED); 00759 } 00760 return TRUE; 00761 } 00762 00763 /******************************************************//** 00764 * @brief Set the user selected minimum speed 00765 * in step/s and step/tick for full, half and wave modes 00766 * in microsteps/s and microsteps/tick for microstep modes 00767 * @param[in] newSpeed speed value (step/s or microstep/s) 00768 * @retval TRUE 00769 * @note One microstep is 1/16 step 00770 **********************************************************/ 00771 bool L6208::L6208_SetMinSpeed(uint16_t newSpeed) 00772 { 00773 if (L6208_SetSpeed(newSpeed, &devicePrm.minSpeedSpt)) 00774 { 00775 devicePrm.minSpeedSps = newSpeed; 00776 } 00777 else 00778 { 00779 L6208_ErrorHandler(L6208_ERROR_SET_MIN_SPEED); 00780 } 00781 return TRUE; 00782 } 00783 00784 /******************************************************//** 00785 * @brief Set the step mode 00786 * @param[in] stepMode 00787 * @retval true if the command is successfully executed, else false 00788 * @note Every time the step mode is changed, the step state machine is reset 00789 **********************************************************/ 00790 bool L6208::L6208_SetStepMode(motorStepMode_t stepMode) 00791 { 00792 devicePrm.stepMode = stepMode; 00793 L6208_ClearSysFlag(fullstep | halfstep | microstep | wavestep); 00794 switch (stepMode) 00795 { 00796 case STEP_MODE_HALF: 00797 /* Set the Half/Full pin low and Reset and the set the Half/Full pin high*/ 00798 L6208_Board_HALF_FULL_PIN_Reset(); 00799 L6208_Board_Reset(); 00800 L6208_Board_HALF_FULL_PIN_Set(); 00801 /* Set system flag */ 00802 L6208_SetSysFlag(halfstep); 00803 break; 00804 case STEP_MODE_FULL: 00805 /* Set the Half/Full pin low and Reset */ 00806 L6208_Board_HALF_FULL_PIN_Reset(); 00807 L6208_Board_Reset(); 00808 /* Set system flag */ 00809 L6208_SetSysFlag(fullstep); 00810 break; 00811 case STEP_MODE_WAVE: 00812 /* Set the Half/Full pin low and Reset and the set the Half/Full pin high*/ 00813 L6208_Board_CLOCK_PIN_Reset(); 00814 L6208_Board_HALF_FULL_PIN_Reset(); 00815 L6208_Board_Reset(); 00816 L6208_Board_CLOCK_PIN_Set(); 00817 L6208_Board_HALF_FULL_PIN_Set(); 00818 L6208_Board_Delay(2); 00819 L6208_Board_CLOCK_PIN_Reset(); 00820 L6208_Board_Delay(2); 00821 L6208_Board_HALF_FULL_PIN_Reset(); 00822 /* Set system flag */ 00823 L6208_SetSysFlag(wavestep); 00824 break; 00825 case STEP_MODE_1_4: 00826 /* Set the Half/Full pin low and Reset */ 00827 L6208_Board_HALF_FULL_PIN_Reset(); 00828 L6208_Board_Reset(); 00829 /* Set system flag */ 00830 L6208_SetSysFlag(microstep); 00831 devicePrm.uStepInc = 4; 00832 break; 00833 case STEP_MODE_1_8: 00834 /* Set the Half/Full pin low and Reset */ 00835 L6208_Board_HALF_FULL_PIN_Reset(); 00836 L6208_Board_Reset(); 00837 /* Set system flag */ 00838 L6208_SetSysFlag(microstep); 00839 devicePrm.uStepInc = 2; 00840 break; 00841 case STEP_MODE_1_16: 00842 /* Set the Half/Full pin low and Reset */ 00843 L6208_Board_HALF_FULL_PIN_Reset(); 00844 L6208_Board_Reset(); 00845 /* Set system flag */ 00846 L6208_SetSysFlag(microstep); 00847 devicePrm.uStepInc = 1; 00848 break; 00849 default: 00850 return FALSE; 00851 } 00852 L6208_Board_Delay(2); 00853 L6208_Board_ReleaseReset(); 00854 L6208_ResetSteps(); 00855 return TRUE; 00856 } 00857 00858 /******************************************************//** 00859 * @brief Select the mode to stop the motor. When the motor 00860 * is stopped, if autoHiZ is TRUE, the power bridges are disabled 00861 * if autoHiZ is FALSE, the power bridges are kept enabled. 00862 * @param[in] stopMode HOLD_MODE to let power bridge enabled 00863 * @retval None 00864 **********************************************************/ 00865 void L6208::L6208_SetStopMode(motorStopMode_t stopMode) 00866 { 00867 if (stopMode == HOLD_MODE) 00868 { 00869 L6208_ClearSysFlag(HiZstop); 00870 } 00871 else 00872 { 00873 L6208_SetSysFlag(HiZstop); 00874 } 00875 } 00876 00877 /******************************************************//** 00878 * @brief Stop the motor by using the device deceleration and set deceleration torque 00879 * @retval true if the command is successfully executed, else false 00880 * @note . 00881 **********************************************************/ 00882 bool L6208::L6208_SoftStop(void) 00883 { 00884 L6208_VectorCalc(devicePrm.decelTorque); 00885 L6208_SetMotionState(DECELERATINGTOSTOP); 00886 return TRUE; 00887 } 00888 00889 /******************************************************//** 00890 * @brief Handle the device state machine at each tick timer pulse end. 00891 * @retval None 00892 **********************************************************/ 00893 void L6208::L6208_TickHandler(void) 00894 { 00895 uint32_t locMaxSpeedSpt = devicePrm.maxSpeedSpt; 00896 uint32_t locMinSpeedSpt = devicePrm.minSpeedSpt; 00897 00898 /* Update state, target speed, acceleration and deceleration rates */ 00899 L6208_Board_CLOCK_PIN_Reset(); 00900 00901 switch(L6208_GetMotionState()) 00902 { 00903 /* ============ Velocity control mode states ======================== */ 00904 case ACCELERATING: 00905 /* velocity mode: acceleration phase */ 00906 /* Increase Speed and update position */ 00907 L6208_DoAccel(); 00908 if(locMaxSpeedSpt < devicePrm.speedSpt) 00909 { 00910 /*Target speed reached */ 00911 devicePrm.speedSpt = locMaxSpeedSpt; 00912 L6208_VectorCalc(devicePrm.runTorque); 00913 L6208_SetMotionState(STEADY); 00914 } 00915 break; 00916 case STEADY: 00917 /* velocity mode: constant speed phase */ 00918 /* Update position */ 00919 L6208_DoRun(); 00920 if(locMaxSpeedSpt != devicePrm.speedSpt) 00921 { 00922 /* targeted speed has changed */ 00923 if(locMaxSpeedSpt< devicePrm.speedSpt) 00924 { 00925 /* Slow down the motor */ 00926 L6208_VectorCalc(devicePrm.decelTorque); 00927 L6208_SetMotionState(DECELERATING); 00928 } 00929 else 00930 { 00931 /* speed up the motor */ 00932 L6208_VectorCalc(devicePrm.accelTorque); 00933 L6208_SetMotionState(ACCELERATING); 00934 } 00935 } 00936 break; 00937 case DECELERATING: 00938 /* velocity mode: running motor deceleration phase */ 00939 /* Decrease Speed and update position */ 00940 L6208_DoDecel(); 00941 if(locMaxSpeedSpt > devicePrm.speedSpt) 00942 { 00943 /*Target speed reached but motor has still to be run*/ 00944 devicePrm.speedSpt = locMaxSpeedSpt; 00945 L6208_VectorCalc(devicePrm.runTorque); 00946 L6208_SetMotionState(STEADY); 00947 } 00948 break; 00949 case DECELERATINGTOSTOP: 00950 /* velocity mode: decelerate to stopped phase */ 00951 /* Decrease current speed */ 00952 L6208_DoDecel(); 00953 if(devicePrm.speedSpt == locMinSpeedSpt) 00954 { 00955 if (L6208_IsSysFlag(dir2change)) 00956 { 00957 L6208_ClearSysFlag(running); 00958 /* Change direction */ 00959 if (L6208_IsSysFlag(forward)) 00960 { 00961 /* switch to reverse rotation */ 00962 L6208_SetDirection(BACKWARD); 00963 } 00964 else 00965 { 00966 /* switch to forward rotation */ 00967 L6208_SetDirection(FORWARD); 00968 } 00969 L6208_SetSysFlag(running); 00970 L6208_SetMotionState(ACCELERATING); 00971 /* Set VRefA and VRefB to the selected acceleration torque */ 00972 L6208_VectorCalc(devicePrm.accelTorque); 00973 } 00974 else 00975 { 00976 if (L6208_IsSysFlag(HiZstop)) 00977 { 00978 L6208_HardHiZ(); 00979 } 00980 else 00981 { 00982 L6208_HardStop(); 00983 } 00984 } 00985 } 00986 break; 00987 00988 /* ============ Position (indexed) control mode states ======================== */ 00989 00990 case INDEX_ACCEL: 00991 /* position mode: acceleration state*/ 00992 00993 /* Increase Speed and update position */ 00994 L6208_DoAccel(); 00995 00996 if(devicePrm.positionTarget1 <= devicePrm.step) 00997 { 00998 /* End of acceleration phase */ 00999 L6208_VectorCalc(devicePrm.runTorque); 01000 L6208_SetMotionState(INDEX_RUN); 01001 } 01002 break; 01003 01004 case INDEX_RUN: 01005 /* position mode: constant speed phase */ 01006 01007 /* Update position */ 01008 L6208_DoRun(); 01009 01010 if(devicePrm.positionTarget2 <= devicePrm.step) 01011 { 01012 /* reach position targeted for constant speed */ 01013 L6208_VectorCalc(devicePrm.decelTorque); 01014 L6208_SetMotionState(INDEX_DECEL); 01015 } 01016 break; 01017 01018 case INDEX_DECEL: 01019 /* position mode: deceleration phase */ 01020 01021 /* Decrease Speed and update position */ 01022 L6208_DoDecel(); 01023 01024 if(devicePrm.positionTarget3 <= devicePrm.step) 01025 { 01026 /* reach position targeted for deceleration phase */ 01027 /* the motor terminated its run */ 01028 /* the torque will be the deceleration one */ 01029 devicePrm.step = devicePrm.positionTarget3; 01030 L6208_SetMotionState(INDEX_DWELL); 01031 } 01032 break; 01033 01034 case INDEX_DWELL: 01035 /* position mode: dwelling state */ 01036 if(devicePrm.dwellCounter > 0) 01037 { 01038 /* decrease the dwelling wait tick counter */ 01039 devicePrm.dwellCounter--; 01040 } 01041 if(devicePrm.dwellCounter == 0) 01042 { 01043 /* dwelling wait time is elapsed */ 01044 /* so stop the motor */ 01045 if (L6208_IsSysFlag(HiZstop)) 01046 { 01047 L6208_HardHiZ(); 01048 } 01049 else 01050 { 01051 L6208_HardStop(); 01052 } 01053 } 01054 break; 01055 01056 /* ============ stopped state ======================== */ 01057 case INACTIVE: 01058 { 01059 if(L6208_IsSysFlag(running)) 01060 { 01061 /* clear the user move command executing */ 01062 /* and the motor running flags */ 01063 L6208_ClearSysFlag(running); 01064 } 01065 break; 01066 } 01067 default: 01068 break; 01069 } /* switch(L6208_GetMotionState()) */ 01070 if(L6208_GetMotionState() != INACTIVE) 01071 { 01072 if (L6208_IsSysFlag(microstep)) 01073 { 01074 /* Microstep handling */ 01075 switch(devicePrm.uStepInc) 01076 { 01077 default: 01078 case 1: 01079 /* 1 microstep increment */ 01080 devicePrm.lsbTicks = (uint8_t)(devicePrm.ticks>>16); 01081 break; 01082 01083 case 2: 01084 /* 2 microsteps increment */ 01085 devicePrm.lsbTicks = (uint8_t)(devicePrm.ticks>>17); 01086 break; 01087 01088 case 4: 01089 /* 4 microsteps increment */ 01090 devicePrm.lsbTicks = (uint8_t)(devicePrm.ticks>>18); 01091 break; 01092 } 01093 devicePrm.lsbTicks &= 0x01; 01094 if(devicePrm.lsbOldUSteppingTicks != devicePrm.lsbTicks) 01095 { 01096 /* waveform sample to update */ 01097 devicePrm.lsbOldUSteppingTicks = devicePrm.lsbTicks; 01098 devicePrm.step++; 01099 if(L6208_IsSysFlag(forward)) 01100 { 01101 /* the motor is going forward */ 01102 devicePrm.absolutePos++; 01103 /* Reset the absolute motor position in step/microsteps */ 01104 /* Get next microstep sample */ 01105 devicePrm.uStepSample += devicePrm.uStepInc; 01106 if(devicePrm.uStepSample > 31) 01107 { 01108 devicePrm.uStepSample = 0; 01109 } 01110 } 01111 else 01112 { 01113 /* the motor is going backward */ 01114 devicePrm.absolutePos--; 01115 if(devicePrm.uStepSample >= devicePrm.uStepInc) 01116 { 01117 /* Get previous microstep sample */ 01118 devicePrm.uStepSample -= devicePrm.uStepInc; 01119 } 01120 else 01121 { 01122 devicePrm.uStepSample = 32 - devicePrm.uStepInc; 01123 } 01124 } 01125 /* set the PWM to update VRefs */ 01126 L6208_VrefPwmComputePulseWidth(BRIDGE_A, pMicroTable2[devicePrm.uStepSample], FALSE); 01127 L6208_VrefPwmComputePulseWidth(BRIDGE_B, microTable1[devicePrm.uStepSample], FALSE); 01128 if(devicePrm.uStepsample2update > 0) 01129 { 01130 /* the waveform samples table has been recalculated 01131 so update the waveform scanning table */ 01132 L6208_UpdateScanWaveformTable(); 01133 devicePrm.uStepsample2update = 0; 01134 } 01135 } 01136 /* Microstep: use the bit4 toggling as step clock */ 01137 /* this bit is used because there are 16 microstep samples per quarter period */ 01138 devicePrm.lsbTicks = (uint8_t)((devicePrm.uStepSample>>4) & 0x01); 01139 if(devicePrm.lsbOldTicks != devicePrm.lsbTicks) 01140 { 01141 /* the selected bit status changed ==> get the next motor step 01142 save the current masked motor tick position for step setting scope ... */ 01143 devicePrm.lsbOldTicks = devicePrm.lsbTicks; 01144 L6208_Board_CLOCK_PIN_Set(); 01145 } 01146 } 01147 else 01148 { 01149 /* Full and half step handling code */ 01150 if(!L6208_IsSysFlag(halfstep)) 01151 { 01152 /* Full step: use the bit 16 toggling as step clock */ 01153 devicePrm.lsbTicks = (uint8_t)((devicePrm.ticks>>16) & 0x00000001); 01154 } 01155 else 01156 { 01157 /* half step: use the bit 15 toggling as step clock */ 01158 devicePrm.lsbTicks = (uint8_t)((devicePrm.ticks>>15) & 0x00000001); 01159 } 01160 if(devicePrm.lsbOldTicks != devicePrm.lsbTicks) 01161 { 01162 /* the selected bit status changed ==> get the next motor step */ 01163 devicePrm.step++; 01164 if(L6208_IsSysFlag(forward)) 01165 { 01166 /* the motor is going forward */ 01167 devicePrm.absolutePos++; 01168 } 01169 else 01170 { 01171 /* the motor is going backward */ 01172 devicePrm.absolutePos--; 01173 } 01174 /* save the current masked motor tick position for step setting scope ... */ 01175 devicePrm.lsbOldTicks = devicePrm.lsbTicks; 01176 L6208_Board_CLOCK_PIN_Set(); 01177 } 01178 } 01179 } 01180 L6208_UstepWaveformHandling(); 01181 L6208_VrefPwmUpdatePulseWidth(); 01182 } 01183 01184 /******************************************************//** 01185 * @brief Get the frequency of VREFA and VREFB PWM 01186 * @retval the frequency of VREFA and VREFB PWM in Hz 01187 * @note 01188 **********************************************************/ 01189 uint32_t L6208::L6208_VrefPwmGetFreq(void) 01190 { 01191 return devicePrm.vrefPwmFreq; 01192 } 01193 01194 /******************************************************//** 01195 * @brief Set the frequency of the VREFA and VREFB PWM 01196 * @param[in] newFreq in Hz 01197 * @retval None 01198 * @note 01199 **********************************************************/ 01200 void L6208::L6208_VrefPwmSetFreq(uint32_t newFreq) 01201 { 01202 devicePrm.vrefPwmFreq = newFreq; 01203 /* Compute the pwm period in 1/256th of a microsecond */ 01204 devicePrm.vrefPwmPeriod = (uint16_t)((1000000<<8)/newFreq); 01205 /* Re-Initialise the PWMs -----------------------------------------------------*/ 01206 L6208_Board_VrefPwmInit(BRIDGE_A, devicePrm.vrefPwmPeriod); 01207 L6208_Board_VrefPwmInit(BRIDGE_B, devicePrm.vrefPwmPeriod); 01208 /* Recompute the waveform samples according to the new PWM frequency */ 01209 L6208_ScaleWaveformTable(); 01210 /* Update the waveform scanning table */ 01211 L6208_UpdateScanWaveformTable(); 01212 if (L6208_IsSysFlag(running)) 01213 { 01214 L6208_Board_VrefPwmStart(BRIDGE_A, devicePrm.vrefPwmPeriod); 01215 L6208_Board_VrefPwmStart(BRIDGE_B, devicePrm.vrefPwmPeriod); 01216 } 01217 } 01218 01219 /******************************************************//** 01220 * @brief Lock while motor is running 01221 * @retval None 01222 **********************************************************/ 01223 void L6208::L6208_WaitWhileActive(void) 01224 { 01225 /* Wait while motor is running */ 01226 while (L6208_IsSysFlag(running)); 01227 } 01228 01229 /* ------------------------------------------------------------------------- */ 01230 /* Private functions ------------------------------------------------------- */ 01231 /* ------------------------------------------------------------------------- */ 01232 /******************************************************//** 01233 * @brief Clear the bit/s of flags according to the specified mask 01234 * @param[in] mask flag bit mask 01235 * @retval None 01236 **********************************************************/ 01237 inline void L6208::L6208_ClearSysFlag(uint32_t mask) 01238 { 01239 devicePrm.flags &= ~mask; 01240 } 01241 01242 /******************************************************//** 01243 * @brief Compute the number of steps at the end of the accereration/deceleration phase 01244 * P = position in steps at the end of the acceleration/deceleration phase 01245 * T = acceleration/deceleration time in seconds 01246 * A = acceleration/deceleration rate in steps per second per second (steps/sec^2) 01247 * V = peak velocity during acceleration/deceleration phase 01248 * V1 = average velocity during acceleration/deceleration phase 01249 * T = V/A 01250 * V1 = V/2 01251 * P = V1*T 01252 * P = V^2/2A 01253 * @param accOrDecRate acceleration/deceleration rate in steps per second per second (steps/sec^2) 01254 * @retval end position or 0xFFFFFFFF on error 01255 **********************************************************/ 01256 uint32_t L6208::L6208_ComputeNbAccOrDecSteps(uint16_t accOrDecRate) 01257 { 01258 uint32_t nbAccOrDecSteps; 01259 uint32_t locMaxSpeedSps = (uint32_t)devicePrm.maxSpeedSps; 01260 01261 if (L6208_IsSysFlag(microstep)) 01262 { 01263 switch(devicePrm.uStepInc) 01264 { 01265 case 1: 01266 locMaxSpeedSps = (uint32_t)devicePrm.maxSpeedSps; 01267 break; 01268 case 2: 01269 locMaxSpeedSps = ((uint32_t)devicePrm.maxSpeedSps)>>1; 01270 accOrDecRate >>= 1; 01271 break; 01272 case 4: 01273 locMaxSpeedSps = ((uint32_t)devicePrm.maxSpeedSps)>>2; 01274 accOrDecRate >>= 2; 01275 break; 01276 default: 01277 break; 01278 } 01279 } 01280 else if (L6208_IsSysFlag(halfstep)) 01281 { 01282 locMaxSpeedSps = ((uint32_t)devicePrm.maxSpeedSps)<<1; 01283 accOrDecRate <<= 1; 01284 } 01285 01286 if(accOrDecRate == 0) 01287 { 01288 /* division by 0 error */ 01289 return 0xFFFFFFFF; 01290 } 01291 nbAccOrDecSteps = locMaxSpeedSps * locMaxSpeedSps; 01292 nbAccOrDecSteps /= (uint32_t)accOrDecRate; 01293 nbAccOrDecSteps /= 2; 01294 01295 return nbAccOrDecSteps; 01296 } 01297 01298 /******************************************************//** 01299 * @brief Compute the acceleration/deceleration speed increment value 01300 * @param[in] newAccOrDecRate acceleration or deceleration value (steps/s^2) greater or equal than 24 01301 * @retval the speed (step/tick) increment value 01302 * LSB = 2^-24 step/tick^2 or 2^-20 microstep/tick^2 01303 * @note return 0 if the rate is too low or if the tick frequency is too small 01304 * or if the device is running in position mode 01305 **********************************************************/ 01306 uint16_t L6208::L6208_ConvertAcceDecelRateValue(uint16_t newAccOrDecRate) 01307 { 01308 uint64_t tmp64; 01309 uint32_t tmp32; 01310 01311 if (((L6208_IsSysFlag(running))&&(L6208_IsSysFlag(positionmode)))||\ 01312 (newAccOrDecRate < L6208_MIN_ACC_DEC_RATE)) 01313 { 01314 return 0; 01315 } 01316 /* Compute (tick frequency)^2 */ 01317 tmp32 = (uint32_t)L6208_Board_TickGetFreq(); 01318 tmp32 *= tmp32; 01319 /* Return 0 if the (tick frequency)^2 is too small */ 01320 if ( tmp32 < (uint32_t)newAccOrDecRate ) 01321 { 01322 return 0; 01323 } 01324 /* Compute the decimal number of microstep or step per tick^2 */ 01325 /* Decimal part is on 32 bits */ 01326 tmp64 = (uint64_t)newAccOrDecRate << 32; 01327 tmp64 /= ((uint64_t)tmp32); 01328 01329 return (uint16_t)((tmp64 & 0x00000000FFFFFFFF)>>8); 01330 } 01331 01332 /******************************************************//** 01333 * @brief Compute next position and speed according to the acceleration rate 01334 * @retval None 01335 **********************************************************/ 01336 void L6208::L6208_DoAccel(void) 01337 { 01338 /* Increase speed by acceleration rate */ 01339 uint32_t locAccelerationSpt2 = (uint32_t)devicePrm.accelerationSpt2; 01340 uint32_t locMinSpeedSpt = devicePrm.minSpeedSpt; 01341 if ((devicePrm.speedSpt + locAccelerationSpt2) < locMinSpeedSpt) 01342 { 01343 devicePrm.speedSpt = locMinSpeedSpt; 01344 } 01345 else 01346 { 01347 devicePrm.speedSpt += locAccelerationSpt2; 01348 } 01349 /* Compute next position */ 01350 L6208_DoRun(); 01351 } 01352 01353 /******************************************************//** 01354 * @brief Compute next position and speed according to the deceleration rate 01355 * @retval None 01356 **********************************************************/ 01357 void L6208::L6208_DoDecel(void) 01358 { 01359 /* Decrease current speed by deceleration rate */ 01360 uint32_t locDecelerationSpt2 = (uint32_t)devicePrm.decelerationSpt2; 01361 uint32_t locMinSpeedSpt = devicePrm.minSpeedSpt; 01362 if((devicePrm.speedSpt - locMinSpeedSpt) > (uint32_t)locDecelerationSpt2) 01363 { 01364 devicePrm.speedSpt -= (uint32_t)locDecelerationSpt2; 01365 } 01366 else 01367 { 01368 /* Set minimum speed */ 01369 devicePrm.speedSpt = locMinSpeedSpt; 01370 } 01371 /* Compute next position */ 01372 L6208_DoRun(); 01373 } 01374 01375 /******************************************************//** 01376 * @brief Compute next position by adding current speed 01377 * @retval None 01378 **********************************************************/ 01379 void L6208::L6208_DoRun(void) 01380 { 01381 devicePrm.ticks += (devicePrm.speedSpt >> 8) & 0x0000FFFF; 01382 } 01383 01384 /******************************************************//** 01385 * @brief Get number of samples to rescale 01386 * @retval uStepsample2scale the number of micro stepping waveform samples to rescale 01387 **********************************************************/ 01388 uint8_t L6208::L6208_GetMicrostepSample2Scale(void) 01389 { 01390 return devicePrm.uStepsample2scale; 01391 } 01392 01393 /******************************************************//** 01394 * @brief Initialize the system for position mode motor moving command 01395 * P = total move distance in steps 01396 * P1 = steps required to accel from 0 to V 01397 * P2 = steps required to decel from V to 0 01398 * V = peak velocity in steps per second (steps/sec) 01399 * V1 = average velocity during accel or decel* 01400 * A = required accel rate in steps per second per second (steps/sec2) 01401 * D = required decel rate in steps per second per second (steps/sec2) 01402 * T1 = acceleration time in seconds 01403 * T2 = deceleration time in seconds* 01404 * 01405 * 1) T1 = V / A 01406 * 2) V1 = V / 2 01407 * 3) P1 = V1 T1 01408 * Substituting 1 and 2 into 3 yields: 01409 * 4) P1 = V2 / 2A 01410 * In the same manner we have: 01411 * 5) P2 = V2 / 2D 01412 * 01413 * P1 = PD/(D+A) 01414 * 01415 * \sa Application Note: AN2044 01416 * @retval None 01417 **********************************************************/ 01418 void L6208::L6208_Indexmodeinit(void) 01419 { 01420 uint32_t tmpVal0; 01421 uint32_t tmpVal1; 01422 uint32_t locAccelSteps; 01423 uint32_t locDecSteps; 01424 01425 /* calculate the number of steps to get the running speed */ 01426 locAccelSteps = L6208_ComputeNbAccOrDecSteps(devicePrm.accelerationSps2); 01427 /* calculate the number of steps to get the motor stopped */ 01428 locDecSteps = L6208_ComputeNbAccOrDecSteps(devicePrm.decelerationSps2); 01429 if(( locAccelSteps + locDecSteps ) > devicePrm.positionTarget) 01430 { 01431 /* Triangular move needed */ 01432 /* accelsteps = P1 = PD/(D+A) */ 01433 tmpVal0 = devicePrm.positionTarget * devicePrm.decelerationSps2; 01434 tmpVal1 = (uint32_t)devicePrm.decelerationSps2; 01435 tmpVal1 += (uint32_t)devicePrm.accelerationSps2; 01436 locAccelSteps = tmpVal0 / tmpVal1; 01437 devicePrm.positionTarget1 = locAccelSteps; 01438 devicePrm.positionTarget2 = devicePrm.positionTarget1 + 1; 01439 devicePrm.positionTarget3 = devicePrm.positionTarget; 01440 if(devicePrm.positionTarget1 == 0) 01441 { 01442 devicePrm.positionTarget1 = 1; 01443 } 01444 } 01445 else 01446 { 01447 /* trapezoidal move needed */ 01448 /* P1 = V^2/2A */ 01449 /* P2 = P - V^2/2D */ 01450 devicePrm.positionTarget1 = locAccelSteps; 01451 devicePrm.positionTarget2 = devicePrm.positionTarget - locDecSteps; 01452 devicePrm.positionTarget3 = devicePrm.positionTarget; 01453 } 01454 L6208_SetMotionState(INDEX_ACCEL); 01455 } 01456 01457 /******************************************************//** 01458 * @brief Check the bit/s of flags according to the specified mask 01459 * @param[in] mask flag bit mask 01460 * @retval TRUE if the bit of the mask are set 01461 **********************************************************/ 01462 inline bool L6208::L6208_IsSysFlag(uint32_t mask) 01463 { 01464 return (bool)((devicePrm.flags & mask) == mask); 01465 } 01466 01467 /******************************************************//** 01468 * @brief Stepper driver device step state reset subroutine 01469 * @retval None 01470 **********************************************************/ 01471 void L6208::L6208_ResetSteps(void) 01472 { 01473 devicePrm.speedSpt = 0; // reset the current speed value 01474 devicePrm.ticks = 0; // reset the current ticks counter value 01475 devicePrm.step = 0; // reset the current step counter value 01476 devicePrm.lsbOldTicks = 0; // reset copy of the previous position (tick) 01477 devicePrm.lsbOldUSteppingTicks = 0; // reset copy of the previous position (tick) ( micro stepping ) 01478 devicePrm.lsbTicks = 0; // reset copy of the current position (tick) 01479 devicePrm.absolutePos = 0; // reset the absolute motor position in step/microsteps 01480 devicePrm.uStepSample = 0; // reset the microstepping waveform sample index 01481 } 01482 01483 /******************************************************//** 01484 * @brief Compute the specified micro stepping waveform sample with the 01485 * current selected torque and pwm period 01486 * @param[in] sampleIndex sample Index 01487 * @retval scaled sample value 01488 **********************************************************/ 01489 uint32_t L6208::L6208_ScaleWaveformSample(uint8_t sampleIndex) 01490 { 01491 uint32_t sample; 01492 01493 sample = (uint32_t)RefMicroTable[sampleIndex]; 01494 sample *= devicePrm.vrefPwmPeriod; 01495 sample >>= (uint32_t)L6208_SINE_WAVEFORM_POWER_OF_TWO_MAX_VALUE; 01496 01497 sample *= (uint32_t)devicePrm.curTorqueScaler; // torque val (%) 01498 sample /= (uint32_t)100; 01499 01500 return sample; 01501 } 01502 01503 /******************************************************//** 01504 * @brief Compute the micro stepping waveform sample table samples with the 01505 * current selected torque and pwm period 01506 * @retval None 01507 **********************************************************/ 01508 void L6208::L6208_ScaleWaveformTable(void) 01509 { 01510 uint8_t index; 01511 for(index=0; index<=L6208_USTEPS_PER_QUARTER_PERIOD; index++) 01512 { 01513 /* Calculate the scaled sample and save its value into the waveform to update table */ 01514 updatedMicroTable[index] = (uint16_t)L6208_ScaleWaveformSample(index); 01515 } 01516 } 01517 01518 /******************************************************//** 01519 * @brief Set the parameters of the device to values of the structure pointed 01520 * by pInitDevicePrm. Set GPIO according to these values. 01521 * @param pInitDevicePrm pointer onto the structure containing values to 01522 * initialize the device parameters. 01523 * @retval None 01524 **********************************************************/ 01525 void L6208::L6208_SetDeviceParamsToGivenValues(l6208_init_t* pInitDevicePrm) 01526 { 01527 memset(&devicePrm, 0, sizeof(devicePrm)); 01528 L6208_SetAcceleration(pInitDevicePrm->accelerationSps2); 01529 L6208_SetDeceleration(pInitDevicePrm->decelerationSps2); 01530 L6208_SetMaxSpeed(pInitDevicePrm->maxSpeedSps); 01531 L6208_SetMinSpeed(L6208_MIN_SPEED); 01532 devicePrm.accelTorque = pInitDevicePrm->accelTorque; 01533 devicePrm.decelTorque = pInitDevicePrm->decelTorque; 01534 devicePrm.runTorque = pInitDevicePrm->runTorque; 01535 devicePrm.holdTorque = pInitDevicePrm->holdTorque; 01536 /* Only once acceleration, deceleration, min speed and max speed have been */ 01537 /* initialized, set the step mode */ 01538 devicePrm.stepMode = pInitDevicePrm->stepMode; 01539 L6208_SetDecayMode(pInitDevicePrm->decayMode); 01540 devicePrm.moveDwellTime = pInitDevicePrm->moveDwellTime; 01541 if (L6208_CONF_PARAM_AUTO_HIZ_STOP) 01542 { 01543 L6208_SetSysFlag(pInitDevicePrm->autoHiZstop); 01544 } 01545 devicePrm.vrefPwmFreq = pInitDevicePrm->vrefPwmFreq; 01546 devicePrm.vrefPwmPeriod = (uint16_t)((1000000<<8)/pInitDevicePrm->vrefPwmFreq); 01547 /* Initialize current stepper state machine index */ 01548 L6208_SetMotionState(INACTIVE); 01549 } 01550 01551 /******************************************************//** 01552 * @brief Set the parameters of the device to predefined values 01553 * Set GPIO according to these values 01554 * from l6208_target_config.h 01555 * @retval None 01556 **********************************************************/ 01557 void L6208::L6208_SetDeviceParamsToPredefinedValues(void) 01558 { 01559 memset(&devicePrm, 0, sizeof(devicePrm)); 01560 L6208_SetAcceleration(L6208_CONF_PARAM_ACC_RATE); 01561 L6208_SetDeceleration(L6208_CONF_PARAM_DEC_RATE); 01562 L6208_SetMaxSpeed(L6208_CONF_PARAM_RUNNING_SPEED); 01563 L6208_SetMinSpeed(L6208_MIN_SPEED); 01564 devicePrm.accelTorque = L6208_CONF_PARAM_ACC_CURRENT; 01565 devicePrm.decelTorque = L6208_CONF_PARAM_DEC_CURRENT; 01566 devicePrm.runTorque = L6208_CONF_PARAM_RUNNING_CURRENT; 01567 devicePrm.holdTorque = L6208_CONF_PARAM_HOLDING_CURRENT; 01568 /* Only once acceleration, deceleration, min speed and max speed have been */ 01569 /* initialized, set the step mode */ 01570 devicePrm.stepMode = (motorStepMode_t) L6208_CONF_PARAM_STEP_MODE; 01571 L6208_SetDecayMode(L6208_CONF_PARAM_DECAY_MODE); 01572 devicePrm.moveDwellTime = L6208_CONF_PARAM_DWELL_TIME; 01573 if (L6208_CONF_PARAM_AUTO_HIZ_STOP) 01574 { 01575 L6208_SetSysFlag(HiZstop); 01576 } 01577 devicePrm.vrefPwmFreq = L6208_CONF_VREF_PWM_FREQUENCY; 01578 devicePrm.vrefPwmPeriod = (uint16_t)((1000000<<8)/L6208_CONF_VREF_PWM_FREQUENCY); 01579 /* Initialize current stepper state machine index */ 01580 L6208_SetMotionState(INACTIVE); 01581 } 01582 01583 /******************************************************//** 01584 * @brief Set the number of micro stepping waveform samples to rescale 01585 * @param[in] value number of micro stepping waveform samples 01586 * @retval None 01587 **********************************************************/ 01588 void L6208::L6208_SetMicrostepSample2Scale(uint8_t value) 01589 { 01590 if(value > L6208_USTEPS_PER_QUARTER_PERIOD) 01591 { 01592 value = L6208_USTEPS_PER_QUARTER_PERIOD; // clamp to maximum number of samples per period/4 01593 } 01594 devicePrm.uStepsample2scale = value; 01595 } 01596 01597 /******************************************************//** 01598 * @brief Set the number of micro stepping waveform samples to update into scanning 01599 * @param[in] value number of micro stepping waveform samples 01600 * @retval None 01601 **********************************************************/ 01602 void L6208::L6208_SetMicrostepSample2Update(uint8_t value) 01603 { 01604 // clamp to maximum number of samples per period/4 01605 if(value > L6208_USTEPS_PER_QUARTER_PERIOD) 01606 { 01607 value = L6208_USTEPS_PER_QUARTER_PERIOD; 01608 } 01609 // copy the stepper acceleration rate 01610 devicePrm.uStepsample2update = value; 01611 } 01612 01613 /******************************************************//** 01614 * @brief Set the stepper state machine index 01615 * @param[in] newMotionState 01616 * @retval None 01617 **********************************************************/ 01618 void L6208::L6208_SetMotionState(motorState_t newMotionState) 01619 { 01620 // sets the new stepper state machine index 01621 devicePrm.motionState = newMotionState; 01622 } 01623 01624 /******************************************************//** 01625 * @brief Set the user selected speed in step/tick 01626 * @param[in] newSpeed speed value (step/s) 01627 * @param[in] pSpeed pointer to the selected speed field 01628 * @retval return FALSE if the speed is too low or too high 01629 * or if the device is running in position mode, else TRUE 01630 **********************************************************/ 01631 bool L6208::L6208_SetSpeed(uint16_t newSpeed, uint32_t volatile *pSpeed) 01632 { 01633 uint64_t tmp64; 01634 uint32_t tmp32; 01635 01636 if (((L6208_IsSysFlag(running))&&(L6208_IsSysFlag(positionmode)))||\ 01637 (newSpeed < L6208_MIN_SPEED)) 01638 { 01639 return FALSE; 01640 } 01641 tmp32 = (uint32_t)L6208_Board_TickGetFreq(); 01642 if (tmp32 < newSpeed) 01643 { 01644 return FALSE; 01645 } 01646 /* Compute the decimal number of microstep or step per tick */ 01647 /* Decimal part is on 32 bits */ 01648 tmp64 = (uint64_t)newSpeed << 32; 01649 tmp64 /= ((uint64_t)tmp32); 01650 /* set the running constant speed value (step/tick) */ 01651 *pSpeed = (uint32_t)((tmp64 & 0x00000000FFFFFFFF)>>8); 01652 01653 return TRUE; 01654 } 01655 01656 /******************************************************//** 01657 * @brief Set the bit/s of flags according to the specified mask 01658 * @param[in] mask flag bit mask 01659 * @retval None 01660 **********************************************************/ 01661 inline void L6208::L6208_SetSysFlag(uint32_t mask) 01662 { 01663 devicePrm.flags |= mask; 01664 } 01665 01666 /******************************************************//** 01667 * @brief Stepper motor start command 01668 * @retval true on correct command execution 01669 **********************************************************/ 01670 bool L6208::L6208_StartMovement(void) 01671 { 01672 uint32_t tmp; 01673 if (L6208_IsSysFlag(running)) 01674 { 01675 /* Motor is already running ==> quit */ 01676 return FALSE; 01677 } 01678 if (!L6208_IsSysFlag(positionmode)) 01679 { 01680 /* Set the VREFA and VREFB to the selected acc. torque */ 01681 L6208_VectorCalc(devicePrm.accelTorque); 01682 01683 /* If the speed control mode is selected */ 01684 /* setup the motor acceleration for velocity mode driving */ 01685 L6208_SetMotionState(ACCELERATING); 01686 } 01687 else 01688 { 01689 /* if position control mode is selected, reset the current step counter */ 01690 devicePrm.step = 0; 01691 if(devicePrm.uStepSample > 31) 01692 { 01693 /* check the micro stepping waveform sample index */ 01694 devicePrm.uStepSample = 0; 01695 } 01696 /* Set the position dwelling wait time */ 01697 /* compute number of ticks per millisecond */ 01698 tmp = (uint32_t)L6208_Board_TickGetFreq() / 1000; 01699 /* Compute the dwelling time in ticks => dwellCounter (ticks) */ 01700 devicePrm.dwellCounter = tmp * (uint32_t)devicePrm.moveDwellTime; 01701 if (devicePrm.positionTarget == 0) 01702 { 01703 /* if the position to go is 0 (no move) */ 01704 /* Set the deceleration torque */ 01705 L6208_VectorCalc(devicePrm.decelTorque); 01706 /* Set the dwelling delay state index */ 01707 L6208_SetMotionState(INDEX_DWELL); 01708 } 01709 else 01710 { 01711 /* Set the VREFA and VREFB to the selected acc. torque */ 01712 L6208_VectorCalc(devicePrm.accelTorque); 01713 /* go to the selected position */ 01714 L6208_Indexmodeinit(); 01715 L6208_SetMotionState(INDEX_ACCEL); 01716 } 01717 } 01718 /* Sets the motor running flag */ 01719 L6208_SetSysFlag(running); 01720 /* Start the VREFA and VREFB PWMs */ 01721 L6208_Board_VrefPwmStart(BRIDGE_A, devicePrm.vrefPwmPeriod); 01722 L6208_Board_VrefPwmStart(BRIDGE_B, devicePrm.vrefPwmPeriod); 01723 if (!(L6208_IsSysFlag(EN_A_set))) 01724 { 01725 /* Enable power bridges */ 01726 L6208_Enable(); 01727 } 01728 /* Start the tick */ 01729 L6208_Board_TickStart(L6208::tickFreq); 01730 01731 return TRUE; 01732 } 01733 01734 /******************************************************//** 01735 * @brief Update the micro stepping waveform samples table with the 01736 * values previously scaled with current selected torque and tick period 01737 * @retval None 01738 **********************************************************/ 01739 void L6208::L6208_UpdateScanWaveformTable(void) 01740 { 01741 uint8_t index; 01742 01743 for(index=0; index<=L6208_USTEPS_PER_QUARTER_PERIOD; index++) 01744 { 01745 microTable1[index] = updatedMicroTable[index]; 01746 microTable1[L6208_USTEPS_PER_QUARTER_PERIOD*2 - index] = microTable1[index]; 01747 microTable1[index + L6208_USTEPS_PER_QUARTER_PERIOD*2] = updatedMicroTable[index]; 01748 } 01749 /* clear the number of samples to update */ 01750 L6208_SetMicrostepSample2Update(0); 01751 } 01752 01753 /******************************************************//** 01754 * @brief Check if there are waveform samples to rescale and if so, perform the rescaling 01755 * @retval None 01756 **********************************************************/ 01757 void L6208::L6208_UstepWaveformHandling(void) 01758 { 01759 /* micro stepper waveform samples rescaling ... and updating */ 01760 uint8_t nbSamplesToRescale = L6208_GetMicrostepSample2Scale(); 01761 if(nbSamplesToRescale > 0) 01762 { 01763 /* Current torque value has been changed, so recalculate the waveform table */ 01764 L6208_ScaleWaveformTable(); 01765 01766 /* Set the number of samples to update */ 01767 L6208_SetMicrostepSample2Update(L6208_USTEPS_PER_QUARTER_PERIOD); 01768 01769 /* Reset the number of samples to rescaled afer rescaling */ 01770 L6208_SetMicrostepSample2Scale(0); 01771 } 01772 } 01773 01774 /******************************************************//** 01775 * @brief Set the current torque value (Vref) 01776 * @param[in] newTorque Selected torque value 01777 * @retval always TRUE 01778 **********************************************************/ 01779 bool L6208::L6208_VectorCalc(uint8_t newTorque) 01780 { 01781 /* save current selected torque value */ 01782 devicePrm.curTorqueScaler = (uint16_t)newTorque; 01783 01784 if(!L6208_IsSysFlag(microstep)) 01785 { 01786 /* full/half step mode or the motor is not running */ 01787 /* set the PWM duty cycle according to the current torque value (%). */ 01788 /* The TON value will be calculated inside the TIMx_PWM_duty_setup f(). */ 01789 L6208_VrefPwmComputePulseWidth(BRIDGE_A, devicePrm.curTorqueScaler, TRUE); 01790 L6208_VrefPwmComputePulseWidth(BRIDGE_B, devicePrm.curTorqueScaler, TRUE); 01791 devicePrm.vRefAVal = devicePrm.curTorqueScaler; // save current VREFA value 01792 devicePrm.vRefBVal = devicePrm.curTorqueScaler; // save current VREFB value 01793 } 01794 else 01795 { 01796 /* microstep mode */ 01797 if(L6208_IsSysFlag(running)) 01798 { 01799 /* set the number of waveform sample to rescale according current selected */ 01800 /* torque value */ 01801 L6208_SetMicrostepSample2Scale(L6208_USTEPS_PER_QUARTER_PERIOD); 01802 } 01803 else 01804 { 01805 /* micro stepping mode motor stopped */ 01806 L6208_ScaleWaveformTable(); 01807 L6208_UpdateScanWaveformTable(); 01808 /* Set the VREF timer PWM TON to update VREFA and VREFB */ 01809 L6208_VrefPwmComputePulseWidth(BRIDGE_A, pMicroTable2[devicePrm.uStepSample], FALSE); 01810 L6208_VrefPwmComputePulseWidth(BRIDGE_B, microTable1[devicePrm.uStepSample], FALSE); 01811 } 01812 } 01813 return TRUE; 01814 } 01815 01816 /******************************************************//** 01817 * @brief Compute the pulse width of VREFA or VREFB PWM 01818 * @param[in] bridgeId 01819 * 0 for BRIDGE_A 01820 * 1 for BRIDGE_B 01821 * @param[in] value pulse length in 1/256th of microsecond 01822 * or PWM duty cycle: 0 - 100 % 01823 * @param[in] valueIsPwmDutyCycle must be TRUE if value is a PWM duty cycle 01824 * @retval FALSE if wrong timer handle is used, else TRUE 01825 **********************************************************/ 01826 bool L6208::L6208_VrefPwmComputePulseWidth(uint8_t bridgeId, uint16_t value, bool valueIsPwmDutyCycle) 01827 { 01828 if(valueIsPwmDutyCycle) 01829 { 01830 if (value > 100) 01831 { 01832 value = 100; 01833 } 01834 value = (uint16_t)(((uint32_t)devicePrm.vrefPwmPeriod * (uint32_t)value) / 100); 01835 } 01836 if (bridgeId == 0) 01837 { 01838 devicePrm.vrefPwmPulseWidthTargetA = value; 01839 devicePrm.vrefPwmPulseWidthToBeGeneratedA = 0; 01840 } 01841 else if (bridgeId == 1) 01842 { 01843 devicePrm.vrefPwmPulseWidthTargetB = value; 01844 devicePrm.vrefPwmPulseWidthToBeGeneratedB = 0; 01845 } 01846 else 01847 { 01848 return FALSE; 01849 } 01850 return TRUE; 01851 } 01852 01853 /******************************************************//** 01854 * @brief Update the pulse width of VREFA or VREFB PWM 01855 * @param None 01856 * @retval None 01857 **********************************************************/ 01858 void L6208::L6208_VrefPwmUpdatePulseWidth(void) 01859 { 01860 uint16_t pulseWidthUs; 01861 01862 devicePrm.vrefPwmPulseWidthToBeGeneratedA += devicePrm.vrefPwmPulseWidthTargetA; 01863 pulseWidthUs = devicePrm.vrefPwmPulseWidthToBeGeneratedA>>8; 01864 if (pulseWidthUs!=0) 01865 { 01866 L6208_Board_VrefPwmSetPulseWidthA(pulseWidthUs); 01867 devicePrm.vrefPwmPulseWidthToBeGeneratedA -= (pulseWidthUs<<8); 01868 } 01869 else 01870 { 01871 L6208_Board_VrefPwmSetPulseWidthA(0); 01872 } 01873 01874 devicePrm.vrefPwmPulseWidthToBeGeneratedB += devicePrm.vrefPwmPulseWidthTargetB; 01875 pulseWidthUs = devicePrm.vrefPwmPulseWidthToBeGeneratedB>>8; 01876 if (pulseWidthUs!=0) 01877 { 01878 L6208_Board_VrefPwmSetPulseWidthB(pulseWidthUs); 01879 devicePrm.vrefPwmPulseWidthToBeGeneratedB -= (pulseWidthUs<<8); 01880 } 01881 else 01882 { 01883 L6208_Board_VrefPwmSetPulseWidthB(0); 01884 } 01885 } 01886 01887 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Thu Jul 14 2022 21:58:52 by 1.7.2