motor control

Dependents:   1-DoorCloser

Fork of X_NUCLEO_IHM01A1 by Robotique FIP

Files at this revision

API Documentation at this revision

Comitter:
Davidroid
Date:
Wed Nov 18 18:41:55 2015 +0000
Parent:
4:83a1eb397a65
Child:
6:a47569fc7534
Commit message:
+ SPI registers set as static variables and as arrays of MAX_NUMBER_OF_DEVICES, in order to support daisy-chain configuration.; + Direction type "StepperMotor::direction_t" modified.

Changed in this revision

Components/Common/motor.h Show annotated file Show diff for this revision Revisions of this file
Components/Interfaces/StepperMotor_class.h Show annotated file Show diff for this revision Revisions of this file
Components/l6474/l6474.h Show annotated file Show diff for this revision Revisions of this file
Components/l6474/l6474_class.cpp Show annotated file Show diff for this revision Revisions of this file
Components/l6474/l6474_class.h Show annotated file Show diff for this revision Revisions of this file
--- a/Components/Common/motor.h	Fri Nov 13 12:56:06 2015 +0000
+++ b/Components/Common/motor.h	Wed Nov 18 18:41:55 2015 +0000
@@ -172,7 +172,6 @@
   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
@@ -183,7 +182,6 @@
   volatile uint16_t minSpeed;      
   /// current speed in pps    
   volatile uint16_t speed;         
-  
   /// command under execution
   volatile deviceCommand_t commandExecuted; 
   /// FORWARD or BACKWARD direction
--- a/Components/Interfaces/StepperMotor_class.h	Fri Nov 13 12:56:06 2015 +0000
+++ b/Components/Interfaces/StepperMotor_class.h	Wed Nov 18 18:41:55 2015 +0000
@@ -58,8 +58,8 @@
     /** Rotation modes. */
     typedef enum
     {
-        CW = 0, /* Clockwise. */
-        CCW     /* Counter-Clockwise. */
+      BWD = 0, /* Backward. */
+      FWD = 1  /* Forward. */
     } direction_t;
 
     /* Get the status. */
@@ -74,9 +74,6 @@
     /* Return the mark position. */
     virtual signed int GetMark(void) = 0;
 
-    /* Get the current direction of rotation. */
-    virtual direction_t GetDirection(void) = 0;
-
     /* Return the current speed in pps. */
     virtual unsigned int GetSpeed(void) = 0;
 
@@ -92,6 +89,9 @@
     /* Return the deceleration in pps^2. */
     virtual unsigned int GetDeceleration(void) = 0;
 
+    /* Get the current direction of rotation. */
+    virtual direction_t GetDirection(void) = 0;
+
     /* Set the specified parameter. */
     virtual void SetParameter(unsigned int parameter, unsigned int value) = 0;
 
@@ -101,9 +101,6 @@
     /* Set the current position to be the mark position. */
     virtual void SetMark(void) = 0;
 
-    /* Set the direction of rotation. */
-    virtual void SetDirection(direction_t direction) = 0;
-
     /* Set the maximum speed in pps. */
     virtual void SetMaxSpeed(unsigned int speed) = 0;
 
--- a/Components/l6474/l6474.h	Fri Nov 13 12:56:06 2015 +0000
+++ b/Components/l6474/l6474.h	Wed Nov 18 18:41:55 2015 +0000
@@ -444,14 +444,14 @@
   void (*flagInterruptCallback)(void);
   /// Function pointer to error handler call back
   void (*errorHandlerCallback)(uint16_t error);
-  uint8_t spiTxBursts[L6474_CMD_ARG_MAX_NB_BYTES]; //[MAX_NUMBER_OF_DEVICES];
-  uint8_t spiRxBursts[L6474_CMD_ARG_MAX_NB_BYTES]; //[MAX_NUMBER_OF_DEVICES];
   bool spiPreemtionByIsr; // = FALSE;
   bool isrFlag; // = FALSE;
   /// L6474 Device Paramaters structure
   deviceParams_t devicePrm; //[MAX_NUMBER_OF_DEVICES];
   uint8_t numberOfDevices;
   uint8_t deviceInstance;
