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