Expansion SW library to control high power stepper motor(s) using IHM03A1 expansion board(s) with Powerstep01 driver.

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Dependents:   IHM03A1_ExampleFor1Motor HelloWorld_IHM03A1 IHM03A1_ExampleFor3Motors KYPHOS_Stepper_Motor_Control

Fork of X_NUCLEO_IHM03A1 by ST Expansion SW Team

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PowerStep01.cpp Source File

PowerStep01.cpp

Go to the documentation of this file.
00001 /**
00002  ******************************************************************************
00003  * @file    PowerStep01.cpp
00004  * @author  IPC Rennes
00005  * @version V1.0.0
00006  * @date    March 18th, 2016
00007  * @brief   Powerstep01 motor driver (Microstepping controller with power MOSFETs)
00008  * @note    (C) COPYRIGHT 2016 STMicroelectronics
00009  ******************************************************************************
00010  * @attention
00011  *
00012  * <h2><center>&copy; 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 "PowerStep01.h"
00041 
00042 /* Definitions ---------------------------------------------------------------*/
00043 
00044 /* Error of bad SPI transaction. */
00045 #define POWERSTEP01_ERROR_1        (POWERSTEP01_ERROR_BASE|0x0001)
00046 
00047 /* Variables  ----------------------------------------------------------------*/
00048 
00049 /* Number of devices. */
00050 uint8_t PowerStep01::numberOfDevices = 0;
00051 
00052 /* ISR flags used to restart an interrupted SPI transfer when an error is reported. */
00053 bool PowerStep01::spiPreemptionByIsr = FALSE;
00054 bool PowerStep01::isrFlag = FALSE;
00055 
00056 /* SPI Transmission for Daisy-Chain Configuration. */
00057 uint8_t PowerStep01::spiTxBursts[POWERSTEP01_CMD_ARG_MAX_NB_BYTES][MAX_NUMBER_OF_DEVICES];
00058 uint8_t PowerStep01::spiRxBursts[POWERSTEP01_CMD_ARG_MAX_NB_BYTES][MAX_NUMBER_OF_DEVICES];
00059 
00060 
00061 /* Methods -------------------------------------------------------------------*/
00062 
00063 /**********************************************************
00064  * @brief Starts the Powerstep01 library
00065  * @param[in] pInit pointer to the initialization data
00066  * @retval COMPONENT_OK in case of success.
00067  **********************************************************/
00068 status_t PowerStep01::Powerstep01_Init(void* pInit)
00069 { 
00070   
00071   /* configure the step clock */
00072   Powerstep01_Board_StepClockInit();
00073   
00074   /* Standby-reset deactivation */
00075   Powerstep01_Board_ReleaseReset();
00076   
00077   /* Let a delay after reset */
00078   Powerstep01_Board_Delay(1);
00079 
00080   if (pInit == 0)
00081   {
00082     // Set all registers to their predefined values 
00083     // from powerstep01_target_config.h 
00084     Powerstep01_SetRegisterToPredefinedValues();
00085   }
00086   else
00087   {
00088     Powerstep01_SetDeviceParamsToGivenValues((powerstep01_init_u_t*) pInit);
00089   }
00090   
00091   // Put the Powerstep01 in HiZ state
00092   Powerstep01_CmdHardHiZ();
00093   
00094   Powerstep01_FetchAndClearAllStatus();
00095 
00096   return COMPONENT_OK;
00097 }
00098 
00099 /**********************************************************
00100  * @brief Read id
00101  * @param[in] id pointer to the identifier to be read.
00102  * @retval COMPONENT_OK in case of success.
00103  **********************************************************/
00104 status_t PowerStep01::Powerstep01_ReadID(uint8_t *id)
00105 {
00106   *id = deviceInstance;
00107 
00108   return COMPONENT_OK;
00109 }
00110 
00111 /**********************************************************
00112  * @brief  Attaches a user callback to the error Handler.
00113  * The call back will be then called each time the library 
00114  * detects an error
00115  * @param[in] callback Name of the callback to attach 
00116  * to the error Hanlder
00117  * @retval None
00118  **********************************************************/
00119 void PowerStep01::Powerstep01_AttachErrorHandler(void (*callback)(uint16_t error))
00120 {
00121   errorHandlerCallback = (void (*)(uint16_t error)) callback;
00122 }
00123 
00124 /**********************************************************
00125  * @brief  Issues the get_status command to the Powerstep01 device
00126  * @retval Status Register value
00127  * @note Once the get_status command is performed, the flags of the
00128  * status register are reset. 
00129  * This is not the case when the status register is read with the
00130  * GetParam command (via the functions Powerstep01_ReadStatusRegister
00131  * or Powerstep01_CmdGetParam).
00132  **********************************************************/
00133 uint16_t PowerStep01::Powerstep01_CmdGetStatus(void)
00134 {
00135   uint16_t status = 0;
00136   uint32_t loop;
00137   uint8_t spiIndex = numberOfDevices - deviceInstance - 1;
00138   bool itDisable = FALSE;  
00139  
00140   do
00141   {
00142     spiPreemptionByIsr = FALSE;
00143     if (itDisable)
00144     {
00145       /* re-enable Powerstep01_Board_EnableIrq if disable in previous iteration */
00146       Powerstep01_Board_EnableIrq();
00147       itDisable = FALSE;
00148     }    
00149     for (loop = 0; loop < numberOfDevices; loop++)
00150     {
00151        spiTxBursts[0][loop] = POWERSTEP01_NOP;
00152        spiTxBursts[1][loop] = POWERSTEP01_NOP;
00153        spiTxBursts[2][loop] = POWERSTEP01_NOP;
00154        spiTxBursts[3][loop] = POWERSTEP01_NOP;
00155        spiRxBursts[0][loop] = 0;
00156        spiRxBursts[1][loop] = 0;
00157        spiRxBursts[2][loop] = 0;
00158        spiRxBursts[3][loop] = 0;       
00159     }
00160     spiTxBursts[0][spiIndex] = POWERSTEP01_GET_STATUS;
00161     /* Disable interruption before checking */
00162     /* pre-emption by ISR and SPI transfers*/
00163     Powerstep01_Board_DisableIrq();
00164     itDisable = TRUE;
00165   } while (spiPreemptionByIsr); // check pre-emption by ISR  
00166   for (loop = 0; loop < POWERSTEP01_CMD_ARG_NB_BYTES_GET_STATUS + POWERSTEP01_RSP_NB_BYTES_GET_STATUS; loop++)
00167   {
00168      Powerstep01_WriteBytes(&spiTxBursts[loop][0], &spiRxBursts[loop][0]);
00169   }
00170   status = (spiRxBursts[1][spiIndex] << 8) | (spiRxBursts[2][spiIndex]);
00171   /* re-enable Powerstep01_Board_EnableIrq after SPI transfers*/
00172   Powerstep01_Board_EnableIrq();  
00173 
00174   return (status);
00175 }
00176 
00177 /**********************************************************
00178  * @brief  Requests the motor to move to the home position (ABS_POSITION = 0)
00179  * @retval None
00180  **********************************************************/
00181 void PowerStep01::Powerstep01_CmdGoHome(void)
00182 {
00183   Powerstep01_SendCommand(POWERSTEP01_GO_HOME, 0);
00184 } 
00185 
00186 /**********************************************************
00187  * @brief  Requests the motor to move to the mark position 
00188  * @retval None
00189  **********************************************************/
00190 void PowerStep01::Powerstep01_CmdGoMark(void)
00191 {
00192     Powerstep01_SendCommand(POWERSTEP01_GO_MARK, 0); 
00193 }
00194 
00195 /**********************************************************
00196  * @brief  Requests the motor to move to the specified position 
00197  * @param[in] targetPosition absolute position in steps
00198  * @retval None
00199  **********************************************************/
00200 void PowerStep01::Powerstep01_CmdGoTo(int32_t targetPosition)
00201 {
00202   Powerstep01_SendCommand(POWERSTEP01_GO_TO, targetPosition);
00203 }
00204 
00205 /******************************************************//**
00206  * @brief Issues PowerStep01 Go To Dir command
00207  * @param[in] direction movement direction
00208  * @param[in] abs_pos absolute position where requested to move
00209  * @retval None
00210  *********************************************************/
00211 void PowerStep01::Powerstep01_CmdGoToDir(motorDir_t direction,
00212                                          int32_t abs_pos)
00213 {
00214   Powerstep01_SendCommand((uint8_t)POWERSTEP01_GO_TO_DIR|
00215                           (uint8_t)direction, abs_pos);  
00216 }
00217 
00218 /******************************************************//**
00219  * @brief Issues PowerStep01 Go Until command
00220  * @param[in] action ACTION_RESET or ACTION_COPY
00221  * @param[in] direction movement direction
00222  * @param[in] speed in steps/tick
00223  * @retval None
00224  *********************************************************/
00225 void PowerStep01::Powerstep01_CmdGoUntil(motorAction_t action,
00226                             motorDir_t direction,
00227                             uint32_t speed)
00228 {
00229   Powerstep01_SendCommand(
00230     (uint8_t)POWERSTEP01_GO_UNTIL|(uint8_t)action|(uint8_t)direction,
00231     speed);
00232 }
00233 
00234 /**********************************************************
00235  * @brief Immediatly stops the motor and disable the power bridge
00236  * @retval None
00237  * @note The hard_hiz command immediately disables the power bridges
00238  * (high impedance state) and raises the HiZ flag. 
00239  * When the motor is stopped, a hard_hiz command forces the bridges 
00240  * to enter high impedance state.
00241  * This command can be given anytime and is immediately executed.
00242  *********************************************************/
00243 void PowerStep01::Powerstep01_CmdHardHiZ(void)
00244 {
00245   Powerstep01_SendCommand(POWERSTEP01_HARD_HIZ, 0);    
00246 }
00247 
00248 /**********************************************************
00249  * @brief  Immediatly stops the motor and disable the power bridge
00250  * @retval None
00251  * @note The hard_stop command causes an immediate motor stop with
00252  * infinite deceleration.
00253  * When the motor is in high impedance state, a hard_stop command
00254  * forces the bridges to exit high impedance state; no motion is performed.
00255  * This command can be given anytime and is immediately executed.
00256  * This command keeps the BUSY flag low until the motor is stopped.
00257  **********************************************************/
00258 void PowerStep01::Powerstep01_CmdHardStop(void) 
00259 {
00260   Powerstep01_SendCommand(POWERSTEP01_HARD_STOP, 0);
00261 }
00262 
00263 /**********************************************************
00264  * @brief  Moves the motor of the specified number of steps
00265  * @param[in] direction FORWARD or BACKWARD
00266  * @param[in] stepCount Number of steps to perform
00267  * @retval None
00268  **********************************************************/
00269 void PowerStep01::Powerstep01_CmdMove(motorDir_t direction,
00270                                       uint32_t stepCount)
00271 {
00272   Powerstep01_SendCommand((uint8_t)POWERSTEP01_MOVE|(uint8_t)direction,
00273     stepCount);
00274 }
00275 
00276 /**********************************************************
00277  * @brief  Issues the Nop command to the Powerstep01 device
00278  * @retval None
00279  **********************************************************/
00280 void PowerStep01::Powerstep01_CmdNop(void)
00281 {
00282   Powerstep01_SendCommand(POWERSTEP01_NOP, 0);
00283 }
00284 
00285 /******************************************************//**
00286  * @brief Issues PowerStep01 Release SW command
00287  * @param[in] action type of action to undertake when the SW
00288  * input is forced high
00289  * @param[in] direction movement direction
00290  * @retval None
00291  *********************************************************/
00292 void PowerStep01::Powerstep01_CmdReleaseSw(motorAction_t action,
00293                                            motorDir_t direction)
00294 {
00295    Powerstep01_SendCommand((uint8_t)POWERSTEP01_RELEASE_SW|
00296                            (uint8_t)action|
00297                            (uint8_t)direction,
00298                            0);
00299 }
00300 
00301 /******************************************************//**
00302  * @brief Issues PowerStep01 Reset Device command
00303  * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
00304  * @retval None
00305  *********************************************************/
00306 void PowerStep01::Powerstep01_CmdResetDevice(void)
00307 {
00308   Powerstep01_SendCommand(POWERSTEP01_RESET_DEVICE, 0);         
00309 }
00310 
00311 /******************************************************//**
00312  * @brief Issues PowerStep01 Reset Pos command
00313  * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
00314  * @retval None
00315  *********************************************************/
00316 void PowerStep01::Powerstep01_CmdResetPos(void)
00317 {
00318   Powerstep01_SendCommand(POWERSTEP01_RESET_POS, 0);       
00319 }
00320 
00321 /**********************************************************
00322  * @brief  Runs the motor. It will accelerate from the min 
00323  * speed up to the max speed by using the device acceleration.
00324  * @param[in] direction FORWARD or BACKWARD
00325  * @param[in] speed in steps/s
00326  * @retval None
00327  **********************************************************/
00328 void PowerStep01::Powerstep01_CmdRun(motorDir_t direction, uint32_t speed)
00329 {
00330   Powerstep01_SendCommand((uint8_t)POWERSTEP01_RUN|(uint8_t)direction, speed);
00331 }
00332 
00333 /**********************************************************
00334  * @brief Stops the motor by using the device deceleration
00335  * and disables the power bridges
00336  * @retval None
00337  * @note The soft_hiz command disables the power bridges
00338  * (high impedance state) after a deceleration to zero.
00339  * The deceleration value used is the one stored in the DEC register.
00340  * When bridges are disabled, the HiZ flag is raised.
00341  * When the motor is stopped, a soft_hiz command forces the bridges
00342  * to enter high impedance state.
00343  * This command can be given anytime and is immediately executed.
00344  * This command keeps the BUSY flag low until the motor is stopped.
00345  *********************************************************/
00346 void PowerStep01::Powerstep01_CmdSoftHiZ(void)
00347 {
00348   Powerstep01_SendCommand(POWERSTEP01_SOFT_HIZ, 0);           
00349 }
00350 
00351 /**********************************************************
00352  * @brief  Stops the motor by using the device deceleration
00353  * @retval None
00354  * @note The soft_stop command causes an immediate deceleration
00355  * to zero speed and a consequent motor stop.
00356  * The deceleration value used is the one stored in the DEC register.
00357  * When the motor is in high impedance state, a soft_stop
00358  * command forces the bridges to exit from high impedance state.
00359  * No motion is performed.
00360  * This command can be given anytime and is immediately executed.
00361  * This command keeps the BUSY flag low until the motor is stopped.
00362  **********************************************************/
00363 void PowerStep01::Powerstep01_CmdSoftStop(void)
00364 {   
00365   Powerstep01_SendCommand(POWERSTEP01_SOFT_STOP, 0);
00366 }
00367 
00368 /******************************************************//**
00369  * @brief Issues PowerStep01 Step Clock command
00370  * @param[in] direction Movement direction (FORWARD, BACKWARD)
00371  * @retval None
00372  *********************************************************/
00373 void PowerStep01::Powerstep01_CmdStepClock(motorDir_t direction)
00374 {
00375   Powerstep01_SendCommand((uint8_t)POWERSTEP01_STEP_CLOCK|(uint8_t)direction,
00376                           0);  
00377 }
00378 
00379 /**********************************************************
00380  * @brief Error handler which calls the user callback (if defined)
00381  * @param[in] error Number of the error
00382  * @retval None
00383  **********************************************************/
00384 void PowerStep01::Powerstep01_ErrorHandler(uint16_t error)
00385 {
00386   if (errorHandlerCallback != 0)
00387   {
00388     (void) errorHandlerCallback(error);
00389   }
00390   else   
00391   {
00392     /* Aborting the program. */
00393     exit(EXIT_FAILURE);
00394   }
00395 }
00396 
00397 /******************************************************//**
00398  * @brief Fetch and clear status flags of all devices 
00399  * by issuing a GET_STATUS command simultaneously  
00400  * to all devices.
00401  * Then, the fetched status of each device can be retrieved
00402  * by using the Powerstep01_GetFetchedStatus function
00403  * provided there is no other calls to functions which 
00404  * use the SPI in between.
00405  * @retval None
00406  *********************************************************/
00407 void PowerStep01::Powerstep01_FetchAndClearAllStatus(void)
00408 {
00409   uint8_t loop;
00410 
00411   for (loop = 0; loop < numberOfDevices; loop++)
00412   {
00413      spiTxBursts[0][loop] = POWERSTEP01_GET_STATUS;
00414      spiTxBursts[1][loop] = POWERSTEP01_NOP;
00415      spiTxBursts[2][loop] = POWERSTEP01_NOP;
00416      spiTxBursts[3][loop] = POWERSTEP01_NOP;
00417      spiRxBursts[0][loop] = 0;
00418      spiRxBursts[1][loop] = 0;
00419      spiRxBursts[2][loop] = 0;
00420      spiRxBursts[3][loop] = 0;
00421   }
00422   for (loop = 0; 
00423        loop < POWERSTEP01_CMD_ARG_NB_BYTES_GET_STATUS + 
00424               POWERSTEP01_RSP_NB_BYTES_GET_STATUS; 
00425        loop++)
00426   {
00427      Powerstep01_WriteBytes(&spiTxBursts[loop][0], &spiRxBursts[loop][0]);
00428   }
00429 }
00430 
00431 /******************************************************//**
00432  * @brief Get the value of the STATUS register which was 
00433  * fetched by using Powerstep01_FetchAndClearAllStatus.
00434  * The fetched values are available  as long as there
00435  * no other calls to functions which use the SPI.
00436  * @retval Last fetched value of the STATUS register
00437  *********************************************************/
00438 uint16_t PowerStep01::Powerstep01_GetFetchedStatus(void)
00439 {
00440   uint16_t status = 0;
00441   if (numberOfDevices > deviceInstance)
00442   {
00443     uint8_t spiIndex = numberOfDevices - deviceInstance - 1;
00444     status = (spiRxBursts[1][spiIndex] << 8) | (spiRxBursts[2][spiIndex]);
00445   }
00446   return (status);
00447 }
00448 
00449 /**********************************************************
00450  * @brief Returns the FW version of the library
00451  * @retval POWERSTEP01_FW_VERSION
00452  **********************************************************/
00453 uint32_t PowerStep01::Powerstep01_GetFwVersion(void)
00454 {
00455   return (POWERSTEP01_FW_VERSION);
00456 }
00457 
00458 /**********************************************************
00459  * @brief  Returns the mark position  device
00460  * @retval Mark register value converted in a 32b signed integer 
00461  **********************************************************/
00462 int32_t PowerStep01::Powerstep01_GetMark(void)
00463 {
00464   return Powerstep01_ConvertPosition(Powerstep01_CmdGetParam(POWERSTEP01_MARK));
00465 }
00466 
00467 /**********************************************************
00468  * @brief  Returns the ABS_POSITION device
00469  * @retval ABS_POSITION register value converted in a 32b signed integer
00470  **********************************************************/
00471 int32_t PowerStep01::Powerstep01_GetPosition(void)
00472 {
00473   return Powerstep01_ConvertPosition(
00474     Powerstep01_CmdGetParam(POWERSTEP01_ABS_POS));
00475 }
00476 
00477 /**********************************************************
00478  * @brief Checks if the device is busy
00479  * by reading the Busy flag bit of its status Register
00480  * This operation clears the status register
00481  * @retval true if device is busy, false zero
00482  *********************************************************/
00483 bool PowerStep01::Powerstep01_IsDeviceBusy(void)
00484 {
00485   if(!(Powerstep01_CmdGetStatus() & POWERSTEP01_STATUS_BUSY)) 
00486   {
00487     return TRUE;
00488   }
00489   else 
00490   {
00491     return FALSE;
00492   }
00493 }
00494 
00495 /**********************************************************
00496  * @brief  Reads the Status Register value
00497  * @retval Status register value
00498  * @note The status register flags are not cleared 
00499  * at the difference with Powerstep01_CmdGetStatus()
00500  **********************************************************/
00501 uint16_t PowerStep01::Powerstep01_ReadStatusRegister(void)
00502 {
00503   return (Powerstep01_CmdGetParam(POWERSTEP01_STATUS));
00504 }
00505 
00506 /**********************************************************
00507  * @brief  Set the stepping mode 
00508  * @param[in] stepMode from full step to 1/128 microstep
00509  * as specified in enum motorStepMode_t
00510  * @retval None
00511  **********************************************************/
00512 bool PowerStep01::Powerstep01_SelectStepMode(motorStepMode_t stepMode)
00513 {
00514   uint8_t stepModeRegister;
00515   powerstep01_StepSel_t powerstep01StepMode;
00516 
00517   switch (stepMode)
00518   {
00519     case STEP_MODE_FULL:
00520       powerstep01StepMode = POWERSTEP01_STEP_SEL_1;
00521       break;
00522     case STEP_MODE_HALF:
00523       powerstep01StepMode = POWERSTEP01_STEP_SEL_1_2;
00524       break;    
00525     case STEP_MODE_1_4:
00526       powerstep01StepMode = POWERSTEP01_STEP_SEL_1_4;
00527       break;        
00528     case STEP_MODE_1_8:
00529       powerstep01StepMode = POWERSTEP01_STEP_SEL_1_8;
00530       break;
00531     case STEP_MODE_1_16:
00532       powerstep01StepMode = POWERSTEP01_STEP_SEL_1_16;
00533       break;        
00534     case STEP_MODE_1_32:
00535       powerstep01StepMode = POWERSTEP01_STEP_SEL_1_32;
00536       break;
00537     case STEP_MODE_1_64:
00538       powerstep01StepMode = POWERSTEP01_STEP_SEL_1_64;
00539       break;
00540     case STEP_MODE_1_128:
00541       powerstep01StepMode = POWERSTEP01_STEP_SEL_1_128;
00542       break;
00543     default:
00544       return false;
00545   }
00546   
00547   /* Set the powerstep01 in HiZ state */
00548   Powerstep01_CmdHardHiZ();  
00549   
00550   /* Read Step mode register and clear STEP_SEL field */
00551   stepModeRegister = (uint8_t)(0xF8 & Powerstep01_CmdGetParam(POWERSTEP01_STEP_MODE)) ;
00552   
00553   /* Apply new step mode */
00554   Powerstep01_CmdSetParam(POWERSTEP01_STEP_MODE, stepModeRegister | (uint8_t)powerstep01StepMode);
00555 
00556   /* Reset abs pos register */
00557   Powerstep01_CmdResetPos();
00558 
00559   return true;
00560 }
00561 
00562 /**********************************************************
00563  * @brief  Set current position to be the Home position (ABS pos set to 0)
00564  * @retval None
00565  **********************************************************/
00566 void PowerStep01::Powerstep01_SetHome(void)
00567 {
00568   Powerstep01_CmdSetParam(POWERSTEP01_ABS_POS, 0);
00569 }
00570 
00571 /**********************************************************
00572  * @brief  Sets current position to be the Mark position 
00573  * @retval None
00574  **********************************************************/
00575 void PowerStep01::Powerstep01_SetMark(void)
00576 {
00577   Powerstep01_CmdSetParam(POWERSTEP01_MARK,
00578     Powerstep01_CmdGetParam(POWERSTEP01_ABS_POS));
00579 }                                                  
00580 
00581 /**********************************************************
00582  * @brief  Locks until the device state becomes Inactive
00583  * @retval None
00584  **********************************************************/
00585 void PowerStep01::Powerstep01_WaitWhileActive(void)
00586 {
00587   /* Wait while motor is running */
00588   while (Powerstep01_IsDeviceBusy() != 0);
00589 }
00590 
00591 /**
00592  * @brief To and from register parameter conversion functions
00593  */
00594 
00595 /**********************************************************
00596  * @brief  Converts the ABS_POSITION register value to a 32b signed integer
00597  * @param[in] abs_position_reg value of the ABS_POSITION register
00598  * @retval operation_result 32b signed integer corresponding to the absolute position 
00599  **********************************************************/
00600 int32_t PowerStep01::Powerstep01_ConvertPosition(uint32_t abs_position_reg)
00601 {
00602   int32_t operation_result;
00603 
00604   if (abs_position_reg & POWERSTEP01_ABS_POS_SIGN_BIT_MASK) 
00605   {
00606     /* Negative register value */
00607     abs_position_reg = ~abs_position_reg;
00608     abs_position_reg += 1;
00609 
00610     operation_result = (int32_t) (abs_position_reg & POWERSTEP01_ABS_POS_VALUE_MASK);
00611     operation_result = -operation_result;
00612   } 
00613   else 
00614   {
00615     operation_result = (int32_t) abs_position_reg;
00616   }
00617   return operation_result;
00618 }
00619 
00620 /**
00621  * @brief Functions to initialize the registers
00622  */
00623 
00624 /**********************************************************
00625  * @brief Set the parameters of the device to values of initPrm structure
00626  * @param[in] initPrm structure containing values to initialize the device
00627  * parameters
00628  * @retval None.
00629  **********************************************************/
00630 void PowerStep01::Powerstep01_SetDeviceParamsToGivenValues(
00631   powerstep01_init_u_t *initPrm)
00632 {
00633   Powerstep01_CmdSetParam(POWERSTEP01_ABS_POS, 0);
00634   Powerstep01_CmdSetParam(POWERSTEP01_EL_POS, 0);
00635   Powerstep01_CmdSetParam(POWERSTEP01_MARK, 0);
00636   Powerstep01_CmdSetParam(POWERSTEP01_ACC,
00637     acc_dec_steps_s2_to_reg_val(initPrm->cm.cp.acceleration));
00638   Powerstep01_CmdSetParam(POWERSTEP01_DEC,
00639     acc_dec_steps_s2_to_reg_val(initPrm->cm.cp.deceleration));
00640   Powerstep01_CmdSetParam(POWERSTEP01_MAX_SPEED,
00641     max_spd_steps_s_to_reg_val(initPrm->cm.cp.maxSpeed));
00642   Powerstep01_CmdSetParam(POWERSTEP01_MIN_SPEED,
00643     initPrm->cm.cp.lowSpeedOptimization|
00644     max_spd_steps_s_to_reg_val(initPrm->cm.cp.minSpeed));
00645   Powerstep01_CmdSetParam(POWERSTEP01_FS_SPD,
00646     initPrm->cm.cp.boostMode|
00647     fs_spd_steps_s_to_reg_val(initPrm->cm.cp.fullStepSpeed));
00648   Powerstep01_CmdSetParam(POWERSTEP01_OCD_TH,
00649     stall_ocd_th_to_reg_val(initPrm->cm.cp.ocdThreshold));
00650   Powerstep01_CmdSetParam(POWERSTEP01_STEP_MODE,
00651     (uint8_t)initPrm->cm.cp.syncClockSelection|
00652     (uint8_t)initPrm->cm.cp.cmVmSelection|
00653     (uint8_t)(uint8_t)initPrm->cm.cp.stepMode);
00654   Powerstep01_CmdSetParam(POWERSTEP01_ALARM_EN,
00655     initPrm->cm.cp.alarmsSelection);
00656   Powerstep01_CmdSetParam(POWERSTEP01_GATECFG1,
00657     (uint16_t)initPrm->cm.cp.iGate|
00658     (uint16_t)initPrm->cm.cp.tcc|
00659     (uint16_t)initPrm->cm.cp.tBoost|
00660     (uint16_t)initPrm->cm.cp.wdEn);
00661   Powerstep01_CmdSetParam(POWERSTEP01_GATECFG2,
00662     (uint16_t)initPrm->cm.cp.tBlank|
00663     (uint16_t)initPrm->cm.cp.tdt);  
00664   if (initPrm->cm.cp.cmVmSelection == POWERSTEP01_CM_VM_VOLTAGE)
00665   {
00666     //Voltage mode
00667     Powerstep01_CmdSetParam(POWERSTEP01_INT_SPD,
00668       int_spd_steps_s_to_reg_val(
00669         initPrm->vm.intersectSpeed));
00670     Powerstep01_CmdSetParam(POWERSTEP01_K_THERM,
00671       k_therm_comp_to_reg_val(
00672         initPrm->vm.thermalCompensationFactor)); 
00673     Powerstep01_CmdSetParam(POWERSTEP01_STALL_TH,
00674       stall_ocd_th_to_reg_val(
00675         initPrm->vm.stallThreshold));
00676     Powerstep01_CmdSetParam(POWERSTEP01_KVAL_HOLD,
00677       k_val_perc_to_reg_val(
00678         initPrm->vm.kvalHold));
00679     Powerstep01_CmdSetParam(POWERSTEP01_KVAL_RUN,
00680       k_val_perc_to_reg_val(
00681         initPrm->vm.kvalRun));
00682     Powerstep01_CmdSetParam(POWERSTEP01_KVAL_ACC,
00683       k_val_perc_to_reg_val(
00684         initPrm->vm.kvalAcc));
00685     Powerstep01_CmdSetParam(POWERSTEP01_KVAL_DEC,
00686       k_val_perc_to_reg_val(
00687         initPrm->vm.kvalDec));
00688     Powerstep01_CmdSetParam(POWERSTEP01_ST_SLP,
00689       bemf_slope_perc_to_reg_val(
00690         initPrm->vm.startSlope));
00691     Powerstep01_CmdSetParam(POWERSTEP01_FN_SLP_ACC,
00692       bemf_slope_perc_to_reg_val(
00693         initPrm->vm.accelerationFinalSlope));
00694     Powerstep01_CmdSetParam(POWERSTEP01_FN_SLP_DEC,
00695       bemf_slope_perc_to_reg_val(
00696         initPrm->vm.decelerationFinalSlope));
00697     Powerstep01_CmdSetParam(POWERSTEP01_CONFIG,
00698       (uint16_t)initPrm->vm.oscClkSel| 
00699       (uint16_t)initPrm->vm.swMode | 
00700       (uint16_t)initPrm->vm.enVsComp| 
00701       (uint16_t)initPrm->vm.ocSd| 
00702       (uint16_t)initPrm->vm.uvloVal| 
00703       (uint16_t)initPrm->vm.vccVal| 
00704       (uint16_t)initPrm->vm.fPwmInt| 
00705       (uint16_t)initPrm->vm.fPwmDec);
00706   }
00707   else
00708   {
00709     // Current mode
00710         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_HOLD,
00711           t_val_ref_voltage_to_reg_val(
00712             initPrm->cm.tvalHold));
00713         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_RUN,
00714           t_val_ref_voltage_to_reg_val(
00715             initPrm->cm.tvalRun));
00716         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_ACC,
00717           t_val_ref_voltage_to_reg_val(
00718             initPrm->cm.tvalAcc));
00719         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_DEC,
00720           t_val_ref_voltage_to_reg_val(
00721             initPrm->cm.tvalDec));
00722         Powerstep01_CmdSetParam(POWERSTEP01_T_FAST,
00723           (uint8_t)initPrm->cm.toffFast|
00724           (uint8_t)initPrm->cm.fastStep);
00725         Powerstep01_CmdSetParam(POWERSTEP01_TON_MIN,
00726           t_min_time_to_reg_val(
00727             initPrm->cm.tonMin));
00728         Powerstep01_CmdSetParam(POWERSTEP01_TOFF_MIN,
00729           t_min_time_to_reg_val(
00730             initPrm->cm.toffMin));       
00731         Powerstep01_CmdSetParam(POWERSTEP01_CONFIG,
00732           (uint16_t)initPrm->cm.oscClkSel| 
00733           (uint16_t)initPrm->cm.swMode| 
00734           (uint16_t)initPrm->cm.tqReg| 
00735           (uint16_t)initPrm->cm.ocSd| 
00736           (uint16_t)initPrm->cm.uvloVal| 
00737           (uint16_t)initPrm->cm.vccVal|
00738           (uint16_t)initPrm->cm.tsw|
00739           (uint16_t)initPrm->cm.predEn);
00740   }
00741 }
00742 
00743 /**********************************************************
00744  * @brief Sets the registers of the Powerstep01 to their predefined values 
00745  * from powerstep01_target_config.h
00746  * @retval None
00747  **********************************************************/
00748 void PowerStep01::Powerstep01_SetRegisterToPredefinedValues(void)
00749 {
00750   powerstep01_CmVm_t cmVm;
00751   
00752   Powerstep01_CmdSetParam(
00753     POWERSTEP01_ABS_POS,
00754     0);
00755   Powerstep01_CmdSetParam(
00756     POWERSTEP01_EL_POS,
00757     0);
00758   Powerstep01_CmdSetParam(
00759     POWERSTEP01_MARK,
00760     0);
00761   switch (deviceInstance)
00762   {
00763     case 0:
00764       cmVm = POWERSTEP01_CONF_PARAM_CM_VM_DEVICE_0;
00765       Powerstep01_CmdSetParam(POWERSTEP01_ACC,
00766         acc_dec_steps_s2_to_reg_val(
00767           POWERSTEP01_CONF_PARAM_ACC_DEVICE_0));
00768       Powerstep01_CmdSetParam(POWERSTEP01_DEC,
00769         acc_dec_steps_s2_to_reg_val(
00770           POWERSTEP01_CONF_PARAM_DEC_DEVICE_0));
00771       Powerstep01_CmdSetParam(POWERSTEP01_MAX_SPEED,
00772         max_spd_steps_s_to_reg_val(
00773           POWERSTEP01_CONF_PARAM_MAX_SPEED_DEVICE_0));
00774       Powerstep01_CmdSetParam(POWERSTEP01_MIN_SPEED,
00775         POWERSTEP01_CONF_PARAM_LSPD_BIT_DEVICE_0|
00776         min_spd_steps_s_to_reg_val(
00777           POWERSTEP01_CONF_PARAM_MIN_SPEED_DEVICE_0));
00778       Powerstep01_CmdSetParam(POWERSTEP01_FS_SPD,
00779         POWERSTEP01_CONF_PARAM_BOOST_MODE_DEVICE_0|
00780         fs_spd_steps_s_to_reg_val(
00781           POWERSTEP01_CONF_PARAM_FS_SPD_DEVICE_0)); 
00782       Powerstep01_CmdSetParam(POWERSTEP01_OCD_TH,
00783         (uint8_t)POWERSTEP01_CONF_PARAM_OCD_TH_DEVICE_0);
00784       Powerstep01_CmdSetParam(POWERSTEP01_STEP_MODE,
00785         (uint8_t)POWERSTEP01_CONF_PARAM_SYNC_MODE_DEVICE_0 |
00786         (uint8_t)POWERSTEP01_CONF_PARAM_CM_VM_DEVICE_0|
00787         (uint8_t)POWERSTEP01_CONF_PARAM_STEP_MODE_DEVICE_0);
00788       Powerstep01_CmdSetParam(POWERSTEP01_ALARM_EN,
00789         POWERSTEP01_CONF_PARAM_ALARM_EN_DEVICE_0);
00790       Powerstep01_CmdSetParam(POWERSTEP01_GATECFG1,
00791         (uint16_t)POWERSTEP01_CONF_PARAM_IGATE_DEVICE_0 | 
00792         (uint16_t)POWERSTEP01_CONF_PARAM_TCC_DEVICE_0   | 
00793         (uint16_t)POWERSTEP01_CONF_PARAM_TBOOST_DEVICE_0|
00794         (uint16_t)POWERSTEP01_CONF_PARAM_WD_EN_DEVICE_0);
00795       Powerstep01_CmdSetParam(POWERSTEP01_GATECFG2,
00796         (uint16_t)POWERSTEP01_CONF_PARAM_TBLANK_DEVICE_0 | 
00797         (uint16_t)POWERSTEP01_CONF_PARAM_TDT_DEVICE_0);
00798       // Voltage mode
00799       if (cmVm == POWERSTEP01_CM_VM_VOLTAGE)
00800       {
00801         Powerstep01_CmdSetParam(POWERSTEP01_INT_SPD,
00802           int_spd_steps_s_to_reg_val(
00803             POWERSTEP01_CONF_PARAM_INT_SPD_DEVICE_0));
00804         Powerstep01_CmdSetParam(POWERSTEP01_K_THERM,
00805           k_therm_comp_to_reg_val(
00806             POWERSTEP01_CONF_PARAM_K_THERM_DEVICE_0));
00807         Powerstep01_CmdSetParam(POWERSTEP01_STALL_TH,
00808           stall_ocd_th_to_reg_val(
00809             POWERSTEP01_CONF_PARAM_STALL_TH_DEVICE_0));
00810         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_HOLD,
00811           k_val_perc_to_reg_val(
00812             POWERSTEP01_CONF_PARAM_KVAL_HOLD_DEVICE_0));
00813         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_RUN,
00814           k_val_perc_to_reg_val(
00815             POWERSTEP01_CONF_PARAM_KVAL_RUN_DEVICE_0));
00816         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_ACC,
00817           k_val_perc_to_reg_val(
00818             POWERSTEP01_CONF_PARAM_KVAL_ACC_DEVICE_0));
00819         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_DEC,
00820           k_val_perc_to_reg_val(
00821             POWERSTEP01_CONF_PARAM_KVAL_DEC_DEVICE_0));
00822         Powerstep01_CmdSetParam(POWERSTEP01_ST_SLP,
00823           bemf_slope_perc_to_reg_val(
00824             POWERSTEP01_CONF_PARAM_ST_SLP_DEVICE_0));
00825         Powerstep01_CmdSetParam(POWERSTEP01_FN_SLP_ACC,
00826           bemf_slope_perc_to_reg_val(
00827             POWERSTEP01_CONF_PARAM_FN_SLP_ACC_DEVICE_0));  
00828         Powerstep01_CmdSetParam(POWERSTEP01_FN_SLP_DEC,
00829           bemf_slope_perc_to_reg_val(
00830             POWERSTEP01_CONF_PARAM_FN_SLP_DEC_DEVICE_0));
00831         Powerstep01_CmdSetParam(POWERSTEP01_CONFIG,
00832           (uint16_t)POWERSTEP01_CONF_PARAM_CLOCK_SETTING_DEVICE_0 | 
00833           (uint16_t)POWERSTEP01_CONF_PARAM_SW_MODE_DEVICE_0       | 
00834           (uint16_t)POWERSTEP01_CONF_PARAM_VS_COMP_DEVICE_0       | 
00835           (uint16_t)POWERSTEP01_CONF_PARAM_OC_SD_DEVICE_0         | 
00836           (uint16_t)POWERSTEP01_CONF_PARAM_UVLOVAL_DEVICE_0       | 
00837           (uint16_t)POWERSTEP01_CONF_PARAM_VCCVAL_DEVICE_0        | 
00838           (uint16_t)POWERSTEP01_CONF_PARAM_PWM_DIV_DEVICE_0       | 
00839           (uint16_t)POWERSTEP01_CONF_PARAM_PWM_MUL_DEVICE_0);
00840       }
00841       else
00842       {
00843         // Current mode
00844         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_HOLD,
00845           t_val_ref_voltage_to_reg_val(
00846             POWERSTEP01_CONF_PARAM_TVAL_HOLD_DEVICE_0));
00847         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_RUN,
00848           t_val_ref_voltage_to_reg_val(
00849             POWERSTEP01_CONF_PARAM_TVAL_RUN_DEVICE_0));
00850         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_ACC,
00851           t_val_ref_voltage_to_reg_val(
00852             POWERSTEP01_CONF_PARAM_TVAL_ACC_DEVICE_0));
00853         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_DEC,
00854           t_val_ref_voltage_to_reg_val(
00855             POWERSTEP01_CONF_PARAM_TVAL_DEC_DEVICE_0));
00856         Powerstep01_CmdSetParam(POWERSTEP01_T_FAST,
00857           (uint8_t)POWERSTEP01_CONF_PARAM_TOFF_FAST_DEVICE_0 |
00858           (uint8_t)POWERSTEP01_CONF_PARAM_FAST_STEP_DEVICE_0);
00859         Powerstep01_CmdSetParam(POWERSTEP01_TON_MIN,
00860           t_min_time_to_reg_val(
00861             POWERSTEP01_CONF_PARAM_TON_MIN_DEVICE_0));
00862         Powerstep01_CmdSetParam(POWERSTEP01_TOFF_MIN,
00863           t_min_time_to_reg_val(
00864             POWERSTEP01_CONF_PARAM_TOFF_MIN_DEVICE_0));
00865         Powerstep01_CmdSetParam(POWERSTEP01_CONFIG,
00866           (uint16_t)POWERSTEP01_CONF_PARAM_CLOCK_SETTING_DEVICE_0 | 
00867           (uint16_t)POWERSTEP01_CONF_PARAM_SW_MODE_DEVICE_0       | 
00868           (uint16_t)POWERSTEP01_CONF_PARAM_TQ_REG_DEVICE_0        | 
00869           (uint16_t)POWERSTEP01_CONF_PARAM_OC_SD_DEVICE_0         | 
00870           (uint16_t)POWERSTEP01_CONF_PARAM_UVLOVAL_DEVICE_0       | 
00871           (uint16_t)POWERSTEP01_CONF_PARAM_VCCVAL_DEVICE_0        | 
00872           (uint16_t)POWERSTEP01_CONF_PARAM_TSW_DEVICE_0           |
00873           (uint16_t)POWERSTEP01_CONF_PARAM_PRED_DEVICE_0);          
00874       }
00875       break;
00876 #if (MAX_NUMBER_OF_DEVICES > 1)
00877    case 1:
00878       cmVm = POWERSTEP01_CONF_PARAM_CM_VM_DEVICE_1;
00879       Powerstep01_CmdSetParam(POWERSTEP01_ACC,
00880         acc_dec_steps_s2_to_reg_val(
00881           POWERSTEP01_CONF_PARAM_ACC_DEVICE_1));
00882       Powerstep01_CmdSetParam(POWERSTEP01_DEC,
00883         acc_dec_steps_s2_to_reg_val(
00884           POWERSTEP01_CONF_PARAM_DEC_DEVICE_1));
00885       Powerstep01_CmdSetParam(POWERSTEP01_MAX_SPEED,
00886         max_spd_steps_s_to_reg_val(
00887           POWERSTEP01_CONF_PARAM_MAX_SPEED_DEVICE_1));
00888       Powerstep01_CmdSetParam(POWERSTEP01_MIN_SPEED,
00889         POWERSTEP01_CONF_PARAM_LSPD_BIT_DEVICE_1|
00890         min_spd_steps_s_to_reg_val(
00891           POWERSTEP01_CONF_PARAM_MIN_SPEED_DEVICE_1));
00892       Powerstep01_CmdSetParam(POWERSTEP01_FS_SPD,
00893         POWERSTEP01_CONF_PARAM_BOOST_MODE_DEVICE_1|
00894         fs_spd_steps_s_to_reg_val(
00895           POWERSTEP01_CONF_PARAM_FS_SPD_DEVICE_1)); 
00896       Powerstep01_CmdSetParam(POWERSTEP01_OCD_TH,
00897         (uint8_t)POWERSTEP01_CONF_PARAM_OCD_TH_DEVICE_1);
00898       Powerstep01_CmdSetParam(POWERSTEP01_STEP_MODE,
00899         (uint8_t)POWERSTEP01_CONF_PARAM_SYNC_MODE_DEVICE_1 |
00900         (uint8_t)POWERSTEP01_CONF_PARAM_CM_VM_DEVICE_1|
00901         (uint8_t)POWERSTEP01_CONF_PARAM_STEP_MODE_DEVICE_1);
00902       Powerstep01_CmdSetParam(POWERSTEP01_ALARM_EN,
00903         POWERSTEP01_CONF_PARAM_ALARM_EN_DEVICE_1);
00904       Powerstep01_CmdSetParam(POWERSTEP01_GATECFG1,
00905         (uint16_t)POWERSTEP01_CONF_PARAM_IGATE_DEVICE_1 | 
00906         (uint16_t)POWERSTEP01_CONF_PARAM_TCC_DEVICE_1   | 
00907         (uint16_t)POWERSTEP01_CONF_PARAM_TBOOST_DEVICE_1|
00908         (uint16_t)POWERSTEP01_CONF_PARAM_WD_EN_DEVICE_1);
00909       Powerstep01_CmdSetParam(POWERSTEP01_GATECFG2,
00910         (uint16_t)POWERSTEP01_CONF_PARAM_TBLANK_DEVICE_1 | 
00911         (uint16_t)POWERSTEP01_CONF_PARAM_TDT_DEVICE_1);
00912       // Voltage mode
00913       if (cmVm == POWERSTEP01_CM_VM_VOLTAGE)
00914       {
00915         Powerstep01_CmdSetParam(POWERSTEP01_INT_SPD,
00916           int_spd_steps_s_to_reg_val(
00917             POWERSTEP01_CONF_PARAM_INT_SPD_DEVICE_1));
00918         Powerstep01_CmdSetParam(POWERSTEP01_K_THERM,
00919           k_therm_comp_to_reg_val(
00920             POWERSTEP01_CONF_PARAM_K_THERM_DEVICE_1));
00921         Powerstep01_CmdSetParam(POWERSTEP01_STALL_TH,
00922           stall_ocd_th_to_reg_val(
00923             POWERSTEP01_CONF_PARAM_STALL_TH_DEVICE_1));
00924         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_HOLD,
00925           k_val_perc_to_reg_val(
00926             POWERSTEP01_CONF_PARAM_KVAL_HOLD_DEVICE_1));
00927         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_RUN,
00928           k_val_perc_to_reg_val(
00929             POWERSTEP01_CONF_PARAM_KVAL_RUN_DEVICE_1));
00930         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_ACC,
00931           k_val_perc_to_reg_val(
00932             POWERSTEP01_CONF_PARAM_KVAL_ACC_DEVICE_1));
00933         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_DEC,
00934           k_val_perc_to_reg_val(
00935             POWERSTEP01_CONF_PARAM_KVAL_DEC_DEVICE_1));
00936         Powerstep01_CmdSetParam(POWERSTEP01_ST_SLP,
00937           bemf_slope_perc_to_reg_val(
00938             POWERSTEP01_CONF_PARAM_ST_SLP_DEVICE_1));
00939         Powerstep01_CmdSetParam(POWERSTEP01_FN_SLP_ACC,
00940           bemf_slope_perc_to_reg_val(
00941             POWERSTEP01_CONF_PARAM_FN_SLP_ACC_DEVICE_1));  
00942         Powerstep01_CmdSetParam(POWERSTEP01_FN_SLP_DEC,
00943           bemf_slope_perc_to_reg_val(
00944             POWERSTEP01_CONF_PARAM_FN_SLP_DEC_DEVICE_1));
00945         Powerstep01_CmdSetParam(POWERSTEP01_CONFIG,
00946           (uint16_t)POWERSTEP01_CONF_PARAM_CLOCK_SETTING_DEVICE_1 | 
00947           (uint16_t)POWERSTEP01_CONF_PARAM_SW_MODE_DEVICE_1       | 
00948           (uint16_t)POWERSTEP01_CONF_PARAM_VS_COMP_DEVICE_1       | 
00949           (uint16_t)POWERSTEP01_CONF_PARAM_OC_SD_DEVICE_1         | 
00950           (uint16_t)POWERSTEP01_CONF_PARAM_UVLOVAL_DEVICE_1       | 
00951           (uint16_t)POWERSTEP01_CONF_PARAM_VCCVAL_DEVICE_1        | 
00952           (uint16_t)POWERSTEP01_CONF_PARAM_PWM_DIV_DEVICE_1       | 
00953           (uint16_t)POWERSTEP01_CONF_PARAM_PWM_MUL_DEVICE_1);
00954       }
00955       else
00956       {
00957         // Current mode
00958         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_HOLD,
00959           t_val_ref_voltage_to_reg_val(
00960             POWERSTEP01_CONF_PARAM_TVAL_HOLD_DEVICE_1));
00961         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_RUN,
00962           t_val_ref_voltage_to_reg_val(
00963             POWERSTEP01_CONF_PARAM_TVAL_RUN_DEVICE_1));
00964         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_ACC,
00965           t_val_ref_voltage_to_reg_val(
00966             POWERSTEP01_CONF_PARAM_TVAL_ACC_DEVICE_1));
00967         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_DEC,
00968           t_val_ref_voltage_to_reg_val(
00969             POWERSTEP01_CONF_PARAM_TVAL_DEC_DEVICE_1));
00970         Powerstep01_CmdSetParam(POWERSTEP01_T_FAST,
00971           (uint8_t)POWERSTEP01_CONF_PARAM_TOFF_FAST_DEVICE_1 |
00972           (uint8_t)POWERSTEP01_CONF_PARAM_FAST_STEP_DEVICE_1);
00973         Powerstep01_CmdSetParam(POWERSTEP01_TON_MIN,
00974           t_min_time_to_reg_val(
00975             POWERSTEP01_CONF_PARAM_TON_MIN_DEVICE_1));
00976         Powerstep01_CmdSetParam(POWERSTEP01_TOFF_MIN,
00977           t_min_time_to_reg_val(
00978             POWERSTEP01_CONF_PARAM_TOFF_MIN_DEVICE_1));
00979         Powerstep01_CmdSetParam(POWERSTEP01_CONFIG,
00980           (uint16_t)POWERSTEP01_CONF_PARAM_CLOCK_SETTING_DEVICE_1 | 
00981           (uint16_t)POWERSTEP01_CONF_PARAM_SW_MODE_DEVICE_1       | 
00982           (uint16_t)POWERSTEP01_CONF_PARAM_TQ_REG_DEVICE_1        | 
00983           (uint16_t)POWERSTEP01_CONF_PARAM_OC_SD_DEVICE_1         | 
00984           (uint16_t)POWERSTEP01_CONF_PARAM_UVLOVAL_DEVICE_1       | 
00985           (uint16_t)POWERSTEP01_CONF_PARAM_VCCVAL_DEVICE_1        | 
00986           (uint16_t)POWERSTEP01_CONF_PARAM_TSW_DEVICE_1           |
00987           (uint16_t)POWERSTEP01_CONF_PARAM_PRED_DEVICE_1);          
00988       }
00989       break;     
00990 #endif
00991 #if (MAX_NUMBER_OF_DEVICES > 2)
00992    case 2:
00993       cmVm = POWERSTEP01_CONF_PARAM_CM_VM_DEVICE_2;
00994       Powerstep01_CmdSetParam(POWERSTEP01_ACC,
00995         acc_dec_steps_s2_to_reg_val(
00996           POWERSTEP01_CONF_PARAM_ACC_DEVICE_2));
00997       Powerstep01_CmdSetParam(POWERSTEP01_DEC,
00998         acc_dec_steps_s2_to_reg_val(
00999           POWERSTEP01_CONF_PARAM_DEC_DEVICE_2));
01000       Powerstep01_CmdSetParam(POWERSTEP01_MAX_SPEED,
01001         max_spd_steps_s_to_reg_val(
01002           POWERSTEP01_CONF_PARAM_MAX_SPEED_DEVICE_2));
01003       Powerstep01_CmdSetParam(POWERSTEP01_MIN_SPEED,
01004         POWERSTEP01_CONF_PARAM_LSPD_BIT_DEVICE_2|
01005         min_spd_steps_s_to_reg_val(
01006           POWERSTEP01_CONF_PARAM_MIN_SPEED_DEVICE_2));
01007       Powerstep01_CmdSetParam(POWERSTEP01_FS_SPD,
01008         POWERSTEP01_CONF_PARAM_BOOST_MODE_DEVICE_2|
01009         fs_spd_steps_s_to_reg_val(
01010           POWERSTEP01_CONF_PARAM_FS_SPD_DEVICE_2)); 
01011       Powerstep01_CmdSetParam(POWERSTEP01_OCD_TH,
01012         (uint8_t)POWERSTEP01_CONF_PARAM_OCD_TH_DEVICE_2);
01013       Powerstep01_CmdSetParam(POWERSTEP01_STEP_MODE,
01014         (uint8_t)POWERSTEP01_CONF_PARAM_SYNC_MODE_DEVICE_2 |
01015         (uint8_t)POWERSTEP01_CONF_PARAM_CM_VM_DEVICE_2|
01016         (uint8_t)POWERSTEP01_CONF_PARAM_STEP_MODE_DEVICE_2);
01017       Powerstep01_CmdSetParam(POWERSTEP01_ALARM_EN,
01018         POWERSTEP01_CONF_PARAM_ALARM_EN_DEVICE_2);
01019       Powerstep01_CmdSetParam(POWERSTEP01_GATECFG1,
01020         (uint16_t)POWERSTEP01_CONF_PARAM_IGATE_DEVICE_2 | 
01021         (uint16_t)POWERSTEP01_CONF_PARAM_TCC_DEVICE_2   | 
01022         (uint16_t)POWERSTEP01_CONF_PARAM_TBOOST_DEVICE_2|
01023         (uint16_t)POWERSTEP01_CONF_PARAM_WD_EN_DEVICE_2);
01024       Powerstep01_CmdSetParam(POWERSTEP01_GATECFG2,
01025         (uint16_t)POWERSTEP01_CONF_PARAM_TBLANK_DEVICE_2 | 
01026         (uint16_t)POWERSTEP01_CONF_PARAM_TDT_DEVICE_2);
01027       // Voltage mode
01028       if (cmVm == POWERSTEP01_CM_VM_VOLTAGE)
01029       {
01030         Powerstep01_CmdSetParam(POWERSTEP01_INT_SPD,
01031           int_spd_steps_s_to_reg_val(
01032             POWERSTEP01_CONF_PARAM_INT_SPD_DEVICE_2));
01033         Powerstep01_CmdSetParam(POWERSTEP01_K_THERM,
01034           k_therm_comp_to_reg_val(
01035             POWERSTEP01_CONF_PARAM_K_THERM_DEVICE_2));
01036         Powerstep01_CmdSetParam(POWERSTEP01_STALL_TH,
01037           stall_ocd_th_to_reg_val(
01038             POWERSTEP01_CONF_PARAM_STALL_TH_DEVICE_2));
01039         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_HOLD,
01040           k_val_perc_to_reg_val(
01041             POWERSTEP01_CONF_PARAM_KVAL_HOLD_DEVICE_2));
01042         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_RUN,
01043           k_val_perc_to_reg_val(
01044             POWERSTEP01_CONF_PARAM_KVAL_RUN_DEVICE_2));
01045         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_ACC,
01046           k_val_perc_to_reg_val(
01047             POWERSTEP01_CONF_PARAM_KVAL_ACC_DEVICE_2));
01048         Powerstep01_CmdSetParam(POWERSTEP01_KVAL_DEC,
01049           k_val_perc_to_reg_val(
01050             POWERSTEP01_CONF_PARAM_KVAL_DEC_DEVICE_2));
01051         Powerstep01_CmdSetParam(POWERSTEP01_ST_SLP,
01052           bemf_slope_perc_to_reg_val(
01053             POWERSTEP01_CONF_PARAM_ST_SLP_DEVICE_2));
01054         Powerstep01_CmdSetParam(POWERSTEP01_FN_SLP_ACC,
01055           bemf_slope_perc_to_reg_val(
01056             POWERSTEP01_CONF_PARAM_FN_SLP_ACC_DEVICE_2));  
01057         Powerstep01_CmdSetParam(POWERSTEP01_FN_SLP_DEC,
01058           bemf_slope_perc_to_reg_val(
01059             POWERSTEP01_CONF_PARAM_FN_SLP_DEC_DEVICE_2));
01060         Powerstep01_CmdSetParam(POWERSTEP01_CONFIG,
01061           (uint16_t)POWERSTEP01_CONF_PARAM_CLOCK_SETTING_DEVICE_2 | 
01062           (uint16_t)POWERSTEP01_CONF_PARAM_SW_MODE_DEVICE_2       | 
01063           (uint16_t)POWERSTEP01_CONF_PARAM_VS_COMP_DEVICE_2       | 
01064           (uint16_t)POWERSTEP01_CONF_PARAM_OC_SD_DEVICE_2         | 
01065           (uint16_t)POWERSTEP01_CONF_PARAM_UVLOVAL_DEVICE_2       | 
01066           (uint16_t)POWERSTEP01_CONF_PARAM_VCCVAL_DEVICE_2        | 
01067           (uint16_t)POWERSTEP01_CONF_PARAM_PWM_DIV_DEVICE_2       | 
01068           (uint16_t)POWERSTEP01_CONF_PARAM_PWM_MUL_DEVICE_2);
01069       }
01070       else
01071       {
01072         // Current mode
01073         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_HOLD,
01074           t_val_ref_voltage_to_reg_val(
01075             POWERSTEP01_CONF_PARAM_TVAL_HOLD_DEVICE_2));
01076         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_RUN,
01077           t_val_ref_voltage_to_reg_val(
01078             POWERSTEP01_CONF_PARAM_TVAL_RUN_DEVICE_2));
01079         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_ACC,
01080           t_val_ref_voltage_to_reg_val(
01081             POWERSTEP01_CONF_PARAM_TVAL_ACC_DEVICE_2));
01082         Powerstep01_CmdSetParam(POWERSTEP01_TVAL_DEC,
01083           t_val_ref_voltage_to_reg_val(
01084             POWERSTEP01_CONF_PARAM_TVAL_DEC_DEVICE_2));
01085         Powerstep01_CmdSetParam(POWERSTEP01_T_FAST,
01086           (uint8_t)POWERSTEP01_CONF_PARAM_TOFF_FAST_DEVICE_2 |
01087           (uint8_t)POWERSTEP01_CONF_PARAM_FAST_STEP_DEVICE_2);
01088         Powerstep01_CmdSetParam(POWERSTEP01_TON_MIN,
01089           t_min_time_to_reg_val(
01090             POWERSTEP01_CONF_PARAM_TON_MIN_DEVICE_2));
01091         Powerstep01_CmdSetParam(POWERSTEP01_TOFF_MIN,
01092           t_min_time_to_reg_val(
01093             POWERSTEP01_CONF_PARAM_TOFF_MIN_DEVICE_2));
01094         Powerstep01_CmdSetParam(POWERSTEP01_CONFIG,
01095           (uint16_t)POWERSTEP01_CONF_PARAM_CLOCK_SETTING_DEVICE_2 | 
01096           (uint16_t)POWERSTEP01_CONF_PARAM_SW_MODE_DEVICE_2       | 
01097           (uint16_t)POWERSTEP01_CONF_PARAM_TQ_REG_DEVICE_2        | 
01098           (uint16_t)POWERSTEP01_CONF_PARAM_OC_SD_DEVICE_2         | 
01099           (uint16_t)POWERSTEP01_CONF_PARAM_UVLOVAL_DEVICE_2       | 
01100           (uint16_t)POWERSTEP01_CONF_PARAM_VCCVAL_DEVICE_2        | 
01101           (uint16_t)POWERSTEP01_CONF_PARAM_TSW_DEVICE_2           |
01102           (uint16_t)POWERSTEP01_CONF_PARAM_PRED_DEVICE_2);          
01103       }
01104       break;
01105 #endif
01106     default: ;
01107   }
01108 }
01109 
01110 /**
01111   * @brief Functions to get and set parameters using digital or analog values
01112   */
01113 
01114 /**********************************************************
01115  * @brief  Issues the GetParam command to the Powerstep01 device
01116  * @param[in] parameter Register adress (POWERSTEP01_ABS_POS,
01117  * POWERSTEP01_MARK,...)
01118  * @retval Register value
01119  **********************************************************/
01120 uint32_t PowerStep01::Powerstep01_CmdGetParam(powerstep01_Registers_t param)
01121 {
01122 
01123   uint32_t spiRxData;
01124   uint32_t loop;
01125   uint8_t maxArgumentNbBytes = 0;
01126   uint8_t spiIndex = numberOfDevices - deviceInstance - 1;
01127   bool itDisable = FALSE;
01128   
01129   do
01130   {
01131     spiPreemptionByIsr = FALSE;
01132     if (itDisable)
01133     {
01134       /* re-enable Powerstep01_Board_EnableIrq if disable in previous iteration */
01135       Powerstep01_Board_EnableIrq();
01136       itDisable = FALSE;
01137     }
01138     for (loop = 0; loop < numberOfDevices; loop++)
01139     {
01140       spiTxBursts[0][loop] = POWERSTEP01_NOP;
01141       spiTxBursts[1][loop] = POWERSTEP01_NOP;
01142       spiTxBursts[2][loop] = POWERSTEP01_NOP;
01143       spiTxBursts[3][loop] = POWERSTEP01_NOP;
01144       spiRxBursts[0][loop] = 0;
01145       spiRxBursts[1][loop] = 0;
01146       spiRxBursts[2][loop] = 0;
01147       spiRxBursts[3][loop] = 0;    
01148     }
01149     switch (param)
01150     {
01151       case POWERSTEP01_ABS_POS: 
01152       case POWERSTEP01_MARK:
01153       case POWERSTEP01_SPEED:
01154         spiTxBursts[0][spiIndex] = ((uint8_t)POWERSTEP01_GET_PARAM )| (param);
01155         maxArgumentNbBytes = 3;
01156         break;
01157       case POWERSTEP01_EL_POS:
01158       case POWERSTEP01_ACC:
01159       case POWERSTEP01_DEC:
01160       case POWERSTEP01_MAX_SPEED:
01161       case POWERSTEP01_MIN_SPEED:
01162       case POWERSTEP01_FS_SPD:
01163       case POWERSTEP01_INT_SPD:
01164       case POWERSTEP01_CONFIG:
01165       case POWERSTEP01_GATECFG1:
01166       case POWERSTEP01_STATUS:
01167         spiTxBursts[1][spiIndex] = ((uint8_t)POWERSTEP01_GET_PARAM )| (param);
01168         maxArgumentNbBytes = 2;
01169         break;
01170     default:
01171         spiTxBursts[2][spiIndex] = ((uint8_t)POWERSTEP01_GET_PARAM )| (param);
01172         maxArgumentNbBytes = 1;
01173     }
01174     /* Disable interruption before checking */
01175     /* pre-emption by ISR and SPI transfers*/
01176     Powerstep01_Board_DisableIrq();
01177     itDisable = TRUE;
01178   } while (spiPreemptionByIsr); // check pre-emption by ISR
01179   for (loop = POWERSTEP01_CMD_ARG_MAX_NB_BYTES-1-maxArgumentNbBytes;
01180        loop < POWERSTEP01_CMD_ARG_MAX_NB_BYTES;
01181        loop++)
01182   {
01183      Powerstep01_WriteBytes(&spiTxBursts[loop][0],
01184                            &spiRxBursts[loop][0]);
01185   }
01186   spiRxData = ((uint32_t)spiRxBursts[1][spiIndex] << 16)|
01187                (spiRxBursts[2][spiIndex] << 8) |
01188                (spiRxBursts[3][spiIndex]);    
01189   /* re-enable Powerstep01_Board_EnableIrq after SPI transfers*/
01190   Powerstep01_Board_EnableIrq();
01191   return (spiRxData);
01192 }
01193 
01194 /**********************************************************
01195  * @brief  Issues the SetParam command to the PowerStep01 device
01196  * @param[in] parameter Register adress (POWERSTEP01_ABS_POS,
01197  * POWERSTEP01_MARK,...)
01198  * @param[in] value Value to set in the register
01199  * @retval None
01200  **********************************************************/
01201 void PowerStep01::Powerstep01_CmdSetParam(powerstep01_Registers_t param,
01202   uint32_t value)
01203 {
01204   uint32_t loop;
01205   uint8_t maxArgumentNbBytes = 0;
01206   uint8_t spiIndex = numberOfDevices - deviceInstance - 1;
01207   bool itDisable = FALSE;
01208   
01209   do
01210   {
01211     spiPreemptionByIsr = FALSE;
01212     if (itDisable)
01213     {
01214       /* re-enable Powerstep01_Board_EnableIrq if disable in previous iteration */
01215       Powerstep01_Board_EnableIrq();
01216       itDisable = FALSE;
01217     }  
01218     for (loop = 0;loop < numberOfDevices; loop++)
01219     {
01220       spiTxBursts[0][loop] = POWERSTEP01_NOP;
01221       spiTxBursts[1][loop] = POWERSTEP01_NOP;
01222       spiTxBursts[2][loop] = POWERSTEP01_NOP;
01223       spiTxBursts[3][loop] = POWERSTEP01_NOP;
01224     }
01225     switch (param)
01226     {
01227       case POWERSTEP01_ABS_POS: ;
01228       case POWERSTEP01_MARK:
01229         spiTxBursts[0][spiIndex] = ((uint8_t)POWERSTEP01_SET_PARAM )| (param);
01230         spiTxBursts[1][spiIndex] = (uint8_t)(value >> 16);
01231         spiTxBursts[2][spiIndex] = (uint8_t)(value >> 8);
01232         maxArgumentNbBytes = 3;
01233         break;
01234       case POWERSTEP01_EL_POS:
01235       case POWERSTEP01_ACC:
01236       case POWERSTEP01_DEC:
01237       case POWERSTEP01_MAX_SPEED:
01238       case POWERSTEP01_MIN_SPEED:
01239       case POWERSTEP01_FS_SPD:
01240       case POWERSTEP01_INT_SPD:
01241       case POWERSTEP01_CONFIG:
01242       case POWERSTEP01_GATECFG1:
01243         spiTxBursts[1][spiIndex] = ((uint8_t)POWERSTEP01_SET_PARAM )| (param);
01244         spiTxBursts[2][spiIndex] = (uint8_t)(value >> 8);
01245         maxArgumentNbBytes = 2;
01246         break;
01247       default:
01248         spiTxBursts[2][spiIndex] = ((uint8_t)POWERSTEP01_SET_PARAM )| (param);
01249         maxArgumentNbBytes = 1;
01250     }
01251     spiTxBursts[3][spiIndex] = (uint8_t)(value);
01252     /* Disable interruption before checking */
01253     /* pre-emption by ISR and SPI transfers*/
01254     Powerstep01_Board_DisableIrq();
01255     itDisable = TRUE;
01256   } while (spiPreemptionByIsr); // check pre-emption by ISR  
01257   /* SPI transfer */
01258   for (loop = POWERSTEP01_CMD_ARG_MAX_NB_BYTES - 1 - maxArgumentNbBytes;
01259        loop < POWERSTEP01_CMD_ARG_MAX_NB_BYTES;
01260        loop++)
01261   {
01262     Powerstep01_WriteBytes(&spiTxBursts[loop][0],&spiRxBursts[loop][0]);
01263   }
01264   /* re-enable Powerstep01_Board_EnableIrq after SPI transfers*/
01265   Powerstep01_Board_EnableIrq();
01266 }
01267 
01268 /**********************************************************
01269  * @brief Issues PowerStep01 Get Parameter command and convert the result to
01270  * float value
01271  * @param[in] param PowerStep01 register address
01272  * @retval The parameter's float value.
01273  *********************************************************/
01274 float PowerStep01::Powerstep01_GetAnalogValue(powerstep01_Registers_t param)
01275 {
01276   bool voltageMode = ((POWERSTEP01_CM_VM_CURRENT&Powerstep01_CmdGetParam(POWERSTEP01_STEP_MODE))==0);
01277   uint32_t registerValue = Powerstep01_CmdGetParam((powerstep01_Registers_t) param);
01278   float value;
01279   switch (param)
01280   {
01281     case POWERSTEP01_ABS_POS:
01282     case POWERSTEP01_MARK:
01283       value = (float) Powerstep01_ConvertPosition(registerValue);
01284       break;
01285     case POWERSTEP01_ACC:
01286     case POWERSTEP01_DEC:
01287       value = acc_dec_reg_val_to_steps_s2(registerValue);
01288       break;
01289     case POWERSTEP01_SPEED:
01290       value = speed_reg_val_to_steps_s(registerValue);
01291       break;
01292     case POWERSTEP01_MAX_SPEED:
01293       value = max_spd_reg_val_to_steps_s(registerValue);
01294       break;
01295     case POWERSTEP01_MIN_SPEED:
01296       registerValue &= POWERSTEP01_MIN_SPEED_MASK;
01297       value = min_spd_reg_val_to_steps_s(registerValue);
01298       break;      
01299     case POWERSTEP01_FS_SPD:
01300       registerValue &= POWERSTEP01_FS_SPD_MASK;
01301       value = fs_spd_reg_val_to_steps_s(registerValue);
01302       break;
01303     case POWERSTEP01_INT_SPD:
01304       value = int_spd_reg_val_to_steps_s(registerValue);
01305       break;
01306     case POWERSTEP01_K_THERM:
01307       value = k_therm_reg_val_to_comp(registerValue);
01308       break;
01309     case POWERSTEP01_OCD_TH:
01310     case POWERSTEP01_STALL_TH:
01311       value = stall_ocd_reg_val_to_th(registerValue);
01312       break;
01313     case POWERSTEP01_KVAL_HOLD:  //POWERSTEP01_TVAL_HOLD
01314     case POWERSTEP01_KVAL_RUN:   //POWERSTEP01_TVAL_RUN
01315     case POWERSTEP01_KVAL_ACC:   //POWERSTEP01_TVAL_ACC
01316     case POWERSTEP01_KVAL_DEC:   //POWERSTEP01_TVAL_DEC
01317       if (voltageMode!=FALSE)  value = k_val_reg_val_to_perc(registerValue);
01318       else value = k_val_reg_val_to_perc(registerValue);     
01319       break;
01320     case POWERSTEP01_ST_SLP:
01321       if (voltageMode==FALSE) 
01322       {
01323         break;
01324       }      
01325     case POWERSTEP01_FN_SLP_ACC: //POWERSTEP01_TON_MIN
01326     case POWERSTEP01_FN_SLP_DEC: //POWERSTEP01_TOFF_MIN
01327       if (voltageMode!=FALSE) value = bemf_slope_reg_val_to_perc(registerValue);
01328       else value = t_min_reg_val_to_time(registerValue);
01329       break;
01330     default:
01331       value = (float) registerValue;
01332   }
01333   return value;
01334 }
01335 
01336 /******************************************************//**
01337  * @brief Put commands in queue before synchronous sending
01338  * done by calling Powerstep01_SendQueuedCommands.
01339  * Any call to functions that use the SPI between the calls of 
01340  * Powerstep01_QueueCommands and Powerstep01_SendQueuedCommands 
01341  * will corrupt the queue.
01342  * A command for each device of the daisy chain must be 
01343  * specified before calling Powerstep01_SendQueuedCommands.
01344  * @param[in] command Command to queue (all Powerstep01 commmands 
01345  * except POWERSTEP01_SET_PARAM, POWERSTEP01_GET_PARAM, 
01346  * POWERSTEP01_GET_STATUS)
01347  * @param[in] value argument of the command to queue
01348  * @retval None
01349  *********************************************************/
01350 void PowerStep01::Powerstep01_QueueCommands(uint8_t command, int32_t value)
01351 {
01352   if (numberOfDevices > deviceInstance)
01353   {
01354     uint8_t spiIndex = numberOfDevices - deviceInstance - 1;
01355     
01356     switch (command & DAISY_CHAIN_COMMAND_MASK)
01357     {
01358       case POWERSTEP01_RUN: ;
01359       case POWERSTEP01_MOVE: ;
01360       case POWERSTEP01_GO_TO: ;
01361       case POWERSTEP01_GO_TO_DIR: ;
01362       case POWERSTEP01_GO_UNTIL: ;
01363       case POWERSTEP01_GO_UNTIL_ACT_CPY:
01364        spiTxBursts[0][spiIndex] = command;
01365        spiTxBursts[1][spiIndex] = (uint8_t)(value >> 16);
01366        spiTxBursts[2][spiIndex] = (uint8_t)(value >> 8);
01367        spiTxBursts[3][spiIndex] = (uint8_t)(value);
01368        break;
01369       default:
01370        spiTxBursts[0][spiIndex] = POWERSTEP01_NOP;
01371        spiTxBursts[1][spiIndex] = POWERSTEP01_NOP;
01372        spiTxBursts[2][spiIndex] = POWERSTEP01_NOP;
01373        spiTxBursts[3][spiIndex] = command;
01374     }
01375   }
01376 }
01377 
01378 /**********************************************************
01379  * @brief  Sends a command to the device via the SPI
01380  * @param[in] command Command to send (all Powerstep01 commmands 
01381  * except POWERSTEP01_SET_PARAM, POWERSTEP01_GET_PARAM, 
01382  * POWERSTEP01_GET_STATUS)
01383  * @param[in] value arguments to send on 32 bits
01384  * @retval None
01385  **********************************************************/
01386 void PowerStep01::Powerstep01_SendCommand(uint8_t command, uint32_t value)
01387 {
01388   uint32_t loop;
01389   uint8_t maxArgumentNbBytes = 0;
01390   bool itDisable = FALSE;
01391   uint8_t spiIndex = numberOfDevices - deviceInstance - 1;
01392   
01393   do
01394   {
01395     spiPreemptionByIsr = FALSE;
01396     if (itDisable)
01397     {
01398       /* re-enable Powerstep01_Board_EnableIrq if disable in previous iteration */
01399       Powerstep01_Board_EnableIrq();
01400       itDisable = FALSE;
01401     }    
01402     for (loop = 0; loop < numberOfDevices; loop++)
01403     {
01404         spiTxBursts[0][loop] = POWERSTEP01_NOP;
01405         spiTxBursts[1][loop] = POWERSTEP01_NOP;
01406         spiTxBursts[2][loop] = POWERSTEP01_NOP;
01407         spiTxBursts[3][loop] = POWERSTEP01_NOP;   
01408     }
01409     switch (command & DAISY_CHAIN_COMMAND_MASK)
01410     {
01411       case POWERSTEP01_GO_TO:
01412       case POWERSTEP01_GO_TO_DIR:
01413         value = value & POWERSTEP01_ABS_POS_VALUE_MASK;
01414       case POWERSTEP01_RUN:
01415       case POWERSTEP01_MOVE:
01416       case POWERSTEP01_GO_UNTIL:
01417       case POWERSTEP01_GO_UNTIL_ACT_CPY:
01418         spiTxBursts[0][spiIndex] = command;
01419         spiTxBursts[1][spiIndex] = (uint8_t)(value >> 16);
01420         spiTxBursts[2][spiIndex] = (uint8_t)(value >> 8);
01421         spiTxBursts[3][spiIndex] = (uint8_t)(value);
01422         maxArgumentNbBytes = 3;
01423         break;
01424     default:
01425         spiTxBursts[0][spiIndex] = POWERSTEP01_NOP;
01426         spiTxBursts[1][spiIndex] = POWERSTEP01_NOP;
01427         spiTxBursts[2][spiIndex] = POWERSTEP01_NOP;
01428         spiTxBursts[3][spiIndex] = command;
01429     }
01430     /* Disable interruption before checking */
01431     /* pre-emption by ISR and SPI transfers*/
01432     Powerstep01_Board_DisableIrq();
01433     itDisable = TRUE;
01434   } while (spiPreemptionByIsr); // check pre-emption by ISR
01435   for (loop = POWERSTEP01_CMD_ARG_MAX_NB_BYTES - 1 - maxArgumentNbBytes; 
01436        loop < POWERSTEP01_CMD_ARG_MAX_NB_BYTES; 
01437        loop++)
01438   {
01439      Powerstep01_WriteBytes(&spiTxBursts[loop][0], &spiRxBursts[loop][0]);
01440   }
01441   /* re-enable Powerstep01_Board_EnableIrq after SPI transfers*/
01442   Powerstep01_Board_EnableIrq();
01443 }
01444 
01445 /******************************************************//**
01446  * @brief Sends commands stored previously in the queue by 
01447  * Powerstep01_QueueCommands
01448  * @retval None
01449  *********************************************************/
01450 void PowerStep01::Powerstep01_SendQueuedCommands(void)
01451 {
01452   uint8_t loop;
01453   
01454   for (loop = 0; 
01455        loop < POWERSTEP01_CMD_ARG_MAX_NB_BYTES; 
01456        loop++)
01457   {
01458      Powerstep01_WriteBytes(&spiTxBursts[loop][0], &spiRxBursts[loop][0]);
01459   }
01460 }
01461 
01462 /**********************************************************
01463  * @brief Issues the SetParam command to the PowerStep01
01464  * @param[in] param PowerStep01 Register address
01465  * @param[in] value Float value to convert and set into the register
01466  * @retval TRUE if param is valid, FALSE otherwise
01467  *********************************************************/
01468 bool PowerStep01::Powerstep01_SetAnalogValue(powerstep01_Registers_t param, float value)
01469 {
01470   uint32_t registerValue;
01471   bool result = TRUE;
01472   bool voltageMode = ((POWERSTEP01_CM_VM_CURRENT&Powerstep01_CmdGetParam(POWERSTEP01_STEP_MODE))==0);
01473   if ((value < 0)&&((param != POWERSTEP01_ABS_POS)&&(param != POWERSTEP01_MARK)))
01474   {
01475     result = FALSE;
01476   }
01477   switch (param)
01478   {
01479     case POWERSTEP01_EL_POS:
01480       if ((value > (POWERSTEP01_ELPOS_STEP_MASK|POWERSTEP01_ELPOS_MICROSTEP_MASK))||
01481           ((value!=0)&&(value < (1<<(7-(POWERSTEP01_STEP_MODE_STEP_SEL&Powerstep01_CmdGetParam(POWERSTEP01_STEP_MODE))))))) {
01482           result = FALSE;
01483       } else {
01484           registerValue = ((uint32_t) value)&(POWERSTEP01_ELPOS_STEP_MASK|POWERSTEP01_ELPOS_MICROSTEP_MASK);
01485       }
01486       break;        
01487     case POWERSTEP01_ABS_POS:
01488     case POWERSTEP01_MARK:
01489       if (value < 0)
01490       {
01491         value=-value;
01492         if (((uint32_t)value)<=(POWERSTEP01_MAX_POSITION+1)) {
01493             registerValue = (POWERSTEP01_ABS_POS_VALUE_MASK+1-(uint32_t)value)&POWERSTEP01_ABS_POS_VALUE_MASK;
01494         } else {
01495             result = FALSE;  
01496         }
01497       }
01498       else
01499       {
01500         if (((uint32_t)value)<=POWERSTEP01_MAX_POSITION) {
01501             registerValue = ((uint32_t) value)&POWERSTEP01_ABS_POS_VALUE_MASK;
01502         } else {
01503             result = FALSE; 
01504         }
01505       }
01506       break;
01507     case POWERSTEP01_ACC:
01508     case POWERSTEP01_DEC:
01509       if (value > POWERSTEP01_ACC_DEC_MAX_VALUE) {
01510           result = FALSE;
01511       } else {
01512           registerValue = acc_dec_steps_s2_to_reg_val(value);
01513       }
01514       break;
01515     case POWERSTEP01_MAX_SPEED:
01516       if (value > POWERSTEP01_MAX_SPEED_MAX_VALUE) {
01517           result = FALSE;
01518       } else {
01519           registerValue = max_spd_steps_s_to_reg_val(value);
01520       }
01521       break;
01522     case POWERSTEP01_MIN_SPEED:
01523       if (value > POWERSTEP01_MIN_SPEED_MAX_VALUE) {
01524           result = FALSE;
01525       } else {
01526           registerValue = (POWERSTEP01_LSPD_OPT&Powerstep01_CmdGetParam(param))|min_spd_steps_s_to_reg_val(value);
01527       }
01528       break;      
01529     case POWERSTEP01_FS_SPD:
01530       if (value > POWERSTEP01_FS_SPD_MAX_VALUE) {
01531           result = FALSE;
01532       } else {
01533           registerValue = (POWERSTEP01_BOOST_MODE&Powerstep01_CmdGetParam(param))|fs_spd_steps_s_to_reg_val(value);
01534       }
01535       break;
01536     case POWERSTEP01_INT_SPD:
01537       if (value > POWERSTEP01_INT_SPD_MAX_VALUE) {
01538           result = FALSE;
01539       } else {
01540           registerValue = int_spd_steps_s_to_reg_val(value);
01541       }
01542       break;
01543     case POWERSTEP01_K_THERM:
01544       if ((value < POWERSTEP01_K_THERM_MIN_VALUE)||
01545           (value > POWERSTEP01_K_THERM_MAX_VALUE)) {
01546           result = FALSE;
01547       } else {
01548           registerValue = k_therm_comp_to_reg_val(value);
01549       }
01550       break;
01551     case POWERSTEP01_OCD_TH:
01552     case POWERSTEP01_STALL_TH:
01553       if (value > POWERSTEP01_STALL_OCD_TH_MAX_VALUE) {
01554           result = FALSE;
01555       } else {
01556           registerValue = stall_ocd_th_to_reg_val(value);
01557       }
01558       break;
01559     case POWERSTEP01_KVAL_HOLD:  //POWERSTEP01_TVAL_HOLD
01560     case POWERSTEP01_KVAL_RUN:   //POWERSTEP01_TVAL_RUN
01561     case POWERSTEP01_KVAL_ACC:   //POWERSTEP01_TVAL_ACC
01562     case POWERSTEP01_KVAL_DEC:   //POWERSTEP01_TVAL_DEC
01563       if (voltageMode==FALSE)
01564       {
01565         if (value > POWERSTEP01_TVAL_MAX_VALUE) {
01566             result = FALSE;
01567         } else {
01568             registerValue = t_val_ref_voltage_to_reg_val(value);
01569         }
01570       }
01571       else
01572       {
01573         if (value > POWERSTEP01_KVAL_MAX_VALUE) {
01574             result = FALSE;
01575         } else {
01576             registerValue = k_val_perc_to_reg_val(value);
01577         }
01578       }
01579       break;
01580     case POWERSTEP01_ST_SLP:
01581       if (voltageMode==FALSE) 
01582       {
01583         result = FALSE;
01584         break;
01585       }
01586     case POWERSTEP01_FN_SLP_ACC: //POWERSTEP01_TON_MIN
01587     case POWERSTEP01_FN_SLP_DEC: //POWERSTEP01_TOFF_MIN
01588       if (voltageMode==FALSE)
01589       {
01590         if (value>POWERSTEP01_TOFF_TON_MIN_MAX_VALUE) {
01591             result = FALSE;
01592         } else {
01593             registerValue = t_min_time_to_reg_val(value);
01594         }
01595       }
01596       else
01597       {
01598         if (value > POWERSTEP01_SLP_MAX_VALUE) {
01599             result = FALSE;
01600         } else {
01601             registerValue = bemf_slope_perc_to_reg_val(value);
01602         }
01603       }
01604       break;
01605     default:
01606       result = FALSE;
01607   }
01608   if (result!=FALSE)
01609   {
01610     Powerstep01_CmdSetParam(param, registerValue);
01611   }
01612   return result;
01613 }
01614 
01615 /**********************************************************
01616  * @brief Write and receive a byte via SPI
01617  * @param[in] pByteToTransmit pointer to the byte to transmit
01618  * @param[in] pReceivedByte pointer to the received byte
01619  * @retval None
01620  *********************************************************/
01621 void PowerStep01::Powerstep01_WriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte)
01622 {
01623   if (Powerstep01_Board_SpiWriteBytes(pByteToTransmit, pReceivedByte) != 0)
01624   {
01625     Powerstep01_ErrorHandler(POWERSTEP01_ERROR_1);
01626   }
01627   if (isrFlag)
01628   {
01629     spiPreemptionByIsr = TRUE;
01630   }
01631 }
01632 
01633 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/