+  uint8_t spiTxBursts[L6474_CMD_ARG_MAX_NB_BYTES][MAX_NUMBER_OF_DEVICES];
+  uint8_t spiRxBursts[L6474_CMD_ARG_MAX_NB_BYTES][MAX_NUMBER_OF_DEVICES];
 } L6474_DrvDataTypeDef;
 
 
--- a/Components/l6474/l6474_class.cpp	Fri Nov 13 12:56:06 2015 +0000
+++ b/Components/l6474/l6474_class.cpp	Wed Nov 18 18:41:55 2015 +0000
@@ -58,12 +58,12 @@
 /* Private constants ---------------------------------------------------------*/    
 
 /// Error while initialising the SPI
-#define L6474_ERROR_0   (0x8000)   
+#define L6474_ERROR_0        (0x8000)   
 /// Error: Bad SPI transaction
-#define L6474_ERROR_1   (0x8001)
+#define L6474_ERROR_1        (0x8001)
     
 /// Maximum number of steps
-#define MAX_STEPS         (0x7FFFFFFF)
+#define MAX_STEPS            (0x7FFFFFFF)
 
 /// Maximum frequency of the PWMs in Hz
 #define L6474_MAX_PWM_FREQ   (10000)
@@ -77,10 +77,14 @@
 /* Number of devices. */
 uint8_t L6474::numberOfDevices = 0;
 
+/* SPI Transmission for Daisy-Chain Configuration. */
+uint8_t L6474::spiTxBursts[L6474_CMD_ARG_MAX_NB_BYTES][MAX_NUMBER_OF_DEVICES];
+uint8_t L6474::spiRxBursts[L6474_CMD_ARG_MAX_NB_BYTES][MAX_NUMBER_OF_DEVICES];
+
 
 /* Methods -------------------------------------------------------------------*/
 
-/******************************************************//**
+/**********************************************************
  * @brief  Attaches a user callback to the error Handler.
  * The call back will be then called each time the library 
  * detects an error
@@ -93,7 +97,7 @@
   errorHandlerCallback = (void (*)(uint16_t error)) 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 
@@ -108,7 +112,7 @@
   flagInterruptCallback = (void (*)(void))callback;
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief Starts the L6474 library
  * @retval COMPONENT_OK in case of success
  **********************************************************/
@@ -137,7 +141,7 @@
   return COMPONENT_OK;
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief Read id
  * @param id pointer to the identifier to be read.
  * @retval COMPONENT_OK in case of success
@@ -149,7 +153,7 @@
   return COMPONENT_OK;
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief Returns the acceleration of the specified device
  * @retval Acceleration in pps^2
  **********************************************************/
@@ -158,7 +162,7 @@
   return (devicePrm.acceleration);
 }            
 
-/******************************************************//**
+/**********************************************************
  * @brief Returns the current speed of the specified device
  * @retval Speed in pps
  **********************************************************/
@@ -167,7 +171,7 @@
   return devicePrm.speed;
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief Returns the deceleration of the specified device
  * @retval Deceleration in pps^2
  **********************************************************/
@@ -176,7 +180,7 @@
   return (devicePrm.deceleration);
 }          
 
-/******************************************************//**
+/**********************************************************
  * @brief Returns the device state
  * @retval State (ACCELERATING, DECELERATING, STEADY or INACTIVE)
  **********************************************************/
@@ -185,7 +189,7 @@
   return devicePrm.motionState;
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief Returns the FW version of the library
  * @param None
  * @retval L6474_FW_VERSION
@@ -195,7 +199,7 @@
   return (L6474_FW_VERSION);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Returns the mark position  of the specified device
  * @retval Mark register value converted in a 32b signed integer 
  **********************************************************/
