X-CUBE-SPN1-20150128 example source code for one motor compiled under mbed. Tested OK on Nucleo F401. l6474.cpp is modified from original with defines in l6474_target_config.h to select the original behaviour (motor de-energised when halted), or new mode to continue powering with a (reduced) current in the coils (braking/position hold capability). On F401 avoid using mbed's InterruptIn on pins 10-15 (any port). Beware of other conflicts! L0 & F0 are included but untested.

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
gregeric
Date:
Sat Sep 05 20:18:14 2015 +0000
Child:
1:75a41f0c0586
Commit message:
X-CUBE-SPN1-20150128 example source code for one motor compiled under mbed. Tested OK on Nucleo F401. On F401 avoid using mbed's InterruptIn on pins 10-15 (any port). Beware of other conflicts!; ; L0 & F0 are included but untested.

Changed in this revision

IHM01A1/l6474.cpp Show annotated file Show diff for this revision Revisions of this file
IHM01A1/l6474.h Show annotated file Show diff for this revision Revisions of this file
IHM01A1/l6474_target_config.h Show annotated file Show diff for this revision Revisions of this file
IHM01A1/motor.h Show annotated file Show diff for this revision Revisions of this file
IHM01A1/motorcontrol.cpp Show annotated file Show diff for this revision Revisions of this file
IHM01A1/motorcontrol.h Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stdint.h Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32f0xx_hal_msp.cpp Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32f0xx_it.cpp Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32f0xx_it.h Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32f0xx_nucleo_ihm01a1.cpp Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32f0xx_nucleo_ihm01a1.h Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32f4xx_hal_msp.cpp Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32f4xx_it.cpp Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32f4xx_it.h Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32f4xx_nucleo_ihm01a1.cpp Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32f4xx_nucleo_ihm01a1.h Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32l0xx_hal_msp.cpp Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32l0xx_it.cpp Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32l0xx_it.h Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32l0xx_nucleo_ihm01a1.cpp Show annotated file Show diff for this revision Revisions of this file
IHM01A1/stm32l0xx_nucleo_ihm01a1.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/l6474.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,1674 @@
+/**
+  ******************************************************************************
+  * @file    l6474.c
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   L6474 driver (fully integrated microstepping motor driver)
+  * @note    (C) COPYRIGHT 2014 STMicroelectronics
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "l6474.h"
+
+/* Private constants  ---------------------------------------------------------*/
+
+    
+/** @addtogroup BSP
+  * @{
+  */   
+   
+/** @defgroup L6474
+  * @{
+  */   
+
+/* Private constants ---------------------------------------------------------*/    
+
+/** @defgroup L6474_Private_Constants
+  * @{
+  */   
+
+/// Error while initialising the SPI
+#define L6474_ERROR_0   (0x8000)   
+/// Error: Bad SPI transaction
+#define L6474_ERROR_1   (0x8001)
+    
+/// Maximum number of steps
+#define MAX_STEPS         (0x7FFFFFFF)
+
+/// Maximum frequency of the PWMs in Hz
+#define L6474_MAX_PWM_FREQ   (10000)
+
+/// Minimum frequency of the PWMs in Hz
+#define L6474_MIN_PWM_FREQ   (2)
+    
+/**
+  * @}
+  */ 
+    
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup L6474_Private_Variables
+  * @{
+  */       
+    
+/// Function pointer to flag interrupt call back
+void (*flagInterruptCallback)(void);
+/// Function pointer to error handler call back
+void (*errorHandlerCallback)(uint16_t);
+static volatile uint8_t numberOfDevices;
+static uint8_t spiTxBursts[L6474_CMD_ARG_MAX_NB_BYTES][MAX_NUMBER_OF_DEVICES];
+static uint8_t spiRxBursts[L6474_CMD_ARG_MAX_NB_BYTES][MAX_NUMBER_OF_DEVICES];
+static volatile bool spiPreemtionByIsr = FALSE;
+static volatile bool isrFlag = FALSE;
+static uint16_t l6474DriverInstance = 0;
+
+/// L6474 Device Paramaters structure
+deviceParams_t devicePrm[MAX_NUMBER_OF_DEVICES];
+
+
+/**
+  * @}
+  */ 
+
+/* Private function prototypes -----------------------------------------------*/
+
+/** @defgroup L6474_Private_functions
+  * @{
+  */  
+void L6474_ApplySpeed(uint8_t pwmId, uint16_t newSpeed);
+void L6474_ComputeSpeedProfile(uint8_t deviceId, uint32_t nbSteps);
+int32_t L6474_ConvertPosition(uint32_t abs_position_reg); 
+void L6474_ErrorHandler(uint16_t error);
+void L6474_FlagInterruptHandler(void);                      
+void L6474_SendCommand(uint8_t deviceId, uint8_t param);
+void L6474_SetRegisterToPredefinedValues(uint8_t deviceId);
+void L6474_WriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte);    
+void L6474_SetDeviceParamsToPredefinedValues(void);
+void L6474_StartMovement(uint8_t deviceId);
+void L6474_StepClockHandler(uint8_t deviceId);  
+uint8_t L6474_Tval_Current_to_Par(double Tval);
+uint8_t L6474_Tmin_Time_to_Par(double Tmin);
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup L6474_Exported_Variables
+  * @{
+  */       
+
+/// L6474 motor driver functions pointer structure 
+motorDrv_t   l6474Drv = 
+{
+  L6474_Init,
+  L6474_ReadId,
+  L6474_AttachErrorHandler,
+  L6474_AttachFlagInterrupt,
+  0,
+  L6474_FlagInterruptHandler,
+  L6474_GetAcceleration,
+  L6474_GetCurrentSpeed,
+  L6474_GetDeceleration,
+  L6474_GetDeviceState,
+  L6474_GetFwVersion,
+  L6474_GetMark,
+  L6474_GetMaxSpeed,
+  L6474_GetMinSpeed,
+  L6474_GetPosition,
+  L6474_GoHome,
+  L6474_GoMark,
+  L6474_GoTo,
+  L6474_HardStop,
+  L6474_Move,
+  L6474_ResetAllDevices,
+  L6474_Run,
+  L6474_SetAcceleration,
+  L6474_SetDeceleration,
+  L6474_SetHome,
+  L6474_SetMark,
+  L6474_SetMaxSpeed,
+  L6474_SetMinSpeed,
+  L6474_SoftStop,
+  L6474_StepClockHandler,    
+  L6474_WaitWhileActive,
+  L6474_CmdDisable,
+  L6474_CmdEnable,
+  L6474_CmdGetParam,
+  L6474_CmdGetStatus,
+  L6474_CmdNop,
+  L6474_CmdSetParam,
+  L6474_ReadStatusRegister,
+  L6474_ReleaseReset,
+  L6474_Reset,
+  L6474_SelectStepMode,
+  L6474_SetDirection,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  L6474_ErrorHandler,
+  0
+};
+
+/**
+  * @}
+  */ 
+
+/** @defgroup Device_Control_Functions
+  * @{
+  */   
+
+/******************************************************//**
+ * @brief  Attaches a user callback to the error Handler.
+ * The call back will be then called each time the library 
+ * detects an error
+ * @param[in] callback Name of the callback to attach 
+ * to the error Hanlder
+ * @retval None
+ **********************************************************/
+void L6474_AttachErrorHandler(void (*callback)(uint16_t))
+{
+  errorHandlerCallback = (void (*)(uint16_t))callback;
+}
+
+/******************************************************//**
+ * @brief  Attaches a user callback to the flag Interrupt
+ * The call back will be then called each time the status 
+ * flag pin will be pulled down due to the occurrence of 
+ * a programmed alarms ( OCD, thermal pre-warning or 
+ * shutdown, UVLO, wrong command, non-performable command)
+ * @param[in] callback Name of the callback to attach 
+ * to the Flag Interrupt
+ * @retval None
+ **********************************************************/
+void L6474_AttachFlagInterrupt(void (*callback)(void))
+{
+  flagInterruptCallback = (void (*)())callback;
+}
+
+/******************************************************//**
+ * @brief Starts the L6474 library
+ * @param[in] nbDevices Number of L6474 devices to use (from 1 to 3)
+ * @retval None
+ **********************************************************/
+void L6474_Init(uint8_t nbDevices)
+{
+  uint32_t i;
+  numberOfDevices = nbDevices;
+  
+  l6474DriverInstance++;
+  
+  /* Initialise the GPIOs */
+  BSP_MotorControlBoard_GpioInit(nbDevices);
+  
+  if(BSP_MotorControlBoard_SpiInit() != 0)
+  {
+    /* Initialization Error */
+    L6474_ErrorHandler(L6474_ERROR_0);
+  } 
+
+  /* Initialise the PWMs used for the Step clocks ----------------------------*/
+  switch (nbDevices)
+  {
+    case 3:
+      BSP_MotorControlBoard_PwmInit(2);
+    case 2:
+      BSP_MotorControlBoard_PwmInit(1);
+    case 1:
+      BSP_MotorControlBoard_PwmInit(0);
+    default:
+      ;
+  }
+ 
+  /* Initialise the L6474s ------------------------------------------------*/
+  
+  /* Standby-reset deactivation */
+  BSP_MotorControlBoard_ReleaseReset();
+  
+  /* Let a delay after reset */
+  BSP_MotorControlBoard_Delay(1); 
+  
+  /* Set all registers and context variables to the predefined values from l6474_target_config.h */
+  L6474_SetDeviceParamsToPredefinedValues();
+  
+  /* Disable L6474 powerstage */
+  for (i = 0; i < nbDevices; i++)
+  {
+    L6474_CmdDisable(i);
+    /* Get Status to clear flags after start up */
+    L6474_CmdGetStatus(i);
+  }
+}
+
+/******************************************************//**
+ * @brief Returns the acceleration of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Acceleration in pps^2
+ **********************************************************/
+uint16_t L6474_GetAcceleration(uint8_t deviceId)
+{                                                  
+  return (devicePrm[deviceId].acceleration);
+}            
+
+/******************************************************//**
+ * @brief Returns the current speed of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Speed in pps
+ **********************************************************/
+uint16_t L6474_GetCurrentSpeed(uint8_t deviceId)
+{
+  return devicePrm[deviceId].speed;
+}
+
+/******************************************************//**
+ * @brief Returns the deceleration of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Deceleration in pps^2
+ **********************************************************/
+uint16_t L6474_GetDeceleration(uint8_t deviceId)
+{                                                  
+  return (devicePrm[deviceId].deceleration);
+}          
+
+/******************************************************//**
+ * @brief Returns the device state
+ * @param[in] deviceId (from 0 to 2)
+ * @retval State (ACCELERATING, DECELERATING, STEADY or INACTIVE)
+ **********************************************************/
+motorState_t L6474_GetDeviceState(uint8_t deviceId)
+{
+  return devicePrm[deviceId].motionState;
+}
+
+/******************************************************//**
+ * @brief Returns the FW version of the library
+ * @param None
+ * @retval L6474_FW_VERSION
+ **********************************************************/
+uint8_t L6474_GetFwVersion(void)
+{
+  return (L6474_FW_VERSION);
+}
+
+/******************************************************//**
+ * @brief  Return motor handle (pointer to the L6474 motor driver structure)
+ * @param None
+ * @retval Pointer to the motorDrv_t structure
+ **********************************************************/
+motorDrv_t* L6474_GetMotorHandle(void)
+{
+  return (&l6474Drv);
+}
+
+/******************************************************//**
+ * @brief  Returns the mark position  of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Mark register value converted in a 32b signed integer 
+ **********************************************************/
+int32_t L6474_GetMark(uint8_t deviceId)
+{
+  return L6474_ConvertPosition(L6474_CmdGetParam(deviceId,L6474_MARK));
+}
+
+/******************************************************//**
+ * @brief  Returns the max speed of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval maxSpeed in pps
+ **********************************************************/
+uint16_t L6474_GetMaxSpeed(uint8_t deviceId)
+{                                                  
+  return (devicePrm[deviceId].maxSpeed);
+}
+
+/******************************************************//**
+ * @brief  Returns the min speed of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval minSpeed in pps
+ **********************************************************/
+uint16_t L6474_GetMinSpeed(uint8_t deviceId)
+{                                                  
+  return (devicePrm[deviceId].minSpeed);
+}                                                     
+
+/******************************************************//**
+ * @brief  Returns the ABS_POSITION of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval ABS_POSITION register value converted in a 32b signed integer
+ **********************************************************/
+int32_t L6474_GetPosition(uint8_t deviceId)
+{
+  return L6474_ConvertPosition(L6474_CmdGetParam(deviceId,L6474_ABS_POS));
+}
+
+
+
+/******************************************************//**
+ * @brief  Requests the motor to move to the home position (ABS_POSITION = 0)
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void L6474_GoHome(uint8_t deviceId)
+{
+  L6474_GoTo(deviceId, 0);
+} 
+  
+/******************************************************//**
+ * @brief  Requests the motor to move to the mark position 
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void L6474_GoMark(uint8_t deviceId)
+{
+    uint32_t mark;
+
+    mark = L6474_ConvertPosition(L6474_CmdGetParam(deviceId,L6474_MARK));
+    L6474_GoTo(deviceId,mark);  
+}
+
+/******************************************************//**
+ * @brief  Requests the motor to move to the specified position 
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] targetPosition absolute position in steps
+ * @retval None
+ **********************************************************/
+void L6474_GoTo(uint8_t deviceId, int32_t targetPosition)
+{
+  motorDir_t direction;
+  int32_t steps;
+  
+  /* Eventually deactivate motor */
+  if (devicePrm[deviceId].motionState != INACTIVE) 
+  {
+    L6474_HardStop(deviceId);
+  }
+
+  /* Get current position */
+  devicePrm[deviceId].currentPosition = L6474_ConvertPosition(L6474_CmdGetParam(deviceId,L6474_ABS_POS));
+  
+  /* Compute the number of steps to perform */
+  steps = targetPosition - devicePrm[deviceId].currentPosition;
+  
+  if (steps >= 0) 
+  {
+    devicePrm[deviceId].stepsToTake = steps;
+    direction = FORWARD;
+    
+  } 
+  else 
+  {
+    devicePrm[deviceId].stepsToTake = -steps;
+    direction = BACKWARD;
+  }
+  
+  if (steps != 0) 
+  {
+    
+    devicePrm[deviceId].commandExecuted = MOVE_CMD;
+        
+    /* Direction setup */
+    L6474_SetDirection(deviceId,direction);
+
+    L6474_ComputeSpeedProfile(deviceId, devicePrm[deviceId].stepsToTake);
+    
+    /* Motor activation */
+    L6474_StartMovement(deviceId);
+  }  
+}
+
+/******************************************************//**
+ * @brief  Immediatly stops the motor and disable the power bridge
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void L6474_HardStop(uint8_t deviceId) 
+{
+  /* Disable corresponding PWM */
+  BSP_MotorControlBoard_PwmStop(deviceId);
+
+  /* Disable power stage */
+#ifndef L6474_CONF_BRAKE_WHEN_HALTED
+  L6474_CmdDisable(deviceId);
+#else
+  /* Set powerstage to reduced current, retaining position */
+  switch (deviceId)
+  {
+    case 0:
+    L6474_CmdSetParam(deviceId,
+                      L6474_TVAL,
+                      L6474_Tval_Current_to_Par(L6474_CONF_PARAM_TVAL_DEVICE_0/L6474_CONF_BRAKE_CURRENT_FACTOR));
+    break;
+    case 1:
+    L6474_CmdSetParam(deviceId,
+                      L6474_TVAL,
+                      L6474_Tval_Current_to_Par(L6474_CONF_PARAM_TVAL_DEVICE_1/L6474_CONF_BRAKE_CURRENT_FACTOR));
+    break;
+    case 2:
+    L6474_CmdSetParam(deviceId,
+                      L6474_TVAL,
+                      L6474_Tval_Current_to_Par(L6474_CONF_PARAM_TVAL_DEVICE_2/L6474_CONF_BRAKE_CURRENT_FACTOR));
+    break;
+    default: ;
+  }
+#endif
+  /* Set inactive state */
+  devicePrm[deviceId].motionState = INACTIVE;
+  devicePrm[deviceId].commandExecuted = NO_CMD;
+  devicePrm[deviceId].stepsToTake = MAX_STEPS;  
+}
+
+/******************************************************//**
+ * @brief  Moves the motor of the specified number of steps
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] direction FORWARD or BACKWARD
+ * @param[in] stepCount Number of steps to perform
+ * @retval None
+ **********************************************************/
+void L6474_Move(uint8_t deviceId, motorDir_t direction, uint32_t stepCount)
+{
+  /* Eventually deactivate motor */
+  if (devicePrm[deviceId].motionState != INACTIVE) 
+  {
+    L6474_HardStop(deviceId);
+  }
+  
+  if (stepCount != 0) 
+  {
+    devicePrm[deviceId].stepsToTake = stepCount;
+    
+    devicePrm[deviceId].commandExecuted = MOVE_CMD;
+    
+    devicePrm[deviceId].currentPosition = L6474_ConvertPosition(L6474_CmdGetParam(deviceId,L6474_ABS_POS));
+    
+    /* Direction setup */
+    L6474_SetDirection(deviceId,direction);
+
+    L6474_ComputeSpeedProfile(deviceId, stepCount);
+    
+    /* Motor activation */
+    L6474_StartMovement(deviceId);
+  }  
+}
+
+/******************************************************//**
+ * @brief Read id
+ * @param None
+ * @retval Id of the l6474 Driver Instance
+ **********************************************************/
+uint16_t L6474_ReadId(void)
+{
+  return(l6474DriverInstance);
+}
+
+/******************************************************//**
+ * @brief Resets all L6474 devices
+ * @param None
+ * @retval None
+ **********************************************************/
+void L6474_ResetAllDevices(void)
+{
+    uint8_t loop;
+    
+    for (loop = 0; loop < numberOfDevices; loop++)
+    {
+    /* Stop movement and disable power stage*/
+    L6474_HardStop(loop);
+  }
+    L6474_Reset();
+  BSP_MotorControlBoard_Delay(1); // Reset pin must be forced low for at least 10us
+    BSP_MotorControlBoard_ReleaseReset();
+  BSP_MotorControlBoard_Delay(1); 
+}
+
+/******************************************************//**
+ * @brief  Runs the motor. It will accelerate from the min 
+ * speed up to the max speed by using the device acceleration.
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] direction FORWARD or BACKWARD
+ * @retval None
+ **********************************************************/
+void L6474_Run(uint8_t deviceId, motorDir_t direction)
+{
+  /* Eventually deactivate motor */
+  if (devicePrm[deviceId].motionState != INACTIVE) 
+  {
+    L6474_HardStop(deviceId);
+  }
+  
+    /* Direction setup */
+    L6474_SetDirection(deviceId,direction);
+
+    devicePrm[deviceId].commandExecuted = RUN_CMD;
+
+    /* Motor activation */
+    L6474_StartMovement(deviceId); 
+}
+
+/******************************************************//**
+ * @brief  Changes the acceleration of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] newAcc New acceleration to apply in pps^2
+ * @retval true if the command is successfully executed, else false
+ * @note The command is not performed is the device is executing 
+ * a MOVE or GOTO command (but it can be used during a RUN command)
+ **********************************************************/
+bool L6474_SetAcceleration(uint8_t deviceId,uint16_t newAcc)
+{                                                  
+  bool cmdExecuted = FALSE;
+  if ((newAcc != 0)&&
+      ((devicePrm[deviceId].motionState == INACTIVE)||
+       (devicePrm[deviceId].commandExecuted == RUN_CMD)))
+  {
+    devicePrm[deviceId].acceleration = newAcc;
+    cmdExecuted = TRUE;
+  }    
+  return cmdExecuted;
+}            
+
+/******************************************************//**
+ * @brief  Changes the deceleration of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] newDec New deceleration to apply in pps^2
+ * @retval true if the command is successfully executed, else false
+ * @note The command is not performed is the device is executing 
+ * a MOVE or GOTO command (but it can be used during a RUN command)
+ **********************************************************/
+bool L6474_SetDeceleration(uint8_t deviceId, uint16_t newDec)
+{                                                  
+  bool cmdExecuted = FALSE;
+  if ((newDec != 0)&& 
+      ((devicePrm[deviceId].motionState == INACTIVE)||
+       (devicePrm[deviceId].commandExecuted == RUN_CMD)))
+  {
+    devicePrm[deviceId].deceleration = newDec;
+    cmdExecuted = TRUE;
+  }      
+  return cmdExecuted;
+}        
+
+/******************************************************//**
+ * @brief  Set current position to be the Home position (ABS pos set to 0)
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void L6474_SetHome(uint8_t deviceId)
+{
+  L6474_CmdSetParam(deviceId, L6474_ABS_POS, 0);
+}
+ 
+/******************************************************//**
+ * @brief  Sets current position to be the Mark position 
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void L6474_SetMark(uint8_t deviceId)
+{
+  uint32_t mark = L6474_CmdGetParam(deviceId,L6474_ABS_POS);
+  L6474_CmdSetParam(deviceId,L6474_MARK, mark);
+}
+
+/******************************************************//**
+ * @brief  Changes the max speed of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] newMaxSpeed New max speed  to apply in pps
+ * @retval true if the command is successfully executed, else false
+ * @note The command is not performed is the device is executing 
+ * a MOVE or GOTO command (but it can be used during a RUN command).
+ **********************************************************/
+bool L6474_SetMaxSpeed(uint8_t deviceId, uint16_t newMaxSpeed)
+{                                                  
+  bool cmdExecuted = FALSE;
+  if ((newMaxSpeed >= L6474_MIN_PWM_FREQ)&&
+      (newMaxSpeed <= L6474_MAX_PWM_FREQ) &&
+      (devicePrm[deviceId].minSpeed <= newMaxSpeed) &&
+      ((devicePrm[deviceId].motionState == INACTIVE)||
+       (devicePrm[deviceId].commandExecuted == RUN_CMD)))
+  {
+    devicePrm[deviceId].maxSpeed = newMaxSpeed;
+    cmdExecuted = TRUE;
+  }
+  return cmdExecuted;
+}                                                     
+
+/******************************************************//**
+ * @brief  Changes the min speed of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] newMinSpeed New min speed  to apply in pps
+ * @retval true if the command is successfully executed, else false
+ * @note The command is not performed is the device is executing 
+ * a MOVE or GOTO command (but it can be used during a RUN command).
+ **********************************************************/
+bool L6474_SetMinSpeed(uint8_t deviceId, uint16_t newMinSpeed)
+{                                                  
+  bool cmdExecuted = FALSE;
+  if ((newMinSpeed >= L6474_MIN_PWM_FREQ)&&
+      (newMinSpeed <= L6474_MAX_PWM_FREQ) &&
+      (newMinSpeed <= devicePrm[deviceId].maxSpeed) && 
+      ((devicePrm[deviceId].motionState == INACTIVE)||
+       (devicePrm[deviceId].commandExecuted == RUN_CMD)))
+  {
+    devicePrm[deviceId].minSpeed = newMinSpeed;
+    cmdExecuted = TRUE;
+  }  
+  return cmdExecuted;
+}                 
+
+/******************************************************//**
+ * @brief  Stops the motor by using the device deceleration
+ * @param[in] deviceId (from 0 to 2)
+ * @retval true if the command is successfully executed, else false
+ * @note The command is not performed is the device is in INACTIVE state.
+ **********************************************************/
+bool L6474_SoftStop(uint8_t deviceId)
+{   
+  bool cmdExecuted = FALSE;
+  if (devicePrm[deviceId].motionState != INACTIVE)
+  {
+    devicePrm[deviceId].commandExecuted = SOFT_STOP_CMD;
+    cmdExecuted = TRUE;
+  }
+  return (cmdExecuted);
+}
+
+/******************************************************//**
+ * @brief  Locks until the device state becomes Inactive
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void L6474_WaitWhileActive(uint8_t deviceId)
+ {
+    /* Wait while motor is running */
+    while (L6474_GetDeviceState(deviceId) != INACTIVE);
+}
+
+/**
+  * @}
+  */
+                         
+/** @defgroup L6474_Control_Functions
+  * @{
+  */   
+
+/******************************************************//**
+ * @brief  Issue the Disable command to the L6474 of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void L6474_CmdDisable(uint8_t deviceId)
+{
+  L6474_SendCommand(deviceId, L6474_DISABLE);
+}
+
+/******************************************************//**
+ * @brief  Issues the Enable command to the L6474 of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void L6474_CmdEnable(uint8_t deviceId)
+{
+  L6474_SendCommand(deviceId, L6474_ENABLE);
+}
+
+/******************************************************//**
+ * @brief  Issues the GetParam command to the L6474 of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] param Register adress (L6474_ABS_POS, L6474_MARK,...)
+ * @retval Register value
+ **********************************************************/
+uint32_t L6474_CmdGetParam(uint8_t deviceId, uint32_t param)
+{
+  uint32_t i;
+  uint32_t spiRxData;
+  uint8_t maxArgumentNbBytes = 0;
+  uint8_t spiIndex = numberOfDevices - deviceId - 1;
+  bool itDisable = FALSE;  
+  
+  do
+  {
+    spiPreemtionByIsr = FALSE;
+    if (itDisable)
+    {
+      /* re-enable BSP_MotorControlBoard_EnableIrq if disable in previous iteration */
+      BSP_MotorControlBoard_EnableIrq();
+      itDisable = FALSE;
+    }
+  
+    for (i = 0; i < numberOfDevices; i++)
+    {
+      spiTxBursts[0][i] = L6474_NOP;
+      spiTxBursts[1][i] = L6474_NOP;
+      spiTxBursts[2][i] = L6474_NOP;
+      spiTxBursts[3][i] = L6474_NOP;
+      spiRxBursts[1][i] = 0;
+      spiRxBursts[2][i] = 0;
+      spiRxBursts[3][i] = 0;    
+    }
+    switch (param)
+    {
+      case L6474_ABS_POS: ;
+      case L6474_MARK:
+        spiTxBursts[0][spiIndex] = ((uint8_t)L6474_GET_PARAM )| (param);
+        maxArgumentNbBytes = 3;
+        break;
+      case L6474_EL_POS: ;
+      case L6474_CONFIG: ;
+      case L6474_STATUS:
+        spiTxBursts[1][spiIndex] = ((uint8_t)L6474_GET_PARAM )| (param);
+        maxArgumentNbBytes = 2;
+        break;
+      default:
+        spiTxBursts[2][spiIndex] = ((uint8_t)L6474_GET_PARAM )| (param);
+        maxArgumentNbBytes = 1;
+    }
+    
+    /* Disable interruption before checking */
+    /* pre-emption by ISR and SPI transfers*/
+    BSP_MotorControlBoard_DisableIrq();
+    itDisable = TRUE;
+  } while (spiPreemtionByIsr); // check pre-emption by ISR
+    
+  for (i = L6474_CMD_ARG_MAX_NB_BYTES-1-maxArgumentNbBytes;
+       i < L6474_CMD_ARG_MAX_NB_BYTES;
+       i++)
+  {
+     L6474_WriteBytes(&spiTxBursts[i][0],
+                          &spiRxBursts[i][0]);
+  }
+  
+  spiRxData = ((uint32_t)spiRxBursts[1][spiIndex] << 16)|
+              (spiRxBursts[2][spiIndex] << 8) |
+              (spiRxBursts[3][spiIndex]);
+  
+  /* re-enable BSP_MotorControlBoard_EnableIrq after SPI transfers*/
+  BSP_MotorControlBoard_EnableIrq();
+    
+  return (spiRxData);
+}
+
+/******************************************************//**
+ * @brief  Issues the GetStatus command to the L6474 of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Status Register value
+ * @note Once the GetStatus command is performed, the flags of the status register
+ * are reset. This is not the case when the status register is read with the
+ * GetParam command (via the functions L6474ReadStatusRegister or L6474CmdGetParam).
+ **********************************************************/
+uint16_t L6474_CmdGetStatus(uint8_t deviceId)
+{
+  uint32_t i;
+  uint16_t status;
+  uint8_t spiIndex = numberOfDevices - deviceId - 1;
+  bool itDisable = FALSE;  
+  
+  do
+  {
+    spiPreemtionByIsr = FALSE;
+    if (itDisable)
+    {
+      /* re-enable BSP_MotorControlBoard_EnableIrq if disable in previous iteration */
+      BSP_MotorControlBoard_EnableIrq();
+      itDisable = FALSE;
+    }
+
+    for (i = 0; i < numberOfDevices; i++)
+    {
+       spiTxBursts[0][i] = L6474_NOP;
+       spiTxBursts[1][i] = L6474_NOP;
+       spiTxBursts[2][i] = L6474_NOP;
+       spiRxBursts[1][i] = 0;
+       spiRxBursts[2][i] = 0;
+    }
+    spiTxBursts[0][spiIndex] = L6474_GET_STATUS;
+
+    /* Disable interruption before checking */
+    /* pre-emption by ISR and SPI transfers*/
+    BSP_MotorControlBoard_DisableIrq();
+    itDisable = TRUE;
+  } while (spiPreemtionByIsr); // check pre-emption by ISR
+
+  for (i = 0; i < L6474_CMD_ARG_NB_BYTES_GET_STATUS + L6474_RSP_NB_BYTES_GET_STATUS; i++)
+  {
+     L6474_WriteBytes(&spiTxBursts[i][0], &spiRxBursts[i][0]);
+  }
+  status = (spiRxBursts[1][spiIndex] << 8) | (spiRxBursts[2][spiIndex]);
+  
+  /* re-enable BSP_MotorControlBoard_EnableIrq after SPI transfers*/
+  BSP_MotorControlBoard_EnableIrq();
+  
+  return (status);
+}
+
+/******************************************************//**
+ * @brief  Issues the Nop command to the L6474 of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void L6474_CmdNop(uint8_t deviceId)
+{
+  L6474_SendCommand(deviceId, L6474_NOP);
+}
+
+/******************************************************//**
+ * @brief  Issues the SetParam command to the L6474 of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] param Register adress (L6474_ABS_POS, L6474_MARK,...)
+ * @param[in] value Value to set in the register
+ * @retval None
+ **********************************************************/
+void L6474_CmdSetParam(uint8_t deviceId,
+                       uint32_t param,
+                       uint32_t value)
+{
+  uint32_t i;
+  uint8_t maxArgumentNbBytes = 0;
+  uint8_t spiIndex = numberOfDevices - deviceId - 1;
+  bool itDisable = FALSE;  
+  do
+  {
+    spiPreemtionByIsr = FALSE;
+    if (itDisable)
+    {
+      /* re-enable BSP_MotorControlBoard_EnableIrq if disable in previous iteration */
+      BSP_MotorControlBoard_EnableIrq();
+      itDisable = FALSE;
+    }
+    for (i = 0; i < numberOfDevices; i++)
+    {
+      spiTxBursts[0][i] = L6474_NOP;
+      spiTxBursts[1][i] = L6474_NOP;
+      spiTxBursts[2][i] = L6474_NOP;
+      spiTxBursts[3][i] = L6474_NOP;
+    }
+    switch (param)
+  {
+    case L6474_ABS_POS: ;
+    case L6474_MARK:
+        spiTxBursts[0][spiIndex] = param;
+        spiTxBursts[1][spiIndex] = (uint8_t)(value >> 16);
+        spiTxBursts[2][spiIndex] = (uint8_t)(value >> 8);
+        maxArgumentNbBytes = 3;
+        break;
+    case L6474_EL_POS: ;
+    case L6474_CONFIG:
+        spiTxBursts[1][spiIndex] = param;
+        spiTxBursts[2][spiIndex] = (uint8_t)(value >> 8);
+        maxArgumentNbBytes = 2;
+        break;
+    default:
+        spiTxBursts[2][spiIndex] = param;
+        maxArgumentNbBytes = 1;
+    }
+    spiTxBursts[3][spiIndex] = (uint8_t)(value);
+    
+    /* Disable interruption before checking */
+    /* pre-emption by ISR and SPI transfers*/
+    BSP_MotorControlBoard_DisableIrq();
+    itDisable = TRUE;
+  } while (spiPreemtionByIsr); // check pre-emption by ISR
+ 
+  /* SPI transfer */
+  for (i = L6474_CMD_ARG_MAX_NB_BYTES-1-maxArgumentNbBytes;
+       i < L6474_CMD_ARG_MAX_NB_BYTES;
+       i++)
+  {
+     L6474_WriteBytes(&spiTxBursts[i][0],&spiRxBursts[i][0]);
+  }
+  /* re-enable BSP_MotorControlBoard_EnableIrq after SPI transfers*/
+  BSP_MotorControlBoard_EnableIrq();
+}
+
+/******************************************************//**
+ * @brief  Reads the Status Register value
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Status register valued
+ * @note The status register flags are not cleared 
+ * at the difference with L6474CmdGetStatus()
+ **********************************************************/
+uint16_t L6474_ReadStatusRegister(uint8_t deviceId)
+{
+  return (L6474_CmdGetParam(deviceId,L6474_STATUS));
+}
+
+/******************************************************//**
+ * @brief  Releases the L6474 reset (pin set to High) of all devices
+ * @param  None
+ * @retval None
+ **********************************************************/
+void L6474_ReleaseReset(void)
+{ 
+  BSP_MotorControlBoard_ReleaseReset(); 
+}
+
+/******************************************************//**
+ * @brief  Resets the L6474 (reset pin set to low) of all devices
+ * @param  None
+ * @retval None
+ **********************************************************/
+void L6474_Reset(void)
+{
+  BSP_MotorControlBoard_Reset(); 
+}
+
+/******************************************************//**
+ * @brief  Set the stepping mode 
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] stepMod from full step to 1/16 microstep as specified in enum motorStepMode_t
+ * @retval None
+ **********************************************************/
+void L6474_SelectStepMode(uint8_t deviceId, motorStepMode_t stepMod)
+{
+  uint8_t stepModeRegister;
+  L6474_STEP_SEL_t l6474StepMod;
+  
+  switch (stepMod)
+  {
+    case STEP_MODE_FULL:
+      l6474StepMod = L6474_STEP_SEL_1;
+      break;
+    case STEP_MODE_HALF:
+      l6474StepMod = L6474_STEP_SEL_1_2;
+      break;    
+    case STEP_MODE_1_4:
+      l6474StepMod = L6474_STEP_SEL_1_4;
+      break;        
+    case STEP_MODE_1_8:
+      l6474StepMod = L6474_STEP_SEL_1_8;
+      break;       
+    case STEP_MODE_1_16:
+    default:
+      l6474StepMod = L6474_STEP_SEL_1_16;
+      break;       
+  }
+
+  /* Eventually deactivate motor */
+  if (devicePrm[deviceId].motionState != INACTIVE) 
+  {
+    L6474_HardStop(deviceId);
+  }
+  
+  /* Read Step mode register and clear STEP_SEL field */
+  stepModeRegister = (uint8_t)(0xF8 & L6474_CmdGetParam(deviceId,L6474_STEP_MODE)) ;
+  
+  /* Apply new step mode */
+  L6474_CmdSetParam(deviceId, L6474_STEP_MODE, stepModeRegister | (uint8_t)l6474StepMod);
+
+  /* Reset abs pos register */
+  L6474_SetHome(deviceId);
+}
+
+/******************************************************//**
+ * @brief  Specifies the direction 
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] dir FORWARD or BACKWARD
+ * @note The direction change is only applied if the device 
+ * is in INACTIVE state
+ * @retval None
+ **********************************************************/
+void L6474_SetDirection(uint8_t deviceId, motorDir_t dir)
+{
+  if (devicePrm[deviceId].motionState == INACTIVE)
+  {
+    devicePrm[deviceId].direction = dir;
+    BSP_MotorControlBoard_SetDirectionGpio(deviceId, dir);
+  }
+}
+
+/**
+  * @}
+  */
+
+/** @addtogroup L6474_Private_functions
+  * @{
+  */  
+
+/******************************************************//**
+ * @brief  Updates the current speed of the device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] newSpeed in pps
+ * @retval None
+ **********************************************************/
+void L6474_ApplySpeed(uint8_t deviceId, uint16_t newSpeed)
+{
+  if (newSpeed < L6474_MIN_PWM_FREQ)
+  {
+    newSpeed = L6474_MIN_PWM_FREQ;  
+  }
+  if (newSpeed > L6474_MAX_PWM_FREQ)
+  {
+    newSpeed = L6474_MAX_PWM_FREQ;
+  }
+  
+  devicePrm[deviceId].speed = newSpeed;
+
+  switch (deviceId)
+  {
+    case  0:
+      BSP_MotorControlBoard_Pwm1SetFreq(newSpeed);
+      break;
+    case 1:
+      BSP_MotorControlBoard_Pwm2SetFreq(newSpeed);
+      break;
+    case 2:
+      BSP_MotorControlBoard_Pwm3SetFreq(newSpeed);
+      break;
+    default:
+      break; //ignore error
+  }
+}
+
+/******************************************************//**
+ * @brief  Computes the speed profile according to the number of steps to move
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] nbSteps number of steps to perform
+ * @retval None
+ * @note Using the acceleration and deceleration of the device,
+ * this function determines the duration in steps of the acceleration,
+ * steady and deceleration phases.
+ * If the total number of steps to perform is big enough, a trapezoidal move
+ * is performed (i.e. there is a steady phase where the motor runs at the maximum
+ * speed.
+ * Else, a triangular move is performed (no steady phase: the maximum speed is never
+ * reached.
+ **********************************************************/
+void L6474_ComputeSpeedProfile(uint8_t deviceId, uint32_t nbSteps)
+{
+  uint32_t reqAccSteps; 
+    uint32_t reqDecSteps;
+   
+  /* compute the number of steps to get the targeted speed */
+  uint16_t minSpeed = devicePrm[deviceId].minSpeed;
+  reqAccSteps = (devicePrm[deviceId].maxSpeed - minSpeed);
+  reqAccSteps *= (devicePrm[deviceId].maxSpeed + minSpeed);
+  reqDecSteps = reqAccSteps;
+  reqAccSteps /= (uint32_t)devicePrm[deviceId].acceleration;
+  reqAccSteps /= 2;
+
+  /* compute the number of steps to stop */
+  reqDecSteps /= (uint32_t)devicePrm[deviceId].deceleration;
+  reqDecSteps /= 2;
+
+    if(( reqAccSteps + reqDecSteps ) > nbSteps)
+    {   
+    /* Triangular move  */
+    /* reqDecSteps = (Pos * Dec) /(Dec+Acc) */
+    uint32_t dec = devicePrm[deviceId].deceleration;
+    uint32_t acc = devicePrm[deviceId].acceleration;
+    
+    reqDecSteps =  ((uint32_t) dec * nbSteps) / (acc + dec);
+    if (reqDecSteps > 1)
+    {
+      reqAccSteps = reqDecSteps - 1;
+      if(reqAccSteps == 0)
+      {
+        reqAccSteps = 1;
+      }      
+    }
+    else
+    {
+      reqAccSteps = 0;
+    }
+    devicePrm[deviceId].endAccPos = reqAccSteps;
+    devicePrm[deviceId].startDecPos = reqDecSteps;
+    }
+    else
+    {    
+    /* Trapezoidal move */
+    /* accelerating phase to endAccPos */
+    /* steady phase from  endAccPos to startDecPos */
+    /* decelerating from startDecPos to stepsToTake*/
+    devicePrm[deviceId].endAccPos = reqAccSteps;
+    devicePrm[deviceId].startDecPos = nbSteps - reqDecSteps - 1;
+    }
+}
+
+/******************************************************//**
+ * @brief  Converts the ABS_POSITION register value to a 32b signed integer
+ * @param[in] abs_position_reg value of the ABS_POSITION register
+ * @retval operation_result 32b signed integer corresponding to the absolute position 
+ **********************************************************/
+int32_t L6474_ConvertPosition(uint32_t abs_position_reg)
+{
+    int32_t operation_result;
+
+  if (abs_position_reg & L6474_ABS_POS_SIGN_BIT_MASK) 
+  {
+        /* Negative register value */
+        abs_position_reg = ~abs_position_reg;
+        abs_position_reg += 1;
+
+        operation_result = (int32_t) (abs_position_reg & L6474_ABS_POS_VALUE_MASK);
+        operation_result = -operation_result;
+  } 
+  else 
+  {
+        operation_result = (int32_t) abs_position_reg;
+    }
+    return operation_result;
+}
+
+/******************************************************//**
+ * @brief Error handler which calls the user callback (if defined)
+ * @param[in] error Number of the error
+ * @retval None
+ **********************************************************/
+void L6474_ErrorHandler(uint16_t error)
+{
+  if (errorHandlerCallback != 0)
+  {
+    (void) errorHandlerCallback(error);
+  }
+  else   
+  {
+    while(1)
+    {
+      /* Infinite loop */
+    }
+  }
+}
+
+/******************************************************//**
+ * @brief  Handlers of the flag interrupt which calls the user callback (if defined)
+ * @param None
+ * @retval None
+ **********************************************************/
+void L6474_FlagInterruptHandler(void)
+{
+  if (flagInterruptCallback != 0)
+  {
+    /* Set isr flag */
+    isrFlag = TRUE;
+    
+    flagInterruptCallback();
+    
+    /* Reset isr flag */
+    isrFlag = FALSE;   
+  }
+}
+
+/******************************************************//**
+ * @brief  Sends a command without arguments to the L6474 via the SPI
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] param Command to send 
+ * @retval None
+ **********************************************************/
+void L6474_SendCommand(uint8_t deviceId, uint8_t param)
+{
+  uint32_t i;
+  uint8_t spiIndex = numberOfDevices - deviceId - 1;
+  bool itDisable = FALSE;  
+  
+  do
+  {
+    spiPreemtionByIsr = FALSE;
+    if (itDisable)
+    {
+      /* re-enable BSP_MotorControlBoard_EnableIrq if disable in previous iteration */
+      BSP_MotorControlBoard_EnableIrq();
+      itDisable = FALSE;
+    }
+  
+    for (i = 0; i < numberOfDevices; i++)
+    {
+      spiTxBursts[3][i] = L6474_NOP;     
+    }
+    spiTxBursts[3][spiIndex] = param;
+    
+    /* Disable interruption before checking */
+    /* pre-emption by ISR and SPI transfers*/
+    BSP_MotorControlBoard_DisableIrq();
+    itDisable = TRUE;
+  } while (spiPreemtionByIsr); // check pre-emption by ISR
+
+  L6474_WriteBytes(&spiTxBursts[3][0], &spiRxBursts[3][0]); 
+  
+  /* re-enable BSP_MotorControlBoard_EnableIrq after SPI transfers*/
+  BSP_MotorControlBoard_EnableIrq();
+}
+
+/******************************************************//**
+ * @brief  Sets the registers of the L6474 to their predefined values 
+ * from l6474_target_config.h
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void L6474_SetRegisterToPredefinedValues(uint8_t deviceId)
+{
+  L6474_CmdSetParam(deviceId,
+                    L6474_ABS_POS,
+                    0);
+  L6474_CmdSetParam(deviceId,
+                    L6474_EL_POS,
+                    0);
+  L6474_CmdSetParam(deviceId,
+                    L6474_MARK,
+                    0);
+  switch (deviceId)
+  {
+    case 0:
+      L6474_CmdSetParam(deviceId,
+                        L6474_TVAL,
+                        L6474_Tval_Current_to_Par(L6474_CONF_PARAM_TVAL_DEVICE_0));
+      L6474_CmdSetParam(deviceId,
+                              L6474_T_FAST,
+                              (uint8_t)L6474_CONF_PARAM_TOFF_FAST_DEVICE_0 |
+                              (uint8_t)L6474_CONF_PARAM_FAST_STEP_DEVICE_0);
+      L6474_CmdSetParam(deviceId,
+                              L6474_TON_MIN,
+                              L6474_Tmin_Time_to_Par(L6474_CONF_PARAM_TON_MIN_DEVICE_0)
+                                );
+      L6474_CmdSetParam(deviceId,
+                              L6474_TOFF_MIN,
+                              L6474_Tmin_Time_to_Par(L6474_CONF_PARAM_TOFF_MIN_DEVICE_0));
+      L6474_CmdSetParam(deviceId,
+                        L6474_OCD_TH,
+                        L6474_CONF_PARAM_OCD_TH_DEVICE_0);
+      L6474_CmdSetParam(deviceId,
+                        L6474_STEP_MODE,
+                        (uint8_t)L6474_CONF_PARAM_STEP_SEL_DEVICE_0 |
+                        (uint8_t)L6474_CONF_PARAM_SYNC_SEL_DEVICE_0);
+      L6474_CmdSetParam(deviceId,
+                        L6474_ALARM_EN,
+                        L6474_CONF_PARAM_ALARM_EN_DEVICE_0);
+      L6474_CmdSetParam(deviceId,
+                        L6474_CONFIG,
+                        (uint16_t)L6474_CONF_PARAM_CLOCK_SETTING_DEVICE_0 |
+                        (uint16_t)L6474_CONF_PARAM_TQ_REG_DEVICE_0 |
+                        (uint16_t)L6474_CONF_PARAM_OC_SD_DEVICE_0 |
+                        (uint16_t)L6474_CONF_PARAM_SR_DEVICE_0 |
+                        (uint16_t)L6474_CONF_PARAM_TOFF_DEVICE_0);
+      break;
+    case 1:
+      L6474_CmdSetParam(deviceId,
+                        L6474_TVAL,
+                        L6474_Tval_Current_to_Par(L6474_CONF_PARAM_TVAL_DEVICE_1));
+      L6474_CmdSetParam(deviceId,
+                        L6474_T_FAST,
+                        (uint8_t)L6474_CONF_PARAM_TOFF_FAST_DEVICE_1 |
+                        (uint8_t)L6474_CONF_PARAM_FAST_STEP_DEVICE_1);
+      L6474_CmdSetParam(deviceId,
+                        L6474_TON_MIN,
+                        L6474_Tmin_Time_to_Par(L6474_CONF_PARAM_TON_MIN_DEVICE_1));
+      L6474_CmdSetParam(deviceId,
+                        L6474_TOFF_MIN,
+                        L6474_Tmin_Time_to_Par(L6474_CONF_PARAM_TOFF_MIN_DEVICE_1));
+      L6474_CmdSetParam(deviceId,
+                        L6474_OCD_TH,
+                        L6474_CONF_PARAM_OCD_TH_DEVICE_1);
+      L6474_CmdSetParam(deviceId,
+                        L6474_STEP_MODE,
+                        (uint8_t)L6474_CONF_PARAM_STEP_SEL_DEVICE_1 |
+                        (uint8_t)L6474_CONF_PARAM_SYNC_SEL_DEVICE_1);
+      L6474_CmdSetParam(deviceId,
+                        L6474_ALARM_EN,
+                        L6474_CONF_PARAM_ALARM_EN_DEVICE_1);
+      L6474_CmdSetParam(deviceId,
+                        L6474_CONFIG,
+                        (uint16_t)L6474_CONF_PARAM_CLOCK_SETTING_DEVICE_1 |
+                        (uint16_t)L6474_CONF_PARAM_TQ_REG_DEVICE_1 |
+                        (uint16_t)L6474_CONF_PARAM_OC_SD_DEVICE_1 |
+                        (uint16_t)L6474_CONF_PARAM_SR_DEVICE_1 |
+                        (uint16_t)L6474_CONF_PARAM_TOFF_DEVICE_1);
+      break;
+    case 2:
+      L6474_CmdSetParam(deviceId,
+                        L6474_TVAL,
+                        L6474_Tval_Current_to_Par(L6474_CONF_PARAM_TVAL_DEVICE_2));
+      L6474_CmdSetParam(deviceId,
+                        L6474_T_FAST,
+                        (uint8_t)L6474_CONF_PARAM_TOFF_FAST_DEVICE_2 |
+                        (uint8_t)L6474_CONF_PARAM_FAST_STEP_DEVICE_2);
+      L6474_CmdSetParam(deviceId,
+                        L6474_TON_MIN,
+                        L6474_Tmin_Time_to_Par(L6474_CONF_PARAM_TON_MIN_DEVICE_2));
+      L6474_CmdSetParam(deviceId,
+                        L6474_TOFF_MIN,
+                        L6474_Tmin_Time_to_Par(L6474_CONF_PARAM_TOFF_MIN_DEVICE_2));
+      L6474_CmdSetParam(deviceId,
+                        L6474_OCD_TH,
+                        L6474_CONF_PARAM_OCD_TH_DEVICE_2);
+      L6474_CmdSetParam(deviceId,
+                        L6474_STEP_MODE,
+                        (uint8_t)L6474_CONF_PARAM_STEP_SEL_DEVICE_2 |
+                        (uint8_t)L6474_CONF_PARAM_SYNC_SEL_DEVICE_2);
+      L6474_CmdSetParam(deviceId,
+                        L6474_ALARM_EN,
+                        L6474_CONF_PARAM_ALARM_EN_DEVICE_2);
+      L6474_CmdSetParam(deviceId,
+                        L6474_CONFIG,
+                        (uint16_t)L6474_CONF_PARAM_CLOCK_SETTING_DEVICE_2 |
+                        (uint16_t)L6474_CONF_PARAM_TQ_REG_DEVICE_2 |
+                        (uint16_t)L6474_CONF_PARAM_OC_SD_DEVICE_2 |
+                        (uint16_t)L6474_CONF_PARAM_SR_DEVICE_2 |
+                        (uint16_t)L6474_CONF_PARAM_TOFF_DEVICE_2);
+      break;
+    default: ;
+  }
+}
+
+/******************************************************//**
+ * @brief  Sets the parameters of the device to predefined values
+ * from l6474_target_config.h
+ * @param None
+ * @retval None
+ **********************************************************/
+void L6474_SetDeviceParamsToPredefinedValues(void)
+{
+  uint32_t i;
+
+  devicePrm[0].acceleration = L6474_CONF_PARAM_ACC_DEVICE_0;
+  devicePrm[0].deceleration = L6474_CONF_PARAM_DEC_DEVICE_0;
+  devicePrm[0].maxSpeed = L6474_CONF_PARAM_MAX_SPEED_DEVICE_0;
+  devicePrm[0].minSpeed = L6474_CONF_PARAM_MIN_SPEED_DEVICE_0;
+  
+  devicePrm[1].acceleration = L6474_CONF_PARAM_ACC_DEVICE_1;
+  devicePrm[1].deceleration = L6474_CONF_PARAM_DEC_DEVICE_1;
+  devicePrm[1].maxSpeed = L6474_CONF_PARAM_MAX_SPEED_DEVICE_1;
+  devicePrm[1].minSpeed = L6474_CONF_PARAM_MIN_SPEED_DEVICE_1;
+  
+  devicePrm[2].acceleration = L6474_CONF_PARAM_ACC_DEVICE_2;
+  devicePrm[2].deceleration = L6474_CONF_PARAM_DEC_DEVICE_2;
+  devicePrm[2].maxSpeed = L6474_CONF_PARAM_MAX_SPEED_DEVICE_2;
+  devicePrm[2].minSpeed = L6474_CONF_PARAM_MIN_SPEED_DEVICE_2;
+  
+  for (i = 0; i < MAX_NUMBER_OF_DEVICES; i++)
+  {
+    devicePrm[i].accu = 0;
+    devicePrm[i].currentPosition = 0;
+    devicePrm[i].endAccPos = 0;
+    devicePrm[i].relativePos = 0;
+    devicePrm[i].startDecPos = 0;
+    devicePrm[i].stepsToTake = 0;
+    devicePrm[i].speed = 0;
+    devicePrm[i].commandExecuted = NO_CMD;
+    devicePrm[i].direction = FORWARD;
+    devicePrm[i].motionState = INACTIVE;
+  }
+  
+  for (i = 0; i < numberOfDevices; i++)
+  {
+    L6474_SetRegisterToPredefinedValues(i);
+  }   
+}
+
+/******************************************************//**
+ * @brief Initialises the bridge parameters to start the movement
+ * and enable the power bridge
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void L6474_StartMovement(uint8_t deviceId)  
+{
+#ifdef L6474_CONF_BRAKE_WHEN_HALTED
+  /* Restore powerstage to full current capability */
+  switch (deviceId)
+  {
+    case 0:
+    L6474_CmdSetParam(deviceId,
+                      L6474_TVAL,
+                      L6474_Tval_Current_to_Par(L6474_CONF_PARAM_TVAL_DEVICE_0));
+    break;
+    case 1:
+    L6474_CmdSetParam(deviceId,
+                      L6474_TVAL,
+                      L6474_Tval_Current_to_Par(L6474_CONF_PARAM_TVAL_DEVICE_1));
+    break;
+    case 2:
+    L6474_CmdSetParam(deviceId,
+                      L6474_TVAL,
+                      L6474_Tval_Current_to_Par(L6474_CONF_PARAM_TVAL_DEVICE_2));
+    break;
+    default: ;
+  }
+#endif
+
+  /* Enable L6474 powerstage */
+  L6474_CmdEnable(deviceId);
+
+  if (devicePrm[deviceId].endAccPos != 0)
+  {
+    devicePrm[deviceId].motionState = ACCELERATING;
+  }
+  else
+  {
+    devicePrm[deviceId].motionState = DECELERATING;    
+  }
+  devicePrm[deviceId].accu = 0;
+  devicePrm[deviceId].relativePos = 0;
+  L6474_ApplySpeed(deviceId, devicePrm[deviceId].minSpeed);
+}
+
+/******************************************************//**
+ * @brief  Handles the device state machine at each ste
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ * @note Must only be called by the timer ISR
+ **********************************************************/
+void L6474_StepClockHandler(uint8_t deviceId)
+{
+  /* Set isr flag */
+  isrFlag = TRUE;
+  
+  /* Incrementation of the relative position */
+  devicePrm[deviceId].relativePos++;
+
+  switch (devicePrm[deviceId].motionState) 
+  {
+    case ACCELERATING: 
+    {
+        uint32_t relPos = devicePrm[deviceId].relativePos;
+        uint32_t endAccPos = devicePrm[deviceId].endAccPos;
+        uint16_t speed = devicePrm[deviceId].speed;
+        uint32_t acc = ((uint32_t)devicePrm[deviceId].acceleration << 16);
+        
+        if ((devicePrm[deviceId].commandExecuted == SOFT_STOP_CMD)||
+            ((devicePrm[deviceId].commandExecuted != RUN_CMD)&&  
+             (relPos == devicePrm[deviceId].startDecPos)))
+        {
+          devicePrm[deviceId].motionState = DECELERATING;
+          devicePrm[deviceId].accu = 0;
+        }
+        else if ((speed >= devicePrm[deviceId].maxSpeed)||
+                 ((devicePrm[deviceId].commandExecuted != RUN_CMD)&&
+                  (relPos == endAccPos)))
+        {
+          devicePrm[deviceId].motionState = STEADY;
+        }
+        else
+        {
+          bool speedUpdated = FALSE;
+          /* Go on accelerating */
+          if (speed == 0) speed =1;
+          devicePrm[deviceId].accu += acc / speed;
+          while (devicePrm[deviceId].accu >= (0X10000L))
+          {
+            devicePrm[deviceId].accu -= (0X10000L);
+            speed +=1;
+            speedUpdated = TRUE;
+          }
+          
+          if (speedUpdated)
+          {
+            if (speed > devicePrm[deviceId].maxSpeed)
+            {
+              speed = devicePrm[deviceId].maxSpeed;
+            }    
+            devicePrm[deviceId].speed = speed;
+            L6474_ApplySpeed(deviceId, devicePrm[deviceId].speed);
+          }
+        }
+        break;
+    }
+    case STEADY: 
+    {
+      uint16_t maxSpeed = devicePrm[deviceId].maxSpeed;
+      uint32_t relativePos = devicePrm[deviceId].relativePos;
+      if  ((devicePrm[deviceId].commandExecuted == SOFT_STOP_CMD)||
+           ((devicePrm[deviceId].commandExecuted != RUN_CMD)&&
+            (relativePos >= (devicePrm[deviceId].startDecPos))) ||
+           ((devicePrm[deviceId].commandExecuted == RUN_CMD)&&
+            (devicePrm[deviceId].speed > maxSpeed)))
+      {
+        devicePrm[deviceId].motionState = DECELERATING;
+        devicePrm[deviceId].accu = 0;
+      }
+      else if ((devicePrm[deviceId].commandExecuted == RUN_CMD)&&
+               (devicePrm[deviceId].speed < maxSpeed))
+      {
+        devicePrm[deviceId].motionState = ACCELERATING;
+        devicePrm[deviceId].accu = 0;
+      }
+      break;
+    }
+    case DECELERATING: 
+    {
+      uint32_t relativePos = devicePrm[deviceId].relativePos;
+      uint16_t speed = devicePrm[deviceId].speed;
+      uint32_t deceleration = ((uint32_t)devicePrm[deviceId].deceleration << 16);
+      if (((devicePrm[deviceId].commandExecuted == SOFT_STOP_CMD)&&(speed <=  devicePrm[deviceId].minSpeed))||
+          ((devicePrm[deviceId].commandExecuted != RUN_CMD)&&
+           (relativePos >= devicePrm[deviceId].stepsToTake)))
+      {
+        /* Motion process complete */
+        L6474_HardStop(deviceId);
+      }
+      else if ((devicePrm[deviceId].commandExecuted == RUN_CMD)&&
+               (speed <= devicePrm[deviceId].maxSpeed))
+      {
+        devicePrm[deviceId].motionState = STEADY;
+      }
+      else
+      {
+        /* Go on decelerating */
+        if (speed > devicePrm[deviceId].minSpeed)
+        {
+          bool speedUpdated = FALSE;
+          if (speed == 0) speed =1;
+          devicePrm[deviceId].accu += deceleration / speed;
+          while (devicePrm[deviceId].accu >= (0X10000L))
+          {
+            devicePrm[deviceId].accu -= (0X10000L);
+            if (speed > 1)
+            {  
+              speed -=1;
+            }
+            speedUpdated = TRUE;
+          }
+        
+          if (speedUpdated)
+          {
+            if (speed < devicePrm[deviceId].minSpeed)
+            {
+              speed = devicePrm[deviceId].minSpeed;
+            }  
+            devicePrm[deviceId].speed = speed;
+            L6474_ApplySpeed(deviceId, devicePrm[deviceId].speed);
+          }
+        }
+      }
+      break;
+    }
+    default: 
+    {
+      break;
+    }
+  }  
+  /* Set isr flag */
+  isrFlag = FALSE;
+}
+
+/******************************************************//**
+ * @brief Converts mA in compatible values for TVAL register 
+ * @param[in] Tval
+ * @retval TVAL values
+ **********************************************************/
+inline uint8_t L6474_Tval_Current_to_Par(double Tval)
+{
+  return ((uint8_t)(((Tval - 31.25)/31.25)+0.5));
+}
+
+/******************************************************//**
+ * @brief Convert time in us in compatible values 
+ * for TON_MIN register
+ * @param[in] Tmin
+ * @retval TON_MIN values
+ **********************************************************/
+inline uint8_t L6474_Tmin_Time_to_Par(double Tmin)
+{
+  return ((uint8_t)(((Tmin - 0.5)*2)+0.5));
+}
+
+/******************************************************//**
+ * @brief  Write and receive a byte via SPI
+ * @param[in] pByteToTransmit pointer to the byte to transmit
+ * @param[in] pReceivedByte pointer to the received byte
+ * @retval None
+ **********************************************************/
+void L6474_WriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte)
+{
+  if (BSP_MotorControlBoard_SpiWriteBytes(pByteToTransmit, pReceivedByte, numberOfDevices) != 0)
+  {
+    L6474_ErrorHandler(L6474_ERROR_1);
+  }
+  
+  if (isrFlag)
+  {
+    spiPreemtionByIsr = TRUE;
+  }
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/l6474.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,628 @@
+/**
+  ******************************************************************************
+  * @file    l6474.h 
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   Header for L6474 driver (fully integrated microstepping motor driver)
+  * @note    (C) COPYRIGHT 2014 STMicroelectronics
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __L6474_H
+#define __L6474_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+#include "l6474_target_config.h"
+#include "motor.h"   
+   
+/** @addtogroup BSP
+  * @{
+  */   
+   
+/** @addtogroup L6474
+  * @{
+  */   
+   
+/* Exported Constants --------------------------------------------------------*/
+
+/** @defgroup L6474_Exported_Constants
+  * @{
+  */   
+
+/// Current FW version
+#define L6474_FW_VERSION (5)
+
+/// L6474 max number of bytes of command & arguments to set a parameter
+#define L6474_CMD_ARG_MAX_NB_BYTES              (4)
+
+/// L6474 command + argument bytes number for GET_STATUS command
+#define L6474_CMD_ARG_NB_BYTES_GET_STATUS       (1)
+
+/// L6474 response bytes number
+#define L6474_RSP_NB_BYTES_GET_STATUS           (2)
+
+/// L6474 value mask for ABS_POS register
+#define L6474_ABS_POS_VALUE_MASK    ((uint32_t) 0x003FFFFF)
+   
+/// L6474 sign bit mask for ABS_POS register
+#define L6474_ABS_POS_SIGN_BIT_MASK ((uint32_t) 0x00200000)
+
+/**
+  * @}
+  */
+
+/** @addtogroup L6474_Exported_Variables
+  * @{
+  */    
+    extern motorDrv_t   l6474Drv;
+/**
+  * @}
+  */
+     
+/* Exported Types  -------------------------------------------------------*/
+
+/** @defgroup L6474_Exported_Types
+  * @{
+  */   
+
+/** @defgroup L6474_Fast_Decay_Time_Options  
+  * @{
+  */
+///TOFF_FAST values for T_FAST register
+typedef enum {
+  L6474_TOFF_FAST_2us = ((uint8_t) 0x00 << 4),
+  L6474_TOFF_FAST_4us = ((uint8_t) 0x01 << 4),
+  L6474_TOFF_FAST_6us = ((uint8_t) 0x02 << 4),
+  L6474_TOFF_FAST_8us = ((uint8_t) 0x03 << 4),
+  L6474_TOFF_FAST_10us = ((uint8_t) 0x04 << 4),
+  L6474_TOFF_FAST_12us = ((uint8_t) 0x05 << 4),
+  L6474_TOFF_FAST_14us = ((uint8_t) 0x06 << 4),
+  L6474_TOFF_FAST_16us = ((uint8_t) 0x07 << 4),
+  L6474_TOFF_FAST_18us = ((uint8_t) 0x08 << 4),
+  L6474_TOFF_FAST_20us = ((uint8_t) 0x09 << 4),
+  L6474_TOFF_FAST_22us = ((uint8_t) 0x0A << 4),
+  L6474_TOFF_FAST_24us = ((uint8_t) 0x0B << 4),
+  L6474_TOFF_FAST_26us = ((uint8_t) 0x0C << 4),
+  L6474_TOFF_FAST_28us = ((uint8_t) 0x0D << 4),
+  L6474_TOFF_FAST_30us = ((uint8_t) 0x0E << 4),
+  L6474_TOFF_FAST_32us = ((uint8_t) 0x0F << 4)
+} L6474_TOFF_FAST_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_Fall_Step_Time_Options 
+  * @{
+  */
+///FAST_STEP values for T_FAST register
+typedef enum {
+  L6474_FAST_STEP_2us = ((uint8_t) 0x00),
+  L6474_FAST_STEP_4us = ((uint8_t) 0x01),
+  L6474_FAST_STEP_6us = ((uint8_t) 0x02),
+  L6474_FAST_STEP_8us = ((uint8_t) 0x03),
+  L6474_FAST_STEP_10us = ((uint8_t) 0x04),
+  L6474_FAST_STEP_12us = ((uint8_t) 0x05),
+  L6474_FAST_STEP_14us = ((uint8_t) 0x06),
+  L6474_FAST_STEP_16us = ((uint8_t) 0x07),
+  L6474_FAST_STEP_18us = ((uint8_t) 0x08),
+  L6474_FAST_STEP_20us = ((uint8_t) 0x09),
+  L6474_FAST_STEP_22us = ((uint8_t) 0x0A),
+  L6474_FAST_STEP_24us = ((uint8_t) 0x0B),
+  L6474_FAST_STEP_26us = ((uint8_t) 0x0C),
+  L6474_FAST_STEP_28us = ((uint8_t) 0x0D),
+  L6474_FAST_STEP_30us = ((uint8_t) 0x0E),
+  L6474_FAST_STEP_32us = ((uint8_t) 0x0F)
+} L6474_FAST_STEP_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_Overcurrent_Threshold_options
+  * @{
+  */
+///OCD_TH register
+typedef enum {
+  L6474_OCD_TH_375mA  = ((uint8_t) 0x00),
+  L6474_OCD_TH_750mA  = ((uint8_t) 0x01),
+  L6474_OCD_TH_1125mA = ((uint8_t) 0x02),
+  L6474_OCD_TH_1500mA = ((uint8_t) 0x03),
+  L6474_OCD_TH_1875mA = ((uint8_t) 0x04),
+  L6474_OCD_TH_2250mA = ((uint8_t) 0x05),
+  L6474_OCD_TH_2625mA = ((uint8_t) 0x06),
+  L6474_OCD_TH_3000mA = ((uint8_t) 0x07),
+  L6474_OCD_TH_3375mA = ((uint8_t) 0x08),
+  L6474_OCD_TH_3750mA = ((uint8_t) 0x09),
+  L6474_OCD_TH_4125mA = ((uint8_t) 0x0A),
+  L6474_OCD_TH_4500mA = ((uint8_t) 0x0B),
+  L6474_OCD_TH_4875mA = ((uint8_t) 0x0C),
+  L6474_OCD_TH_5250mA = ((uint8_t) 0x0D),
+  L6474_OCD_TH_5625mA = ((uint8_t) 0x0E),
+  L6474_OCD_TH_6000mA = ((uint8_t) 0x0F)
+} L6474_OCD_TH_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_STEP_MODE_Register_Masks 
+  * @{
+  */  
+///STEP_MODE register
+typedef enum {
+  L6474_STEP_MODE_STEP_SEL = ((uint8_t) 0x07),
+  L6474_STEP_MODE_SYNC_SEL = ((uint8_t) 0x70)
+} L6474_STEP_MODE_Masks_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_STEP_SEL_Options_For_STEP_MODE_Register
+  * @{
+  */
+///STEP_SEL field of STEP_MODE register
+typedef enum {
+  L6474_STEP_SEL_1    = ((uint8_t) 0x08),  //full step
+  L6474_STEP_SEL_1_2  = ((uint8_t) 0x09),  //half step
+  L6474_STEP_SEL_1_4  = ((uint8_t) 0x0A),  //1/4 microstep
+  L6474_STEP_SEL_1_8  = ((uint8_t) 0x0B),  //1/8 microstep
+  L6474_STEP_SEL_1_16 = ((uint8_t) 0x0C)   //1/16 microstep
+} L6474_STEP_SEL_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_SYNC_SEL_Options_For_STEP_MODE_Register 
+  * @{
+  */
+///SYNC_SEL field of STEP_MODE register
+typedef enum {
+  L6474_SYNC_SEL_1_2    = ((uint8_t) 0x80),
+  L6474_SYNC_SEL_1      = ((uint8_t) 0x90),
+  L6474_SYNC_SEL_2      = ((uint8_t) 0xA0),
+  L6474_SYNC_SEL_4      = ((uint8_t) 0xB0),
+  L6474_SYNC_SEL_8      = ((uint8_t) 0xC0),
+  L6474_SYNC_SEL_UNUSED = ((uint8_t) 0xD0)
+} L6474_SYNC_SEL_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_ALARM_EN_Register_Options
+  * @{
+  */
+///ALARM_EN register
+typedef enum {
+  L6474_ALARM_EN_OVERCURRENT      = ((uint8_t) 0x01),
+  L6474_ALARM_EN_THERMAL_SHUTDOWN = ((uint8_t) 0x02),
+  L6474_ALARM_EN_THERMAL_WARNING  = ((uint8_t) 0x04),
+  L6474_ALARM_EN_UNDERVOLTAGE     = ((uint8_t) 0x08),
+  L6474_ALARM_EN_SW_TURN_ON       = ((uint8_t) 0x40),
+  L6474_ALARM_EN_WRONG_NPERF_CMD  = ((uint8_t) 0x80)
+} L6474_ALARM_EN_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_CONFIG_Register_Masks
+  * @{
+  */
+///CONFIG register
+typedef enum {
+  L6474_CONFIG_OSC_SEL  = ((uint16_t) 0x0007),
+  L6474_CONFIG_EXT_CLK  = ((uint16_t) 0x0008),
+  L6474_CONFIG_EN_TQREG = ((uint16_t) 0x0020),
+  L6474_CONFIG_OC_SD    = ((uint16_t) 0x0080),
+  L6474_CONFIG_POW_SR   = ((uint16_t) 0x0300),
+  L6474_CONFIG_TOFF      = ((uint16_t) 0x7C00)
+} L6474_CONFIG_Masks_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_Clock_Source_Options_For_CONFIG_Register
+  * @{
+  */
+///Clock source option for CONFIG register
+typedef enum {
+  L6474_CONFIG_INT_16MHZ = ((uint16_t) 0x0000),
+  L6474_CONFIG_INT_16MHZ_OSCOUT_2MHZ   = ((uint16_t) 0x0008),
+  L6474_CONFIG_INT_16MHZ_OSCOUT_4MHZ   = ((uint16_t) 0x0009),
+  L6474_CONFIG_INT_16MHZ_OSCOUT_8MHZ   = ((uint16_t) 0x000A),
+  L6474_CONFIG_INT_16MHZ_OSCOUT_16MHZ  = ((uint16_t) 0x000B),
+  L6474_CONFIG_EXT_8MHZ_XTAL_DRIVE     = ((uint16_t) 0x0004),
+  L6474_CONFIG_EXT_16MHZ_XTAL_DRIVE    = ((uint16_t) 0x0005),
+  L6474_CONFIG_EXT_24MHZ_XTAL_DRIVE    = ((uint16_t) 0x0006),
+  L6474_CONFIG_EXT_32MHZ_XTAL_DRIVE    = ((uint16_t) 0x0007),
+  L6474_CONFIG_EXT_8MHZ_OSCOUT_INVERT  = ((uint16_t) 0x000C),
+  L6474_CONFIG_EXT_16MHZ_OSCOUT_INVERT = ((uint16_t) 0x000D),
+  L6474_CONFIG_EXT_24MHZ_OSCOUT_INVERT = ((uint16_t) 0x000E),
+  L6474_CONFIG_EXT_32MHZ_OSCOUT_INVERT = ((uint16_t) 0x000F)
+} L6474_CONFIG_OSC_MGMT_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_External_Torque_Regulation_Options_For_CONFIG_Register
+  * @{
+  */
+///External Torque regulation options for CONFIG register
+typedef enum {
+  L6474_CONFIG_EN_TQREG_TVAL_USED = ((uint16_t) 0x0000),
+  L6474_CONFIG_EN_TQREG_ADC_OUT = ((uint16_t) 0x0020)
+} L6474_CONFIG_EN_TQREG_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_Over_Current_Shutdown_Options_For_CONFIG_Register
+  * @{
+  */
+///Over Current Shutdown options for CONFIG register
+typedef enum {
+  L6474_CONFIG_OC_SD_DISABLE = ((uint16_t) 0x0000),
+  L6474_CONFIG_OC_SD_ENABLE  = ((uint16_t) 0x0080)
+} L6474_CONFIG_OC_SD_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_Power_Bridge_Output_Slew_Rate_Options
+  * @{
+  */
+/// POW_SR values for CONFIG register
+typedef enum {
+  L6474_CONFIG_SR_320V_us    =((uint16_t)0x0000),
+  L6474_CONFIG_SR_075V_us    =((uint16_t)0x0100),
+  L6474_CONFIG_SR_110V_us    =((uint16_t)0x0200),
+  L6474_CONFIG_SR_260V_us    =((uint16_t)0x0300)
+} L6474_CONFIG_POW_SR_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_Off_Time_Options
+  * @{
+  */
+/// TOFF values for CONFIG register
+typedef enum {
+  L6474_CONFIG_TOFF_004us   = (((uint16_t) 0x01) << 10),
+  L6474_CONFIG_TOFF_008us   = (((uint16_t) 0x02) << 10),
+  L6474_CONFIG_TOFF_012us  = (((uint16_t) 0x03) << 10),
+  L6474_CONFIG_TOFF_016us  = (((uint16_t) 0x04) << 10),
+  L6474_CONFIG_TOFF_020us  = (((uint16_t) 0x05) << 10),
+  L6474_CONFIG_TOFF_024us  = (((uint16_t) 0x06) << 10),
+  L6474_CONFIG_TOFF_028us  = (((uint16_t) 0x07) << 10),
+  L6474_CONFIG_TOFF_032us  = (((uint16_t) 0x08) << 10),
+  L6474_CONFIG_TOFF_036us  = (((uint16_t) 0x09) << 10),
+  L6474_CONFIG_TOFF_040us  = (((uint16_t) 0x0A) << 10),
+  L6474_CONFIG_TOFF_044us  = (((uint16_t) 0x0B) << 10),
+  L6474_CONFIG_TOFF_048us  = (((uint16_t) 0x0C) << 10),
+  L6474_CONFIG_TOFF_052us  = (((uint16_t) 0x0D) << 10),
+  L6474_CONFIG_TOFF_056us  = (((uint16_t) 0x0E) << 10),
+  L6474_CONFIG_TOFF_060us  = (((uint16_t) 0x0F) << 10),
+  L6474_CONFIG_TOFF_064us  = (((uint16_t) 0x10) << 10),
+  L6474_CONFIG_TOFF_068us  = (((uint16_t) 0x11) << 10),
+  L6474_CONFIG_TOFF_072us  = (((uint16_t) 0x12) << 10),
+  L6474_CONFIG_TOFF_076us  = (((uint16_t) 0x13) << 10),
+  L6474_CONFIG_TOFF_080us  = (((uint16_t) 0x14) << 10),
+  L6474_CONFIG_TOFF_084us  = (((uint16_t) 0x15) << 10),
+  L6474_CONFIG_TOFF_088us  = (((uint16_t) 0x16) << 10),
+  L6474_CONFIG_TOFF_092us  = (((uint16_t) 0x17) << 10),
+  L6474_CONFIG_TOFF_096us  = (((uint16_t) 0x18) << 10),
+  L6474_CONFIG_TOFF_100us = (((uint16_t) 0x19) << 10),
+  L6474_CONFIG_TOFF_104us = (((uint16_t) 0x1A) << 10),
+  L6474_CONFIG_TOFF_108us = (((uint16_t) 0x1B) << 10),
+  L6474_CONFIG_TOFF_112us = (((uint16_t) 0x1C) << 10),
+  L6474_CONFIG_TOFF_116us = (((uint16_t) 0x1D) << 10),
+  L6474_CONFIG_TOFF_120us = (((uint16_t) 0x1E) << 10),
+  L6474_CONFIG_TOFF_124us = (((uint16_t) 0x1F) << 10)
+} L6474_CONFIG_TOFF_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_STATUS_Register_Bit_Masks
+  * @{
+  */
+///STATUS Register Bit Masks
+typedef enum {
+  L6474_STATUS_HIZ         = (((uint16_t) 0x0001)),
+  L6474_STATUS_DIR         = (((uint16_t) 0x0010)),
+  L6474_STATUS_NOTPERF_CMD = (((uint16_t) 0x0080)),
+  L6474_STATUS_WRONG_CMD   = (((uint16_t) 0x0100)),
+  L6474_STATUS_UVLO        = (((uint16_t) 0x0200)),
+  L6474_STATUS_TH_WRN      = (((uint16_t) 0x0400)),
+  L6474_STATUS_TH_SD       = (((uint16_t) 0x0800)),
+  L6474_STATUS_OCD         = (((uint16_t) 0x1000))
+} L6474_STATUS_Masks_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_Direction_Field_Of_STATUS_Register
+  * @{
+  */  
+///Diretion field of STATUS register
+typedef enum {
+  L6474_STATUS_DIR_FORWARD = (((uint16_t) 0x0001) << 4),
+  L6474_STATUS_DIR_REVERSE = (((uint16_t) 0x0000) << 4)
+} L6474_STATUS_DIR_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_Internal_Register_Addresses
+  * @{
+  */
+/// Internal L6474 register addresses
+typedef enum {
+  L6474_ABS_POS        = ((uint8_t) 0x01),
+  L6474_EL_POS         = ((uint8_t) 0x02),
+  L6474_MARK           = ((uint8_t) 0x03),
+  L6474_RESERVED_REG01 = ((uint8_t) 0x04),
+  L6474_RESERVED_REG02 = ((uint8_t) 0x05),
+  L6474_RESERVED_REG03 = ((uint8_t) 0x06),
+  L6474_RESERVED_REG04 = ((uint8_t) 0x07),
+  L6474_RESERVED_REG05 = ((uint8_t) 0x08),
+  L6474_RESERVED_REG06 = ((uint8_t) 0x15),
+  L6474_TVAL           = ((uint8_t) 0x09),
+  L6474_RESERVED_REG07 = ((uint8_t) 0x0A),
+  L6474_RESERVED_REG08 = ((uint8_t) 0x0B),
+  L6474_RESERVED_REG09 = ((uint8_t) 0x0C),
+  L6474_RESERVED_REG10 = ((uint8_t) 0x0D),
+  L6474_T_FAST         = ((uint8_t) 0x0E),
+  L6474_TON_MIN        = ((uint8_t) 0x0F),
+  L6474_TOFF_MIN       = ((uint8_t) 0x10),
+  L6474_RESERVED_REG11 = ((uint8_t) 0x11),
+  L6474_ADC_OUT        = ((uint8_t) 0x12),
+  L6474_OCD_TH         = ((uint8_t) 0x13),
+  L6474_RESERVED_REG12 = ((uint8_t) 0x14),
+  L6474_STEP_MODE      = ((uint8_t) 0x16),
+  L6474_ALARM_EN       = ((uint8_t) 0x17),
+  L6474_CONFIG         = ((uint8_t) 0x18),
+  L6474_STATUS         = ((uint8_t) 0x19),
+  L6474_RESERVED_REG13 = ((uint8_t) 0x1A),
+  L6474_RESERVED_REG14 = ((uint8_t) 0x1B),
+  L6474_INEXISTENT_REG = ((uint8_t) 0x1F)
+} L6474_Registers_t;
+/**
+  * @}
+  */
+
+/** @defgroup L6474_Command_Set
+  * @{
+  */
+/// L6474 command set
+typedef enum {
+  L6474_NOP           = ((uint8_t) 0x00),
+  L6474_SET_PARAM     = ((uint8_t) 0x00),
+  L6474_GET_PARAM     = ((uint8_t) 0x20),
+  L6474_ENABLE        = ((uint8_t) 0xB8),
+  L6474_DISABLE       = ((uint8_t) 0xA8),
+  L6474_GET_STATUS    = ((uint8_t) 0xD0),
+  L6474_RESERVED_CMD1 = ((uint8_t) 0xEB),
+  L6474_RESERVED_CMD2 = ((uint8_t) 0xF8)
+} L6474_Commands_t;
+/**
+  * @}
+  */
+
+
+/** @defgroup Device_Commands
+  * @{
+  */
+/// Device commands 
+typedef enum {
+  RUN_CMD, 
+  MOVE_CMD, 
+  SOFT_STOP_CMD, 
+  NO_CMD
+} deviceCommand_t;
+/**
+  * @}
+  */
+
+
+/** @defgroup Device_Parameters
+  * @{
+  */
+
+/// Device Parameters Structure Type
+typedef struct {
+    /// accumulator used to store speed increase smaller than 1 pps
+    volatile uint32_t accu;           
+    /// Position in steps at the start of the goto or move commands
+    volatile int32_t currentPosition; 
+    /// position in step at the end of the accelerating phase
+    volatile uint32_t endAccPos;      
+    /// nb steps performed from the beggining of the goto or the move command
+    volatile uint32_t relativePos;    
+    /// position in step at the start of the decelerating phase
+    volatile uint32_t startDecPos;    
+    /// nb steps to perform for the goto or move commands
+    volatile uint32_t stepsToTake;   
+    
+    /// acceleration in pps^2 
+    volatile uint16_t acceleration;  
+    /// deceleration in pps^2
+    volatile uint16_t deceleration;  
+    /// max speed in pps (speed use for goto or move command)
+    volatile uint16_t maxSpeed;      
+    /// min speed in pps
+    volatile uint16_t minSpeed;      
+    /// current speed in pps    
+    volatile uint16_t speed;         
+    
+    /// command under execution
+    volatile deviceCommand_t commandExecuted; 
+    /// FORWARD or BACKWARD direction
+    volatile motorDir_t direction;                 
+    /// Current State of the device
+    volatile motorState_t motionState;       
+}deviceParams_t; 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/* Exported functions --------------------------------------------------------*/
+
+
+/** @defgroup L6474_Exported_Functions
+  * @{
+  */   
+
+/** @defgroup Device_Control_Functions
+  * @{
+  */   
+void L6474_AttachErrorHandler(void (*callback)(uint16_t));  //Attach a user callback to the error handler
+void L6474_AttachFlagInterrupt(void (*callback)(void));     //Attach a user callback to the flag Interrupt
+void L6474_Init(uint8_t nbDevices);                         //Start the L6474 library
+uint16_t L6474_GetAcceleration(uint8_t deviceId);           //Return the acceleration in pps^2
+uint16_t L6474_GetCurrentSpeed(uint8_t deviceId);           //Return the current speed in pps
+uint16_t L6474_GetDeceleration(uint8_t deviceId);           //Return the deceleration in pps^2
+motorState_t L6474_GetDeviceState(uint8_t deviceId);        //Return the device state
+motorDrv_t* L6474_GetMotorHandle(void);                     //Return handle of the motor driver handle
+uint8_t L6474_GetFwVersion(void);                           //Return the FW version
+int32_t L6474_GetMark(uint8_t deviceId);                    //Return the mark position 
+uint16_t L6474_GetMaxSpeed(uint8_t deviceId);               //Return the max speed in pps
+uint16_t L6474_GetMinSpeed(uint8_t deviceId);               //Return the min speed in pps
+int32_t L6474_GetPosition(uint8_t deviceId);                //Return the ABS_POSITION (32b signed)
+void L6474_GoHome(uint8_t deviceId);                        //Move to the home position
+void L6474_GoMark(uint8_t deviceId);                        //Move to the Mark position
+void L6474_GoTo(uint8_t deviceId, int32_t targetPosition);  //Go to the specified position
+void L6474_HardStop(uint8_t deviceId);                      //Stop the motor and disable the power bridge
+void L6474_Move(uint8_t deviceId,                           //Move the motor of the specified number of steps
+                motorDir_t direction,
+                uint32_t stepCount);    
+uint16_t L6474_ReadId(void);                                //Read Id to get driver instance
+void L6474_ResetAllDevices(void);                           //Reset all L6474 devices
+void L6474_Run(uint8_t deviceId, motorDir_t direction);     //Run the motor 
+bool L6474_SetAcceleration(uint8_t deviceId,uint16_t newAcc); //Set the acceleration in pps^2
+bool L6474_SetDeceleration(uint8_t deviceId,uint16_t newDec); //Set the deceleration in pps^2
+void L6474_SetHome(uint8_t deviceId);                         //Set current position to be the home position
+void L6474_SetMark(uint8_t deviceId);                         //Set current position to be the Markposition
+bool L6474_SetMaxSpeed(uint8_t deviceId,uint16_t newMaxSpeed); //Set the max speed in pps
+bool L6474_SetMinSpeed(uint8_t deviceId,uint16_t newMinSpeed); //Set the min speed in pps   
+bool L6474_SoftStop(uint8_t deviceId);                         //Progressively stops the motor 
+void L6474_WaitWhileActive(uint8_t deviceId);                  //Wait for the device state becomes Inactive
+/**
+  * @}
+  */
+
+/** @defgroup L6474_Control_Functions
+  * @{
+  */   
+void L6474_CmdDisable(uint8_t deviceId);              //Send the L6474_DISABLE command
+void L6474_CmdEnable(uint8_t deviceId);               //Send the L6474_ENABLE command
+uint32_t L6474_CmdGetParam(uint8_t deviceId,          //Send the L6474_GET_PARAM command
+                           uint32_t param);
+uint16_t L6474_CmdGetStatus(uint8_t deviceId);        // Send the L6474_GET_STATUS command
+void L6474_CmdNop(uint8_t deviceId);                  //Send the L6474_NOP command
+void L6474_CmdSetParam(uint8_t deviceId,              //Send the L6474_SET_PARAM command
+                       uint32_t param,       
+                       uint32_t value);
+uint16_t L6474_ReadStatusRegister(uint8_t deviceId);  // Read the L6474_STATUS register without
+                                                        // clearing the flags
+void L6474_Reset(void);                               //Set the L6474 reset pin 
+void L6474_ReleaseReset(void);                        //Release the L6474 reset pin 
+void L6474_SelectStepMode(uint8_t deviceId,           // Step mode selection
+                          motorStepMode_t stepMod);     
+void L6474_SetDirection(uint8_t deviceId,             //Set the L6474 direction pin
+                        motorDir_t direction);      
+/**
+  * @}
+  */
+
+/** @defgroup MotorControl_Board_Linked_Functions
+  * @{
+  */   
+///Delay of the requested number of milliseconds
+void BSP_MotorControlBoard_Delay(uint32_t delay);         
+///Enable Irq
+void BSP_MotorControlBoard_EnableIrq(void);               
+///Disable Irq
+void BSP_MotorControlBoard_DisableIrq(void);              
+///Initialise GPIOs used for L6474s
+void BSP_MotorControlBoard_GpioInit(uint8_t nbDevices);   
+///Set PWM1 frequency and start it
+void BSP_MotorControlBoard_Pwm1SetFreq(uint16_t newFreq); 
+///Set PWM2 frequency and start it  
+void BSP_MotorControlBoard_Pwm2SetFreq(uint16_t newFreq); 
+///Set PWM3 frequency and start it
+void BSP_MotorControlBoard_Pwm3SetFreq(uint16_t newFreq); 
+///Init the PWM of the specified device
+void BSP_MotorControlBoard_PwmInit(uint8_t deviceId);    
+///Stop the PWM of the specified device
+void BSP_MotorControlBoard_PwmStop(uint8_t deviceId);    
+///Reset the L6474 reset pin 
+void BSP_MotorControlBoard_ReleaseReset(void);           
+///Set the L6474 reset pin 
+void BSP_MotorControlBoard_Reset(void);                  
+///Set direction GPIO
+void BSP_MotorControlBoard_SetDirectionGpio(uint8_t deviceId, uint8_t gpioState); 
+///Initialise the SPI used for L6474s
+uint8_t BSP_MotorControlBoard_SpiInit(void);   
+///Write bytes to the L6474s via SPI
+uint8_t BSP_MotorControlBoard_SpiWriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte, uint8_t nbDevices); 
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* #ifndef __L6474_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/l6474_target_config.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,246 @@
+/**************************************************************************//**
+  * @file    l6474_target_config.h
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   Predefines values for the L6474 registers
+  * and for the devices parameters
+  * @note    (C) COPYRIGHT 2014 STMicroelectronics
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __L6474_TARGET_CONFIG_H
+#define __L6474_TARGET_CONFIG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/** @addtogroup BSP
+  * @{
+  */   
+   
+/** @addtogroup L6474
+  * @{
+  */   
+
+/** @addtogroup L6474_Exported_Constants
+  * @{
+  */   
+   
+/** @defgroup Predefined_L6474_Registers_Values
+  * @{
+  */   
+
+   
+/// The maximum number of devices in the daisy chain
+#define MAX_NUMBER_OF_DEVICES                 (3)
+
+/************** Motor Energised When Halted or Not  ********************/
+
+/// Switch behaviour: motors de-energised when halted, or energised/braked.
+#define L6474_CONF_BRAKE_WHEN_HALTED
+/// Reduced motor current, eg half power when halted.
+#define L6474_CONF_BRAKE_CURRENT_FACTOR       (2)
+
+/************************ Speed Profile  *******************************/
+
+/// Acceleration rate in step/s2 for device 0 (must be greater than 0)
+#define L6474_CONF_PARAM_ACC_DEVICE_0        (160)
+/// Acceleration rate in step/s2 for device 1 (must be greater than 0)
+#define L6474_CONF_PARAM_ACC_DEVICE_1        (160)
+/// Acceleration rate in step/s2 for device 2 (must be greater than 0)
+#define L6474_CONF_PARAM_ACC_DEVICE_2        (160)
+
+/// Deceleration rate in step/s2 for device 0 (must be greater than 0)
+#define L6474_CONF_PARAM_DEC_DEVICE_0        (160)
+/// Deceleration rate in step/s2 for device 1 (must be greater than 0)
+#define L6474_CONF_PARAM_DEC_DEVICE_1        (160)
+/// Deceleration rate in step/s2 for device 2 (must be greater than 0)
+#define L6474_CONF_PARAM_DEC_DEVICE_2        (160)
+
+/// Maximum speed in step/s for device 0 (30 step/s < Maximum speed <= 10 000 step/s )
+#define L6474_CONF_PARAM_MAX_SPEED_DEVICE_0  (1600)
+/// Maximum speed in step/s for device 1 (30 step/s < Maximum speed <= 10 000 step/s )
+#define L6474_CONF_PARAM_MAX_SPEED_DEVICE_1  (1600)
+/// Maximum speed in step/s for device 2 (30 step/s < Maximum speed <= 10 000 step/s )
+#define L6474_CONF_PARAM_MAX_SPEED_DEVICE_2  (1600)
+
+/// Minimum speed in step/s for device 0 (30 step/s <= Minimum speed < 10 000 step/s)
+#define L6474_CONF_PARAM_MIN_SPEED_DEVICE_0  (800)
+/// Minimum speed in step/s for device 1 (30 step/s <= Minimum speed < 10 000 step/s)
+#define L6474_CONF_PARAM_MIN_SPEED_DEVICE_1  (800)
+/// Minimum speed in step/s for device 2 (30 step/s <= Minimum speed < 10 000 step/s)
+#define L6474_CONF_PARAM_MIN_SPEED_DEVICE_2  (800)
+
+
+/************************ Phase Current Control *******************************/
+
+// Current value that is assigned to the torque regulation DAC
+/// TVAL register value for device 0 (range 31.25mA to 4000mA)
+#define L6474_CONF_PARAM_TVAL_DEVICE_0  (250)
+/// TVAL register value for device 1 (range 31.25mA to 4000mA)
+#define L6474_CONF_PARAM_TVAL_DEVICE_1  (250)
+/// TVAL register value for device 2 (range 31.25mA to 4000mA)
+#define L6474_CONF_PARAM_TVAL_DEVICE_2  (250)
+
+/// Fall time value (T_FAST field of T_FAST register) for device 0 (range 2us to 32us)
+#define L6474_CONF_PARAM_FAST_STEP_DEVICE_0  (L6474_FAST_STEP_12us)
+/// Fall time value (T_FAST field of T_FAST register) for device 1 (range 2us to 32us)
+#define L6474_CONF_PARAM_FAST_STEP_DEVICE_1  (L6474_FAST_STEP_12us)
+/// Fall time value (T_FAST field of T_FAST register) for device 2 (range 2us to 32us)
+#define L6474_CONF_PARAM_FAST_STEP_DEVICE_2  (L6474_FAST_STEP_12us)
+
+/// Maximum fast decay time (T_OFF field of T_FAST register) for device 0 (range 2us to 32us)
+#define L6474_CONF_PARAM_TOFF_FAST_DEVICE_0  (L6474_TOFF_FAST_8us)
+/// Maximum fast decay time (T_OFF field of T_FAST register) for device 1 (range 2us to 32us)
+#define L6474_CONF_PARAM_TOFF_FAST_DEVICE_1  (L6474_TOFF_FAST_8us)
+/// Maximum fast decay time (T_OFF field of T_FAST register) for device 2 (range 2us to 32us)
+#define L6474_CONF_PARAM_TOFF_FAST_DEVICE_2  (L6474_TOFF_FAST_8us)
+
+/// Minimum ON time (TON_MIN register) for device 0 (range 0.5us to 64us)
+#define L6474_CONF_PARAM_TON_MIN_DEVICE_0 (3)
+/// Minimum ON time (TON_MIN register) for device 1 (range 0.5us to 64us)
+#define L6474_CONF_PARAM_TON_MIN_DEVICE_1 (3)
+/// Minimum ON time (TON_MIN register) for device 2 (range 0.5us to 64us)
+#define L6474_CONF_PARAM_TON_MIN_DEVICE_2 (3)
+
+/// Minimum OFF time (TOFF_MIN register) for device 0 (range 0.5us to 64us)
+#define L6474_CONF_PARAM_TOFF_MIN_DEVICE_0 (21)
+/// Minimum OFF time (TOFF_MIN register) for device 1 (range 0.5us to 64us)
+#define L6474_CONF_PARAM_TOFF_MIN_DEVICE_1 (21)
+/// Minimum OFF time (TOFF_MIN register) for device 2 (range 0.5us to 64us)
+#define L6474_CONF_PARAM_TOFF_MIN_DEVICE_2 (21)
+
+/******************************* Others ***************************************/
+
+/// Overcurrent threshold settings for device 0 (OCD_TH register)
+#define L6474_CONF_PARAM_OCD_TH_DEVICE_0  (L6474_OCD_TH_750mA)
+/// Overcurrent threshold settings for device 1 (OCD_TH register)
+#define L6474_CONF_PARAM_OCD_TH_DEVICE_1  (L6474_OCD_TH_750mA)
+/// Overcurrent threshold settings for device 2 (OCD_TH register)
+#define L6474_CONF_PARAM_OCD_TH_DEVICE_2  (L6474_OCD_TH_750mA)
+
+/// Alarm settings for device 0 (ALARM_EN register)
+#define L6474_CONF_PARAM_ALARM_EN_DEVICE_0  (L6474_ALARM_EN_OVERCURRENT |\
+                                             L6474_ALARM_EN_THERMAL_SHUTDOWN |\
+                                             L6474_ALARM_EN_THERMAL_WARNING |\
+                                             L6474_ALARM_EN_UNDERVOLTAGE |\
+                                             L6474_ALARM_EN_SW_TURN_ON |\
+                                             L6474_ALARM_EN_WRONG_NPERF_CMD)
+
+///Alarm settings for device 1 (ALARM_EN register)
+#define L6474_CONF_PARAM_ALARM_EN_DEVICE_1  (L6474_ALARM_EN_OVERCURRENT |\
+                                             L6474_ALARM_EN_THERMAL_SHUTDOWN |\
+                                             L6474_ALARM_EN_THERMAL_WARNING |\
+                                             L6474_ALARM_EN_UNDERVOLTAGE |\
+                                             L6474_ALARM_EN_SW_TURN_ON |\
+                                             L6474_ALARM_EN_WRONG_NPERF_CMD)
+
+/// Alarm settings for device 2 (ALARM_EN register)
+#define L6474_CONF_PARAM_ALARM_EN_DEVICE_2  (L6474_ALARM_EN_OVERCURRENT |\
+                                             L6474_ALARM_EN_THERMAL_SHUTDOWN |\
+                                             L6474_ALARM_EN_THERMAL_WARNING |\
+                                             L6474_ALARM_EN_UNDERVOLTAGE |\
+                                             L6474_ALARM_EN_SW_TURN_ON |\
+                                             L6474_ALARM_EN_WRONG_NPERF_CMD)
+
+/// Step selection settings for device 0 (STEP_SEL field of STEP_MODE register)
+#define L6474_CONF_PARAM_STEP_SEL_DEVICE_0  (L6474_STEP_SEL_1_16)
+/// Step selection settings for device 1 (STEP_SEL field of STEP_MODE register)
+#define L6474_CONF_PARAM_STEP_SEL_DEVICE_1  (L6474_STEP_SEL_1_16)
+/// Step selection settings for device 2 (STEP_SEL field of STEP_MODE register)
+#define L6474_CONF_PARAM_STEP_SEL_DEVICE_2  (L6474_STEP_SEL_1_16)
+
+/// Synch. selection settings for device 0 (SYNC_SEL field of STEP_MODE register)
+#define L6474_CONF_PARAM_SYNC_SEL_DEVICE_0  (L6474_SYNC_SEL_1_2)
+/// Synch. selection settings for device 1 (SYNC_SEL field of STEP_MODE register)
+#define L6474_CONF_PARAM_SYNC_SEL_DEVICE_1  (L6474_SYNC_SEL_1_2)
+/// Synch. selection settings for device 2 (SYNC_SEL field of STEP_MODE register)
+#define L6474_CONF_PARAM_SYNC_SEL_DEVICE_2  (L6474_SYNC_SEL_1_2)
+
+/// Target Swicthing Period for device 0 (field TOFF of CONFIG register)
+#define L6474_CONF_PARAM_TOFF_DEVICE_0  (L6474_CONFIG_TOFF_044us)
+/// Target Swicthing Period for device 1 (field TOFF of CONFIG register)
+#define L6474_CONF_PARAM_TOFF_DEVICE_1  (L6474_CONFIG_TOFF_044us)
+/// Target Swicthing Period for device 2 (field TOFF of CONFIG register)
+#define L6474_CONF_PARAM_TOFF_DEVICE_2  (L6474_CONFIG_TOFF_044us)
+
+/// Slew rate for device 0 (POW_SR field of CONFIG register)
+#define L6474_CONF_PARAM_SR_DEVICE_0  (L6474_CONFIG_SR_320V_us)
+/// Slew rate for device 1 (POW_SR field of CONFIG register)
+#define L6474_CONF_PARAM_SR_DEVICE_1  (L6474_CONFIG_SR_320V_us)
+/// Slew rate for device 2 (POW_SR field of CONFIG register)
+#define L6474_CONF_PARAM_SR_DEVICE_2  (L6474_CONFIG_SR_320V_us)
+
+/// Over current shutwdown enabling for device 0 (OC_SD field of CONFIG register)
+#define L6474_CONF_PARAM_OC_SD_DEVICE_0  (L6474_CONFIG_OC_SD_ENABLE)
+/// Over current shutwdown enabling for device 1 (OC_SD field of CONFIG register)
+#define L6474_CONF_PARAM_OC_SD_DEVICE_1  (L6474_CONFIG_OC_SD_ENABLE)
+/// Over current shutwdown enabling for device 2 (OC_SD field of CONFIG register)
+#define L6474_CONF_PARAM_OC_SD_DEVICE_2  (L6474_CONFIG_OC_SD_ENABLE)
+
+/// Torque regulation method for device 0 (EN_TQREG field of CONFIG register)
+#define L6474_CONF_PARAM_TQ_REG_DEVICE_0  (L6474_CONFIG_EN_TQREG_TVAL_USED)
+///Torque regulation method for device 1 (EN_TQREG field of CONFIG register)
+#define L6474_CONF_PARAM_TQ_REG_DEVICE_1  (L6474_CONFIG_EN_TQREG_TVAL_USED)
+/// Torque regulation method for device 2 (EN_TQREG field of CONFIG register)
+#define L6474_CONF_PARAM_TQ_REG_DEVICE_2  (L6474_CONFIG_EN_TQREG_TVAL_USED)
+
+/// Clock setting for device 0 (OSC_CLK_SEL field of CONFIG register)
+#define L6474_CONF_PARAM_CLOCK_SETTING_DEVICE_0  (L6474_CONFIG_INT_16MHZ)
+/// Clock setting for device 1 (OSC_CLK_SEL field of CONFIG register)
+#define L6474_CONF_PARAM_CLOCK_SETTING_DEVICE_1  (L6474_CONFIG_INT_16MHZ)
+/// Clock setting for device 2 (OSC_CLK_SEL field of CONFIG register)
+#define L6474_CONF_PARAM_CLOCK_SETTING_DEVICE_2  (L6474_CONFIG_INT_16MHZ)
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* __L6474_TARGET_CONFIG_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/motor.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,308 @@
+/**
+  ******************************************************************************
+  * @file    motor.h
+  * @author  IPC Rennes
+  * @version V1.3.0
+  * @date    November 12, 2014
+  * @brief   This file contains all the functions prototypes for motor drivers.   
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MOTOR_H
+#define __MOTOR_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+   
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */ 
+
+/** @defgroup Motor
+  * @{
+  */
+    
+/** @defgroup Motor_Exported_Constants
+  * @{
+  */   
+   
+/// boolean for false condition 
+#ifndef FALSE
+#define FALSE (0)
+#endif
+/// boolean for true condition 
+#ifndef TRUE
+#define TRUE  (1)
+#endif
+
+   /**
+  * @}
+  */
+   
+/** @defgroup Motor_Exported_Types
+  * @{
+  */
+
+   /** @defgroup Motor_Boolean_Type
+  * @{
+  */
+///bool Type
+//mbed typedef uint8_t  bool;
+/**
+  * @}
+  */   
+   
+/** @defgroup Device_Direction_Options
+  * @{
+  */
+/// Direction options
+typedef enum {
+  BACKWARD = 0,
+  FORWARD = 1
+} motorDir_t;
+/**
+  * @}
+  */
+  
+/** @defgroup Device_Action_Options
+  * @{
+  */
+/// Action options
+typedef enum {
+  ACTION_RESET = ((uint8_t)0x00),
+  ACTION_COPY  = ((uint8_t)0x08)
+} motorAction_t;
+/**
+  * @}
+  */  
+
+/** @defgroup Device_States
+  * @{
+  */
+/// Device states
+typedef enum {
+  ACCELERATING = 0, 
+  DECELERATING = 1, 
+  STEADY = 2,
+  INACTIVE= 3
+} motorState_t;
+/**
+  * @}
+  */   
+
+/** @defgroup Device_Step_mode
+  * @{
+  */
+ /// Stepping options 
+typedef enum {
+  STEP_MODE_FULL   = ((uint8_t)0x00), 
+  STEP_MODE_HALF   = ((uint8_t)0x01),
+  STEP_MODE_1_4    = ((uint8_t)0x02),
+  STEP_MODE_1_8    = ((uint8_t)0x03),
+  STEP_MODE_1_16   = ((uint8_t)0x04),
+  STEP_MODE_1_32   = ((uint8_t)0x05),
+  STEP_MODE_1_64   = ((uint8_t)0x06),
+  STEP_MODE_1_128  = ((uint8_t)0x07)
+} motorStepMode_t;
+/**
+  * @}
+  */   
+
+
+/** @defgroup Motor_Driver_Structure
+  * @{
+  */
+/// Motor driver structure definition  
+typedef struct
+{
+  /// Function pointer to Init
+  void (*Init)(uint8_t); 
+  /// Function pointer to ReadID
+  uint16_t (*ReadID)(void);   
+  /// Function pointer to AttachErrorHandler
+  void(*AttachErrorHandler)(void (*callback)(uint16_t));
+  /// Function pointer to AttachFlagInterrupt
+  void (*AttachFlagInterrupt)(void (*callback)(void));
+  /// Function pointer to AttachBusyInterrupt
+  void (*AttachBusyInterrupt)(void (*callback)(void));
+  /// Function pointer to FlagInterruptHandler
+  void (*FlagInterruptHandler)(void);  
+  /// Function pointer to GetAcceleration
+  uint16_t (*GetAcceleration)(uint8_t); 
+  /// Function pointer to GetCurrentSpeed
+  uint16_t (*GetCurrentSpeed)(uint8_t); 
+  /// Function pointer to GetDeceleration
+  uint16_t (*GetDeceleration)(uint8_t); 
+  /// Function pointer to GetDeviceState
+  motorState_t(*GetDeviceState)(uint8_t); 
+  /// Function pointer to GetFwVersion
+  uint8_t (*GetFwVersion)(void); 
+  /// Function pointer to GetMark
+  int32_t (*GetMark)(uint8_t); 
+  /// Function pointer to GetMaxSpeed
+  uint16_t (*GetMaxSpeed)(uint8_t); 
+  /// Function pointer to GetMinSpeed
+  uint16_t (*GetMinSpeed)(uint8_t); 
+  /// Function pointer to GetPosition
+  int32_t (*GetPosition)(uint8_t); 
+  /// Function pointer to GoHome
+  void (*GoHome)(uint8_t); 
+  /// Function pointer to GoMark
+  void (*GoMark)(uint8_t); 
+  /// Function pointer to GoTo
+  void (*GoTo)(uint8_t, int32_t); 
+  /// Function pointer to HardStop
+  void (*HardStop)(uint8_t); 
+  /// Function pointer to Move
+  void (*Move)(uint8_t, motorDir_t, uint32_t ); 
+  /// Function pointer to ResetAllDevices
+  void (*ResetAllDevices)(void); 
+  /// Function pointer to Run
+  void (*Run)(uint8_t, motorDir_t); 
+  /// Function pointer to SetAcceleration
+  bool(*SetAcceleration)(uint8_t ,uint16_t ); 
+  /// Function pointer to SetDeceleration
+  bool(*SetDeceleration)(uint8_t , uint16_t ); 
+  /// Function pointer to SetHome
+  void (*SetHome)(uint8_t); 
+  /// Function pointer to SetMark
+  void (*SetMark)(uint8_t); 
+  /// Function pointer to SetMaxSpeed
+  bool (*SetMaxSpeed)(uint8_t, uint16_t ); 
+  /// Function pointer to SetMinSpeed
+  bool (*SetMinSpeed)(uint8_t, uint16_t ); 
+  /// Function pointer to SoftStop
+  bool (*SoftStop)(uint8_t); 
+  /// Function pointer to StepClockHandler
+  void (*StepClockHandler)(uint8_t deviceId);  
+  /// Function pointer to WaitWhileActive
+  void (*WaitWhileActive)(uint8_t); 
+  /// Function pointer to CmdDisable
+  void (*CmdDisable)(uint8_t); 
+  /// Function pointer to CmdEnable
+  void (*CmdEnable)(uint8_t);
+  /// Function pointer to CmdGetParam
+  uint32_t (*CmdGetParam)(uint8_t, uint32_t);
+  /// Function pointer to CmdGetStatus
+  uint16_t (*CmdGetStatus)(uint8_t); 
+  /// Function pointer to CmdNop
+  void (*CmdNop)(uint8_t); 
+  /// Function pointer to CmdSetParam  
+  void (*CmdSetParam)(uint8_t, uint32_t, uint32_t);
+  /// Function pointer to ReadStatusRegister
+  uint16_t (*ReadStatusRegister)(uint8_t); 
+  /// Function pointer to ReleaseReset
+  void (*ReleaseReset)(void);
+  /// Function pointer to Reset
+  void (*Reset)(void); 
+  /// Function pointer to SelectStepMode
+  void (*SelectStepMode)(uint8_t deviceId, motorStepMode_t); 
+  /// Function pointer to SetDirection
+  void (*SetDirection)(uint8_t, motorDir_t);  
+  /// Function pointer to CmdGoToDir
+  void (*CmdGoToDir)(uint8_t, motorDir_t, int32_t);
+  /// Function pointer to CheckBusyHw
+  uint8_t (*CheckBusyHw)(void);
+  /// Function pointer to CheckStatusHw
+  uint8_t (*CheckStatusHw)(void);
+  /// Function pointer to CmdGoUntil
+  void (*CmdGoUntil)(uint8_t, motorAction_t, motorDir_t, uint32_t);
+  /// Function pointer to CmdHardHiZ
+  void (*CmdHardHiZ)(uint8_t);
+  /// Function pointer to CmdReleaseSw
+  void (*CmdReleaseSw)(uint8_t, motorAction_t, motorDir_t);
+  /// Function pointer to CmdResetDevice
+  void (*CmdResetDevice)(uint8_t);
+  /// Function pointer to CmdResetPos
+  void (*CmdResetPos)(uint8_t);
+  /// Function pointer to CmdRun
+  void (*CmdRun)(uint8_t, motorDir_t, uint32_t);
+  /// Function pointer to CmdSoftHiZ
+  void (*CmdSoftHiZ)(uint8_t);
+  /// Function pointer to CmdStepClock
+  void (*CmdStepClock)(uint8_t, motorDir_t);
+  /// Function pointer to FetchAndClearAllStatus
+  void (*FetchAndClearAllStatus)(void);
+  /// Function pointer to GetFetchedStatus
+  uint16_t (*GetFetchedStatus)(uint8_t);
+  /// Function pointer to GetNbDevices
+  uint8_t (*GetNbDevices)(void);
+  /// Function pointer to IsDeviceBusy
+  bool (*IsDeviceBusy)(uint8_t);
+  /// Function pointer to SendQueuedCommands
+  void (*SendQueuedCommands)(void);
+  /// Function pointer to QueueCommands  
+  void (*QueueCommands)(uint8_t, uint8_t, uint32_t);
+  /// Function pointer to WaitForAllDevicesNotBusy  
+  void (*WaitForAllDevicesNotBusy)(void);  
+  /// Function pointer to ErrorHandler  
+  void (*ErrorHandler)(uint16_t);
+  /// Function pointer to BusyInterruptHandler  
+  void (*BusyInterruptHandler)(void);
+  void (*CmdSoftStop)(uint8_t); 
+}motorDrv_t;    
+      
+/**
+  
+* @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+  
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MOTOR_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/motorcontrol.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,1339 @@
+/**
+ ******************************************************************************
+ * @file    motorcontrol.c
+ * @author  IPC Rennes
+ * @version V1.0.0
+ * @date    12-November-2014
+ * @brief   This file provides common functions for motor control 
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "motorcontrol.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @defgroup MOTOR_CONTROL
+ * @{
+ */
+
+/** @defgroup MOTOR_CONTROL_Private_Types_Definitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MOTOR_CONTROL_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup MOTOR_CONTROL_Private_Constants
+ * @{
+ */
+/// Error when trying to call undefined functions via motorDrvHandle
+#define MOTOR_CONTROL_ERROR_0   (0x0800)   
+
+/**
+ * @}
+ */
+
+/** @defgroup MOTOR_CONTROL_Private_Macros
+ * @{
+ */
+/// Error when trying to call undefined functions via motorDrvHandle
+#define MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(errorNb)   (BSP_MotorControl_ErrorHandler(MOTOR_CONTROL_ERROR_0|(errorNb)))   
+
+/**
+ * @}
+ */   
+   
+/** @defgroup MOTOR_CONTROL_Private_Variables
+ * @{
+ */
+
+static motorDrv_t *motorDrvHandle = 0;
+static uint16_t MotorControlBoardId;
+/**
+ * @}
+ */
+
+/** @defgroup MOTOR_CONTROL_Weak_Private_Functions
+ * @{
+ */
+/// Get motor handle for L6474
+__weak motorDrv_t* L6474_GetMotorHandle(void){return ((motorDrv_t* )0);}
+/// Get motor handle for Powerstep
+__weak motorDrv_t* Powerstep01_GetMotorHandle(void){return ((motorDrv_t* )0);}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup MOTOR_CONTROL_Private_Functions
+ * @{
+ */
+
+/******************************************************//**
+ * @brief  Attaches a user callback to the error Handler.
+ * The call back will be then called each time the library 
+ * detects an error
+ * @param[in] callback Name of the callback to attach 
+ * to the error Hanlder
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_AttachErrorHandler(void (*callback)(uint16_t))
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->AttachErrorHandler != 0))
+  {
+    motorDrvHandle->AttachErrorHandler(callback);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(1);
+  }
+}
+
+/******************************************************//**
+ * @brief  Attaches a user callback to the Flag interrupt Handler.
+ * The call back will be then called each time the library 
+ * detects a FLAG signal falling edge.
+ * @param[in] callback Name of the callback to attach 
+ * to the Flag interrupt Hanlder
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_AttachFlagInterrupt(void (*callback)(void))
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->AttachFlagInterrupt != 0))
+  {
+    motorDrvHandle->AttachFlagInterrupt(callback);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(2);
+  }  
+}
+
+/******************************************************//**
+ * @brief  Attaches a user callback to the Busy interrupt Handler.
+ * The call back will be then called each time the library 
+ * detects a BUSY signal falling edge.
+ * @param[in] callback Name of the callback to attach 
+ * to the Busy interrupt Hanlder
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_AttachBusyInterrupt(void (*callback)(void))
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->AttachBusyInterrupt != 0))
+  {
+    motorDrvHandle->AttachBusyInterrupt(callback);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(3);
+  }  
+}
+
+/******************************************************//**
+ * @brief Motor control error handler
+ * @param[in] error number of the error
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_ErrorHandler(uint16_t error)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->ErrorHandler != 0))
+  {
+    motorDrvHandle->ErrorHandler(error);
+  }  
+  else
+  {
+    while(1)
+    {
+      /* Infinite loop as Error handler must be defined*/
+    }
+  }
+}
+/******************************************************//**
+ * @brief Initialises the motor driver
+ * @param[in] id Component Id (L6474, Powerstep01,...)
+ * @param[in] nbDevices Number of motor devices to use (from 1 to 3)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_Init(uint16_t  id, uint8_t nbDevices)
+{
+  MotorControlBoardId = id;
+  
+  if (id == BSP_MOTOR_CONTROL_BOARD_ID_L6474)
+  {
+    motorDrvHandle = L6474_GetMotorHandle();
+  }
+  else if (id == BSP_MOTOR_CONTROL_BOARD_ID_POWERSTEP01)
+  {
+    motorDrvHandle = Powerstep01_GetMotorHandle();
+  }
+  else
+  {
+    motorDrvHandle = 0;
+  }
+
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->Init != 0))
+  {
+    motorDrvHandle->Init(nbDevices);
+  }  
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(4);
+  }  
+}
+
+/******************************************************//**
+ * @brief  Handlers of the flag interrupt which calls the user callback (if defined)
+ * @param None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_FlagInterruptHandler(void)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->FlagInterruptHandler != 0))
+  {
+    motorDrvHandle->FlagInterruptHandler();
+  }    
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(5);
+  }  
+}
+/******************************************************//**
+ * @brief Returns the acceleration of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Acceleration in pps^2
+ **********************************************************/
+uint16_t BSP_MotorControl_GetAcceleration(uint8_t deviceId)
+{                                                  
+  uint16_t acceleration = 0;
+
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GetAcceleration != 0))
+  {
+    acceleration = motorDrvHandle->GetAcceleration(deviceId);
+  }      
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(6);
+  }  
+  return(acceleration);    
+}            
+
+/******************************************************//**
+ * @brief Get board Id  the motor driver
+ * @param None
+ * @retval Motor control board Id
+ **********************************************************/
+uint16_t BSP_MotorControl_GetBoardId(void)
+{
+  return (MotorControlBoardId);
+}
+/******************************************************//**
+ * @brief Returns the current speed of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Speed in pps
+ **********************************************************/
+uint16_t BSP_MotorControl_GetCurrentSpeed(uint8_t deviceId)
+{
+  uint16_t currentSpeed = 0;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GetCurrentSpeed != 0))
+  {
+    currentSpeed = motorDrvHandle->GetCurrentSpeed(deviceId);
+  }      
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(7);
+  }  
+  return(currentSpeed); 
+}
+
+/******************************************************//**
+ * @brief Returns the deceleration of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Deceleration in pps^2
+ **********************************************************/
+uint16_t BSP_MotorControl_GetDeceleration(uint8_t deviceId)
+{                                                  
+  uint16_t deceleration = 0;
+
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GetDeceleration != 0))
+  {
+    deceleration = motorDrvHandle->GetDeceleration(deviceId);
+  }      
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(8);
+  }  
+  return(deceleration);   
+}          
+
+/******************************************************//**
+ * @brief Returns the device state
+ * @param[in] deviceId (from 0 to 2)
+ * @retval State (ACCELERATING, DECELERATING, STEADY or INACTIVE)
+ **********************************************************/
+motorState_t BSP_MotorControl_GetDeviceState(uint8_t deviceId)
+{
+  motorState_t state = INACTIVE;
+
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GetDeviceState != 0))
+  {
+    state = motorDrvHandle->GetDeviceState(deviceId);
+  }      
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(9);
+  }  
+  return(state);   
+}
+
+/******************************************************//**
+ * @brief Returns the FW version of the library
+ * @param None
+ * @retval BSP_MotorControl_FW_VERSION
+ **********************************************************/
+uint8_t BSP_MotorControl_GetFwVersion(void)
+{
+  uint8_t version = 0;
+  
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GetFwVersion != 0))
+  {
+    version = motorDrvHandle->GetFwVersion();
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(10);
+  }  
+  return(version);
+}
+
+/******************************************************//**
+ * @brief  Returns the mark position  of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Mark register value converted in a 32b signed integer 
+ **********************************************************/
+int32_t BSP_MotorControl_GetMark(uint8_t deviceId)
+{
+  int32_t mark = 0;
+  
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GetMark != 0))
+  {
+    mark = motorDrvHandle->GetMark(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(11);
+  }  
+  return(mark);
+}
+
+/******************************************************//**
+ * @brief  Returns the max speed of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval maxSpeed in pps
+ **********************************************************/
+uint16_t BSP_MotorControl_GetMaxSpeed(uint8_t deviceId)
+{                                                  
+  uint16_t maxSpeed = 0;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GetMaxSpeed != 0))
+  {
+    maxSpeed = motorDrvHandle->GetMaxSpeed(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(12);
+  }    
+  return(maxSpeed);
+}
+
+/******************************************************//**
+ * @brief  Returns the min speed of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval minSpeed in pps
+ **********************************************************/
+uint16_t BSP_MotorControl_GetMinSpeed(uint8_t deviceId)
+{                                                  
+  uint16_t minSpeed = 0;
+
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GetMinSpeed != 0))
+  {
+    minSpeed = motorDrvHandle->GetMinSpeed(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(13);
+  }    
+  return(minSpeed);  
+}                                                     
+
+/******************************************************//**
+ * @brief  Returns the ABS_POSITION of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval ABS_POSITION register value converted in a 32b signed integer
+ **********************************************************/
+int32_t BSP_MotorControl_GetPosition(uint8_t deviceId)
+{
+  int32_t pos = 0;
+  
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GetPosition != 0))
+  {
+    pos = motorDrvHandle->GetPosition(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(14);
+  }      
+  return(pos);
+}
+
+/******************************************************//**
+ * @brief  Requests the motor to move to the home position (ABS_POSITION = 0)
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_GoHome(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GoHome != 0))
+  {
+    motorDrvHandle->GoHome(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(15);
+  }      
+} 
+  
+/******************************************************//**
+ * @brief  Requests the motor to move to the mark position 
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_GoMark(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GoMark != 0))
+  {
+    motorDrvHandle->GoMark(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(16);
+  }     
+}
+
+/******************************************************//**
+ * @brief  Requests the motor to move to the specified position 
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] targetPosition absolute position in steps
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_GoTo(uint8_t deviceId, int32_t targetPosition)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GoTo != 0))
+  {
+    motorDrvHandle->GoTo(deviceId, targetPosition);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(17);
+  }      
+}
+
+/******************************************************//**
+ * @brief  Immediatly stops the motor and disable the power bridge
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_HardStop(uint8_t deviceId) 
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->HardStop != 0))
+  {
+    motorDrvHandle->HardStop(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(18);
+  }      
+}
+
+/******************************************************//**
+ * @brief  Moves the motor of the specified number of steps
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] direction FORWARD or BACKWARD
+ * @param[in] stepCount Number of steps to perform
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_Move(uint8_t deviceId, motorDir_t direction, uint32_t stepCount)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->Move != 0))
+  {
+    motorDrvHandle->Move(deviceId, direction, stepCount);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(19);
+  }      
+}
+
+/******************************************************//**
+ * @brief Resets all motor driver devices
+ * @param None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_ResetAllDevices(void)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->ResetAllDevices != 0))
+  {
+    motorDrvHandle->ResetAllDevices(); 
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(20);
+  }      
+}
+
+/******************************************************//**
+ * @brief  Runs the motor. It will accelerate from the min 
+ * speed up to the max speed by using the device acceleration.
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] direction FORWARD or BACKWARD
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_Run(uint8_t deviceId, motorDir_t direction)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->Run != 0))
+  {
+    motorDrvHandle->Run(deviceId, direction); 
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(21);
+  }      
+}
+/******************************************************//**
+ * @brief  Changes the acceleration of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] newAcc New acceleration to apply in pps^2
+ * @retval true if the command is successfully executed, else false
+ * @note The command is not performed is the device is executing 
+ * a MOVE or GOTO command (but it can be used during a RUN command)
+ **********************************************************/
+bool BSP_MotorControl_SetAcceleration(uint8_t deviceId,uint16_t newAcc)
+{                                                  
+  bool status = FALSE;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->SetAcceleration != 0))
+  {
+    status = motorDrvHandle->SetAcceleration(deviceId, newAcc);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(22);
+  }      
+  return (status);
+}            
+
+/******************************************************//**
+ * @brief  Changes the deceleration of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] newDec New deceleration to apply in pps^2
+ * @retval true if the command is successfully executed, else false
+ * @note The command is not performed is the device is executing 
+ * a MOVE or GOTO command (but it can be used during a RUN command)
+ **********************************************************/
+bool BSP_MotorControl_SetDeceleration(uint8_t deviceId, uint16_t newDec)
+{                                                  
+  bool status = FALSE;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->SetDeceleration != 0))
+  {
+    status = motorDrvHandle->SetDeceleration(deviceId, newDec);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(23);
+  }        
+  return (status);
+}        
+
+/******************************************************//**
+ * @brief  Set current position to be the Home position (ABS pos set to 0)
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_SetHome(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->SetHome != 0))
+  {
+    motorDrvHandle->SetHome(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(24);
+  }        
+}
+ 
+/******************************************************//**
+ * @brief  Sets current position to be the Mark position 
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_SetMark(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->SetMark != 0))
+  {
+    motorDrvHandle->SetMark(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(25);
+  }    
+}
+
+/******************************************************//**
+ * @brief  Changes the max speed of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] newMaxSpeed New max speed  to apply in pps
+ * @retval true if the command is successfully executed, else false
+ * @note The command is not performed is the device is executing 
+ * a MOVE or GOTO command (but it can be used during a RUN command).
+ **********************************************************/
+bool BSP_MotorControl_SetMaxSpeed(uint8_t deviceId, uint16_t newMaxSpeed)
+{                                                  
+  bool status = FALSE;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->SetMaxSpeed != 0))
+  {
+    status = motorDrvHandle->SetMaxSpeed(deviceId, newMaxSpeed);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(26);
+  }     
+  return (status);  
+}                                                     
+
+/******************************************************//**
+ * @brief  Changes the min speed of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] newMinSpeed New min speed  to apply in pps
+ * @retval true if the command is successfully executed, else false
+ * @note The command is not performed is the device is executing 
+ * a MOVE or GOTO command (but it can be used during a RUN command).
+ **********************************************************/
+bool BSP_MotorControl_SetMinSpeed(uint8_t deviceId, uint16_t newMinSpeed)
+{                                                  
+  bool status = FALSE;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->SetMinSpeed != 0))
+  {
+    status = motorDrvHandle->SetMinSpeed(deviceId, newMinSpeed);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(27);
+  }     
+  
+  return (status);  
+}                 
+
+/******************************************************//**
+ * @brief  Stops the motor by using the device deceleration
+ * @param[in] deviceId (from 0 to 2)
+ * @retval true if the command is successfully executed, else false
+ * @note The command is not performed is the device is in INACTIVE state.
+ **********************************************************/
+bool BSP_MotorControl_SoftStop(uint8_t deviceId)
+{   
+  bool status = FALSE;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->SoftStop != 0))
+  {
+    status = motorDrvHandle->SoftStop(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(28);
+  }    
+  return (status);  
+}
+
+/******************************************************//**
+ * @brief  Handles the device state machine at each ste
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ * @note Must only be called by the timer ISR
+ **********************************************************/
+void BSP_MotorControl_StepClockHandler(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->StepClockHandler != 0))
+  {
+    motorDrvHandle->StepClockHandler(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(29);
+  }   
+}
+/******************************************************//**
+ * @brief  Locks until the device state becomes Inactive
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_WaitWhileActive(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->WaitWhileActive != 0))
+  {
+    motorDrvHandle->WaitWhileActive(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(30);
+  }    
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup BSP_MotorControl_Control_Functions
+  * @{
+  */   
+
+/******************************************************//**
+ * @brief  Issue the Disable command to the motor driver of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdDisable(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdDisable != 0))
+  {
+    motorDrvHandle->CmdDisable(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(31);
+  }    
+}
+
+/******************************************************//**
+ * @brief  Issues the Enable command to the motor driver of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdEnable(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdEnable != 0))
+  {
+    motorDrvHandle->CmdEnable(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(32);
+  }      
+}
+
+/******************************************************//**
+ * @brief  Issues the GetParam command to the motor driver of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] param Register adress (BSP_MotorControl_ABS_POS, BSP_MotorControl_MARK,...)
+ * @retval Register value
+ **********************************************************/
+uint32_t BSP_MotorControl_CmdGetParam(uint8_t deviceId,
+                                      uint32_t param)
+{
+  uint32_t value = 0;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdGetParam != 0))
+  {
+    value = motorDrvHandle->CmdGetParam(deviceId, param);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(33);
+  }       
+  return (value);
+}
+
+/******************************************************//**
+ * @brief  Issues the GetStatus command to the motor driver of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Status Register value
+ * @note Once the GetStatus command is performed, the flags of the status register
+ * are reset. This is not the case when the status register is read with the
+ * GetParam command (via the functions ReadStatusRegister or CmdGetParam).
+ **********************************************************/
+uint16_t BSP_MotorControl_CmdGetStatus(uint8_t deviceId)
+{
+  uint16_t status = 0;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdGetStatus != 0))
+  {
+    status = motorDrvHandle->CmdGetStatus(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(34);
+  }      
+  return (status);
+}
+
+/******************************************************//**
+ * @brief  Issues the Nop command to the motor driver of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdNop(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdNop != 0))
+  {
+    motorDrvHandle->CmdNop(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(35);
+  }   
+}
+
+/******************************************************//**
+ * @brief  Issues the SetParam command to the motor driver of the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] param Register adress (BSP_MotorControl_ABS_POS, BSP_MotorControl_MARK,...)
+ * @param[in] value Value to set in the register
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdSetParam(uint8_t deviceId,
+                                   uint32_t param,
+                                   uint32_t value)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdSetParam != 0))
+  {
+    motorDrvHandle->CmdSetParam(deviceId, param, value);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(36);
+  }     
+}
+
+/******************************************************//**
+ * @brief  Reads the Status Register value
+ * @param[in] deviceId (from 0 to 2)
+ * @retval Status register valued
+ * @note The status register flags are not cleared 
+ * at the difference with CmdGetStatus()
+ **********************************************************/
+uint16_t BSP_MotorControl_ReadStatusRegister(uint8_t deviceId)
+{
+  uint16_t status = 0;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->ReadStatusRegister != 0))
+  {
+    status = motorDrvHandle->ReadStatusRegister(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(37);
+  }   
+  return (status);
+}
+
+/******************************************************//**
+ * @brief  Releases the motor driver (pin set to High) of all devices
+ * @param  None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_ReleaseReset(void)
+{ 
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->ReleaseReset != 0))
+  {
+    motorDrvHandle->ReleaseReset();
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(38);
+  }   
+}
+
+/******************************************************//**
+ * @brief  Resets the motor driver (reset pin set to low) of all devices
+ * @param  None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_Reset(void)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->Reset != 0))
+  {
+    motorDrvHandle->Reset();
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(39);
+  }   
+}
+
+/******************************************************//**
+ * @brief  Set the stepping mode 
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] stepMod from full step to 1/16 microstep as specified in enum BSP_MotorControl_STEP_SEL_t
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_SelectStepMode(uint8_t deviceId, motorStepMode_t stepMod)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->SelectStepMode != 0))
+  {
+    motorDrvHandle->SelectStepMode(deviceId, stepMod);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(40);
+  }   
+}
+
+/******************************************************//**
+ * @brief  Specifies the direction 
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] dir FORWARD or BACKWARD
+ * @note The direction change is only applied if the device 
+ * is in INACTIVE state
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_SetDirection(uint8_t deviceId, motorDir_t dir)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->SetDirection != 0))
+  {
+    motorDrvHandle->SetDirection(deviceId, dir);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(41);
+  }     
+}
+
+/******************************************************//**
+ * @brief Issues Go To Dir command
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @param[in] dir movement direction
+ * @param[in] abs_pos absolute position where requested to move
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdGoToDir(uint8_t deviceId, motorDir_t dir, int32_t abs_pos)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdGoToDir != 0))
+  {
+    motorDrvHandle->CmdGoToDir(deviceId, dir, abs_pos);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(42);
+  }
+}
+
+/******************************************************//**
+ * @brief Checks if at least one device is busy by checking 
+ * busy pin position. 
+ * The busy pin is shared between all devices.
+ * @param None
+ * @retval One if at least one device is busy, otherwise zero
+ **********************************************************/
+uint8_t BSP_MotorControl_CheckBusyHw(void)
+{
+  uint8_t value = 0;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CheckBusyHw != 0))
+  {
+    value = motorDrvHandle->CheckBusyHw();
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(43);
+  }
+  return (value);
+}
+
+/******************************************************//**
+ * @brief Checks if at least one device has an alarm flag set
+ * by reading flag pin position.
+ * The flag pin is shared between all devices.
+ * @param None
+ * @retval One if at least one device has an alarm flag set ,
+ * otherwise zero
+ **********************************************************/
+uint8_t BSP_MotorControl_CheckStatusHw(void)
+{
+  uint8_t value = 0;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CheckStatusHw != 0))
+  {
+    value = motorDrvHandle->CheckStatusHw();
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(44);
+  }
+  return (value);
+}
+
+/******************************************************//**
+ * @brief Issues Go Until command
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @param[in] action ACTION_RESET or ACTION_COPY
+ * @param[in] dir movement direction
+ * @param[in] speed
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdGoUntil(uint8_t deviceId, motorAction_t action, motorDir_t dir, uint32_t speed)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdGoUntil != 0))
+  {
+    motorDrvHandle->CmdGoUntil(deviceId, action, dir, speed);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(45);
+  }
+}
+
+/******************************************************//**
+ * @brief Issues Hard HiZ command
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdHardHiZ(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdHardHiZ != 0))
+  {
+    motorDrvHandle->CmdHardHiZ(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(46);
+  }
+}
+
+/******************************************************//**
+ * @brief Issues Release SW command
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @param[in] action
+ * @param[in] dir movement direction
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdReleaseSw(uint8_t deviceId, motorAction_t action, motorDir_t dir)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdReleaseSw != 0))
+  {
+    motorDrvHandle->CmdReleaseSw(deviceId, action, dir);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(47);
+  }
+}
+
+/******************************************************//**
+ * @brief Issues Reset Device command
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdResetDevice(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdResetDevice != 0))
+  {
+    motorDrvHandle->CmdResetDevice(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(48);
+  }
+}
+
+/******************************************************//**
+ * @brief Issues Reset Pos command
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdResetPos(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdResetPos != 0))
+  {
+    motorDrvHandle->CmdResetPos(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(49);
+  }
+}
+
+/******************************************************//**
+ * @brief Issues Run command
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @param[in] dir Movement direction (FORWARD, BACKWARD)
+ * @param[in] speed in steps/s
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdRun(uint8_t deviceId, motorDir_t dir, uint32_t speed)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdRun != 0))
+  {
+    motorDrvHandle->CmdRun(deviceId, dir, speed);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(50);
+  }
+}
+
+/******************************************************//**
+ * @brief Issues Soft HiZ command
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdSoftHiZ(uint8_t deviceId)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdSoftHiZ != 0))
+  {
+    motorDrvHandle->CmdSoftHiZ(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(51);
+  }
+}
+
+/******************************************************//**
+ * @brief Issues Step Clock command
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @param[in] dir Movement direction (FORWARD, BACKWARD)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdStepClock(uint8_t deviceId, motorDir_t dir)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdStepClock != 0))
+  {
+    motorDrvHandle->CmdStepClock(deviceId, dir);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(52);
+  }
+}
+
+/******************************************************//**
+ * @brief Fetch and clear status flags of all devices 
+ * by issuing a GET_STATUS command simultaneously  
+ * to all devices.
+ * Then, the fetched status of each device can be retrieved
+ * by using the BSP_MotorControl_GetFetchedStatus function
+ * provided there is no other calls to functions which 
+ * use the SPI in between.
+ * @param None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_FetchAndClearAllStatus(void)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->FetchAndClearAllStatus != 0))
+  {
+    motorDrvHandle->FetchAndClearAllStatus();
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(53);
+  }
+}
+
+/******************************************************//**
+ * @brief Get the value of the STATUS register which was 
+ * fetched by using BSP_MotorControl_FetchAndClearAllStatus.
+ * The fetched values are available  as long as there
+ * no other calls to functions which use the SPI.
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @retval Last fetched value of the STATUS register
+ **********************************************************/
+uint16_t BSP_MotorControl_GetFetchedStatus(uint8_t deviceId)
+{
+  uint16_t value = 0;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GetFetchedStatus != 0))
+  {
+    value = motorDrvHandle->GetFetchedStatus(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(54);
+  }
+  return (value);
+}
+
+/******************************************************//**
+ * @brief Return the number of devices in the daisy chain 
+ * @param None
+ * @retval number of devices from 1 to MAX_NUMBER_OF_DEVICES
+ **********************************************************/
+uint8_t BSP_MotorControl_GetNbDevices(void)
+{
+  uint8_t value = 0;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->GetNbDevices != 0))
+  {
+    value = motorDrvHandle->GetNbDevices();
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(55);
+  }
+  return (value);
+}
+
+/******************************************************//**
+ * @brief Checks if the specified device is busy
+ * by reading the Busy flag bit ot its status Register
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @retval true if device is busy, false zero
+ **********************************************************/
+bool BSP_MotorControl_IsDeviceBusy(uint8_t deviceId)
+{
+  bool value = 0;
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->IsDeviceBusy != 0))
+  {
+    value = motorDrvHandle->IsDeviceBusy(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(56);
+  }
+  return (value);
+}
+
+/******************************************************//**
+ * @brief Sends commands stored in the queue by previously
+ * Powerstep01_QueueCommands
+ * @param None
+ * @retval None
+ *********************************************************/
+void BSP_MotorControl_SendQueuedCommands(void)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->SendQueuedCommands != 0))
+  {
+    motorDrvHandle->SendQueuedCommands();
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(57);
+  }
+}
+
+/******************************************************//**
+ * @brief Put commands in queue before synchronous sending
+ * done by calling BSP_MotorControl_SendQueuedCommands.
+ * Any call to functions that use the SPI between the calls of 
+ * BSP_MotorControl_QueueCommands and BSP_MotorControl_SendQueuedCommands 
+ * will corrupt the queue.
+ * A command for each device of the daisy chain must be 
+ * specified before calling BSP_MotorControl_SendQueuedCommands.
+ * @param[in] deviceId deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @param[in] param Command to queue (all BSP_MotorControl commmands 
+ * except SET_PARAM, GET_PARAM, GET_STATUS)
+ * @param[in] value argument of the command to queue
+ * @retval None
+ *********************************************************/
+void BSP_MotorControl_QueueCommands(uint8_t deviceId, uint8_t param, uint32_t value)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->QueueCommands != 0))
+  {
+    motorDrvHandle->QueueCommands(deviceId, param, value);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(58);
+  }
+}
+
+/******************************************************//**
+ * @brief  Locks until all devices become not busy
+ * @param None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_WaitForAllDevicesNotBusy(void)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->WaitForAllDevicesNotBusy != 0))
+  {
+    motorDrvHandle->WaitForAllDevicesNotBusy();
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(59);
+  }  
+}
+
+/******************************************************//**
+ * @brief Handler of the busy interrupt which calls the user callback (if defined)
+ * @param None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_BusyInterruptHandler(void)
+{
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->BusyInterruptHandler != 0))
+  {
+    motorDrvHandle->BusyInterruptHandler();
+  }    
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(60);
+  }  
+}
+
+/******************************************************//**
+ * @brief Issues PowerStep01 Soft Stop command
+ * @param[in] deviceId (from 0 to MAX_NUMBER_OF_DEVICES-1 )
+ * @retval None
+ **********************************************************/
+void BSP_MotorControl_CmdSoftStop(uint8_t deviceId)
+{   
+  if ((motorDrvHandle != 0)&&(motorDrvHandle->CmdSoftStop != 0))
+  {
+    motorDrvHandle->CmdSoftStop(deviceId);
+  }
+  else
+  {
+    MOTOR_CONTROL_ERROR_UNDEFINED_FUNCTION(61);
+  }    
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/motorcontrol.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,188 @@
+/**
+  ******************************************************************************
+  * @file    motorcontrol.h
+  * @author  IPC Rennes
+  * @version V1.0.0
+  * @date    12-November-2014
+  * @brief   This file provides common definitions for motor control 
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MOTOR_CONTROL_H
+#define __MOTOR_CONTROL_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "motor.h"   
+   
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup MOTOR_CONTROL
+  * @{
+  */
+
+/** @defgroup MOTOR_CONTROL_Exported_Types
+  * @{
+  */
+
+
+
+/**
+  * @}
+  */
+
+/** @defgroup MOTOR_CONTROL_Exported_Constants
+  * @{
+  */
+///Motor control board id for L6474
+#define BSP_MOTOR_CONTROL_BOARD_ID_L6474  (6474)
+///Motor control board id for Powerstep01
+#define BSP_MOTOR_CONTROL_BOARD_ID_POWERSTEP01 (0001)
+
+/**
+  * @}
+  */
+
+
+/** @defgroup MOTOR_CONTROL_Exported_Macros
+  * @{
+  */
+#if  defined ( __GNUC__ )
+  #ifndef __weak
+    #define __weak   __attribute__((weak))
+  #endif /* __weak */
+#endif /* __GNUC__ */
+/**
+  * @}
+  */
+
+/** @defgroup MOTOR_CONTROL_Weak_Function_Prototypes
+  * @{
+  */
+ __weak motorDrv_t* L6474_GetMotorHandle(void);
+ __weak motorDrv_t* Powerstep01_GetMotorHandle(void);
+/**
+  * @}
+  */   
+   
+/** @defgroup MOTOR_CONTROL_Exported_Functions
+  * @{
+  */
+void BSP_MotorControl_AttachErrorHandler(void (*callback)(uint16_t));
+void BSP_MotorControl_AttachFlagInterrupt(void (*callback)(void));
+void BSP_MotorControl_AttachBusyInterrupt(void (*callback)(void));
+void BSP_MotorControl_ErrorHandler(uint16_t error);
+void BSP_MotorControl_Init(uint16_t  id, uint8_t nbDevices); 
+void BSP_MotorControl_FlagInterruptHandler(void);
+uint16_t BSP_MotorControl_GetAcceleration(uint8_t deviceId); 
+uint16_t BSP_MotorControl_GetBoardId(void);
+uint16_t BSP_MotorControl_GetCurrentSpeed(uint8_t deviceId); 
+uint16_t BSP_MotorControl_GetDeceleration(uint8_t deviceId); 
+motorState_t BSP_MotorControl_GetDeviceState(uint8_t deviceId); 
+uint8_t BSP_MotorControl_GetFwVersion(void); 
+int32_t BSP_MotorControl_GetMark(uint8_t deviceId); 
+uint16_t BSP_MotorControl_GetMaxSpeed(uint8_t deviceId); 
+uint16_t BSP_MotorControl_GetMinSpeed(uint8_t deviceId); 
+int32_t BSP_MotorControl_GetPosition(uint8_t deviceId); 
+void BSP_MotorControl_GoHome(uint8_t deviceId); 
+void BSP_MotorControl_GoMark(uint8_t deviceId); 
+void BSP_MotorControl_GoTo(uint8_t deviceId, int32_t targetPosition); 
+void BSP_MotorControl_HardStop(uint8_t deviceId); 
+void BSP_MotorControl_Move(uint8_t deviceId, motorDir_t direction, uint32_t stepCount); 
+void BSP_MotorControl_ResetAllDevices(void); 
+void BSP_MotorControl_Run(uint8_t deviceId, motorDir_t direction); 
+bool BSP_MotorControl_SetAcceleration(uint8_t deviceId,uint16_t newAcc); 
+bool BSP_MotorControl_SetDeceleration(uint8_t deviceId, uint16_t newDec); 
+void BSP_MotorControl_SetHome(uint8_t deviceId); 
+void BSP_MotorControl_SetMark(uint8_t deviceId); 
+bool BSP_MotorControl_SetMaxSpeed(uint8_t deviceId, uint16_t newMaxSpeed); 
+bool BSP_MotorControl_SetMinSpeed(uint8_t deviceId, uint16_t newMinSpeed); 
+bool BSP_MotorControl_SoftStop(uint8_t deviceId); 
+void BSP_MotorControl_StepClockHandler(uint8_t deviceId); 
+void BSP_MotorControl_WaitWhileActive(uint8_t deviceId); 
+void BSP_MotorControl_CmdDisable(uint8_t deviceId); 
+void BSP_MotorControl_CmdEnable(uint8_t deviceId); 
+uint32_t BSP_MotorControl_CmdGetParam(uint8_t deviceId, uint32_t param); 
+uint16_t BSP_MotorControl_CmdGetStatus(uint8_t deviceId);
+void BSP_MotorControl_CmdNop(uint8_t deviceId); 
+void BSP_MotorControl_CmdSetParam(uint8_t deviceId, uint32_t param, uint32_t value);
+uint16_t BSP_MotorControl_ReadStatusRegister(uint8_t deviceId); 
+void BSP_MotorControl_ReleaseReset(void) ;
+void BSP_MotorControl_Reset(void); 
+void BSP_MotorControl_SelectStepMode(uint8_t deviceId,  motorStepMode_t stepMod); 
+void BSP_MotorControl_SetDirection(uint8_t deviceId, motorDir_t dir);
+void BSP_MotorControl_CmdGoToDir(uint8_t deviceId, motorDir_t dir, int32_t abs_pos);
+uint8_t BSP_MotorControl_CheckBusyHw(void);
+uint8_t BSP_MotorControl_CheckStatusHw(void);
+void BSP_MotorControl_CmdGoUntil(uint8_t deviceId, motorAction_t action, motorDir_t dir, uint32_t speed);
+void BSP_MotorControl_CmdHardHiZ(uint8_t deviceId);
+void BSP_MotorControl_CmdReleaseSw(uint8_t deviceId, motorAction_t action, motorDir_t dir);
+void BSP_MotorControl_CmdResetDevice(uint8_t deviceId);
+void BSP_MotorControl_CmdResetPos(uint8_t deviceId);
+void BSP_MotorControl_CmdRun(uint8_t deviceId, motorDir_t dir, uint32_t speed);
+void BSP_MotorControl_CmdSoftHiZ(uint8_t deviceId);
+void BSP_MotorControl_CmdStepClock(uint8_t deviceId, motorDir_t dir);
+void BSP_MotorControl_FetchAndClearAllStatus(void);
+uint16_t BSP_MotorControl_GetFetchedStatus(uint8_t deviceId);
+uint8_t BSP_MotorControl_GetNbDevices(void);
+bool BSP_MotorControl_IsDeviceBusy(uint8_t deviceId);
+void BSP_MotorControl_SendQueuedCommands(void);
+void BSP_MotorControl_QueueCommands(uint8_t deviceId, uint8_t param, uint32_t value);
+void BSP_MotorControl_WaitForAllDevicesNotBusy(void);
+void BSP_MotorControl_BusyInterruptHandler(void);
+void BSP_MotorControl_CmdSoftStop(uint8_t deviceId);
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* __MOTOR_CONTROL_H */
+
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stdint.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,311 @@
+/* Copyright (C) ARM Ltd., 1999,2014 */
+/* All rights reserved */
+
+/*
+ * RCS $Revision: 185525 $
+ * Checkin $Date: 2014-05-29 12:44:48 +0100 (Thu, 29 May 2014) $
+ * Revising $Author: agrant $
+ */
+
+#ifndef __stdint_h
+#define __stdint_h
+#define __ARMCLIB_VERSION 5060001
+
+  #ifdef __INT64_TYPE__
+    /* armclang predefines '__INT64_TYPE__' and '__INT64_C_SUFFIX__' */
+    #define __INT64 __INT64_TYPE__
+  #else
+    /* armcc has builtin '__int64' which can be used in --strict mode */
+    #define __INT64 __int64
+    #define __INT64_C_SUFFIX__ ll
+  #endif
+  #define __PASTE2(x, y) x ## y
+  #define __PASTE(x, y) __PASTE2(x, y)
+  #define __INT64_C(x)  __ESCAPE__(__PASTE(x, __INT64_C_SUFFIX__))
+  #define __UINT64_C(x)  __ESCAPE__(__PASTE(x ## u, __INT64_C_SUFFIX__))
+  #if defined(__clang__) || (defined(__ARMCC_VERSION) && !defined(__STRICT_ANSI__))
+    /* armclang and non-strict armcc allow 'long long' in system headers */
+    #define __LONGLONG long long
+  #else
+    /* strict armcc has '__int64' */
+    #define __LONGLONG __int64
+  #endif
+
+  #ifndef __STDINT_DECLS
+  #define __STDINT_DECLS
+
+    #undef __CLIBNS
+
+    #ifdef __cplusplus
+      namespace std {
+          #define __CLIBNS std::
+          extern "C" {
+    #else
+      #define __CLIBNS
+    #endif  /* __cplusplus */
+
+
+/*
+ * 'signed' is redundant below, except for 'signed char' and if
+ * the typedef is used to declare a bitfield.
+ */
+
+    /* 7.18.1.1 */
+
+    /* exact-width signed integer types */
+typedef   signed          char int8_t;
+typedef   signed short     int int16_t;
+typedef   signed           int int32_t;
+typedef   signed       __INT64 int64_t;
+
+    /* exact-width unsigned integer types */
+typedef unsigned          char uint8_t;
+typedef unsigned short     int uint16_t;
+typedef unsigned           int uint32_t;
+typedef unsigned       __INT64 uint64_t;
+
+    /* 7.18.1.2 */
+
+    /* smallest type of at least n bits */
+    /* minimum-width signed integer types */
+typedef   signed          char int_least8_t;
+typedef   signed short     int int_least16_t;
+typedef   signed           int int_least32_t;
+typedef   signed       __INT64 int_least64_t;
+
+    /* minimum-width unsigned integer types */
+typedef unsigned          char uint_least8_t;
+typedef unsigned short     int uint_least16_t;
+typedef unsigned           int uint_least32_t;
+typedef unsigned       __INT64 uint_least64_t;
+
+    /* 7.18.1.3 */
+
+    /* fastest minimum-width signed integer types */
+typedef   signed           int int_fast8_t;
+typedef   signed           int int_fast16_t;
+typedef   signed           int int_fast32_t;
+typedef   signed       __INT64 int_fast64_t;
+
+    /* fastest minimum-width unsigned integer types */
+typedef unsigned           int uint_fast8_t;
+typedef unsigned           int uint_fast16_t;
+typedef unsigned           int uint_fast32_t;
+typedef unsigned       __INT64 uint_fast64_t;
+
+    /* 7.18.1.4 integer types capable of holding object pointers */
+#if __sizeof_ptr == 8
+typedef   signed       __INT64 intptr_t;
+typedef unsigned       __INT64 uintptr_t;
+#else
+typedef   signed           int intptr_t;
+typedef unsigned           int uintptr_t;
+#endif
+
+    /* 7.18.1.5 greatest-width integer types */
+typedef   signed     __LONGLONG intmax_t;
+typedef unsigned     __LONGLONG uintmax_t;
+
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
+
+    /* 7.18.2.1 */
+
+    /* minimum values of exact-width signed integer types */
+#define INT8_MIN                   -128
+#define INT16_MIN                -32768
+#define INT32_MIN          (~0x7fffffff)   /* -2147483648 is unsigned */
+#define INT64_MIN  __INT64_C(~0x7fffffffffffffff) /* -9223372036854775808 is unsigned */
+
+    /* maximum values of exact-width signed integer types */
+#define INT8_MAX                    127
+#define INT16_MAX                 32767
+#define INT32_MAX            2147483647
+#define INT64_MAX  __INT64_C(9223372036854775807)
+
+    /* maximum values of exact-width unsigned integer types */
+#define UINT8_MAX                   255
+#define UINT16_MAX                65535
+#define UINT32_MAX           4294967295u
+#define UINT64_MAX __UINT64_C(18446744073709551615)
+
+    /* 7.18.2.2 */
+
+    /* minimum values of minimum-width signed integer types */
+#define INT_LEAST8_MIN                   -128
+#define INT_LEAST16_MIN                -32768
+#define INT_LEAST32_MIN          (~0x7fffffff)
+#define INT_LEAST64_MIN  __INT64_C(~0x7fffffffffffffff)
+
+    /* maximum values of minimum-width signed integer types */
+#define INT_LEAST8_MAX                    127
+#define INT_LEAST16_MAX                 32767
+#define INT_LEAST32_MAX            2147483647
+#define INT_LEAST64_MAX  __INT64_C(9223372036854775807)
+
+    /* maximum values of minimum-width unsigned integer types */
+#define UINT_LEAST8_MAX                   255
+#define UINT_LEAST16_MAX                65535
+#define UINT_LEAST32_MAX           4294967295u
+#define UINT_LEAST64_MAX __UINT64_C(18446744073709551615)
+
+    /* 7.18.2.3 */
+
+    /* minimum values of fastest minimum-width signed integer types */
+#define INT_FAST8_MIN           (~0x7fffffff)
+#define INT_FAST16_MIN          (~0x7fffffff)
+#define INT_FAST32_MIN          (~0x7fffffff)
+#define INT_FAST64_MIN  __INT64_C(~0x7fffffffffffffff)
+
+    /* maximum values of fastest minimum-width signed integer types */
+#define INT_FAST8_MAX             2147483647
+#define INT_FAST16_MAX            2147483647
+#define INT_FAST32_MAX            2147483647
+#define INT_FAST64_MAX  __INT64_C(9223372036854775807)
+
+    /* maximum values of fastest minimum-width unsigned integer types */
+#define UINT_FAST8_MAX            4294967295u
+#define UINT_FAST16_MAX           4294967295u
+#define UINT_FAST32_MAX           4294967295u
+#define UINT_FAST64_MAX __UINT64_C(18446744073709551615)
+
+    /* 7.18.2.4 */
+
+    /* minimum value of pointer-holding signed integer type */
+#if __sizeof_ptr == 8
+#define INTPTR_MIN INT64_MIN
+#else
+#define INTPTR_MIN INT32_MIN
+#endif
+
+    /* maximum value of pointer-holding signed integer type */
+#if __sizeof_ptr == 8
+#define INTPTR_MAX INT64_MAX
+#else
+#define INTPTR_MAX INT32_MAX
+#endif
+
+    /* maximum value of pointer-holding unsigned integer type */
+#if __sizeof_ptr == 8
+#define UINTPTR_MAX INT64_MAX
+#else
+#define UINTPTR_MAX INT32_MAX
+#endif
+
+    /* 7.18.2.5 */
+
+    /* minimum value of greatest-width signed integer type */
+#define INTMAX_MIN  __ESCAPE__(~0x7fffffffffffffffll)
+
+    /* maximum value of greatest-width signed integer type */
+#define INTMAX_MAX  __ESCAPE__(9223372036854775807ll)
+
+    /* maximum value of greatest-width unsigned integer type */
+#define UINTMAX_MAX __ESCAPE__(18446744073709551615ull)
+
+    /* 7.18.3 */
+
+    /* limits of ptrdiff_t */
+#if __sizeof_ptr == 8
+#define PTRDIFF_MIN INT64_MIN
+#define PTRDIFF_MAX INT64_MAX
+#else
+#define PTRDIFF_MIN INT32_MIN
+#define PTRDIFF_MAX INT32_MAX
+#endif
+
+    /* limits of sig_atomic_t */
+#define SIG_ATOMIC_MIN (~0x7fffffff)
+#define SIG_ATOMIC_MAX   2147483647
+
+    /* limit of size_t */
+#if __sizeof_ptr == 8
+#define SIZE_MAX UINT64_MAX
+#else
+#define SIZE_MAX UINT32_MAX
+#endif
+
+    /* limits of wchar_t */
+    /* NB we have to undef and redef because they're defined in both
+     * stdint.h and wchar.h */
+#undef WCHAR_MIN
+#undef WCHAR_MAX
+
+#if defined(__WCHAR32) || (defined(__ARM_SIZEOF_WCHAR_T) && __ARM_SIZEOF_WCHAR_T == 4)
+  #define WCHAR_MIN   0
+  #define WCHAR_MAX   0xffffffffU
+#else
+  #define WCHAR_MIN   0
+  #define WCHAR_MAX   65535
+#endif
+
+    /* limits of wint_t */
+#define WINT_MIN (~0x7fffffff)
+#define WINT_MAX 2147483647
+
+#endif /* __STDC_LIMIT_MACROS */
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
+
+    /* 7.18.4.1 macros for minimum-width integer constants */
+#define INT8_C(x)   (x)
+#define INT16_C(x)  (x)
+#define INT32_C(x)  (x)
+#define INT64_C(x)  __INT64_C(x)
+
+#define UINT8_C(x)  (x ## u)
+#define UINT16_C(x) (x ## u)
+#define UINT32_C(x) (x ## u)
+#define UINT64_C(x) __UINT64_C(x)
+
+    /* 7.18.4.2 macros for greatest-width integer constants */
+#define INTMAX_C(x)  __ESCAPE__(x ## ll)
+#define UINTMAX_C(x) __ESCAPE__(x ## ull)
+
+#endif /* __STDC_CONSTANT_MACROS */
+
+    #ifdef __cplusplus
+         }  /* extern "C" */
+      }  /* namespace std */
+    #endif /* __cplusplus */
+  #endif /* __STDINT_DECLS */
+
+  #ifdef __cplusplus
+    #ifndef __STDINT_NO_EXPORTS
+      using ::std::int8_t;
+      using ::std::int16_t;
+      using ::std::int32_t;
+      using ::std::int64_t;
+      using ::std::uint8_t;
+      using ::std::uint16_t;
+      using ::std::uint32_t;
+      using ::std::uint64_t;
+      using ::std::int_least8_t;
+      using ::std::int_least16_t;
+      using ::std::int_least32_t;
+      using ::std::int_least64_t;
+      using ::std::uint_least8_t;
+      using ::std::uint_least16_t;
+      using ::std::uint_least32_t;
+      using ::std::uint_least64_t;
+      using ::std::int_fast8_t;
+      using ::std::int_fast16_t;
+      using ::std::int_fast32_t;
+      using ::std::int_fast64_t;
+      using ::std::uint_fast8_t;
+      using ::std::uint_fast16_t;
+      using ::std::uint_fast32_t;
+      using ::std::uint_fast64_t;
+      using ::std::intptr_t;
+      using ::std::uintptr_t;
+      using ::std::intmax_t;
+      using ::std::uintmax_t;
+    #endif
+  #endif /* __cplusplus */
+
+#undef __INT64
+#undef __LONGLONG
+
+#endif /* __stdint_h */
+
+/* end of stdint.h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32f0xx_hal_msp.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,289 @@
+/**
+  ******************************************************************************
+  * @file    Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Src/stm32f0xx_hal_msp.c
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   HAL MSP module.    
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************  
+  */ 
+#ifdef TARGET_STM32F0
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include "main.h"
+
+
+/** @defgroup MSP_module
+  * @brief HAL MSP module.
+  * @{
+  */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private function prototypes -----------------------------------------------*/
+extern void BSP_MotorControl_StepClockHandler(uint8_t deviceId); 
+extern void BSP_MotorControl_FlagInterruptHandler(void);
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup HAL_MSP_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief SPI MSP Initialization 
+  *        This function configures the hardware resources used in this example: 
+  *           - Peripheral's clock enable
+  *           - Peripheral's GPIO Configuration  
+  * @param[in] hspi SPI handle pointer
+  * @retval None
+  */
+void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
+{
+  GPIO_InitTypeDef  GPIO_InitStruct;
+  
+  if(hspi->Instance == SPIx)
+  {  
+    /*##-1- Enable peripherals and GPIO Clocks #################################*/
+    /* Enable GPIO TX/RX clock */
+    SPIx_SCK_GPIO_CLK_ENABLE();
+    SPIx_MISO_GPIO_CLK_ENABLE();
+    SPIx_MOSI_GPIO_CLK_ENABLE();
+    /* Enable SPI clock */
+    SPIx_CLK_ENABLE(); 
+    
+    /*##-2- Configure peripheral GPIO ##########################################*/  
+    /* SPI SCK GPIO pin configuration  */
+    GPIO_InitStruct.Pin       = SPIx_SCK_PIN;
+    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull      = GPIO_NOPULL;
+    GPIO_InitStruct.Speed     = GPIO_SPEED_MEDIUM;
+    GPIO_InitStruct.Alternate = SPIx_SCK_AF;
+    
+    HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);
+      
+    /* SPI MISO GPIO pin configuration  */
+    GPIO_InitStruct.Pin = SPIx_MISO_PIN;
+    GPIO_InitStruct.Alternate = SPIx_MISO_AF;
+    
+    HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct);
+    
+    /* SPI MOSI GPIO pin configuration  */
+    GPIO_InitStruct.Pin = SPIx_MOSI_PIN;
+    GPIO_InitStruct.Alternate = SPIx_MOSI_AF;
+      
+    HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct);   
+  }
+}
+
+/**
+  * @brief SPI MSP De-Initialization 
+  *        This function frees the hardware resources used in this example:
+  *          - Disable the Peripheral's clock
+  *          - Revert GPIO configuration to its default state
+  * @param[in] hspi SPI handle pointer
+  * @retval None
+  */
+void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
+{
+  if(hspi->Instance == SPIx)
+  {  
+    /*##-1- Reset peripherals ##################################################*/
+    SPIx_FORCE_RESET();
+    SPIx_RELEASE_RESET();
+
+    /*##-2- Disable peripherals and GPIO Clocks ################################*/
+    /* Configure SPI SCK as alternate function  */
+    HAL_GPIO_DeInit(SPIx_SCK_GPIO_PORT, SPIx_SCK_PIN);
+    /* Configure SPI MISO as alternate function  */
+    HAL_GPIO_DeInit(SPIx_MISO_GPIO_PORT, SPIx_MISO_PIN);
+    /* Configure SPI MOSI as alternate function  */
+    HAL_GPIO_DeInit(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_PIN);
+  }
+}
+
+/**
+  * @brief PWM MSP Initialization 
+  * @param[in] htim_pwm PWM handle pointer
+  * @retval None
+  */
+void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* htim_pwm)
+{
+  GPIO_InitTypeDef GPIO_InitStruct;
+  if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1)
+  {
+    /* Peripheral clock enable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_ENABLE();
+  
+    /* GPIO configuration */
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_PWM_1_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = BSP_MOTOR_CONTROL_BOARD_AFx_TIMx_PWM1;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_PWM_1_PORT, &GPIO_InitStruct);
+
+    /* Set Interrupt Group Priority of Timer Interrupt*/ 
+    HAL_NVIC_SetPriority(BSP_MOTOR_CONTROL_BOARD_PWM1_IRQn, 4, 0);
+    
+    /* Enable the timer global Interrupt */
+    HAL_NVIC_EnableIRQ(BSP_MOTOR_CONTROL_BOARD_PWM1_IRQn);  
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2)
+  {
+    /* Peripheral clock enable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_ENABLE();
+  
+    /* GPIO configuration */
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_PWM_2_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_PWM_2_PORT, &GPIO_InitStruct);
+    
+    /* Set Interrupt Group Priority of Timer Interrupt*/ 
+    HAL_NVIC_SetPriority(BSP_MOTOR_CONTROL_BOARD_PWM2_IRQn, 3, 0);
+    
+    /* Enable the timer global Interrupt */
+    HAL_NVIC_EnableIRQ(BSP_MOTOR_CONTROL_BOARD_PWM2_IRQn);    
+
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3)
+  {
+    /* Peripheral clock enable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_ENABLE();
+  
+    /* GPIO configuration */
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, &GPIO_InitStruct);    
+    
+    /* Set Interrupt Group Priority of Timer Interrupt*/ 
+    HAL_NVIC_SetPriority(BSP_MOTOR_CONTROL_BOARD_PWM3_IRQn, 3, 0);
+    
+    /* Enable the timer global Interrupt */
+    HAL_NVIC_EnableIRQ(BSP_MOTOR_CONTROL_BOARD_PWM3_IRQn);  
+  }
+}
+
+/**
+  * @brief PWM MSP De-Initialization
+  * @param[in] htim_pwm PWM handle pointer
+  * @retval None
+  */
+void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* htim_pwm)
+{
+  if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1)
+  {
+    /* Peripheral clock disable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_DISABLE();
+  
+    /* GPIO Deconfiguration */
+    HAL_GPIO_DeInit(BSP_MOTOR_CONTROL_BOARD_PWM_1_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_1_PIN);
+
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2)
+  {
+    /* Peripheral clock disable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_DISABLE();
+  
+    /* GPIO Deconfiguration */
+    HAL_GPIO_DeInit(BSP_MOTOR_CONTROL_BOARD_PWM_2_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_2_PIN);
+
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3)
+  {
+    /* Peripheral clock disable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_DISABLE();
+    
+    /* GPIO Deconfiguration */
+    HAL_GPIO_DeInit(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN);
+  }
+}
+
+/**
+  * @brief PWM Callback
+  * @param[in] htim PWM handle pointer
+  * @retval None
+  */
+void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
+{
+  if ((htim->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1)&& (htim->Channel == BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM1))
+  {
+    if (BSP_MotorControl_GetDeviceState(0) != INACTIVE)
+    {
+      BSP_MotorControl_StepClockHandler(0);
+    }
+  }
+  if ((htim->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2)&& (htim->Channel == BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM2))
+  {
+    HAL_GPIO_TogglePin(BSP_MOTOR_CONTROL_BOARD_PWM_2_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_2_PIN);
+    if ((BSP_MotorControl_GetDeviceState(1) != INACTIVE)&& 
+        (HAL_GPIO_ReadPin(BSP_MOTOR_CONTROL_BOARD_PWM_2_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_2_PIN) == GPIO_PIN_SET))
+    { 
+      BSP_MotorControl_StepClockHandler(1);
+    }
+  }
+  if ((htim->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3)&& (htim->Channel == BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM3))
+  {
+    HAL_GPIO_TogglePin(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN);
+    if ((BSP_MotorControl_GetDeviceState(2) != INACTIVE)&& 
+        (HAL_GPIO_ReadPin(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN) == GPIO_PIN_SET))
+    {
+      BSP_MotorControl_StepClockHandler(2);
+    }
+  }
+}
+
+/**
+  * @brief External Line Callback 
+  * @param[in] GPIO_Pin pin number
+  * @retval None
+  */
+void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
+{
+  if (GPIO_Pin == BSP_MOTOR_CONTROL_BOARD_FLAG_PIN)
+  {
+    BSP_MotorControl_FlagInterruptHandler();
+  }
+ }
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+#endif
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32f0xx_it.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,174 @@
+/**
+  ******************************************************************************
+  * @file    Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Src/stm32f0xx_it.c 
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   Main Interrupt Service Routines.
+  *          This file provides template for all exceptions handler and 
+  *          peripherals interrupt service routine.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+#ifdef TARGET_STM32F0
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include "stm32f0xx_it.h"
+#include "motorcontrol.h"
+    
+/** @addtogroup Interrupt_Handlers
+  * @{
+  */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+extern TIM_HandleTypeDef hTimPwm1;
+extern TIM_HandleTypeDef hTimPwm2;
+extern TIM_HandleTypeDef hTimPwm3;
+    
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+
+/******************************************************************************/
+/*            Cortex-M0 Processor Exceptions Handlers                         */
+/******************************************************************************/
+
+/**
+  * @brief   This function handles NMI exception.
+  * @param  None
+  * @retval None
+  */
+void NMI_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles Hard Fault exception.
+  * @param  None
+  * @retval None
+  */
+void HardFault_Handler(void)
+{
+  /* Go to infinite loop when Hard Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/**
+  * @brief  This function handles SVCall exception.
+  * @param  None
+  * @retval None
+  */
+void SVC_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles PendSVC exception.
+  * @param  None
+  * @retval None
+  */
+void PendSV_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles SysTick Handler.
+  * @param  None
+  * @retval None
+  */
+void SysTick_Handler(void)
+{
+  HAL_IncTick();
+}
+
+/******************************************************************************/
+/*                 STM32F0xx Peripherals Interrupt Handlers                   */
+/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
+/*  available peripheral interrupt handler's name please refer to the startup */
+/*  file (startup_stm32f0xx.s).                                               */
+/******************************************************************************/
+
+/**
+  * @brief  This function handles interrupt for External lines 4 to 15
+  * @param  None
+  * @retval None
+  */
+void EXTI4_15_IRQHandler(void)
+{
+  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
+}
+
+/**
+  * @brief  This function handles TIM14 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void TIM14_IRQHandler(void)
+{
+  HAL_TIM_IRQHandler(&hTimPwm2);
+}
+
+/**
+  * @brief  This function handles TIM3 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void TIM3_IRQHandler(void)
+{
+  HAL_TIM_IRQHandler(&hTimPwm1);
+}
+
+/**
+  * @brief  This function handles TIM15 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void TIM15_IRQHandler(void)
+{
+  HAL_TIM_IRQHandler(&hTimPwm3);
+}
+/**
+  * @brief  This function handles PPP interrupt request.
+  * @param  None
+  * @retval None
+  */
+/*void PPP_IRQHandler(void)
+{
+}*/
+
+/**
+  * @}
+  */ 
+#endif
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32f0xx_it.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,72 @@
+/**
+  ******************************************************************************
+  * @file    Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Inc/stm32f0xx_it.h
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   This file contains the headers of the interrupt handlers.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+#ifdef TARGET_STM32F0
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F0xx_IT_H
+#define __STM32F0xx_IT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void SVC_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+
+void EXTI4_15_IRQHandler(void);
+void TIM3_IRQHandler(void);
+void TIM14_IRQHandler(void);
+void TIM15_IRQHandler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F0xx_IT_H */
+
+#endif
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32f0xx_nucleo_ihm01a1.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,434 @@
+/**
+  ******************************************************************************
+  * @file    stm32f0xx_nucleo_ihm01a1.c
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   BSP driver for x-nucleo-ihm01a1 Nucleo extension board 
+  *  (based on L6474)
+  ******************************************************************************
+* @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+#ifdef TARGET_STM32F0  
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include "stm32f0xx_nucleo_ihm01a1.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @defgroup  STM32F0XX_NUCLEO_IHM01A1
+  * @{
+  */   
+    
+/* Private constants ---------------------------------------------------------*/    
+
+/** @defgroup IHM01A1_Private_Constants
+  * @{
+  */   
+    
+/// Timer Prescaler
+#define TIMER_PRESCALER (1024)
+
+/// SPI Maximum Timeout values for flags waiting loops
+#define SPIx_TIMEOUT_MAX                      ((uint32_t)0x1000)
+
+/**
+  * @}
+  */ 
+
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup IHM01A1_Board_Private_Variables
+  * @{
+  */       
+/// SPI handler declaration
+static SPI_HandleTypeDef SpiHandle;
+/// Timer handler for PWM1
+TIM_HandleTypeDef hTimPwm1;
+/// imer handler for PWM2
+TIM_HandleTypeDef hTimPwm2;
+/// Timer handler for PWM3
+TIM_HandleTypeDef hTimPwm3;
+/**
+  * @}
+  */ 
+
+
+/**
+  * @}
+  */
+
+
+/** @defgroup  IHM01A1_Board_Private_Functions
+  * @{
+  */   
+
+/******************************************************//**
+ * @brief This function provides an accurate delay in milliseconds
+ * @param[in] delay  time length in milliseconds
+  * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_Delay(uint32_t delay)
+{
+  HAL_Delay(delay);
+}
+
+/******************************************************//**
+ * @brief This function disable the interruptions
+ * @param None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_DisableIrq(void)
+{
+  __disable_irq();
+}
+
+/******************************************************//**
+ * @brief This function enable the interruptions
+ * @param None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_EnableIrq(void)
+{
+  __enable_irq();
+}
+
+/******************************************************//**
+ * @brief  Initiliases the GPIOs used by the L6474s
+ * @param[in] nbDevices number of L6474 devices
+ * @retval None
+  **********************************************************/
+void BSP_MotorControlBoard_GpioInit(uint8_t nbDevices)
+{
+   GPIO_InitTypeDef GPIO_InitStruct;
+  
+  /* GPIO Ports Clock Enable */
+  __GPIOC_CLK_ENABLE();
+  __GPIOA_CLK_ENABLE();
+  __GPIOB_CLK_ENABLE();
+
+  /* Configure L6474  - DIR pin for device 1 -------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT, &GPIO_InitStruct);
+  
+  /* Configure L6474 - Flag pin -------------------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_FLAG_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_FLAG_PORT, &GPIO_InitStruct);
+  
+ /* Set Priority of External Line Interrupt used for the Flag interrupt*/ 
+  HAL_NVIC_SetPriority(EXTI_MCU_LINE_IRQn, 5, 0);
+    
+  /* Enable the External Line Interrupt used for the Flag interrupt*/
+  HAL_NVIC_EnableIRQ(EXTI_MCU_LINE_IRQn);    
+
+  /* Configure L6474 - CS pin ---------------------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_CS_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_CS_PORT, &GPIO_InitStruct);
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_SET); 
+  
+  /* Configure L6474 - STBY/RESET pin -------------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_RESET_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, &GPIO_InitStruct);
+  BSP_MotorControlBoard_Reset();  
+
+  if (nbDevices > 1) 
+  {
+    /* Configure L6474 - DIR pin for device  2 ----------------------------*/
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT, &GPIO_InitStruct);    
+  }
+  if (nbDevices > 2) 
+  {
+    /* Configure L6474 - DIR pin for device  3 ----------------------------*/
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT, &GPIO_InitStruct);    
+  }  
+}
+
+/******************************************************//**
+ * @brief  Sets the frequency of PWM1 used by device 0
+ * @param[in] newFreq in Hz
+ * @retval None
+ * @note The frequency is directly the current speed of the device
+ **********************************************************/
+void BSP_MotorControlBoard_Pwm1SetFreq(uint16_t newFreq)
+{
+  uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
+  uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM1_FREQ_RESCALER * (uint32_t)newFreq)) - 1;
+  
+  __HAL_TIM_SetAutoreload(&hTimPwm1, period);
+  __HAL_TIM_SetCompare(&hTimPwm1, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1, period >> 1);
+  HAL_TIM_PWM_Start_IT(&hTimPwm1, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1);  
+}
+
+/******************************************************//**
+ * @brief  Sets the frequency of PWM2 used by device 1
+ * @param[in] newFreq in Hz
+ * @retval None
+ * @note The frequency is directly the current speed of the device
+ **********************************************************/
+void BSP_MotorControlBoard_Pwm2SetFreq(uint16_t newFreq)
+{
+  uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
+  uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM2_FREQ_RESCALER  * (uint32_t)newFreq)) - 1;
+  
+  __HAL_TIM_SetAutoreload(&hTimPwm2, period);
+  __HAL_TIM_SetCompare(&hTimPwm2, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2, period >> 1);
+  HAL_TIM_PWM_Start_IT(&hTimPwm2, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2);
+}
+/******************************************************//**
+ * @brief  Sets the frequency of PWM3 used by device 2
+ * @param[in] newFreq in Hz
+ * @retval None
+ * @note The frequency is directly the current speed of the device
+ **********************************************************/
+void BSP_MotorControlBoard_Pwm3SetFreq(uint16_t newFreq)
+{
+  uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
+  /* Double the frequency as the SW is generated by SW */
+  uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM3_FREQ_RESCALER * (uint32_t)newFreq)) - 1;
+  
+  __HAL_TIM_SetAutoreload(&hTimPwm3, period);
+  __HAL_TIM_SetCompare(&hTimPwm3, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3, period >> 1);
+  HAL_TIM_PWM_Start_IT(&hTimPwm3, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3);  
+}
+
+/******************************************************//**
+ * @brief  Initialises the PWM uses by the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ * @note Device 0 uses PWM1 based on timer 1 
+ * Device 1 uses PWM 2 based on timer 2
+ * Device 2 uses PWM3 based timer 0
+ **********************************************************/
+void BSP_MotorControlBoard_PwmInit(uint8_t deviceId)
+{
+  TIM_OC_InitTypeDef sConfigOC;
+  TIM_MasterConfigTypeDef sMasterConfig;
+  TIM_HandleTypeDef *pHTim;
+  uint32_t  channel;
+
+  switch (deviceId)
+  {
+
+  case 0:
+  default:
+      pHTim = &hTimPwm1;
+      pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1;
+      channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1;
+
+      break;
+    case  1:
+      pHTim = &hTimPwm2;
+      pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2;
+      channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2;
+      break;
+
+
+    case 2:
+      pHTim = &hTimPwm3;
+      pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3;
+      channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3;
+      break;
+  }
+  pHTim->Init.Prescaler = TIMER_PRESCALER -1;
+  pHTim->Init.CounterMode = TIM_COUNTERMODE_UP;
+  pHTim->Init.Period = 0;
+  pHTim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+  HAL_TIM_PWM_Init(pHTim);
+  
+  sConfigOC.OCMode = TIM_OCMODE_PWM1;
+  sConfigOC.Pulse = 0;
+  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
+  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
+  HAL_TIM_PWM_ConfigChannel(pHTim, &sConfigOC, channel);
+  
+  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
+  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+  HAL_TIMEx_MasterConfigSynchronization(pHTim, &sMasterConfig);
+}
+
+/******************************************************//**
+ * @brief  Stops the PWM uses by the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_PwmStop(uint8_t deviceId)
+{
+  switch (deviceId)
+  {
+    case 0:
+       HAL_TIM_PWM_Stop(&hTimPwm1,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1);
+    
+      break;
+    case  1:
+      HAL_TIM_PWM_Stop(&hTimPwm2,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2);
+      
+      break;
+    case 2:
+       HAL_TIM_PWM_Stop(&hTimPwm3,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3);
+      
+      break;
+    default:
+      break;//ignore error
+  }
+}
+
+/******************************************************//**
+ * @brief  Releases the L6474 reset (pin set to High) of all devices
+ * @param  None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_ReleaseReset(void)
+{ 
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_SET); 
+}
+
+/******************************************************//**
+ * @brief  Resets the L6474 (reset pin set to low) of all devices
+ * @param  None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_Reset(void)
+{
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_RESET); 
+}
+
+/******************************************************//**
+ * @brief  Set the GPIO used for the direction
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] gpioState state of the direction gpio (0 to reset, 1 to set)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_SetDirectionGpio(uint8_t deviceId, uint8_t gpioState)
+{
+  switch (deviceId)
+  {
+    case 2:
+      HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN, (GPIO_PinState)gpioState); 
+      break;
+    case 1:
+      HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN, (GPIO_PinState)gpioState); 
+      break;
+    case 0:
+      HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN, (GPIO_PinState)gpioState); 
+      break;
+    default:
+      ;
+  }
+}
+
+/******************************************************//**
+ * @brief  Initialise the SPI used by L6474
+ * @param None
+ * @retval HAL_OK if SPI transaction is OK, HAL_KO else
+ **********************************************************/
+uint8_t BSP_MotorControlBoard_SpiInit(void)
+{
+  HAL_StatusTypeDef status;
+  
+  /* Initialises the SPI  --------------------------------------------------*/
+  SpiHandle.Instance               = SPIx;
+  SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; 
+  SpiHandle.Init.Direction         = SPI_DIRECTION_2LINES;
+  SpiHandle.Init.CLKPhase          = SPI_PHASE_2EDGE;    
+  SpiHandle.Init.CLKPolarity       = SPI_POLARITY_HIGH;
+  SpiHandle.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLED;
+  SpiHandle.Init.CRCPolynomial     = 7;
+  SpiHandle.Init.DataSize          = SPI_DATASIZE_8BIT;
+  SpiHandle.Init.FirstBit          = SPI_FIRSTBIT_MSB;
+  SpiHandle.Init.NSS               = SPI_NSS_SOFT;
+  SpiHandle.Init.TIMode            = SPI_TIMODE_DISABLED;
+  
+  SpiHandle.Init.Mode = SPI_MODE_MASTER;
+  
+  status = HAL_SPI_Init(&SpiHandle);
+  
+  return (uint8_t) status;
+}
+/******************************************************//**
+ * @brief  Write and read SPI byte to the L6474
+ * @param[in] pByteToTransmit pointer to the byte to transmit
+ * @param[in] pReceivedByte pointer to the received byte
+ * @param[in] nbDevices Number of device in the SPI chain
+ * @retval HAL_OK if SPI transaction is OK, HAL_KO else 
+ **********************************************************/
+uint8_t BSP_MotorControlBoard_SpiWriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte, uint8_t nbDevices)
+{
+  HAL_StatusTypeDef status;
+  uint32_t i;
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_RESET); 
+  for (i = 0; i < nbDevices; i++)
+  {
+    status = HAL_SPI_TransmitReceive(&SpiHandle, pByteToTransmit, pReceivedByte, 1, SPIx_TIMEOUT_MAX);
+    if (status != HAL_OK)
+    {
+      break;
+    }
+    pByteToTransmit++;
+    pReceivedByte++;
+  }
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_SET); 
+  
+  return (uint8_t) status;  
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */    
+
+/**
+  * @}
+  */ 
+#endif    
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32f0xx_nucleo_ihm01a1.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,338 @@
+/** 
+  ******************************************************************************
+  * @file    stm32f0xx_nucleo_ihm01a1.h
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   Header for BSP driver for x-nucleo-ihm01a1 Nucleo extension board 
+  *  (based on L6474)
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************  
+  */ 
+  
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F0XX_NUCLEO_IHM01A1_H
+#define __STM32F0XX_NUCLEO_IHM01A1_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+//mbed #include "stm32f0xx_nucleo.h"
+   
+/** @addtogroup BSP
+  * @{
+  */   
+   
+/** @addtogroup STM32F0XX_NUCLEO_IHM01A1
+  * @{   
+  */   
+
+/** @defgroup IHM01A1_Board_Private_Function_Prototypes
+  * @{
+  */   
+   
+void BSP_MotorControlBoard_Delay(uint32_t delay);         //Delay of the requested number of milliseconds
+void BSP_MotorControlBoard_DisableIrq(void);              //Disable Irq
+void BSP_MotorControlBoard_EnableIrq(void);               //Enable Irq
+void BSP_MotorControlBoard_GpioInit(uint8_t nbDevices);   //Initialise GPIOs used for L6474s
+void BSP_MotorControlBoard_Pwm1SetFreq(uint16_t newFreq); //Set PWM1 frequency and start it
+void BSP_MotorControlBoard_Pwm2SetFreq(uint16_t newFreq); //Set PWM2 frequency and start it  
+void BSP_MotorControlBoard_Pwm3SetFreq(uint16_t newFreq); //Set PWM3 frequency and start it
+void BSP_MotorControlBoard_PwmInit(uint8_t deviceId);    //Init the PWM of the specified device
+void BSP_MotorControlBoard_PwmStop(uint8_t deviceId);    //Stop the PWM of the specified device
+void BSP_MotorControlBoard_ReleaseReset(void);           //Reset the L6474 reset pin 
+void BSP_MotorControlBoard_Reset(void);                  //Set the L6474 reset pin 
+void BSP_MotorControlBoard_SetDirectionGpio(uint8_t deviceId, uint8_t gpioState); //Set direction GPIO
+uint8_t BSP_MotorControlBoard_SpiInit(void);   //Initialise the SPI used for L6474s
+uint8_t BSP_MotorControlBoard_SpiWriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte, uint8_t nbDevices); //Write bytes to the L6474s via SPI
+
+   
+/* Exported Constants --------------------------------------------------------*/
+   
+/** @defgroup IHM01A1_Exported_Constants
+  * @{
+  */   
+   
+/******************************************************************************/
+/* USE_STM32F0XX_NUCLEO                                                       */
+/******************************************************************************/
+
+ /** @defgroup Constants_For_STM32F0XX_NUCLEO  
+* @{
+*/   
+///Define BUTTON KEY
+#define BUTTON_KEY (BUTTON_USER)   
+   
+/// Interrupt line used for L6474 FLAG
+#define EXTI_MCU_LINE_IRQn           (EXTI4_15_IRQn)
+
+/// Timer used for PWM1
+#define BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1      (TIM3)
+
+/// Timer used for PWM2
+#define BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2      (TIM14)
+
+/// Timer used for PWM3
+#define BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3      (TIM15)
+
+/// Channel Timer used for PWM1
+#define BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1      (TIM_CHANNEL_2)
+
+/// Channel Timer used for PWM2
+#define BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2      (TIM_CHANNEL_1)
+
+/// Channel Timer used for PWM3
+#define BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3      (TIM_CHANNEL_1)
+
+/// HAL Active Channel Timer used for PWM1
+#define BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM1      (HAL_TIM_ACTIVE_CHANNEL_2)
+
+/// HAL Active Channel Timer used for PWM2
+#define BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM2      (HAL_TIM_ACTIVE_CHANNEL_1)
+
+/// HAL Active Channel Timer used for PWM3
+#define BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM3      (HAL_TIM_ACTIVE_CHANNEL_1)
+
+/// Timer Clock Enable for PWM1
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_ENABLE()  __TIM3_CLK_ENABLE()
+
+/// Timer Clock Enable for PWM2
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_ENABLE()    __TIM14_CLK_ENABLE()
+
+/// Timer Clock Enable for PWM1
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_ENABLE()    __TIM15_CLK_ENABLE()
+
+/// Timer Clock Disable for PWM1
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_DISABLE()  __TIM3_CLK_DISABLE()
+
+/// Timer Clock Disable for PWM2
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_DISABLE()    __TIM14_CLK_DISABLE()
+
+/// Timer Clock Disable for PWM3
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_DISABLE()    __TIM15_CLK_DISABLE()
+
+/// PWM1 global interrupt
+#define BSP_MOTOR_CONTROL_BOARD_PWM1_IRQn   (TIM3_IRQn)
+
+/// PWM2 global interrupt
+#define BSP_MOTOR_CONTROL_BOARD_PWM2_IRQn   (TIM14_IRQn)
+
+/// PWM3 global interrupt
+#define BSP_MOTOR_CONTROL_BOARD_PWM3_IRQn   (TIM15_IRQn)
+
+/// PWM1 GPIO alternate function 
+#define BSP_MOTOR_CONTROL_BOARD_AFx_TIMx_PWM1  (GPIO_AF1_TIM3)
+
+#ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2
+/// SPI SCK AF
+//mbed (NUCLEO_SPIx_MISO_MOSI_AF)
+#define SPIx_SCK_AF    (GPIO_AF0_SPI1)
+#else /* #ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2 */
+/// SPI SCK AF
+#define SPIx_SCK_AF    (GPIO_AF0_SPI2)
+#endif /* #ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2 */
+
+/// PWM1 frequency rescaler (1 for HW PWM, 2 for SW PWM)
+#define BSP_MOTOR_CONTROL_BOARD_PWM1_FREQ_RESCALER    (1)   
+/// PWM2 frequency rescaler (1 for HW PWM, 2 for SW PWM)
+#define BSP_MOTOR_CONTROL_BOARD_PWM2_FREQ_RESCALER    (2)   
+/// PWM3 frequency rescaler (1 for HW PWM, 2 for SW PWM)   
+#define BSP_MOTOR_CONTROL_BOARD_PWM3_FREQ_RESCALER    (2)   
+   
+ /**
+* @}
+*/
+
+/******************************************************************************/
+/* Independent plateform definitions                                          */
+/******************************************************************************/
+
+   /** @defgroup Constants_For_All_Nucleo_Platforms
+* @{
+*/   
+
+/// GPIO Pin used for the L6474 flag pin
+#define BSP_MOTOR_CONTROL_BOARD_FLAG_PIN   (GPIO_PIN_10)
+/// GPIO port used for the L6474 flag pin
+#define BSP_MOTOR_CONTROL_BOARD_FLAG_PORT   (GPIOA)
+
+/// GPIO Pin used for the L6474 step clock pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_PWM_1_PIN  (GPIO_PIN_7)
+/// GPIO Port used for the L6474 step clock pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_PWM_1_PORT  (GPIOC)
+
+/// GPIO Pin used for the L6474 step clock pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_PWM_2_PIN  (GPIO_PIN_3)
+/// GPIO port used for the L6474 step clock pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_PWM_2_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 step clock pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN   (GPIO_PIN_10)
+/// GPIO port used for the L6474 step clock pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 direction pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN  (GPIO_PIN_8)
+/// GPIO port used for the L6474 direction pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT  (GPIOA)
+
+/// GPIO Pin used for the L6474 direction pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN   (GPIO_PIN_5)
+/// GPIO port used for the L6474 direction pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 direction pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN   (GPIO_PIN_4)
+/// GPIO port used for the L6474 direction pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 reset pin
+#define BSP_MOTOR_CONTROL_BOARD_RESET_PIN  (GPIO_PIN_9)
+/// GPIO port used for the L6474 reset pin
+#define BSP_MOTOR_CONTROL_BOARD_RESET_PORT (GPIOA)
+
+/// GPIO Pin used for the L6474 SPI chip select pin
+#define BSP_MOTOR_CONTROL_BOARD_CS_PIN  (GPIO_PIN_6)
+/// GPIO port used for the L6474 SPI chip select  pin
+#define BSP_MOTOR_CONTROL_BOARD_CS_PORT (GPIOB)
+
+/* Definition for SPIx clock resources */
+
+#ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2
+/* Default SPI is SPI1 */
+
+/// Used SPI
+#define SPIx                             (SPI1)
+
+/// SPI clock enable
+#define SPIx_CLK_ENABLE()                __SPI1_CLK_ENABLE()
+
+/// SPI SCK enable
+#define SPIx_SCK_GPIO_CLK_ENABLE()       __GPIOA_CLK_ENABLE()
+
+/// SPI MISO enable
+#define SPIx_MISO_GPIO_CLK_ENABLE()      __GPIOA_CLK_ENABLE() 
+
+/// SPI MOSI enable
+#define SPIx_MOSI_GPIO_CLK_ENABLE()      __GPIOA_CLK_ENABLE() 
+
+/// SPI Force reset
+#define SPIx_FORCE_RESET()               __SPI1_FORCE_RESET()
+
+/// SPI Release reset
+#define SPIx_RELEASE_RESET()             __SPI1_RELEASE_RESET()
+
+/// SPI SCK pin
+#define SPIx_SCK_PIN                     (GPIO_PIN_5)
+
+/// SPI SCK port
+#define SPIx_SCK_GPIO_PORT               (GPIOA)
+
+
+/// SPI MISO pin 
+#define SPIx_MISO_PIN                    (GPIO_PIN_6)
+
+/// SPI MISO port
+#define SPIx_MISO_GPIO_PORT              (GPIOA)
+
+/// SPI MOSI pin
+#define SPIx_MOSI_PIN                    (GPIO_PIN_7)
+
+/// SPI MOSI port
+#define SPIx_MOSI_GPIO_PORT              (GPIOA)
+
+#else  /* USE SPI2 */
+
+/// Used SPI
+#define SPIx                             (SPI2)
+
+/// SPI clock enable
+#define SPIx_CLK_ENABLE()                __SPI2_CLK_ENABLE()
+
+/// SPI SCK enable
+#define SPIx_SCK_GPIO_CLK_ENABLE()       __GPIOB_CLK_ENABLE()
+
+/// SPI MISO enable
+#define SPIx_MISO_GPIO_CLK_ENABLE()      __GPIOB_CLK_ENABLE() 
+
+/// SPI MOSI enable
+#define SPIx_MOSI_GPIO_CLK_ENABLE()      __GPIOB_CLK_ENABLE() 
+
+/// SPI Force reset
+#define SPIx_FORCE_RESET()               __SPI2_FORCE_RESET()
+
+/// SPI Release reset
+#define SPIx_RELEASE_RESET()             __SPI2_RELEASE_RESET()
+
+/// SPI SCK pin
+#define SPIx_SCK_PIN                     (GPIO_PIN_13)
+
+/// SPI SCK port
+#define SPIx_SCK_GPIO_PORT               (GPIOB)
+
+/// SPI MISO pin 
+#define SPIx_MISO_PIN                    (GPIO_PIN_14)
+
+/// SPI MISO port
+#define SPIx_MISO_GPIO_PORT              (GPIOB)
+
+/// SPI MISO AF 
+#define SPIx_MISO_AF                     (SPIx_SCK_AF)
+  
+/// SPI MOSI pin
+#define SPIx_MOSI_PIN                    (GPIO_PIN_15)
+
+/// SPI MOSI port
+#define SPIx_MOSI_GPIO_PORT              (GPIOB)
+
+#endif
+   
+/// SPI MISO AF 
+#define SPIx_MISO_AF                     (SPIx_SCK_AF)
+
+/// SPI MOSI AF
+#define SPIx_MOSI_AF                     (SPIx_SCK_AF)
+   
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F0XX_NUCLEO_IHM01A1_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32f4xx_hal_msp.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,288 @@
+/**
+  ******************************************************************************
+  * @file    Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Src/stm32f4xx_hal_msp.c
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   HAL MSP module.    
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************  
+  */ 
+#ifdef TARGET_STM32F4
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+#include "mbed.h"
+
+/** @defgroup MSP_module
+  * @brief HAL MSP module.
+  * @{
+  */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private function prototypes -----------------------------------------------*/
+extern void BSP_MotorControl_StepClockHandler(uint8_t deviceId); 
+extern void BSP_MotorControl_FlagInterruptHandler(void);
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup HAL_MSP_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief SPI MSP Initialization 
+  *        This function configures the hardware resources used in this example: 
+  *           - Peripheral's clock enable
+  *           - Peripheral's GPIO Configuration  
+  * @param[in] hspi SPI handle pointer
+  * @retval None
+  */
+void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
+{
+  GPIO_InitTypeDef  GPIO_InitStruct;
+  
+  if(hspi->Instance == SPIx)
+  {  
+    /*##-1- Enable peripherals and GPIO Clocks #################################*/
+    /* Enable GPIO TX/RX clock */
+    SPIx_SCK_GPIO_CLK_ENABLE();
+    SPIx_MISO_GPIO_CLK_ENABLE();
+    SPIx_MOSI_GPIO_CLK_ENABLE();
+    /* Enable SPI clock */
+    SPIx_CLK_ENABLE(); 
+    
+    /*##-2- Configure peripheral GPIO ##########################################*/  
+    /* SPI SCK GPIO pin configuration  */
+    GPIO_InitStruct.Pin       = SPIx_SCK_PIN;
+    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull      = GPIO_NOPULL;
+    GPIO_InitStruct.Speed     = GPIO_SPEED_MEDIUM;
+    GPIO_InitStruct.Alternate = SPIx_SCK_AF;
+    
+    HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);
+      
+    /* SPI MISO GPIO pin configuration  */
+    GPIO_InitStruct.Pin = SPIx_MISO_PIN;
+    GPIO_InitStruct.Alternate = SPIx_MISO_AF;
+    
+    HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct);
+    
+    /* SPI MOSI GPIO pin configuration  */
+    GPIO_InitStruct.Pin = SPIx_MOSI_PIN;
+    GPIO_InitStruct.Alternate = SPIx_MOSI_AF;
+      
+    HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct);   
+  }
+}
+
+/**
+  * @brief SPI MSP De-Initialization 
+  *        This function frees the hardware resources used in this example:
+  *          - Disable the Peripheral's clock
+  *          - Revert GPIO configuration to its default state
+  * @param[in] hspi SPI handle pointer
+  * @retval None
+  */
+void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
+{
+  if(hspi->Instance == SPIx)
+  {  
+    /*##-1- Reset peripherals ##################################################*/
+    SPIx_FORCE_RESET();
+    SPIx_RELEASE_RESET();
+
+    /*##-2- Disable peripherals and GPIO Clocks ################################*/
+    /* Configure SPI SCK as alternate function  */
+    HAL_GPIO_DeInit(SPIx_SCK_GPIO_PORT, SPIx_SCK_PIN);
+    /* Configure SPI MISO as alternate function  */
+    HAL_GPIO_DeInit(SPIx_MISO_GPIO_PORT, SPIx_MISO_PIN);
+    /* Configure SPI MOSI as alternate function  */
+    HAL_GPIO_DeInit(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_PIN);
+  }
+}
+
+/**
+  * @brief PWM MSP Initialization 
+  * @param[in] htim_pwm PWM handle pointer
+  * @retval None
+  */
+void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* htim_pwm)
+{
+  GPIO_InitTypeDef GPIO_InitStruct;
+  if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1)
+  {
+    /* Peripheral clock enable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_ENABLE();
+  
+    /* GPIO configuration */
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_PWM_1_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = BSP_MOTOR_CONTROL_BOARD_AFx_TIMx_PWM1;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_PWM_1_PORT, &GPIO_InitStruct);
+
+    /* Set Interrupt Group Priority of Timer Interrupt*/ 
+    HAL_NVIC_SetPriority(BSP_MOTOR_CONTROL_BOARD_PWM1_IRQn, 4, 0);
+    
+    /* Enable the timer global Interrupt */
+    HAL_NVIC_EnableIRQ(BSP_MOTOR_CONTROL_BOARD_PWM1_IRQn);  
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2)
+  {
+    /* Peripheral clock enable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_ENABLE();
+  
+    /* GPIO configuration */
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_PWM_2_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = BSP_MOTOR_CONTROL_BOARD_AFx_TIMx_PWM2;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_PWM_2_PORT, &GPIO_InitStruct);
+    
+    /* Set Interrupt Group Priority of Timer Interrupt*/ 
+    HAL_NVIC_SetPriority(BSP_MOTOR_CONTROL_BOARD_PWM2_IRQn, 4, 0);
+    
+    /* Enable the timer2 global Interrupt */
+    HAL_NVIC_EnableIRQ(BSP_MOTOR_CONTROL_BOARD_PWM2_IRQn);    
+
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3)
+  {
+    /* Peripheral clock enable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_ENABLE();
+  
+    /* GPIO configuration */
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, &GPIO_InitStruct);    
+    
+    /* Set Interrupt Group Priority of Timer Interrupt*/ 
+    HAL_NVIC_SetPriority(BSP_MOTOR_CONTROL_BOARD_PWM3_IRQn, 3, 0);
+    
+    /* Enable the timer global Interrupt */
+    HAL_NVIC_EnableIRQ(BSP_MOTOR_CONTROL_BOARD_PWM3_IRQn);  
+  }
+}
+
+/**
+  * @brief PWM MSP De-Initialization
+  * @param[in] htim_pwm PWM handle pointer
+  * @retval None
+  */
+void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* htim_pwm)
+{
+  if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1)
+  {
+    /* Peripheral clock disable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_DISABLE();
+  
+    /* GPIO Deconfiguration */
+    HAL_GPIO_DeInit(BSP_MOTOR_CONTROL_BOARD_PWM_1_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_1_PIN);
+
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2)
+  {
+    /* Peripheral clock disable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_DISABLE();
+  
+    /* GPIO Deconfiguration */
+    HAL_GPIO_DeInit(BSP_MOTOR_CONTROL_BOARD_PWM_2_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_2_PIN);
+
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3)
+  {
+    /* Peripheral clock disable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_DISABLE();
+    
+    /* GPIO Deconfiguration */
+    HAL_GPIO_DeInit(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN);
+  }
+}
+
+/**
+  * @brief PWM Callback
+  * @param[in] htim PWM handle pointer
+  * @retval None
+  */
+void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
+{
+  if ((htim->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1)&& (htim->Channel == BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM1))
+  {
+    if (BSP_MotorControl_GetDeviceState(0) != INACTIVE)
+    {
+      BSP_MotorControl_StepClockHandler(0);
+    }
+  }
+  if ((htim->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2)&& (htim->Channel == BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM2))
+  {
+    if (BSP_MotorControl_GetDeviceState(1) != INACTIVE)
+    { 
+      BSP_MotorControl_StepClockHandler(1);
+    }
+  }
+  if ((htim->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3)&& (htim->Channel == BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM3))
+  {
+    HAL_GPIO_TogglePin(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN);
+    if ((BSP_MotorControl_GetDeviceState(2) != INACTIVE)&& 
+        (HAL_GPIO_ReadPin(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN) == GPIO_PIN_SET))
+    {
+      BSP_MotorControl_StepClockHandler(2);
+    }
+  }
+}
+
+/**
+  * @brief External Line Callback 
+  * @param[in] GPIO_Pin pin number
+  * @retval None
+  */
+void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
+{
+  if (GPIO_Pin == BSP_MOTOR_CONTROL_BOARD_FLAG_PIN)
+  {
+    BSP_MotorControl_FlagInterruptHandler();
+  }
+ }
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32f4xx_it.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,222 @@
+/**
+  ******************************************************************************
+  * @file    Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Src/stm32f4xx_it.c 
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   Main Interrupt Service Routines.
+  *          This file provides template for all exceptions handler and 
+  *          peripherals interrupt service routine.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+#ifdef TARGET_STM32F4
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include "stm32f4xx_it.h"
+#include "motorcontrol.h"
+    
+/** @addtogroup Interrupt_Handlers
+  * @{
+  */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+extern TIM_HandleTypeDef hTimPwm1;
+extern TIM_HandleTypeDef hTimPwm2;
+extern TIM_HandleTypeDef hTimPwm3;
+    
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+
+/******************************************************************************/
+/*            Cortex-M4 Processor Exceptions Handlers                         */
+/******************************************************************************/
+
+/**
+  * @brief   This function handles NMI exception.
+  * @param  None
+  * @retval None
+  */
+void NMI_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles Hard Fault exception.
+  * @param  None
+  * @retval None
+  */
+void HardFault_Handler(void)
+{
+  /* Go to infinite loop when Hard Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/**
+  * @brief  This function handles Memory Manage exception.
+  * @param  None
+  * @retval None
+  */
+void MemManage_Handler(void)
+{
+  /* Go to infinite loop when Memory Manage exception occurs */
+  while (1)
+  {
+  }
+}
+
+/**
+  * @brief  This function handles Bus Fault exception.
+  * @param  None
+  * @retval None
+  */
+void BusFault_Handler(void)
+{
+  /* Go to infinite loop when Bus Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/**
+  * @brief  This function handles Usage Fault exception.
+  * @param  None
+  * @retval None
+  */
+void UsageFault_Handler(void)
+{
+  /* Go to infinite loop when Usage Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/**
+  * @brief  This function handles SVCall exception.
+  * @param  None
+  * @retval None
+  */
+void SVC_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles Debug Monitor exception.
+  * @param  None
+  * @retval None
+  */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles PendSVC exception.
+  * @param  None
+  * @retval None
+  */
+void PendSV_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles SysTick Handler.
+  * @param  None
+  * @retval None
+  */
+void SysTick_Handler(void)
+{
+  HAL_IncTick();
+}
+
+/******************************************************************************/
+/*                 STM32F4xx Peripherals Interrupt Handlers                   */
+/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
+/*  available peripheral interrupt handler's name please refer to the startup */
+/*  file (startup_stm32f4xx.s).                                               */
+/******************************************************************************/
+
+/**
+  * @brief  This function handles interrupt for External lines 10 to 15
+  * @param  None
+  * @retval None
+  */
+void EXTI15_10_IRQHandler(void)
+{
+  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
+}
+
+/**
+  * @brief  This function handles TIM2 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void TIM2_IRQHandler(void)
+{
+  HAL_TIM_IRQHandler(&hTimPwm2);
+}
+
+/**
+  * @brief  This function handles TIM3 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void TIM3_IRQHandler(void)
+{
+  HAL_TIM_IRQHandler(&hTimPwm1);
+}
+
+/**
+  * @brief  This function handles TIM4 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void TIM4_IRQHandler(void)
+{
+  HAL_TIM_IRQHandler(&hTimPwm3);
+}
+/**
+  * @brief  This function handles PPP interrupt request.
+  * @param  None
+  * @retval None
+  */
+/*void PPP_IRQHandler(void)
+{
+}*/
+
+/**
+  * @}
+  */ 
+#endif
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32f4xx_it.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,76 @@
+/**
+  ******************************************************************************
+  * @file    Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Inc/stm32f4xx_it.h
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   This file contains the headers of the interrupt handlers.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+#ifdef TARGET_STM32F4
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_IT_H
+#define __STM32F4xx_IT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+
+void EXTI15_10_IRQHandler(void);
+void TIM2_IRQHandler(void);
+void TIM3_IRQHandler(void);
+void TIM4_IRQHandler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_IT_H */
+
+#endif
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32f4xx_nucleo_ihm01a1.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,439 @@
+/**
+  ******************************************************************************
+  * @file    stm32f4xx_nucleo_ihm01a1.c
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   BSP driver for x-nucleo-ihm01a1 Nucleo extension board 
+  *  (based on L6474)
+  ******************************************************************************
+* @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+#ifdef TARGET_STM32F4  
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include "stm32f4xx_nucleo_ihm01a1.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @defgroup STM32F4XX_NUCLEO_IHM01A1
+  * @{
+  */   
+    
+/* Private constants ---------------------------------------------------------*/    
+
+/** @defgroup IHM01A1_Private_Constants
+  * @{
+  */   
+    
+/// Timer Prescaler
+#define TIMER_PRESCALER (1024)
+
+/// SPI Maximum Timeout values for flags waiting loops
+#define SPIx_TIMEOUT_MAX                      ((uint32_t)0x1000)
+
+/**
+  * @}
+  */ 
+
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup IHM01A1_Board_Private_Variables
+  * @{
+  */       
+/// SPI handler declaration
+static SPI_HandleTypeDef SpiHandle;
+/// Timer handler for PWM1
+TIM_HandleTypeDef hTimPwm1;
+/// imer handler for PWM2
+TIM_HandleTypeDef hTimPwm2;
+/// Timer handler for PWM3
+TIM_HandleTypeDef hTimPwm3;
+/**
+  * @}
+  */ 
+
+/** @defgroup IHM01A1_Board_Private_Function_Prototypes
+  * @{
+  */   
+   
+//mbed moved to header file
+
+/**
+  * @}
+  */
+
+
+/** @defgroup  IHM01A1_Board_Private_Functions
+  * @{
+  */   
+
+/******************************************************//**
+ * @brief This function provides an accurate delay in milliseconds
+ * @param[in] delay  time length in milliseconds
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_Delay(uint32_t delay)
+{
+  HAL_Delay(delay);
+}
+
+/******************************************************//**
+ * @brief This function disable the interruptions
+ * @param None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_DisableIrq(void)
+{
+  __disable_irq();
+}
+
+/******************************************************//**
+ * @brief This function enable the interruptions
+ * @param None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_EnableIrq(void)
+{
+  __enable_irq();
+}
+
+/******************************************************//**
+ * @brief  Initiliases the GPIOs used by the L6474s
+ * @param[in] nbDevices number of L6474 devices
+ * @retval None
+  **********************************************************/
+void BSP_MotorControlBoard_GpioInit(uint8_t nbDevices)
+{
+   GPIO_InitTypeDef GPIO_InitStruct;
+  
+  /* GPIO Ports Clock Enable */
+  __GPIOC_CLK_ENABLE();
+  __GPIOA_CLK_ENABLE();
+  __GPIOB_CLK_ENABLE();
+
+  /* Configure L6474 - DIR pin for device 1 -------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT, &GPIO_InitStruct);
+  
+  /* Configure L6474 - Flag pin -------------------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_FLAG_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_FLAG_PORT, &GPIO_InitStruct);
+  
+ /* Set Priority of External Line Interrupt used for the Flag interrupt*/ 
+  HAL_NVIC_SetPriority(EXTI_MCU_LINE_IRQn, 5, 0);
+    
+  /* Enable the External Line Interrupt used for the Flag interrupt*/
+  HAL_NVIC_EnableIRQ(EXTI_MCU_LINE_IRQn);    
+
+  /* Configure L6474 - CS pin ---------------------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_CS_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_CS_PORT, &GPIO_InitStruct);
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_SET); 
+  
+  /* Configure L6474 - STBY/RESET pin -------------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_RESET_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, &GPIO_InitStruct);
+  BSP_MotorControlBoard_Reset();  
+
+  if (nbDevices > 1) 
+  {
+    /* Configure L6474 - DIR pin for device  2 ----------------------------*/
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT, &GPIO_InitStruct);    
+  }
+  if (nbDevices > 2) 
+  {
+    /* Configure L6474 - DIR pin for device  3 ----------------------------*/
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT, &GPIO_InitStruct);    
+  }  
+}
+
+/******************************************************//**
+ * @brief  Sets the frequency of PWM1 used by device 0
+ * @param[in] newFreq in Hz
+ * @retval None
+ * @note The frequency is directly the current speed of the device
+ **********************************************************/
+void BSP_MotorControlBoard_Pwm1SetFreq(uint16_t newFreq)
+{
+  uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
+  uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM1_FREQ_RESCALER * (uint32_t)newFreq)) - 1;
+  
+  __HAL_TIM_SetAutoreload(&hTimPwm1, period);
+  __HAL_TIM_SetCompare(&hTimPwm1, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1, period >> 1);
+  HAL_TIM_PWM_Start_IT(&hTimPwm1, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1);  
+}
+
+/******************************************************//**
+ * @brief  Sets the frequency of PWM2 used by device 1
+ * @param[in] newFreq in Hz
+ * @retval None
+ * @note The frequency is directly the current speed of the device
+ **********************************************************/
+void BSP_MotorControlBoard_Pwm2SetFreq(uint16_t newFreq)
+{
+  uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
+  uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM2_FREQ_RESCALER  * (uint32_t)newFreq)) - 1;
+  
+  __HAL_TIM_SetAutoreload(&hTimPwm2, period);
+  __HAL_TIM_SetCompare(&hTimPwm2, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2, period >> 1);
+  HAL_TIM_PWM_Start_IT(&hTimPwm2, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2);
+}
+/******************************************************//**
+ * @brief  Sets the frequency of PWM3 used by device 2
+ * @param[in] newFreq in Hz
+ * @retval None
+ * @note The frequency is directly the current speed of the device
+ **********************************************************/
+void BSP_MotorControlBoard_Pwm3SetFreq(uint16_t newFreq)
+{
+  uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
+  /* Double the frequency as the SW is generated by SW */
+  uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM3_FREQ_RESCALER * (uint32_t)newFreq)) - 1;
+  
+  __HAL_TIM_SetAutoreload(&hTimPwm3, period);
+  __HAL_TIM_SetCompare(&hTimPwm3, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3, period >> 1);
+  HAL_TIM_PWM_Start_IT(&hTimPwm3, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3);  
+}
+
+/******************************************************//**
+ * @brief  Initialises the PWM uses by the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ * @note Device 0 uses PWM1 based on timer 1 
+ * Device 1 uses PWM 2 based on timer 2
+ * Device 2 uses PWM3 based timer 0
+ **********************************************************/
+void BSP_MotorControlBoard_PwmInit(uint8_t deviceId)
+{
+  TIM_OC_InitTypeDef sConfigOC;
+  TIM_MasterConfigTypeDef sMasterConfig;
+  TIM_HandleTypeDef *pHTim;
+  uint32_t  channel;
+
+  switch (deviceId)
+  {
+
+  case 0:
+  default:
+      pHTim = &hTimPwm1;
+      pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1;
+      channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1;
+
+      break;
+    case  1:
+      pHTim = &hTimPwm2;
+      pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2;
+      channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2;
+      break;
+
+
+    case 2:
+      pHTim = &hTimPwm3;
+      pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3;
+      channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3;
+      break;
+  }
+  pHTim->Init.Prescaler = TIMER_PRESCALER -1;
+  pHTim->Init.CounterMode = TIM_COUNTERMODE_UP;
+  pHTim->Init.Period = 0;
+  pHTim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+  HAL_TIM_PWM_Init(pHTim);
+  
+  sConfigOC.OCMode = TIM_OCMODE_PWM1;
+  sConfigOC.Pulse = 0;
+  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
+  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
+  HAL_TIM_PWM_ConfigChannel(pHTim, &sConfigOC, channel);
+  
+  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
+  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+  HAL_TIMEx_MasterConfigSynchronization(pHTim, &sMasterConfig);
+}
+
+/******************************************************//**
+ * @brief  Stops the PWM uses by the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_PwmStop(uint8_t deviceId)
+{
+  switch (deviceId)
+  {
+    case 0:
+       HAL_TIM_PWM_Stop(&hTimPwm1,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1);
+    
+      break;
+    case  1:
+      HAL_TIM_PWM_Stop(&hTimPwm2,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2);
+      
+      break;
+    case 2:
+       HAL_TIM_PWM_Stop(&hTimPwm3,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3);
+      
+      break;
+    default:
+      break;//ignore error
+  }
+}
+
+/******************************************************//**
+ * @brief  Releases the L6474 reset (pin set to High) of all devices
+ * @param  None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_ReleaseReset(void)
+{ 
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_SET); 
+}
+
+/******************************************************//**
+ * @brief  Resets the L6474 (reset pin set to low) of all devices
+ * @param  None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_Reset(void)
+{
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_RESET); 
+}
+
+/******************************************************//**
+ * @brief  Set the GPIO used for the direction
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] gpioState state of the direction gpio (0 to reset, 1 to set)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_SetDirectionGpio(uint8_t deviceId, uint8_t gpioState)
+{
+  switch (deviceId)
+  {
+    case 2:
+      HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN, (GPIO_PinState)gpioState); 
+      break;
+    case 1:
+      HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN, (GPIO_PinState)gpioState); 
+      break;
+    case 0:
+      HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN, (GPIO_PinState)gpioState); 
+      break;
+    default:
+      ;
+  }
+}
+
+/******************************************************//**
+ * @brief  Initialise the SPI used by L6474
+ * @param None
+ * @retval HAL_OK if SPI transaction is OK, HAL_KO else
+ **********************************************************/
+uint8_t BSP_MotorControlBoard_SpiInit(void)
+{
+  HAL_StatusTypeDef status;
+  
+  /* Initialises the SPI  --------------------------------------------------*/
+  SpiHandle.Instance               = SPIx;
+  SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; 
+  SpiHandle.Init.Direction         = SPI_DIRECTION_2LINES;
+  SpiHandle.Init.CLKPhase          = SPI_PHASE_2EDGE;    
+  SpiHandle.Init.CLKPolarity       = SPI_POLARITY_HIGH;
+  SpiHandle.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLED;
+  SpiHandle.Init.CRCPolynomial     = 7;
+  SpiHandle.Init.DataSize          = SPI_DATASIZE_8BIT;
+  SpiHandle.Init.FirstBit          = SPI_FIRSTBIT_MSB;
+  SpiHandle.Init.NSS               = SPI_NSS_SOFT;
+  SpiHandle.Init.TIMode            = SPI_TIMODE_DISABLED;
+  
+  SpiHandle.Init.Mode = SPI_MODE_MASTER;
+  
+  status = HAL_SPI_Init(&SpiHandle);
+  
+  return (uint8_t) status;
+}
+/******************************************************//**
+ * @brief  Write and read SPI byte to the L6474
+ * @param[in] pByteToTransmit pointer to the byte to transmit
+ * @param[in] pReceivedByte pointer to the received byte
+ * @param[in] nbDevices Number of device in the SPI chain
+ * @retval HAL_OK if SPI transaction is OK, HAL_KO else 
+ **********************************************************/
+uint8_t BSP_MotorControlBoard_SpiWriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte, uint8_t nbDevices)
+{
+  HAL_StatusTypeDef status;
+  uint32_t i;
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_RESET); 
+  for (i = 0; i < nbDevices; i++)
+  {
+    status = HAL_SPI_TransmitReceive(&SpiHandle, pByteToTransmit, pReceivedByte, 1, SPIx_TIMEOUT_MAX);
+    if (status != HAL_OK)
+    {
+      break;
+    }
+    pByteToTransmit++;
+    pReceivedByte++;
+  }
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_SET); 
+  
+  return (uint8_t) status;  
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */    
+
+/**
+  * @}
+  */ 
+#endif    
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32f4xx_nucleo_ihm01a1.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,336 @@
+/** 
+  ******************************************************************************
+  * @file    stm32f4xx_nucleo_ihm01a1.h
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   Header for BSP driver for x-nucleo-ihm01a1 Nucleo extension board 
+  *  (based on L6474)
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************  
+  */ 
+  
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4XX_NUCLEO_IHM01A1_H
+#define __STM32F4XX_NUCLEO_IHM01A1_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+//mbed #include "stm32f4xx_nucleo.h"
+   
+/** @addtogroup BSP
+  * @{
+  */   
+   
+/** @addtogroup STM32F4XX_NUCLEO_IHM01A1
+  * @{   
+  */   
+
+/** @defgroup IHM01A1_Board_Private_Function_Prototypes
+  * @{
+  */   
+
+void BSP_MotorControlBoard_Delay(uint32_t delay);         //Delay of the requested number of milliseconds
+void BSP_MotorControlBoard_DisableIrq(void);              //Disable Irq
+void BSP_MotorControlBoard_EnableIrq(void);               //Enable Irq
+void BSP_MotorControlBoard_GpioInit(uint8_t nbDevices);   //Initialise GPIOs used for L6474s
+void BSP_MotorControlBoard_Pwm1SetFreq(uint16_t newFreq); //Set PWM1 frequency and start it
+void BSP_MotorControlBoard_Pwm2SetFreq(uint16_t newFreq); //Set PWM2 frequency and start it  
+void BSP_MotorControlBoard_Pwm3SetFreq(uint16_t newFreq); //Set PWM3 frequency and start it
+void BSP_MotorControlBoard_PwmInit(uint8_t deviceId);    //Init the PWM of the specified device
+void BSP_MotorControlBoard_PwmStop(uint8_t deviceId);    //Stop the PWM of the specified device
+void BSP_MotorControlBoard_ReleaseReset(void);           //Reset the L6474 reset pin 
+void BSP_MotorControlBoard_Reset(void);                  //Set the L6474 reset pin 
+void BSP_MotorControlBoard_SetDirectionGpio(uint8_t deviceId, uint8_t gpioState); //Set direction GPIO
+uint8_t BSP_MotorControlBoard_SpiInit(void);   //Initialise the SPI used for L6474s
+uint8_t BSP_MotorControlBoard_SpiWriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte, uint8_t nbDevices); //Write bytes to the L6474s via SPI
+   
+/* Exported Constants --------------------------------------------------------*/
+   
+/** @defgroup IHM01A1_Exported_Constants
+  * @{
+  */   
+   
+/******************************************************************************/
+/* USE_STM32F4XX_NUCLEO                                                       */
+/******************************************************************************/
+
+ /** @defgroup Constants_For_STM32F4XX_NUCLEO  
+* @{
+*/   
+/// Interrupt line used for L6474 FLAG
+#define EXTI_MCU_LINE_IRQn           (EXTI15_10_IRQn)
+
+/// Timer used for PWM1
+#define BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1      (TIM3)
+
+/// Timer used for PWM2
+#define BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2      (TIM2)
+
+/// Timer used for PWM3
+#define BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3      (TIM4)
+
+/// Channel Timer used for PWM1
+#define BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1      (TIM_CHANNEL_2)
+
+/// Channel Timer used for PWM2
+#define BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2      (TIM_CHANNEL_2)
+
+/// Channel Timer used for PWM3
+#define BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3      (TIM_CHANNEL_3)
+
+/// HAL Active Channel Timer used for PWM1
+#define BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM1      (HAL_TIM_ACTIVE_CHANNEL_2)
+
+/// HAL Active Channel Timer used for PWM2
+#define BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM2      (HAL_TIM_ACTIVE_CHANNEL_2)
+
+/// HAL Active Channel Timer used for PWM3
+#define BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM3      (HAL_TIM_ACTIVE_CHANNEL_3)
+
+/// Timer Clock Enable for PWM1
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_ENABLE()  __TIM3_CLK_ENABLE()
+
+/// Timer Clock Enable for PWM2
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_ENABLE()    __TIM2_CLK_ENABLE()
+
+/// Timer Clock Enable for PWM1
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_ENABLE()    __TIM4_CLK_ENABLE()
+
+/// Timer Clock Disable for PWM1
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_DISABLE()  __TIM3_CLK_DISABLE()
+
+/// Timer Clock Disable for PWM2
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_DISABLE()    __TIM2_CLK_DISABLE()
+
+/// Timer Clock Disable for PWM3
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_DISABLE()    __TIM4_CLK_DISABLE()
+
+/// PWM1 global interrupt
+#define BSP_MOTOR_CONTROL_BOARD_PWM1_IRQn   (TIM3_IRQn)
+
+/// PWM2 global interrupt
+#define BSP_MOTOR_CONTROL_BOARD_PWM2_IRQn   (TIM2_IRQn)
+
+/// PWM3 global interrupt
+#define BSP_MOTOR_CONTROL_BOARD_PWM3_IRQn   (TIM4_IRQn)
+
+/// PWM1 GPIO alternate function 
+#define BSP_MOTOR_CONTROL_BOARD_AFx_TIMx_PWM1  (GPIO_AF2_TIM3)
+
+/// PWM2 GPIO alternate function 
+#define BSP_MOTOR_CONTROL_BOARD_AFx_TIMx_PWM2  (GPIO_AF1_TIM2)
+
+#ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2
+/// SPI SCK AF
+#define SPIx_SCK_AF    (GPIO_AF5_SPI1)
+#else /* #ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2 */
+/// SPI SCK AF
+#define SPIx_SCK_AF    (GPIO_AF5_SPI2)
+#endif /* #ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2 */
+
+/// PWM1 frequency rescaler (1 for HW PWM, 2 for SW PWM)
+#define BSP_MOTOR_CONTROL_BOARD_PWM1_FREQ_RESCALER    (1)   
+/// PWM2 frequency rescaler (1 for HW PWM, 2 for SW PWM)
+#define BSP_MOTOR_CONTROL_BOARD_PWM2_FREQ_RESCALER    (1)   
+/// PWM3 frequency rescaler (1 for HW PWM, 2 for SW PWM)   
+#define BSP_MOTOR_CONTROL_BOARD_PWM3_FREQ_RESCALER    (2)   
+   
+ /**
+* @}
+*/
+
+/******************************************************************************/
+/* Independent plateform definitions                                          */
+/******************************************************************************/
+
+   /** @defgroup Constants_For_All_Nucleo_Platforms
+* @{
+*/   
+
+/// GPIO Pin used for the L6474 flag pin
+#define BSP_MOTOR_CONTROL_BOARD_FLAG_PIN   (GPIO_PIN_10)
+/// GPIO port used for the L6474 flag pin
+#define BSP_MOTOR_CONTROL_BOARD_FLAG_PORT   (GPIOA)
+
+/// GPIO Pin used for the L6474 step clock pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_PWM_1_PIN  (GPIO_PIN_7)
+/// GPIO Port used for the L6474 step clock pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_PWM_1_PORT  (GPIOC)
+
+/// GPIO Pin used for the L6474 step clock pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_PWM_2_PIN  (GPIO_PIN_3)
+/// GPIO port used for the L6474 step clock pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_PWM_2_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 step clock pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN   (GPIO_PIN_10)
+/// GPIO port used for the L6474 step clock pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 direction pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN  (GPIO_PIN_8)
+/// GPIO port used for the L6474 direction pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT  (GPIOA)
+
+/// GPIO Pin used for the L6474 direction pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN   (GPIO_PIN_5)
+/// GPIO port used for the L6474 direction pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 direction pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN   (GPIO_PIN_4)
+/// GPIO port used for the L6474 direction pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 reset pin
+#define BSP_MOTOR_CONTROL_BOARD_RESET_PIN  (GPIO_PIN_9)
+/// GPIO port used for the L6474 reset pin
+#define BSP_MOTOR_CONTROL_BOARD_RESET_PORT (GPIOA)
+
+/// GPIO Pin used for the L6474 SPI chip select pin
+#define BSP_MOTOR_CONTROL_BOARD_CS_PIN  (GPIO_PIN_6)
+/// GPIO port used for the L6474 SPI chip select  pin
+#define BSP_MOTOR_CONTROL_BOARD_CS_PORT (GPIOB)
+
+/* Definition for SPIx clock resources */
+
+#ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2
+/* Default SPI is SPI1 */
+
+/// Used SPI
+#define SPIx                             (SPI1)
+
+/// SPI clock enable
+#define SPIx_CLK_ENABLE()                __SPI1_CLK_ENABLE()
+
+/// SPI SCK enable
+#define SPIx_SCK_GPIO_CLK_ENABLE()       __GPIOA_CLK_ENABLE()
+
+/// SPI MISO enable
+#define SPIx_MISO_GPIO_CLK_ENABLE()      __GPIOA_CLK_ENABLE() 
+
+/// SPI MOSI enable
+#define SPIx_MOSI_GPIO_CLK_ENABLE()      __GPIOA_CLK_ENABLE() 
+
+/// SPI Force reset
+#define SPIx_FORCE_RESET()               __SPI1_FORCE_RESET()
+
+/// SPI Release reset
+#define SPIx_RELEASE_RESET()             __SPI1_RELEASE_RESET()
+
+/// SPI SCK pin
+#define SPIx_SCK_PIN                     (GPIO_PIN_5)
+
+/// SPI SCK port
+#define SPIx_SCK_GPIO_PORT               (GPIOA)
+
+
+/// SPI MISO pin 
+#define SPIx_MISO_PIN                    (GPIO_PIN_6)
+
+/// SPI MISO port
+#define SPIx_MISO_GPIO_PORT              (GPIOA)
+
+/// SPI MOSI pin
+#define SPIx_MOSI_PIN                    (GPIO_PIN_7)
+
+/// SPI MOSI port
+#define SPIx_MOSI_GPIO_PORT              (GPIOA)
+
+#else  /* USE SPI2 */
+
+/// Used SPI
+#define SPIx                             (SPI2)
+
+/// SPI clock enable
+#define SPIx_CLK_ENABLE()                __SPI2_CLK_ENABLE()
+
+/// SPI SCK enable
+#define SPIx_SCK_GPIO_CLK_ENABLE()       __GPIOB_CLK_ENABLE()
+
+/// SPI MISO enable
+#define SPIx_MISO_GPIO_CLK_ENABLE()      __GPIOB_CLK_ENABLE() 
+
+/// SPI MOSI enable
+#define SPIx_MOSI_GPIO_CLK_ENABLE()      __GPIOB_CLK_ENABLE() 
+
+/// SPI Force reset
+#define SPIx_FORCE_RESET()               __SPI2_FORCE_RESET()
+
+/// SPI Release reset
+#define SPIx_RELEASE_RESET()             __SPI2_RELEASE_RESET()
+
+/// SPI SCK pin
+#define SPIx_SCK_PIN                     (GPIO_PIN_13)
+
+/// SPI SCK port
+#define SPIx_SCK_GPIO_PORT               (GPIOB)
+
+/// SPI MISO pin 
+#define SPIx_MISO_PIN                    (GPIO_PIN_14)
+
+/// SPI MISO port
+#define SPIx_MISO_GPIO_PORT              (GPIOB)
+
+/// SPI MISO AF 
+#define SPIx_MISO_AF                     (SPIx_SCK_AF)
+  
+/// SPI MOSI pin
+#define SPIx_MOSI_PIN                    (GPIO_PIN_15)
+
+/// SPI MOSI port
+#define SPIx_MOSI_GPIO_PORT              (GPIOB)
+
+#endif
+   
+/// SPI MISO AF 
+#define SPIx_MISO_AF                     (SPIx_SCK_AF)
+
+/// SPI MOSI AF
+#define SPIx_MOSI_AF                     (SPIx_SCK_AF)
+   
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4XX_NUCLEO_IHM01A1_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32l0xx_hal_msp.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,287 @@
+/**
+  ******************************************************************************
+  * @file    Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Src/stm32l0xx_hal_msp.c
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   HAL MSP module.    
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************  
+  */ 
+#ifdef TARGET_STM32L0
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+#include "mbed.h"
+
+/** @defgroup HAL_MSP
+  * @brief HAL MSP module.
+  * @{
+  */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private function prototypes -----------------------------------------------*/
+extern void BSP_MotorControl_StepClockHandler(uint8_t deviceId); 
+extern void BSP_MotorControl_FlagInterruptHandler(void);
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup HAL_MSP_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief SPI MSP Initialization 
+  *        This function configures the hardware resources used in this example: 
+  *           - Peripheral's clock enable
+  *           - Peripheral's GPIO Configuration  
+  * @param[in] hspi SPI handle pointer
+  * @retval None
+  */
+void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
+{
+  GPIO_InitTypeDef  GPIO_InitStruct;
+  
+  if(hspi->Instance == SPIx)
+  {  
+    /*##-1- Enable peripherals and GPIO Clocks #################################*/
+    /* Enable GPIO TX/RX clock */
+    SPIx_SCK_GPIO_CLK_ENABLE();
+    SPIx_MISO_GPIO_CLK_ENABLE();
+    SPIx_MOSI_GPIO_CLK_ENABLE();
+    /* Enable SPI clock */
+    SPIx_CLK_ENABLE(); 
+    
+    /*##-2- Configure peripheral GPIO ##########################################*/  
+    /* SPI SCK GPIO pin configuration  */
+    GPIO_InitStruct.Pin       = SPIx_SCK_PIN;
+    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull      = GPIO_NOPULL;
+    GPIO_InitStruct.Speed     = GPIO_SPEED_MEDIUM;
+    GPIO_InitStruct.Alternate = SPIx_SCK_AF;
+    
+    HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);
+      
+    /* SPI MISO GPIO pin configuration  */
+    GPIO_InitStruct.Pin = SPIx_MISO_PIN;
+    GPIO_InitStruct.Alternate = SPIx_MISO_AF;
+    
+    HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct);
+    
+    /* SPI MOSI GPIO pin configuration  */
+    GPIO_InitStruct.Pin = SPIx_MOSI_PIN;
+    GPIO_InitStruct.Alternate = SPIx_MOSI_AF;
+      
+    HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct);   
+  }
+}
+
+/**
+  * @brief SPI MSP De-Initialization 
+  *        This function frees the hardware resources used in this example:
+  *          - Disable the Peripheral's clock
+  *          - Revert GPIO configuration to its default state
+  * @param[in] hspi SPI handle pointer
+  * @retval None
+  */
+void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
+{
+  if(hspi->Instance == SPIx)
+  {  
+    /*##-1- Reset peripherals ##################################################*/
+    SPIx_FORCE_RESET();
+    SPIx_RELEASE_RESET();
+
+    /*##-2- Disable peripherals and GPIO Clocks ################################*/
+    /* Configure SPI SCK as alternate function  */
+    HAL_GPIO_DeInit(SPIx_SCK_GPIO_PORT, SPIx_SCK_PIN);
+    /* Configure SPI MISO as alternate function  */
+    HAL_GPIO_DeInit(SPIx_MISO_GPIO_PORT, SPIx_MISO_PIN);
+    /* Configure SPI MOSI as alternate function  */
+    HAL_GPIO_DeInit(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_PIN);
+  }
+}
+
+/**
+  * @brief PWM MSP Initialization 
+  * @param[in] htim_pwm PWM handle pointer
+  * @retval None
+  */
+void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* htim_pwm)
+{
+  GPIO_InitTypeDef GPIO_InitStruct;
+  if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1)
+  {
+    /* Peripheral clock enable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_ENABLE();
+  
+    /* GPIO configuration */
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_PWM_1_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = BSP_MOTOR_CONTROL_BOARD_AFx_TIMx_PWM1;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_PWM_1_PORT, &GPIO_InitStruct);
+
+    /* Set Interrupt Group Priority of Timer Interrupt*/ 
+    HAL_NVIC_SetPriority(BSP_MOTOR_CONTROL_BOARD_PWM1_IRQn, 4, 0);
+    
+    /* Enable the timer global Interrupt */
+    HAL_NVIC_EnableIRQ(BSP_MOTOR_CONTROL_BOARD_PWM1_IRQn);  
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2)
+  {
+    /* Peripheral clock enable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_ENABLE();
+  
+    /* GPIO configuration */
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_PWM_2_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = BSP_MOTOR_CONTROL_BOARD_AFx_TIMx_PWM2;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_PWM_2_PORT, &GPIO_InitStruct);
+    
+    /* Set Interrupt Group Priority of Timer Interrupt*/ 
+    HAL_NVIC_SetPriority(BSP_MOTOR_CONTROL_BOARD_PWM2_IRQn, 4, 0);
+    
+    /* Enable the timer2 global Interrupt */
+    HAL_NVIC_EnableIRQ(BSP_MOTOR_CONTROL_BOARD_PWM2_IRQn);    
+
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3)
+  {
+    /* Peripheral clock enable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_ENABLE();
+  
+    /* GPIO configuration */
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, &GPIO_InitStruct);    
+    
+    /* Set Interrupt Group Priority of Timer Interrupt*/ 
+    HAL_NVIC_SetPriority(BSP_MOTOR_CONTROL_BOARD_PWM3_IRQn, 3, 0);
+    
+    /* Enable the timer global Interrupt */
+    HAL_NVIC_EnableIRQ(BSP_MOTOR_CONTROL_BOARD_PWM3_IRQn);  
+  }
+}
+
+/**
+  * @brief PWM MSP De-Initialization
+  * @param[in] htim_pwm PWM handle pointer
+  * @retval None
+  */
+void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* htim_pwm)
+{
+  if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1)
+  {
+    /* Peripheral clock disable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_DISABLE();
+  
+    /* GPIO Deconfiguration */
+    HAL_GPIO_DeInit(BSP_MOTOR_CONTROL_BOARD_PWM_1_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_1_PIN);
+
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2)
+  {
+    /* Peripheral clock disable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_DISABLE();
+  
+    /* GPIO Deconfiguration */
+    HAL_GPIO_DeInit(BSP_MOTOR_CONTROL_BOARD_PWM_2_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_2_PIN);
+
+  }
+  else if(htim_pwm->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3)
+  {
+    /* Peripheral clock disable */
+    __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_DISABLE();
+    
+    /* GPIO Deconfiguration */
+    HAL_GPIO_DeInit(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN);
+  }
+}
+
+/**
+  * @brief PWM Callback
+  * @param[in] htim PWM handle pointer
+  * @retval None
+  */
+void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
+{
+  if ((htim->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1)&& (htim->Channel == BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM1))
+  {
+    if (BSP_MotorControl_GetDeviceState(0) != INACTIVE)
+    {
+      BSP_MotorControl_StepClockHandler(0);
+    }
+  }
+  if ((htim->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2)&& (htim->Channel == BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM2))
+  {
+    if (BSP_MotorControl_GetDeviceState(1) != INACTIVE)
+    { 
+      BSP_MotorControl_StepClockHandler(1);
+    }
+  }
+  if ((htim->Instance == BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3)&& (htim->Channel == BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM3))
+  {
+    HAL_GPIO_TogglePin(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN);
+    if ((BSP_MotorControl_GetDeviceState(2) != INACTIVE)&& 
+        (HAL_GPIO_ReadPin(BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT, BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN) == GPIO_PIN_SET))
+    {
+      BSP_MotorControl_StepClockHandler(2);
+    }
+  }
+}
+
+/**
+  * @brief External Line Callback 
+  * @param[in] GPIO_Pin pin number
+  * @retval None
+  */
+void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
+{
+  if (GPIO_Pin == BSP_MOTOR_CONTROL_BOARD_FLAG_PIN)
+  {
+    BSP_MotorControl_FlagInterruptHandler();
+  }
+ }
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+#endif
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32l0xx_it.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,183 @@
+/**
+  ******************************************************************************
+  * @file    Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Src/stm32l0xx_it.c 
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   Main Interrupt Service Routines.
+  *          This file provides template for all exceptions handler and 
+  *          peripherals interrupt service routine.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+#ifdef TARGET_STM32L0
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include "stm32l0xx_it.h"
+#include "motorcontrol.h"
+    
+/** @addtogroup Interrupt_Handlers
+  * @{
+  */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+extern TIM_HandleTypeDef hTimPwm1;
+extern TIM_HandleTypeDef hTimPwm2;
+extern TIM_HandleTypeDef hTimPwm3;
+    
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+
+/******************************************************************************/
+/*            Cortex-M0+ Processor Exceptions Handlers                         */
+/******************************************************************************/
+
+/**
+  * @brief   This function handles NMI exception.
+  * @param  None
+  * @retval None
+  */
+void NMI_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles Hard Fault exception.
+  * @param  None
+  * @retval None
+  */
+void HardFault_Handler(void)
+{
+  /* Go to infinite loop when Hard Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/**
+  * @brief  This function handles SVCall exception.
+  * @param  None
+  * @retval None
+  */
+void SVC_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles Debug Monitor exception.
+  * @param  None
+  * @retval None
+  */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles PendSVC exception.
+  * @param  None
+  * @retval None
+  */
+void PendSV_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles SysTick Handler.
+  * @param  None
+  * @retval None
+  */
+void SysTick_Handler(void)
+{
+  HAL_IncTick();
+}
+
+/******************************************************************************/
+/*                 STM32L0xx Peripherals Interrupt Handlers                   */
+/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
+/*  available peripheral interrupt handler's name please refer to the startup */
+/*  file (startup_stm32l0xx.s).                                               */
+/******************************************************************************/
+
+/**
+  * @brief  This function handles interrupt for External lines 4 to 15
+  * @param  None
+  * @retval None
+  */
+void EXTI4_15_IRQHandler(void)
+{
+  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
+}
+
+/**
+  * @brief  This function handles TIM2 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void TIM2_IRQHandler(void)
+{
+  HAL_TIM_IRQHandler(&hTimPwm2);
+}
+
+/**
+  * @brief  This function handles TIM22 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void TIM22_IRQHandler(void)
+{
+  HAL_TIM_IRQHandler(&hTimPwm1);
+}
+
+/**
+  * @brief  This function handles TIM21 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void TIM21_IRQHandler(void)
+{
+  HAL_TIM_IRQHandler(&hTimPwm3);
+}
+/**
+  * @brief  This function handles PPP interrupt request.
+  * @param  None
+  * @retval None
+  */
+/*void PPP_IRQHandler(void)
+{
+}*/
+
+/**
+  * @}
+  */ 
+#endif
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32l0xx_it.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,72 @@
+/**
+  ******************************************************************************
+  * @file    Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Inc/stm32l0xx_it.h
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   This file contains the headers of the interrupt handlers.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32L0xx_IT_H
+#define __STM32L0xx_IT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+
+void EXTI4_15_IRQHandler(void);
+void TIM2_IRQHandler(void);
+void TIM21_IRQHandler(void);
+void TIM22_IRQHandler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32L0xx_IT_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32l0xx_nucleo_ihm01a1.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,433 @@
+/**
+  ******************************************************************************
+  * @file    stm32l0xx_nucleo_ihm01a1.c
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   BSP driver for x-nucleo-ihm01a1 Nucleo extension board 
+  *  (based on L6474)
+  ******************************************************************************
+* @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+#ifdef TARGET_STM32L0  
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include "stm32l0xx_nucleo_ihm01a1.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @defgroup STM32L0XX_NUCLEO_IHM01A1
+  * @{
+  */   
+    
+/* Private constants ---------------------------------------------------------*/    
+
+/** @defgroup IHM01A1_Private_Constants
+  * @{
+  */   
+    
+/// Timer Prescaler
+#define TIMER_PRESCALER (1024)
+
+/// SPI Maximum Timeout values for flags waiting loops
+#define SPIx_TIMEOUT_MAX                      ((uint32_t)0x1000)
+
+/**
+  * @}
+  */ 
+
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup IHM01A1_Board_Private_Variables
+  * @{
+  */       
+/// SPI handler declaration
+static SPI_HandleTypeDef SpiHandle;
+/// Timer handler for PWM1
+TIM_HandleTypeDef hTimPwm1;
+/// imer handler for PWM2
+TIM_HandleTypeDef hTimPwm2;
+/// Timer handler for PWM3
+TIM_HandleTypeDef hTimPwm3;
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+
+/** @defgroup  IHM01A1_Board_Private_Functions
+  * @{
+  */   
+
+/******************************************************//**
+ * @brief This function provides an accurate delay in milliseconds
+ * @param[in] delay  time length in milliseconds
+  * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_Delay(uint32_t delay)
+{
+  HAL_Delay(delay);
+}
+
+/******************************************************//**
+ * @brief This function disable the interruptions
+ * @param None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_DisableIrq(void)
+{
+  __disable_irq();
+}
+
+/******************************************************//**
+ * @brief This function enable the interruptions
+ * @param None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_EnableIrq(void)
+{
+  __enable_irq();
+}
+
+/******************************************************//**
+ * @brief  Initiliases the GPIOs used by the L6474s
+ * @param[in] nbDevices number of L6474 devices
+ * @retval None
+  **********************************************************/
+void BSP_MotorControlBoard_GpioInit(uint8_t nbDevices)
+{
+   GPIO_InitTypeDef GPIO_InitStruct;
+  
+  /* GPIO Ports Clock Enable */
+  __GPIOC_CLK_ENABLE();
+  __GPIOA_CLK_ENABLE();
+  __GPIOB_CLK_ENABLE();
+
+  /* Configure L6474 - DIR pin for device 1 -------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT, &GPIO_InitStruct);
+  
+  /* Configure L6474 - Flag pin -------------------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_FLAG_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_FLAG_PORT, &GPIO_InitStruct);
+  
+ /* Set Priority of External Line Interrupt used for the Flag interrupt*/ 
+  HAL_NVIC_SetPriority(EXTI_MCU_LINE_IRQn, 5, 0);
+    
+  /* Enable the External Line Interrupt used for the Flag interrupt*/
+  HAL_NVIC_EnableIRQ(EXTI_MCU_LINE_IRQn);    
+
+  /* Configure L6474 - CS pin ---------------------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_CS_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_CS_PORT, &GPIO_InitStruct);
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_SET); 
+  
+  /* Configure L6474 - STBY/RESET pin -------------------------------------*/
+  GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_RESET_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+  HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, &GPIO_InitStruct);
+  BSP_MotorControlBoard_Reset();  
+
+  if (nbDevices > 1) 
+  {
+    /* Configure L6474 - DIR pin for device  2 ----------------------------*/
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT, &GPIO_InitStruct);    
+  }
+  if (nbDevices > 2) 
+  {
+    /* Configure L6474 - DIR pin for device  3 ----------------------------*/
+    GPIO_InitStruct.Pin = BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
+    HAL_GPIO_Init(BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT, &GPIO_InitStruct);    
+  }  
+}
+
+/******************************************************//**
+ * @brief  Sets the frequency of PWM1 used by device 0
+ * @param[in] newFreq in Hz
+ * @retval None
+ * @note The frequency is directly the current speed of the device
+ **********************************************************/
+void BSP_MotorControlBoard_Pwm1SetFreq(uint16_t newFreq)
+{
+  uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
+  uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM1_FREQ_RESCALER * (uint32_t)newFreq)) - 1;
+  
+  __HAL_TIM_SetAutoreload(&hTimPwm1, period);
+  __HAL_TIM_SetCompare(&hTimPwm1, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1, period >> 1);
+  HAL_TIM_PWM_Start_IT(&hTimPwm1, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1);  
+}
+
+/******************************************************//**
+ * @brief  Sets the frequency of PWM2 used by device 1
+ * @param[in] newFreq in Hz
+ * @retval None
+ * @note The frequency is directly the current speed of the device
+ **********************************************************/
+void BSP_MotorControlBoard_Pwm2SetFreq(uint16_t newFreq)
+{
+  uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
+  uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM2_FREQ_RESCALER  * (uint32_t)newFreq)) - 1;
+  
+  __HAL_TIM_SetAutoreload(&hTimPwm2, period);
+  __HAL_TIM_SetCompare(&hTimPwm2, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2, period >> 1);
+  HAL_TIM_PWM_Start_IT(&hTimPwm2, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2);
+}
+/******************************************************//**
+ * @brief  Sets the frequency of PWM3 used by device 2
+ * @param[in] newFreq in Hz
+ * @retval None
+ * @note The frequency is directly the current speed of the device
+ **********************************************************/
+void BSP_MotorControlBoard_Pwm3SetFreq(uint16_t newFreq)
+{
+  uint32_t sysFreq = HAL_RCC_GetSysClockFreq();
+  /* Double the frequency as the SW is generated by SW */
+  uint32_t period = (sysFreq/ (TIMER_PRESCALER * BSP_MOTOR_CONTROL_BOARD_PWM3_FREQ_RESCALER * (uint32_t)newFreq)) - 1;
+  
+  __HAL_TIM_SetAutoreload(&hTimPwm3, period);
+  __HAL_TIM_SetCompare(&hTimPwm3, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3, period >> 1);
+  HAL_TIM_PWM_Start_IT(&hTimPwm3, BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3);  
+}
+
+/******************************************************//**
+ * @brief  Initialises the PWM uses by the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ * @note Device 0 uses PWM1 based on timer 1 
+ * Device 1 uses PWM 2 based on timer 2
+ * Device 2 uses PWM3 based timer 0
+ **********************************************************/
+void BSP_MotorControlBoard_PwmInit(uint8_t deviceId)
+{
+  TIM_OC_InitTypeDef sConfigOC;
+  TIM_MasterConfigTypeDef sMasterConfig;
+  TIM_HandleTypeDef *pHTim;
+  uint32_t  channel;
+
+  switch (deviceId)
+  {
+
+  case 0:
+  default:
+      pHTim = &hTimPwm1;
+      pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1;
+      channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1;
+
+      break;
+    case  1:
+      pHTim = &hTimPwm2;
+      pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2;
+      channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2;
+      break;
+
+
+    case 2:
+      pHTim = &hTimPwm3;
+      pHTim->Instance = BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3;
+      channel = BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3;
+      break;
+  }
+  pHTim->Init.Prescaler = TIMER_PRESCALER -1;
+  pHTim->Init.CounterMode = TIM_COUNTERMODE_UP;
+  pHTim->Init.Period = 0;
+  pHTim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+  HAL_TIM_PWM_Init(pHTim);
+  
+  sConfigOC.OCMode = TIM_OCMODE_PWM1;
+  sConfigOC.Pulse = 0;
+  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
+  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
+  HAL_TIM_PWM_ConfigChannel(pHTim, &sConfigOC, channel);
+  
+  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
+  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+  HAL_TIMEx_MasterConfigSynchronization(pHTim, &sMasterConfig);
+}
+
+/******************************************************//**
+ * @brief  Stops the PWM uses by the specified device
+ * @param[in] deviceId (from 0 to 2)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_PwmStop(uint8_t deviceId)
+{
+  switch (deviceId)
+  {
+    case 0:
+       HAL_TIM_PWM_Stop(&hTimPwm1,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1);
+    
+      break;
+    case  1:
+      HAL_TIM_PWM_Stop(&hTimPwm2,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2);
+      
+      break;
+    case 2:
+       HAL_TIM_PWM_Stop(&hTimPwm3,BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3);
+      
+      break;
+    default:
+      break;//ignore error
+  }
+}
+
+/******************************************************//**
+ * @brief  Releases the L6474 reset (pin set to High) of all devices
+ * @param  None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_ReleaseReset(void)
+{ 
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_SET); 
+}
+
+/******************************************************//**
+ * @brief  Resets the L6474 (reset pin set to low) of all devices
+ * @param  None
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_Reset(void)
+{
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_RESET_PORT, BSP_MOTOR_CONTROL_BOARD_RESET_PIN, GPIO_PIN_RESET); 
+}
+
+/******************************************************//**
+ * @brief  Set the GPIO used for the direction
+ * @param[in] deviceId (from 0 to 2)
+ * @param[in] gpioState state of the direction gpio (0 to reset, 1 to set)
+ * @retval None
+ **********************************************************/
+void BSP_MotorControlBoard_SetDirectionGpio(uint8_t deviceId, uint8_t gpioState)
+{
+  switch (deviceId)
+  {
+    case 2:
+      HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN, (GPIO_PinState)gpioState); 
+      break;
+    case 1:
+      HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN, (GPIO_PinState)gpioState); 
+      break;
+    case 0:
+      HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT, BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN, (GPIO_PinState)gpioState); 
+      break;
+    default:
+      ;
+  }
+}
+
+/******************************************************//**
+ * @brief  Initialise the SPI used by L6474
+ * @param None
+ * @retval HAL_OK if SPI transaction is OK, HAL_KO else
+ **********************************************************/
+uint8_t BSP_MotorControlBoard_SpiInit(void)
+{
+  HAL_StatusTypeDef status;
+  
+  /* Initialises the SPI  --------------------------------------------------*/
+  SpiHandle.Instance               = SPIx;
+  SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; 
+  SpiHandle.Init.Direction         = SPI_DIRECTION_2LINES;
+  SpiHandle.Init.CLKPhase          = SPI_PHASE_2EDGE;    
+  SpiHandle.Init.CLKPolarity       = SPI_POLARITY_HIGH;
+  SpiHandle.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLED;
+  SpiHandle.Init.CRCPolynomial     = 7;
+  SpiHandle.Init.DataSize          = SPI_DATASIZE_8BIT;
+  SpiHandle.Init.FirstBit          = SPI_FIRSTBIT_MSB;
+  SpiHandle.Init.NSS               = SPI_NSS_SOFT;
+  SpiHandle.Init.TIMode            = SPI_TIMODE_DISABLED;
+  
+  SpiHandle.Init.Mode = SPI_MODE_MASTER;
+  
+  status = HAL_SPI_Init(&SpiHandle);
+  
+  return (uint8_t) status;
+}
+/******************************************************//**
+ * @brief  Write and read SPI byte to the L6474
+ * @param[in] pByteToTransmit pointer to the byte to transmit
+ * @param[in] pReceivedByte pointer to the received byte
+ * @param[in] nbDevices Number of device in the SPI chain
+ * @retval HAL_OK if SPI transaction is OK, HAL_KO else 
+ **********************************************************/
+uint8_t BSP_MotorControlBoard_SpiWriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte, uint8_t nbDevices)
+{
+  HAL_StatusTypeDef status;
+  uint32_t i;
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_RESET); 
+  for (i = 0; i < nbDevices; i++)
+  {
+    status = HAL_SPI_TransmitReceive(&SpiHandle, pByteToTransmit, pReceivedByte, 1, SPIx_TIMEOUT_MAX);
+    if (status != HAL_OK)
+    {
+      break;
+    }
+    pByteToTransmit++;
+    pReceivedByte++;
+  }
+  HAL_GPIO_WritePin(BSP_MOTOR_CONTROL_BOARD_CS_PORT, BSP_MOTOR_CONTROL_BOARD_CS_PIN, GPIO_PIN_SET); 
+  
+  return (uint8_t) status;  
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */    
+
+/**
+  * @}
+  */ 
+#endif    
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IHM01A1/stm32l0xx_nucleo_ihm01a1.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,337 @@
+/** 
+  ******************************************************************************
+  * @file    stm32l0xx_nucleo_ihm01a1.h
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   Header for BSP driver for x-nucleo-ihm01a1 Nucleo extension board 
+  *  (based on L6474)
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************  
+  */ 
+  
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32L0XX_NUCLEO_IHM01A1_H
+#define __STM32L0XX_NUCLEO_IHM01A1_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+//#include "stm32l0xx_nucleo.h"
+   
+/** @addtogroup BSP
+  * @{
+  */   
+   
+/** @addtogroup STM32L0XX_NUCLEO_IHM01A1
+  * @{   
+  */   
+   
+/** @defgroup IHM01A1_Board_Private_Function_Prototypes
+  * @{
+  */   
+   
+void BSP_MotorControlBoard_Delay(uint32_t delay);         //Delay of the requested number of milliseconds
+void BSP_MotorControlBoard_DisableIrq(void);              //Disable Irq
+void BSP_MotorControlBoard_EnableIrq(void);               //Enable Irq
+void BSP_MotorControlBoard_GpioInit(uint8_t nbDevices);   //Initialise GPIOs used for L6474s
+void BSP_MotorControlBoard_Pwm1SetFreq(uint16_t newFreq); //Set PWM1 frequency and start it
+void BSP_MotorControlBoard_Pwm2SetFreq(uint16_t newFreq); //Set PWM2 frequency and start it  
+void BSP_MotorControlBoard_Pwm3SetFreq(uint16_t newFreq); //Set PWM3 frequency and start it
+void BSP_MotorControlBoard_PwmInit(uint8_t deviceId);    //Init the PWM of the specified device
+void BSP_MotorControlBoard_PwmStop(uint8_t deviceId);    //Stop the PWM of the specified device
+void BSP_MotorControlBoard_ReleaseReset(void);           //Reset the L6474 reset pin 
+void BSP_MotorControlBoard_Reset(void);                  //Set the L6474 reset pin 
+void BSP_MotorControlBoard_SetDirectionGpio(uint8_t deviceId, uint8_t gpioState); //Set direction GPIO
+uint8_t BSP_MotorControlBoard_SpiInit(void);   //Initialise the SPI used for L6474s
+uint8_t BSP_MotorControlBoard_SpiWriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte, uint8_t nbDevices); //Write bytes to the L6474s via SPI
+
+
+/* Exported Constants --------------------------------------------------------*/
+   
+/** @defgroup IHM01A1_Exported_Constants
+  * @{
+  */   
+   
+/******************************************************************************/
+/* USE_STM32L0XX_NUCLEO                                                       */
+/******************************************************************************/
+
+ /** @defgroup Constants_For_STM32L0XX_NUCLEO  
+* @{
+*/   
+/// Interrupt line used for L6474 FLAG
+#define EXTI_MCU_LINE_IRQn           (EXTI4_15_IRQn)
+
+/// Timer used for PWM1
+#define BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1      (TIM22)
+
+/// Timer used for PWM2
+#define BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2      (TIM2)
+
+/// Timer used for PWM3
+#define BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3      (TIM21)
+
+/// Channel Timer used for PWM1
+#define BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM1      (TIM_CHANNEL_2)
+
+/// Channel Timer used for PWM2
+#define BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM2      (TIM_CHANNEL_2)
+
+/// Channel Timer used for PWM3
+#define BSP_MOTOR_CONTROL_BOARD_CHAN_TIMER_PWM3      (TIM_CHANNEL_1)
+
+/// HAL Active Channel Timer used for PWM1
+#define BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM1      (HAL_TIM_ACTIVE_CHANNEL_2)
+
+/// HAL Active Channel Timer used for PWM2
+#define BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM2      (HAL_TIM_ACTIVE_CHANNEL_2)
+
+/// HAL Active Channel Timer used for PWM3
+#define BSP_MOTOR_CONTROL_BOARD_HAL_ACT_CHAN_TIMER_PWM3      (HAL_TIM_ACTIVE_CHANNEL_1)
+
+/// Timer Clock Enable for PWM1
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_ENABLE()  __TIM22_CLK_ENABLE()
+
+/// Timer Clock Enable for PWM2
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_ENABLE()    __TIM2_CLK_ENABLE()
+
+/// Timer Clock Enable for PWM1
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_ENABLE()    __TIM21_CLK_ENABLE()
+
+/// Timer Clock Disable for PWM1
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM1_CLCK_DISABLE()  __TIM22_CLK_DISABLE()
+
+/// Timer Clock Disable for PWM2
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM2_CLCK_DISABLE()    __TIM2_CLK_DISABLE()
+
+/// Timer Clock Disable for PWM3
+#define __BSP_MOTOR_CONTROL_BOARD_TIMER_PWM3_CLCK_DISABLE()    __TIM21_CLK_DISABLE()
+
+/// PWM1 global interrupt
+#define BSP_MOTOR_CONTROL_BOARD_PWM1_IRQn   (TIM22_IRQn)
+
+/// PWM2 global interrupt
+#define BSP_MOTOR_CONTROL_BOARD_PWM2_IRQn   (TIM2_IRQn)
+
+/// PWM3 global interrupt
+#define BSP_MOTOR_CONTROL_BOARD_PWM3_IRQn   (TIM21_IRQn)
+
+/// PWM1 GPIO alternate function 
+#define BSP_MOTOR_CONTROL_BOARD_AFx_TIMx_PWM1  (GPIO_AF0_TIM22)
+
+/// PWM2 GPIO alternate function 
+#define BSP_MOTOR_CONTROL_BOARD_AFx_TIMx_PWM2  (GPIO_AF2_TIM2)
+
+#ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2
+/// SPI SCK AF
+#define SPIx_SCK_AF    (GPIO_AF0_SPI1)
+#else /* #ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2 */
+/// SPI SCK AF
+#define SPIx_SCK_AF    (GPIO_AF0_SPI2)
+#endif /* #ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2 */
+
+/// PWM1 frequency rescaler (1 for HW PWM, 2 for SW PWM)
+#define BSP_MOTOR_CONTROL_BOARD_PWM1_FREQ_RESCALER    (1)   
+/// PWM2 frequency rescaler (1 for HW PWM, 2 for SW PWM)
+#define BSP_MOTOR_CONTROL_BOARD_PWM2_FREQ_RESCALER    (1)   
+/// PWM3 frequency rescaler (1 for HW PWM, 2 for SW PWM)   
+#define BSP_MOTOR_CONTROL_BOARD_PWM3_FREQ_RESCALER    (2)  
+   
+ /**
+* @}
+*/
+
+/******************************************************************************/
+/* Independent plateform definitions                                          */
+/******************************************************************************/
+
+   /** @defgroup Constants_For_All_Nucleo_Platforms
+* @{
+*/   
+
+/// GPIO Pin used for the L6474 flag pin
+#define BSP_MOTOR_CONTROL_BOARD_FLAG_PIN   (GPIO_PIN_10)
+/// GPIO port used for the L6474 flag pin
+#define BSP_MOTOR_CONTROL_BOARD_FLAG_PORT   (GPIOA)
+
+/// GPIO Pin used for the L6474 step clock pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_PWM_1_PIN  (GPIO_PIN_7)
+/// GPIO Port used for the L6474 step clock pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_PWM_1_PORT  (GPIOC)
+
+/// GPIO Pin used for the L6474 step clock pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_PWM_2_PIN  (GPIO_PIN_3)
+/// GPIO port used for the L6474 step clock pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_PWM_2_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 step clock pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_PWM_3_PIN   (GPIO_PIN_10)
+/// GPIO port used for the L6474 step clock pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_PWM_3_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 direction pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_DIR_1_PIN  (GPIO_PIN_8)
+/// GPIO port used for the L6474 direction pin of device 0
+#define BSP_MOTOR_CONTROL_BOARD_DIR_1_PORT  (GPIOA)
+
+/// GPIO Pin used for the L6474 direction pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_DIR_2_PIN   (GPIO_PIN_5)
+/// GPIO port used for the L6474 direction pin of device 1
+#define BSP_MOTOR_CONTROL_BOARD_DIR_2_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 direction pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_DIR_3_PIN   (GPIO_PIN_4)
+/// GPIO port used for the L6474 direction pin of device 2
+#define BSP_MOTOR_CONTROL_BOARD_DIR_3_PORT  (GPIOB)
+
+/// GPIO Pin used for the L6474 reset pin
+#define BSP_MOTOR_CONTROL_BOARD_RESET_PIN  (GPIO_PIN_9)
+/// GPIO port used for the L6474 reset pin
+#define BSP_MOTOR_CONTROL_BOARD_RESET_PORT (GPIOA)
+
+/// GPIO Pin used for the L6474 SPI chip select pin
+#define BSP_MOTOR_CONTROL_BOARD_CS_PIN  (GPIO_PIN_6)
+/// GPIO port used for the L6474 SPI chip select  pin
+#define BSP_MOTOR_CONTROL_BOARD_CS_PORT (GPIOB)
+
+/* Definition for SPIx clock resources */
+
+#ifndef BSP_MOTOR_CONTROL_BOARD_USE_SPI2
+/* Default SPI is SPI1 */
+
+/// Used SPI
+#define SPIx                             (SPI1)
+
+/// SPI clock enable
+#define SPIx_CLK_ENABLE()                __SPI1_CLK_ENABLE()
+
+/// SPI SCK enable
+#define SPIx_SCK_GPIO_CLK_ENABLE()       __GPIOA_CLK_ENABLE()
+
+/// SPI MISO enable
+#define SPIx_MISO_GPIO_CLK_ENABLE()      __GPIOA_CLK_ENABLE() 
+
+/// SPI MOSI enable
+#define SPIx_MOSI_GPIO_CLK_ENABLE()      __GPIOA_CLK_ENABLE() 
+
+/// SPI Force reset
+#define SPIx_FORCE_RESET()               __SPI1_FORCE_RESET()
+
+/// SPI Release reset
+#define SPIx_RELEASE_RESET()             __SPI1_RELEASE_RESET()
+
+/// SPI SCK pin
+#define SPIx_SCK_PIN                     (GPIO_PIN_5)
+
+/// SPI SCK port
+#define SPIx_SCK_GPIO_PORT               (GPIOA)
+
+
+/// SPI MISO pin 
+#define SPIx_MISO_PIN                    (GPIO_PIN_6)
+
+/// SPI MISO port
+#define SPIx_MISO_GPIO_PORT              (GPIOA)
+
+/// SPI MOSI pin
+#define SPIx_MOSI_PIN                    (GPIO_PIN_7)
+
+/// SPI MOSI port
+#define SPIx_MOSI_GPIO_PORT              (GPIOA)
+
+#else  /* USE SPI2 */
+
+/// Used SPI
+#define SPIx                             (SPI2)
+
+/// SPI clock enable
+#define SPIx_CLK_ENABLE()                __SPI2_CLK_ENABLE()
+
+/// SPI SCK enable
+#define SPIx_SCK_GPIO_CLK_ENABLE()       __GPIOB_CLK_ENABLE()
+
+/// SPI MISO enable
+#define SPIx_MISO_GPIO_CLK_ENABLE()      __GPIOB_CLK_ENABLE() 
+
+/// SPI MOSI enable
+#define SPIx_MOSI_GPIO_CLK_ENABLE()      __GPIOB_CLK_ENABLE() 
+
+/// SPI Force reset
+#define SPIx_FORCE_RESET()               __SPI2_FORCE_RESET()
+
+/// SPI Release reset
+#define SPIx_RELEASE_RESET()             __SPI2_RELEASE_RESET()
+
+/// SPI SCK pin
+#define SPIx_SCK_PIN                     (GPIO_PIN_13)
+
+/// SPI SCK port
+#define SPIx_SCK_GPIO_PORT               (GPIOB)
+
+/// SPI MISO pin 
+#define SPIx_MISO_PIN                    (GPIO_PIN_14)
+
+/// SPI MISO port
+#define SPIx_MISO_GPIO_PORT              (GPIOB)
+
+/// SPI MISO AF 
+#define SPIx_MISO_AF                     (SPIx_SCK_AF)
+  
+/// SPI MOSI pin
+#define SPIx_MOSI_PIN                    (GPIO_PIN_15)
+
+/// SPI MOSI port
+#define SPIx_MOSI_GPIO_PORT              (GPIOB)
+
+#endif
+   
+/// SPI MISO AF 
+#define SPIx_MISO_AF                     (SPIx_SCK_AF)
+
+/// SPI MOSI AF
+#define SPIx_MOSI_AF                     (SPIx_SCK_AF)
+   
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32L0XX_NUCLEO_IHM01A1_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,442 @@
+/**
+  ******************************************************************************
+  * @file    Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Src/main.c 
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   This example shows how to use 1 IHM01A1 expansion board
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include "main.h"
+
+/** @defgroup IHM01A1_Example_for_1_motor_device
+  * @{
+  */ 
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+ static volatile uint16_t gLastError;
+
+/* Private function prototypes -----------------------------------------------*/
+static void MyFlagInterruptHandler(void);
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+  * @brief  Main program
+  * @param  None
+  * @retval None
+  */
+int main(void)
+{
+  int32_t pos;
+  uint16_t mySpeed;
+
+  /* STM32xx HAL library initialization */
+//  HAL_Init();
+  
+  /* Configure the system clock */
+//mbed  SystemClock_Config();
+    
+//----- Init of the Motor control library 
+  /* Start the L6474 library to use 1 device */
+  /* The L6474 registers are set with the predefined values */
+  /* from file l6474_target_config.h*/
+  BSP_MotorControl_Init(BSP_MOTOR_CONTROL_BOARD_ID_L6474, 1);
+  
+  /* Attach the function MyFlagInterruptHandler (defined below) to the flag interrupt */
+  BSP_MotorControl_AttachFlagInterrupt(MyFlagInterruptHandler);
+
+  /* Attach the function Error_Handler (defined below) to the error Handler*/
+  BSP_MotorControl_AttachErrorHandler(Error_Handler);
+
+//----- Move of 16000 steps in the FW direction
+
+  /* Move device 0 of 16000 steps in the FORWARD direction*/
+  BSP_MotorControl_Move(0, FORWARD, 16000);
+
+  /* Wait for the motor of device 0 ends moving */
+  BSP_MotorControl_WaitWhileActive(0);
+
+  /* Wait for 2 seconds */
+  HAL_Delay(2000);  
+  
+//----- Move of 16000 steps in the BW direction
+
+  /* Move device 0 of 16000 steps in the BACKWARD direction*/
+  BSP_MotorControl_Move(0, BACKWARD, 16000);
+
+  /* Wait for the motor of device 0 ends moving */
+  BSP_MotorControl_WaitWhileActive(0);
+
+   /* Set the current position of device 0 to be the Home position */
+  BSP_MotorControl_SetHome(0);
+  
+  /* Wait for 2 seconds */
+  HAL_Delay(2000);
+
+//----- Go to position -6400
+
+  /* Request device 0 to go to position -6400 */
+  BSP_MotorControl_GoTo(0,-6400);  
+  
+  /* Wait for the motor ends moving */
+  BSP_MotorControl_WaitWhileActive(0);
+
+  /* Get current position of device 0*/
+  pos = BSP_MotorControl_GetPosition(0);
+
+  if (pos != -6400) 
+  {
+    Error_Handler(11);
+  }
+  
+  /* Set the current position of device 0 to be the Mark position */
+  BSP_MotorControl_SetMark(0);
+
+  /* Wait for 2 seconds */
+  HAL_Delay(2000);
+  
+//----- Go Home
+
+  /* Request device 0 to go to Home */
+  BSP_MotorControl_GoHome(0);  
+  BSP_MotorControl_WaitWhileActive(0);
+
+  /* Get current position of device 0 */
+  pos = BSP_MotorControl_GetPosition(0);
+  
+  /* Wait for 2 seconds */
+  HAL_Delay(2000);
+
+//----- Go to position 6400
+
+  /* Request device 0 to go to position 6400 */
+  BSP_MotorControl_GoTo(0,6400);  
+  
+  /* Wait for the motor of device 0 ends moving */
+  BSP_MotorControl_WaitWhileActive(0);
+
+  /* Get current position of device 0*/
+  pos = BSP_MotorControl_GetPosition(0);
+
+  /* Wait for 2 seconds */
+  HAL_Delay(2000);
+  
+//----- Go Mark which was set previously after go to -6400
+
+  /* Request device 0 to go to Mark position */
+  BSP_MotorControl_GoMark(0);  
+  
+  /* Wait for the motor of device 0 ends moving */
+  BSP_MotorControl_WaitWhileActive(0);
+
+  /* Get current position of device 0 */
+  pos = BSP_MotorControl_GetPosition(0);
+
+  /* Wait for 2 seconds */
+  HAL_Delay(2000);
+
+//----- Run the motor BACKWARD
+
+  /* Request device 0 to run BACKWARD */
+   BSP_MotorControl_Run(0,BACKWARD);       
+   HAL_Delay(5000);
+
+   /* Get current speed of device 0 */
+   mySpeed = BSP_MotorControl_GetCurrentSpeed(0);
+
+//----- Increase the speed while running
+
+  /* Increase speed of device 0 to 2400 step/s */
+  BSP_MotorControl_SetMaxSpeed(0,4800);
+  HAL_Delay(9000);
+
+   /* Get current speed of device 0 */
+   mySpeed = BSP_MotorControl_GetCurrentSpeed(0);
+
+//----- Decrease the speed while running
+
+  /* Decrease speed of device 0 to 1200 step/s */
+  BSP_MotorControl_SetMaxSpeed(0,1200);
+  HAL_Delay(5000);
+
+  /* Get current speed */
+  mySpeed = BSP_MotorControl_GetCurrentSpeed(0);
+
+//----- Increase acceleration while running
+
+  /* Increase acceleration of device 0 to 480 step/s^2 */
+  BSP_MotorControl_SetAcceleration(0,480);
+  HAL_Delay(5000);
+
+  /* Increase speed of device 0 to 2400 step/s */
+  BSP_MotorControl_SetMaxSpeed(0,2400);
+  HAL_Delay(5000);
+
+  /* Get current speed of device 0 */
+  mySpeed = BSP_MotorControl_GetCurrentSpeed(0);
+
+  if (mySpeed != 2400)
+  {
+    Error_Handler(10);
+  }
+//----- Increase deceleration while running
+
+  /* Increase deceleration of device 0 to 480 step/s^2 */
+  BSP_MotorControl_SetDeceleration(0,480);
+  HAL_Delay(5000);
+
+  /* Decrease speed of device 0 to 1200 step/s */
+  BSP_MotorControl_SetMaxSpeed(0,1200);
+  HAL_Delay(5000);
+
+  /* Get current speed */
+  mySpeed = BSP_MotorControl_GetCurrentSpeed(0);
+
+//----- Soft stopped required while running
+
+  /* Request soft stop of device 0 */
+  BSP_MotorControl_SoftStop(0);
+
+  /* Wait for the motor of device 0 ends moving */  
+  BSP_MotorControl_WaitWhileActive(0);
+
+  /* Wait for 2 seconds */
+  HAL_Delay(2000);
+
+//----- Run stopped by hardstop
+
+  /* Request device 0 to run in FORWARD direction */
+  BSP_MotorControl_Run(0,FORWARD);       
+  HAL_Delay(5000);
+  
+  /* Request device 0 to immediatly stop */
+  BSP_MotorControl_HardStop(0);
+  BSP_MotorControl_WaitWhileActive(0);
+
+  /* Wait for 2 seconds */
+  HAL_Delay(2000);
+  
+//----- GOTO stopped by softstop
+
+ /* Request device 0 to go to position 20000  */
+  BSP_MotorControl_GoTo(0,20000);  
+  HAL_Delay(5000);
+
+  /* Request device 0 to perform a soft stop */
+  BSP_MotorControl_SoftStop(0);
+  BSP_MotorControl_WaitWhileActive(0);
+
+  /* Wait for 2 seconds */
+  HAL_Delay(2000);  
+
+  //----- Read inexistent register to test MyFlagInterruptHandler
+
+  /* Try to read an inexistent register */
+  /* the flag interrupt should be raised */
+  /* and the MyFlagInterruptHandler function called */
+  BSP_MotorControl_CmdGetParam(0,0x1F);
+  HAL_Delay(500);
+
+//----- Change step mode to full step mode
+
+  /* Select full step mode for device 0 */
+   BSP_MotorControl_SelectStepMode(0,STEP_MODE_FULL);
+
+  /* Set speed and acceleration to be consistent with full step mode */
+   BSP_MotorControl_SetMaxSpeed(0,100);
+   BSP_MotorControl_SetMinSpeed(0,50);
+   BSP_MotorControl_SetAcceleration(0,10);
+   BSP_MotorControl_SetDeceleration(0,10);
+
+  /* Request device 0 to go position 200 */
+   BSP_MotorControl_GoTo(0,200);  
+
+  /* Wait for the motor of device 0 ends moving */
+   BSP_MotorControl_WaitWhileActive(0);
+
+  /* Get current position */
+  pos =  BSP_MotorControl_GetPosition(0);
+
+  /* Wait for 2 seconds */
+  HAL_Delay(2000);
+  
+//----- Restore 1/16 microstepping mode
+
+  /* Reset device 0 to 1/16 microstepping mode */
+  BSP_MotorControl_SelectStepMode(0,STEP_MODE_1_16);   //_FULL _HALF 1_16  
+
+  /* Update speed, acceleration, deceleration for 1/16 microstepping mode*/
+  BSP_MotorControl_SetMaxSpeed(0,40000);
+  BSP_MotorControl_SetMinSpeed(0,800);
+  BSP_MotorControl_SetAcceleration(0,160);
+  BSP_MotorControl_SetDeceleration(0,160);  
+  
+  /* Infinite loop */
+  while(1)
+  {
+    /* Request device 0 to go position -6400 */
+    BSP_MotorControl_GoTo(0,-6400);
+
+    /* Wait for the motor of device 0 ends moving */
+    BSP_MotorControl_WaitWhileActive(0);
+
+    /* Request device 0 to go position 6400 */
+    BSP_MotorControl_GoTo(0,6400);
+
+    /* Wait for the motor of device 0 ends moving */
+    BSP_MotorControl_WaitWhileActive(0);  
+  }
+}
+
+/**
+  * @brief  This function is the User handler for the flag interrupt
+  * @param  None
+  * @retval None
+  */
+void MyFlagInterruptHandler(void)
+{
+  /* Get the value of the status register via the L6474 command GET_STATUS */
+  uint16_t statusRegister = BSP_MotorControl_CmdGetStatus(0);
+  
+  /* Check HIZ flag: if set, power brigdes are disabled */
+  if ((statusRegister & L6474_STATUS_HIZ) == L6474_STATUS_HIZ)
+  {
+    // HIZ state
+    // Action to be customized            
+  }
+
+  /* Check direction bit */
+  if ((statusRegister & L6474_STATUS_DIR) == L6474_STATUS_DIR)
+  {
+    // Forward direction is set
+    // Action to be customized            
+  }  
+  else
+  {
+    // Backward direction is set
+    // Action to be customized            
+  }  
+
+  /* Check NOTPERF_CMD flag: if set, the command received by SPI can't be performed */
+  /* This often occures when a command is sent to the L6474 */
+  /* while it is in HIZ state */
+  if ((statusRegister & L6474_STATUS_NOTPERF_CMD) == L6474_STATUS_NOTPERF_CMD)
+  {
+      // Command received by SPI can't be performed
+     // Action to be customized            
+  }  
+
+  /* Check WRONG_CMD flag: if set, the command does not exist */
+  if ((statusRegister & L6474_STATUS_WRONG_CMD) == L6474_STATUS_WRONG_CMD)
+  {
+     //command received by SPI does not exist 
+     // Action to be customized          
+  }  
+
+  /* Check UVLO flag: if not set, there is an undervoltage lock-out */
+  if ((statusRegister & L6474_STATUS_UVLO) == 0)
+  {
+     //undervoltage lock-out 
+     // Action to be customized          
+  }  
+
+  /* Check TH_WRN flag: if not set, the thermal warning threshold is reached */
+  if ((statusRegister & L6474_STATUS_TH_WRN) == 0)
+  {
+    //thermal warning threshold is reached
+    // Action to be customized          
+  }    
+
+  /* Check TH_SHD flag: if not set, the thermal shut down threshold is reached */
+  if ((statusRegister & L6474_STATUS_TH_SD) == 0)
+  {
+    //thermal shut down threshold is reached 
+    // Action to be customized          
+  }    
+
+  /* Check OCD  flag: if not set, there is an overcurrent detection */
+  if ((statusRegister & L6474_STATUS_OCD) == 0)
+  {
+    //overcurrent detection 
+    // Action to be customized          
+  }      
+ 
+}
+
+/**
+  * @brief  This function is executed in case of error occurrence.
+  * @param  error number of the error
+  * @retval None
+  */
+void Error_Handler(uint16_t error)
+{
+  /* Backup error number */
+  gLastError = error;
+  
+  /* Infinite loop */
+  while(1)
+  {
+  }
+}
+
+#ifdef  USE_FULL_ASSERT
+
+/**
+  * @brief  Reports the name of the source file and the source line number
+  *         where the assert_param error has occurred.
+  * @param  file: pointer to the source file name
+  * @param  line: assert_param error line source number
+  * @retval None
+  */
+void assert_failed(uint8_t* file, uint32_t line)
+{ 
+  /* User can add his own implementation to report the file name and line number,
+     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+
+  /* Infinite loop */
+  while (1)
+  {
+  }
+}
+#endif
+
+/**
+  * @}
+  */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,65 @@
+
+/**
+  ******************************************************************************
+  * @file    Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Inc/main.h
+  * @author  IPC Rennes
+  * @version V1.5.0
+  * @date    November 12, 2014
+  * @brief   Header for main.c module
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MAIN_H
+#define __MAIN_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "motorcontrol.h"
+#include "l6474.h"
+
+#if defined TARGET_STM32F4
+#include "stm32f4xx_nucleo_ihm01a1.h"
+#elif defined TARGET_STM32F0
+#include "stm32f0xx_nucleo_ihm01a1.h"
+#elif defined TARGET_STM32L0
+#include "stm32l0xx_nucleo_ihm01a1.h"
+#else
+#error Unknown Target: only STM32F0xx, F4xx, L0xx are supported.
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void SystemClock_Config(void);
+void Error_Handler(uint16_t error);
+
+#endif /* __MAIN_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Sep 05 20:18:14 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/ba1f97679dad
\ No newline at end of file