@@ -204,7 +208,7 @@
   return L6474_ConvertPosition(L6474_CmdGetParam(L6474_MARK));
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Returns the max speed of the specified device
  * @retval maxSpeed in pps
  **********************************************************/
@@ -213,7 +217,7 @@
   return (devicePrm.maxSpeed);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Returns the min speed of the specified device
  * @retval minSpeed in pps
  **********************************************************/
@@ -222,7 +226,7 @@
   return (devicePrm.minSpeed);
 }                                                     
 
-/******************************************************//**
+/**********************************************************
  * @brief  Returns the ABS_POSITION of the specified device
  * @retval ABS_POSITION register value converted in a 32b signed integer
  **********************************************************/
@@ -231,7 +235,7 @@
   return L6474_ConvertPosition(L6474_CmdGetParam(L6474_ABS_POS));
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Requests the motor to move to the home position (ABS_POSITION = 0)
  * @retval None
  **********************************************************/
@@ -240,7 +244,7 @@
   L6474_GoTo(0);
 } 
   
-/******************************************************//**
+/**********************************************************
  * @brief  Requests the motor to move to the mark position 
  * @retval None
  **********************************************************/
@@ -252,14 +256,14 @@
     L6474_GoTo(mark);  
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Requests the motor to move to the specified position 
  * @param[in] targetPosition absolute position in steps
  * @retval None
  **********************************************************/
 void L6474::L6474_GoTo(int32_t targetPosition)
 {
-  direction_t direction;
+  motorDir_t direction;
   int32_t steps;
   
   /* Eventually deactivate motor */
@@ -277,12 +281,12 @@
   if (steps >= 0) 
   {
     devicePrm.stepsToTake = steps;
-    direction = CW;
+    direction = FORWARD;
   } 
   else 
   {
     devicePrm.stepsToTake = -steps;
-    direction = CCW;
+    direction = BACKWARD;
   }
   
   if (steps != 0) 
@@ -299,7 +303,7 @@
   }  
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Immediatly stops the motor and disable the power bridge
  * @retval None
  **********************************************************/
@@ -317,13 +321,13 @@
   devicePrm.stepsToTake = MAX_STEPS;  
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Moves the motor of the specified number of steps
  * @param[in] direction FORWARD or BACKWARD
  * @param[in] stepCount Number of steps to perform
  * @retval None
  **********************************************************/
-void L6474::L6474_Move(direction_t direction, uint32_t stepCount)
+void L6474::L6474_Move(motorDir_t direction, uint32_t stepCount)
 {
   /* Eventually deactivate motor */
   if (devicePrm.motionState != INACTIVE) 
@@ -350,7 +354,7 @@
 }
 
 #if 0
-/******************************************************//**
+/**********************************************************
  * @brief Resets all L6474 devices
  * @param None
  * @retval None
@@ -371,13 +375,13 @@
 }
 #endif
 
-/******************************************************//**
+/**********************************************************
  * @brief  Runs the motor. It will accelerate from the min 
  * speed up to the max speed by using the device acceleration.
  * @param[in] direction FORWARD or BACKWARD
  * @retval None
  **********************************************************/
-void L6474::L6474_Run(direction_t direction)
+void L6474::L6474_Run(motorDir_t direction)
 {
   /* Eventually deactivate motor */
   if (devicePrm.motionState != INACTIVE) 
@@ -394,7 +398,7 @@
   L6474_StartMovement(); 
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Changes the acceleration of the specified device
  * @param[in] newAcc New acceleration to apply in pps^2
  * @retval true if the command is successfully executed, else false
@@ -414,7 +418,7 @@
   return cmdExecuted;
 }            
 
-/******************************************************//**
+/**********************************************************
  * @brief  Changes the deceleration of the specified device
  * @param[in] newDec New deceleration to apply in pps^2
  * @retval true if the command is successfully executed, else false
@@ -434,7 +438,7 @@
   return cmdExecuted;
 }        
 
-/******************************************************//**
+/**********************************************************
  * @brief  Set current position to be the Home position (ABS pos set to 0)
  * @retval None
  **********************************************************/
@@ -443,7 +447,7 @@
   L6474_CmdSetParam(L6474_ABS_POS, 0);
 }
  
-/******************************************************//**
+/**********************************************************
  * @brief  Sets current position to be the Mark position 
  * @retval None
  **********************************************************/
@@ -453,7 +457,7 @@
   L6474_CmdSetParam(L6474_MARK, mark);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Changes the max speed of the specified device
  * @param[in] newMaxSpeed New max speed  to apply in pps
  * @retval true if the command is successfully executed, else false
@@ -475,7 +479,7 @@
   return cmdExecuted;
 }                                                     
 
-/******************************************************//**
+/**********************************************************
  * @brief  Changes the min speed of the specified device
  * @param[in] newMinSpeed New min speed  to apply in pps
  * @retval true if the command is successfully executed, else false
@@ -497,7 +501,7 @@
   return cmdExecuted;
 }                 
 
-/******************************************************//**
+/**********************************************************
  * @brief  Stops the motor by using the device deceleration
  * @retval true if the command is successfully executed, else false
  * @note The command is not performed is the device is in INACTIVE state.
@@ -513,7 +517,7 @@
   return (cmdExecuted);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Locks until the device state becomes Inactive
  * @retval None
  **********************************************************/
@@ -523,7 +527,7 @@
   while (L6474_GetDeviceState() != INACTIVE);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Issue the Disable command to the L6474 of the specified device
  * @retval None
  **********************************************************/
@@ -532,7 +536,7 @@
   L6474_SendCommand(L6474_DISABLE);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Issues the Enable command to the L6474 of the specified device
  * @retval None
  **********************************************************/
@@ -541,7 +545,7 @@
   L6474_SendCommand(L6474_ENABLE);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Issues the GetParam command to the L6474 of the specified device
  * @param[in] param Register adress (L6474_ABS_POS, L6474_MARK,...)
  * @retval Register value
@@ -551,6 +555,7 @@
   uint32_t i;
   uint32_t spiRxData;
   uint8_t maxArgumentNbBytes = 0;
+  uint8_t spiIndex = numberOfDevices - deviceInstance - 1;
   bool itDisable = FALSE;  
   
   do
@@ -563,29 +568,32 @@
       itDisable = FALSE;
     }
   
-    spiTxBursts[0] = L6474_NOP;
-    spiTxBursts[1] = L6474_NOP;
-    spiTxBursts[2] = L6474_NOP;
-    spiTxBursts[3] = L6474_NOP;
-    spiRxBursts[1] = 0;
-    spiRxBursts[2] = 0;
-    spiRxBursts[3] = 0;    
+    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] = ((uint8_t)L6474_GET_PARAM )| (param);
+        spiTxBursts[0][spiIndex] = ((uint8_t)L6474_GET_PARAM )| (param);
         maxArgumentNbBytes = 3;
         break;
       case L6474_EL_POS: ;
       case L6474_CONFIG: ;
       case L6474_STATUS:
-        spiTxBursts[1] = ((uint8_t)L6474_GET_PARAM )| (param);
+        spiTxBursts[1][spiIndex] = ((uint8_t)L6474_GET_PARAM )| (param);
         maxArgumentNbBytes = 2;
         break;
       default:
-        spiTxBursts[2] = ((uint8_t)L6474_GET_PARAM )| (param);
+        spiTxBursts[2][spiIndex] = ((uint8_t)L6474_GET_PARAM )| (param);
         maxArgumentNbBytes = 1;
     }
     
@@ -599,12 +607,12 @@
        i < L6474_CMD_ARG_MAX_NB_BYTES;
        i++)
   {
-     L6474_WriteBytes(&spiTxBursts[i], &spiRxBursts[i]);
+     L6474_WriteBytes(&spiTxBursts[i][0], &spiRxBursts[i][0]);
   }
   
-  spiRxData = ((uint32_t)spiRxBursts[1] << 16) |
-              (spiRxBursts[2] << 8) |
-              (spiRxBursts[3]);
+  spiRxData = ((uint32_t)spiRxBursts[1][spiIndex] << 16) |
+              (spiRxBursts[2][spiIndex] << 8) |
+              (spiRxBursts[3][spiIndex]);
   
   /* re-enable L6474_EnableIrq after SPI transfers*/
   L6474_EnableIrq();
@@ -612,7 +620,7 @@
   return (spiRxData);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Issues the GetStatus command to the L6474 of the specified device
  * @retval Status Register value
  * @note Once the GetStatus command is performed, the flags of the status register
@@ -623,6 +631,7 @@
 {
   uint32_t i;
   uint16_t status;
+  uint8_t spiIndex = numberOfDevices - deviceInstance - 1;
   bool itDisable = FALSE;  
   
   do
@@ -635,12 +644,15 @@
       itDisable = FALSE;
     }
 
-    spiTxBursts[0] = L6474_NOP;
-    spiTxBursts[1] = L6474_NOP;
-    spiTxBursts[2] = L6474_NOP;
-    spiRxBursts[1] = 0;
-    spiRxBursts[2] = 0;
-    spiTxBursts[0] = L6474_GET_STATUS;
+    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*/
@@ -650,9 +662,9 @@
 
   for (i = 0; i < L6474_CMD_ARG_NB_BYTES_GET_STATUS + L6474_RSP_NB_BYTES_GET_STATUS; i++)
   {
-     L6474_WriteBytes(&spiTxBursts[i], &spiRxBursts[i]);
+     L6474_WriteBytes(&spiTxBursts[i][0], &spiRxBursts[i][0]);
   }
-  status = (spiRxBursts[1] << 8) | (spiRxBursts[2]);
+  status = (spiRxBursts[1][spiIndex] << 8) | (spiRxBursts[2][spiIndex]);
   
   /* re-enable L6474_EnableIrq after SPI transfers*/
   L6474_EnableIrq();
@@ -660,7 +672,7 @@
   return (status);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Issues the Nop command to the L6474 of the specified device
  * @retval None
  **********************************************************/
@@ -669,7 +681,7 @@
   L6474_SendCommand(L6474_NOP);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Issues the SetParam command to the L6474 of the specified device
  * @param[in] param Register adress (L6474_ABS_POS, L6474_MARK,...)
  * @param[in] value Value to set in the register
@@ -679,6 +691,7 @@
 {
   uint32_t i;
   uint8_t maxArgumentNbBytes = 0;
+  uint8_t spiIndex = numberOfDevices - deviceInstance - 1;
   bool itDisable = FALSE;  
   do
   {
@@ -690,32 +703,35 @@
       itDisable = FALSE;
     }
 
-    spiTxBursts[0] = L6474_NOP;
-    spiTxBursts[1] = L6474_NOP;
-    spiTxBursts[2] = L6474_NOP;
-    spiTxBursts[3] = L6474_NOP;
+    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] = param;
-          spiTxBursts[1] = (uint8_t)(value >> 16);
-          spiTxBursts[2] = (uint8_t)(value >> 8);
+          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] = param;
-          spiTxBursts[2] = (uint8_t)(value >> 8);
+          spiTxBursts[1][spiIndex] = param;
+          spiTxBursts[2][spiIndex] = (uint8_t)(value >> 8);
           maxArgumentNbBytes = 2;
           break;
       default:
-          spiTxBursts[2] = param;
+          spiTxBursts[2][spiIndex] = param;
           maxArgumentNbBytes = 1;
           break;
     }
-    spiTxBursts[3] = (uint8_t)(value);
+    spiTxBursts[3][spiIndex] = (uint8_t)(value);
     
     /* Disable interruption before checking */
     /* pre-emption by ISR and SPI transfers*/
@@ -728,13 +744,13 @@
        i < L6474_CMD_ARG_MAX_NB_BYTES;
        i++)
   {
-     L6474_WriteBytes(&spiTxBursts[i],&spiRxBursts[i]);
+     L6474_WriteBytes(&spiTxBursts[i][0],&spiRxBursts[i][0]);
   }
   /* re-enable L6474_EnableIrq after SPI transfers*/
   L6474_EnableIrq();
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Reads the Status Register value
  * @retval Status register valued
  * @note The status register flags are not cleared 
@@ -745,7 +761,7 @@
   return (L6474_CmdGetParam(L6474_STATUS));
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Set the stepping mode 
  * @param[in] stepMod from full step to 1/16 microstep as specified in enum motorStepMode_t
  * @retval None
@@ -791,32 +807,33 @@
   L6474_SetHome();
 }
 
-/******************************************************//**
- * @brief  Get the direction 
- * @retval direction clockwise or counter-clockwise
+/**********************************************************
+ * @brief  Get the direction
+ * @param  None
+ * @retval direction FORWARD or BACKWARD
  **********************************************************/
-StepperMotor::direction_t L6474::L6474_GetDirection(void)
+motorDir_t L6474::L6474_GetDirection(void)
 {
-  return (devicePrm.direction == FORWARD ? CW : CCW);
+  return devicePrm.direction;
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Specifies the direction 
  * @param[in] dir FORWARD or BACKWARD
  * @note The direction change is only applied if the device 
  * is in INACTIVE state
  * @retval None
  **********************************************************/
-void L6474::L6474_SetDirection(direction_t direction)
+void L6474::L6474_SetDirection(motorDir_t direction)
 {
   if (devicePrm.motionState == INACTIVE)
   {
-    devicePrm.direction = (direction == CW ? FORWARD : BACKWARD);
-    L6474_SetDirectionGpio(direction == CW ? 1 : 0);
+    devicePrm.direction = direction;
+    L6474_SetDirectionGpio(direction);
   }
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Updates the current speed of the device
  * @param[in] newSpeed in pps
  * @retval None
@@ -837,7 +854,7 @@
   L6474_PwmSetFreq(newSpeed);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Computes the speed profile according to the number of steps to move
  * @param[in] nbSteps number of steps to perform
  * @retval None
@@ -901,7 +918,7 @@
   }
 }
 
-/******************************************************//**
+/**********************************************************
  * @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 
@@ -923,10 +940,11 @@
   {
     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
@@ -946,7 +964,7 @@
   }
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Handlers of the flag interrupt which calls the user callback (if defined)
  * @param None
  * @retval None
@@ -965,14 +983,16 @@
   }
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Sends a command without arguments to the L6474 via the SPI
  * @param[in] param Command to send 
  * @retval None
  **********************************************************/
 void L6474::L6474_SendCommand(uint8_t param)
 {
-  bool itDisable = FALSE;  
+  uint32_t i;
+  bool itDisable = FALSE;
+  uint8_t spiIndex = numberOfDevices - deviceInstance - 1;
   
   do
   {
@@ -984,8 +1004,11 @@
       itDisable = FALSE;
     }
   
-    spiTxBursts[3] = L6474_NOP;     
-    spiTxBursts[3] = param;
+    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*/
@@ -993,13 +1016,13 @@
     itDisable = TRUE;
   } while (spiPreemtionByIsr); // check pre-emption by ISR
 
-  L6474_WriteBytes(&spiTxBursts[3], &spiRxBursts[3]); 
+  L6474_WriteBytes(&spiTxBursts[3][0], &spiRxBursts[3][0]); 
   
   /* re-enable L6474_EnableIrq after SPI transfers*/
   L6474_EnableIrq();
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Sets the registers of the L6474 to their predefined values 
  * from l6474_target_config.h
  * @retval None
@@ -1118,7 +1141,7 @@
   }
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Sets the parameters of the device to predefined values
  * from l6474_target_config.h
  * @param None
@@ -1164,7 +1187,7 @@
   L6474_SetRegisterToPredefinedValues();
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief Initialises the bridge parameters to start the movement
  * and enable the power bridge
  * @retval None
@@ -1186,7 +1209,7 @@
   L6474_ApplySpeed(devicePrm.minSpeed);
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief  Handles the device state machine at each ste
  * @retval None
  * @note Must only be called by the timer ISR
@@ -1324,7 +1347,7 @@
   isrFlag = FALSE;
 }
 
-/******************************************************//**
+/**********************************************************
  * @brief Converts mA in compatible values for TVAL register 
  * @param[in] Tval
  * @retval TVAL values
@@ -1334,7 +1357,7 @@
   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
@@ -1345,7 +1368,7 @@
   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
--- a/Components/l6474/l6474_class.h	Fri Nov 13 12:56:06 2015 +0000
+++ b/Components/l6474/l6474_class.h	Wed Nov 18 18:41:55 2015 +0000
@@ -108,13 +108,13 @@
          *--------------------------------------------------------------------*/
         flagInterruptCallback = 0;
         errorHandlerCallback = 0;
-        memset(spiTxBursts, 0, L6474_CMD_ARG_MAX_NB_BYTES);
-        memset(spiRxBursts, 0, L6474_CMD_ARG_MAX_NB_BYTES);
         spiPreemtionByIsr = 0;
         isrFlag = 0;
         //devicePrm = 0;
         deviceInstance = numberOfDevices;
         numberOfDevices++;
+        memset(spiTxBursts, 0, L6474_CMD_ARG_MAX_NB_BYTES * MAX_NUMBER_OF_DEVICES * sizeof(uint8_t));
+        memset(spiRxBursts, 0, L6474_CMD_ARG_MAX_NB_BYTES * MAX_NUMBER_OF_DEVICES * sizeof(uint8_t));
     }
     
     /**
@@ -175,11 +175,6 @@
         return (signed int) L6474_GetMark();
     }
     
-    virtual direction_t GetDirection(void)
-    {
-        return (direction_t) L6474_GetDirection();
-    }
-
     virtual unsigned int GetSpeed(void)
     {
         return (unsigned int) L6474_GetCurrentSpeed();
@@ -205,6 +200,11 @@
         return (unsigned int) L6474_GetDeceleration();
     }
 
+    virtual direction_t GetDirection(void)
+    {
+        return (direction_t) (L6474_GetDirection() == FORWARD ? StepperMotor::FWD : StepperMotor::BWD);
+    }
+
     virtual void SetParameter(unsigned int parameter, unsigned int value)
     {
         L6474_CmdSetParam((unsigned int) parameter, (unsigned int) value);
@@ -220,11 +220,6 @@
         L6474_SetMark();
     }
 
-    virtual void SetDirection(direction_t direction)
-    {
-        L6474_SetDirection((direction_t) direction);
-    }
-
     virtual void SetMaxSpeed(unsigned int speed)
     {
         L6474_SetMaxSpeed((unsigned int) speed);
@@ -262,12 +257,12 @@
 
     virtual void Run(direction_t direction)
     {
-        L6474_Run((direction_t) direction);
+        L6474_Run((motorDir_t) (direction == StepperMotor::FWD ? FORWARD : BACKWARD));
     }
 
     virtual void Move(direction_t direction, unsigned int steps)
     {
-        L6474_Move((direction_t) direction, (unsigned int) steps);
+        L6474_Move((motorDir_t) (direction == StepperMotor::FWD ? FORWARD : BACKWARD), (unsigned int) steps);
     }
 
     virtual void SoftStop(void)
@@ -290,6 +285,11 @@
         return (uint8_t) L6474_GetFwVersion();
     }
 
+    virtual void SetDirection(direction_t direction)
+    {
+        L6474_SetDirection((motorDir_t) (direction == StepperMotor::FWD ? FORWARD : BACKWARD));
+    }
+
     virtual void StepClockHandler(void)
     {
         L6474_StepClockHandler();
@@ -425,8 +425,8 @@
     void L6474_GoMark(void);                                         //Move to the Mark position
     void L6474_GoTo(int32_t targetPosition);                         //Go to the specified position
     void L6474_HardStop(void);                                       //Stop the motor and disable the power bridge
-    void L6474_Move(direction_t direction, uint32_t stepCount);       //Move the motor of the specified number of steps
-    void L6474_Run(direction_t direction);                            //Run the motor 
+    void L6474_Move(motorDir_t direction, uint32_t stepCount);       //Move the motor of the specified number of steps
+    void L6474_Run(motorDir_t direction);                            //Run the motor 
     bool L6474_SetAcceleration(uint16_t newAcc);                     //Set the acceleration in pps^2
     bool L6474_SetDeceleration(uint16_t newDec);                     //Set the deceleration in pps^2
     void L6474_SetHome(void);                                        //Set current position to be the home position
@@ -443,8 +443,8 @@
     void L6474_CmdSetParam(uint32_t param, uint32_t value);          //Send the L6474_SET_PARAM command
     uint16_t L6474_ReadStatusRegister(void);                         //Read the L6474_STATUS register without clearing the flags
     void L6474_SelectStepMode(motorStepMode_t stepMod);              //Step mode selection
-    direction_t L6474_GetDirection(void);                             //Get the direction of rotation
-    void L6474_SetDirection(direction_t direction);                   //Set the direction of rotation
+    motorDir_t L6474_GetDirection(void);                             //Get the direction of rotation
+    void L6474_SetDirection(motorDir_t direction);                   //Set the direction of rotation
     void L6474_ApplySpeed(uint16_t newSpeed);
     void L6474_ComputeSpeedProfile(uint32_t nbSteps);
     int32_t L6474_ConvertPosition(uint32_t abs_position_reg); 
@@ -511,7 +511,7 @@
      */
     void L6474_Delay(uint32_t delay)
     {
-        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs */
+        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs.*/
         wait_ms(delay);
     }
 
@@ -520,7 +520,7 @@
      */
     void L6474_EnableIrq(void)
     {
-        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs */
+        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs.*/
         __enable_irq();
     }
 
@@ -529,7 +529,7 @@
      */
     void L6474_DisableIrq(void)
     {
-        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs */
+        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs.*/
         __disable_irq();
     }
 
@@ -539,7 +539,7 @@
      */
     void L6474_PwmSetFreq(uint16_t newFreq)
     {
-        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs */
+        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs.*/
         double period = 1.0f / newFreq;
         pwm.period(period);
         pwm.write(0.5f);
@@ -554,7 +554,7 @@
      */
     void L6474_PwmInit(void)
     {
-        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs */
+        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs.*/
     }
 
     /*
@@ -562,7 +562,7 @@
      */
     void L6474_PwmStop(void)
     {
-        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs */
+        /* TO BE IMPLEMENTED BY USING TARGET PLATFORM'S APIs.*/
         pwm.write(0.0f);
         ticker.detach();
     }
@@ -655,13 +655,13 @@
      *------------------------------------------------------------------------*/
     void (*flagInterruptCallback)(void);
     void (*errorHandlerCallback)(uint16_t error);
-    uint8_t spiTxBursts[L6474_CMD_ARG_MAX_NB_BYTES];
-    uint8_t spiRxBursts[L6474_CMD_ARG_MAX_NB_BYTES];
     bool spiPreemtionByIsr;
     bool isrFlag;
     deviceParams_t devicePrm;
+    uint8_t deviceInstance;
     static uint8_t numberOfDevices;
-    uint8_t deviceInstance;
+    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];
 };
 
 #endif // __L6474_CLASS_H