Speed profile working

Fork of Easyspin_lib by Julien Tiron

Committer:
julientiron
Date:
Wed Aug 26 13:35:55 2015 +0000
Revision:
1:9efe863db15e
Parent:
0:cba942f8172a
Update for speed profile

Who changed what in which revision?

UserRevisionLine numberNew contents of line
julientiron 0:cba942f8172a 1 /******************************************************//**
julientiron 1:9efe863db15e 2 * @file easyspin.cpp
julientiron 0:cba942f8172a 3 * @version V1.0
julientiron 0:cba942f8172a 4 * @date June 29, 2015
julientiron 0:cba942f8172a 5 * @brief easyspin library for mbed
julientiron 0:cba942f8172a 6 *
julientiron 0:cba942f8172a 7 * This file is free software; you can redistribute it and/or modify
julientiron 0:cba942f8172a 8 * it under the terms of either the GNU General Public License version 2
julientiron 0:cba942f8172a 9 * or the GNU Lesser General Public License version 2.1, both as
julientiron 0:cba942f8172a 10 * published by the Free Software Foundation.
julientiron 1:9efe863db15e 11 **********************************************************/
julientiron 0:cba942f8172a 12
julientiron 0:cba942f8172a 13 #include "easyspin.h"
julientiron 0:cba942f8172a 14 #include "mbed.h"
julientiron 0:cba942f8172a 15
julientiron 0:cba942f8172a 16 const uint16_t Easyspin::prescalerArrayTimer0_1[PRESCALER_ARRAY_TIMER0_1_SIZE] = { 0, 1, 8, 64, 256, 1024};
julientiron 0:cba942f8172a 17 const uint16_t Easyspin::prescalerArrayTimer2[PRESCALER_ARRAY_TIMER2_SIZE] = {0, 1, 8, 32, 64, 128, 256, 1024};
julientiron 0:cba942f8172a 18 volatile void (*Easyspin::flagInterruptCallback)(void);
julientiron 0:cba942f8172a 19 volatile uint8_t Easyspin::numberOfShields;
julientiron 0:cba942f8172a 20 uint8_t Easyspin::spiTxBursts[Easyspin_CMD_ARG_MAX_NB_BYTES][MAX_NUMBER_OF_SHIELDS];
julientiron 0:cba942f8172a 21 uint8_t Easyspin::spiRxBursts[Easyspin_CMD_ARG_MAX_NB_BYTES][MAX_NUMBER_OF_SHIELDS];
julientiron 0:cba942f8172a 22 volatile bool Easyspin::spiPreemtionByIsr = false;
julientiron 0:cba942f8172a 23 volatile bool Easyspin::isrFlag = false;
julientiron 0:cba942f8172a 24 volatile class Easyspin* Easyspin::instancePtr = NULL;
julientiron 1:9efe863db15e 25
julientiron 0:cba942f8172a 26 /******************************************************//**
julientiron 0:cba942f8172a 27 * @brief Constructor
julientiron 0:cba942f8172a 28 * @param None
julientiron 0:cba942f8172a 29 * @retval None
julientiron 1:9efe863db15e 30 **********************************************************/
julientiron 0:cba942f8172a 31 Easyspin::Easyspin():reset(Easyspin_Reset_Pin), dir1(Easyspin_DIR_1_Pin), dir2(Easyspin_DIR_2_Pin),
julientiron 1:9efe863db15e 32 dir3(Easyspin_DIR_3_Pin), CS(Easyspin_CS_Pin), flag(Easyspin_FLAG_Pin), pwm1(Easyspin_PWM_1_Pin),
julientiron 1:9efe863db15e 33 pwm2(Easyspin_PWM_2_Pin), pwm3(Easyspin_PWM_3_Pin), spi(Easyspin_MOSI_Pin, Easyspin_MISO_Pin, Easyspin_SCK_Pin)
julientiron 0:cba942f8172a 34 {
julientiron 1:9efe863db15e 35 uint8_t i;
julientiron 1:9efe863db15e 36 for (i = 0; i < MAX_NUMBER_OF_SHIELDS; i++) {
julientiron 1:9efe863db15e 37 shieldPrm[i].motionState = INACTIVE;
julientiron 1:9efe863db15e 38 shieldPrm[i].commandExecuted = NO_CMD;
julientiron 1:9efe863db15e 39 shieldPrm[i].stepsToTake = MAX_STEPS;
julientiron 1:9efe863db15e 40 }
julientiron 0:cba942f8172a 41 instancePtr = this;
julientiron 0:cba942f8172a 42 }
julientiron 0:cba942f8172a 43
julientiron 0:cba942f8172a 44 /******************************************************//**
julientiron 0:cba942f8172a 45 * @brief Attaches a user callback to the flag Interrupt
julientiron 1:9efe863db15e 46 * The call back will be then called each time the status
julientiron 1:9efe863db15e 47 * flag pin will be pulled down due to the occurrence of
julientiron 1:9efe863db15e 48 * a programmed alarms ( OCD, thermal pre-warning or
julientiron 0:cba942f8172a 49 * shutdown, UVLO, wrong command, non-performable command)
julientiron 1:9efe863db15e 50 * @param[in] callback Name of the callback to attach
julientiron 0:cba942f8172a 51 * to the Flag Interrupt
julientiron 0:cba942f8172a 52 * @retval None
julientiron 0:cba942f8172a 53 **********************************************************/
julientiron 0:cba942f8172a 54 void Easyspin::AttachFlagInterrupt(void (*callback)(void))
julientiron 0:cba942f8172a 55 {
julientiron 1:9efe863db15e 56 flagInterruptCallback = (volatile void (*)())callback;
julientiron 0:cba942f8172a 57 }
julientiron 0:cba942f8172a 58
julientiron 0:cba942f8172a 59 /******************************************************//**
julientiron 0:cba942f8172a 60 * @brief Starts the Easyspin library
julientiron 0:cba942f8172a 61 * @param[in] nbShields Number of Easyspin shields to use (from 1 to 3)
julientiron 0:cba942f8172a 62 * @retval None
julientiron 0:cba942f8172a 63 **********************************************************/
julientiron 0:cba942f8172a 64 void Easyspin::Begin(uint8_t nbShields)
julientiron 0:cba942f8172a 65 {
julientiron 1:9efe863db15e 66 numberOfShields = nbShields;
julientiron 1:9efe863db15e 67
julientiron 1:9efe863db15e 68 // start the SPI library:
julientiron 1:9efe863db15e 69 //SPI.begin();
julientiron 1:9efe863db15e 70 //SPI.setBitOrder(MSBFIRST);
julientiron 1:9efe863db15e 71 spi.format(8, 3);
julientiron 1:9efe863db15e 72 //SPI.setClockDivider(SPI_CLOCK_DIV4);
julientiron 1:9efe863db15e 73
julientiron 1:9efe863db15e 74 // flag pin
julientiron 1:9efe863db15e 75 //pinMode(Easyspin_FLAG_Pin, INPUT_PULLUP);
julientiron 1:9efe863db15e 76 flag.mode(PullUp);
julientiron 1:9efe863db15e 77 flag.fall(&FlagInterruptHandler);
julientiron 1:9efe863db15e 78
julientiron 1:9efe863db15e 79 //reset pin
julientiron 1:9efe863db15e 80 //pinMode(Easyspin_Reset_Pin, OUTPUT);
julientiron 1:9efe863db15e 81
julientiron 1:9efe863db15e 82 switch (nbShields) {
julientiron 1:9efe863db15e 83 case 3:
julientiron 1:9efe863db15e 84 //pinMode(Easyspin_DIR_3_Pin, OUTPUT);
julientiron 1:9efe863db15e 85 //pinMode(Easyspin_PWM_3_Pin, OUTPUT);
julientiron 1:9efe863db15e 86 PwmInit(2);
julientiron 1:9efe863db15e 87 case 2:
julientiron 1:9efe863db15e 88 //pinMode(Easyspin_DIR_2_Pin, OUTPUT);
julientiron 1:9efe863db15e 89 //pinMode(Easyspin_PWM_2_Pin, OUTPUT);
julientiron 1:9efe863db15e 90 PwmInit(1);
julientiron 1:9efe863db15e 91 case 1:
julientiron 1:9efe863db15e 92 //pinMode(Easyspin_DIR_1_Pin, OUTPUT);
julientiron 1:9efe863db15e 93 //pinMode(Easyspin_PWM_1_Pin, OUTPUT);
julientiron 1:9efe863db15e 94 PwmInit(0);
julientiron 1:9efe863db15e 95 default:
julientiron 1:9efe863db15e 96 ;
julientiron 1:9efe863db15e 97 }
julientiron 1:9efe863db15e 98
julientiron 1:9efe863db15e 99 /* Standby-reset deactivation */
julientiron 1:9efe863db15e 100 ReleaseReset();
julientiron 1:9efe863db15e 101
julientiron 1:9efe863db15e 102 /* Set all registers and context variables to the predefined values from Easyspin_target_config.h */
julientiron 1:9efe863db15e 103 SetShieldParamsToPredefinedValues();
julientiron 1:9efe863db15e 104
julientiron 1:9efe863db15e 105 /* Disable Easyspin powerstage */
julientiron 1:9efe863db15e 106 for (uint32_t i = 0; i < nbShields; i++) {
julientiron 1:9efe863db15e 107 CmdDisable(i);
julientiron 1:9efe863db15e 108 /* Get Status to clear flags after start up */
julientiron 1:9efe863db15e 109 CmdGetStatus(i);
julientiron 1:9efe863db15e 110 }
julientiron 0:cba942f8172a 111 }
julientiron 0:cba942f8172a 112
julientiron 0:cba942f8172a 113 /******************************************************//**
julientiron 0:cba942f8172a 114 * @brief Returns the acceleration of the specified shield
julientiron 0:cba942f8172a 115 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 116 * @retval Acceleration in pps^2
julientiron 0:cba942f8172a 117 **********************************************************/
julientiron 0:cba942f8172a 118 uint16_t Easyspin::GetAcceleration(uint8_t shieldId)
julientiron 1:9efe863db15e 119 {
julientiron 1:9efe863db15e 120 return (shieldPrm[shieldId].acceleration);
julientiron 1:9efe863db15e 121 }
julientiron 0:cba942f8172a 122
julientiron 0:cba942f8172a 123 /******************************************************//**
julientiron 0:cba942f8172a 124 * @brief Returns the current speed of the specified shield
julientiron 0:cba942f8172a 125 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 126 * @retval Speed in pps
julientiron 0:cba942f8172a 127 **********************************************************/
julientiron 0:cba942f8172a 128 uint16_t Easyspin::GetCurrentSpeed(uint8_t shieldId)
julientiron 0:cba942f8172a 129 {
julientiron 1:9efe863db15e 130 return shieldPrm[shieldId].speed;
julientiron 0:cba942f8172a 131 }
julientiron 0:cba942f8172a 132
julientiron 0:cba942f8172a 133 /******************************************************//**
julientiron 0:cba942f8172a 134 * @brief Returns the deceleration of the specified shield
julientiron 0:cba942f8172a 135 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 136 * @retval Deceleration in pps^2
julientiron 0:cba942f8172a 137 **********************************************************/
julientiron 0:cba942f8172a 138 uint16_t Easyspin::GetDeceleration(uint8_t shieldId)
julientiron 1:9efe863db15e 139 {
julientiron 1:9efe863db15e 140 return (shieldPrm[shieldId].deceleration);
julientiron 1:9efe863db15e 141 }
julientiron 0:cba942f8172a 142
julientiron 0:cba942f8172a 143 /******************************************************//**
julientiron 0:cba942f8172a 144 * @brief Returns the FW version of the library
julientiron 0:cba942f8172a 145 * @param None
julientiron 0:cba942f8172a 146 * @retval Easyspin_FW_VERSION
julientiron 0:cba942f8172a 147 **********************************************************/
julientiron 0:cba942f8172a 148 uint8_t Easyspin::GetFwVersion(void)
julientiron 0:cba942f8172a 149 {
julientiron 1:9efe863db15e 150 return (Easyspin_FW_VERSION);
julientiron 0:cba942f8172a 151 }
julientiron 0:cba942f8172a 152
julientiron 0:cba942f8172a 153 /******************************************************//**
julientiron 0:cba942f8172a 154 * @brief Returns the mark position of the specified shield
julientiron 0:cba942f8172a 155 * @param[in] shieldId (from 0 to 2)
julientiron 1:9efe863db15e 156 * @retval Mark register value converted in a 32b signed integer
julientiron 0:cba942f8172a 157 **********************************************************/
julientiron 0:cba942f8172a 158 int32_t Easyspin::GetMark(uint8_t shieldId)
julientiron 0:cba942f8172a 159 {
julientiron 1:9efe863db15e 160 return ConvertPosition(CmdGetParam(shieldId,Easyspin_MARK));
julientiron 0:cba942f8172a 161 }
julientiron 0:cba942f8172a 162
julientiron 0:cba942f8172a 163 /******************************************************//**
julientiron 0:cba942f8172a 164 * @brief Returns the max speed of the specified shield
julientiron 0:cba942f8172a 165 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 166 * @retval maxSpeed in pps
julientiron 0:cba942f8172a 167 **********************************************************/
julientiron 0:cba942f8172a 168 uint16_t Easyspin::GetMaxSpeed(uint8_t shieldId)
julientiron 1:9efe863db15e 169 {
julientiron 1:9efe863db15e 170 return (shieldPrm[shieldId].maxSpeed);
julientiron 1:9efe863db15e 171 }
julientiron 0:cba942f8172a 172
julientiron 0:cba942f8172a 173 /******************************************************//**
julientiron 0:cba942f8172a 174 * @brief Returns the min speed of the specified shield
julientiron 0:cba942f8172a 175 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 176 * @retval minSpeed in pps
julientiron 0:cba942f8172a 177 **********************************************************/
julientiron 0:cba942f8172a 178 uint16_t Easyspin::GetMinSpeed(uint8_t shieldId)
julientiron 1:9efe863db15e 179 {
julientiron 1:9efe863db15e 180 return (shieldPrm[shieldId].minSpeed);
julientiron 1:9efe863db15e 181 }
julientiron 0:cba942f8172a 182
julientiron 0:cba942f8172a 183 /******************************************************//**
julientiron 0:cba942f8172a 184 * @brief Returns the ABS_POSITION of the specified shield
julientiron 0:cba942f8172a 185 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 186 * @retval ABS_POSITION register value converted in a 32b signed integer
julientiron 0:cba942f8172a 187 **********************************************************/
julientiron 0:cba942f8172a 188 int32_t Easyspin::GetPosition(uint8_t shieldId)
julientiron 0:cba942f8172a 189 {
julientiron 1:9efe863db15e 190 return ConvertPosition(CmdGetParam(shieldId,Easyspin_ABS_POS));
julientiron 0:cba942f8172a 191 }
julientiron 0:cba942f8172a 192
julientiron 0:cba942f8172a 193 /******************************************************//**
julientiron 0:cba942f8172a 194 * @brief Returns the shield state
julientiron 0:cba942f8172a 195 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 196 * @retval State (ACCELERATING, DECELERATING, STEADY or INACTIVE)
julientiron 0:cba942f8172a 197 **********************************************************/
julientiron 0:cba942f8172a 198 shieldState_t Easyspin::GetShieldState(uint8_t shieldId)
julientiron 0:cba942f8172a 199 {
julientiron 1:9efe863db15e 200 return shieldPrm[shieldId].motionState;
julientiron 0:cba942f8172a 201 }
julientiron 0:cba942f8172a 202
julientiron 0:cba942f8172a 203 /******************************************************//**
julientiron 0:cba942f8172a 204 * @brief Requests the motor to move to the home position (ABS_POSITION = 0)
julientiron 0:cba942f8172a 205 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 206 * @retval None
julientiron 0:cba942f8172a 207 **********************************************************/
julientiron 0:cba942f8172a 208 void Easyspin::GoHome(uint8_t shieldId)
julientiron 0:cba942f8172a 209 {
julientiron 1:9efe863db15e 210 GoTo(shieldId, 0);
julientiron 1:9efe863db15e 211 }
julientiron 1:9efe863db15e 212
julientiron 0:cba942f8172a 213 /******************************************************//**
julientiron 1:9efe863db15e 214 * @brief Requests the motor to move to the mark position
julientiron 0:cba942f8172a 215 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 216 * @retval None
julientiron 0:cba942f8172a 217 **********************************************************/
julientiron 0:cba942f8172a 218 void Easyspin::GoMark(uint8_t shieldId)
julientiron 0:cba942f8172a 219 {
julientiron 0:cba942f8172a 220 uint32_t mark;
julientiron 0:cba942f8172a 221
julientiron 0:cba942f8172a 222 mark = ConvertPosition(CmdGetParam(shieldId,Easyspin_MARK));
julientiron 1:9efe863db15e 223 GoTo(shieldId,mark);
julientiron 0:cba942f8172a 224 }
julientiron 0:cba942f8172a 225
julientiron 0:cba942f8172a 226 /******************************************************//**
julientiron 1:9efe863db15e 227 * @brief Requests the motor to move to the specified position
julientiron 0:cba942f8172a 228 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 229 * @param[in] targetPosition absolute position in steps
julientiron 0:cba942f8172a 230 * @retval None
julientiron 0:cba942f8172a 231 **********************************************************/
julientiron 0:cba942f8172a 232 void Easyspin::GoTo(uint8_t shieldId, int32_t targetPosition)
julientiron 0:cba942f8172a 233 {
julientiron 1:9efe863db15e 234 dir_t direction;
julientiron 1:9efe863db15e 235 int32_t steps;
julientiron 1:9efe863db15e 236
julientiron 1:9efe863db15e 237 /* Eventually deactivate motor */
julientiron 1:9efe863db15e 238 if (shieldPrm[shieldId].motionState != INACTIVE) {
julientiron 1:9efe863db15e 239 HardStop(shieldId);
julientiron 1:9efe863db15e 240 }
julientiron 1:9efe863db15e 241
julientiron 1:9efe863db15e 242 /* Get current position */
julientiron 1:9efe863db15e 243 shieldPrm[shieldId].currentPosition = ConvertPosition(CmdGetParam(shieldId,Easyspin_ABS_POS));
julientiron 1:9efe863db15e 244
julientiron 1:9efe863db15e 245 /* Compute the number of steps to perform */
julientiron 1:9efe863db15e 246 steps = targetPosition - shieldPrm[shieldId].currentPosition;
julientiron 1:9efe863db15e 247
julientiron 1:9efe863db15e 248 if (steps >= 0) {
julientiron 1:9efe863db15e 249 shieldPrm[shieldId].stepsToTake = steps;
julientiron 1:9efe863db15e 250 direction = FORWARD;
julientiron 0:cba942f8172a 251
julientiron 1:9efe863db15e 252 } else {
julientiron 1:9efe863db15e 253 shieldPrm[shieldId].stepsToTake = -steps;
julientiron 1:9efe863db15e 254 direction = BACKWARD;
julientiron 1:9efe863db15e 255 }
julientiron 1:9efe863db15e 256
julientiron 1:9efe863db15e 257 if (steps != 0) {
julientiron 1:9efe863db15e 258
julientiron 1:9efe863db15e 259 shieldPrm[shieldId].commandExecuted = MOVE_CMD;
julientiron 0:cba942f8172a 260
julientiron 1:9efe863db15e 261 /* Direction setup */
julientiron 1:9efe863db15e 262 SetDirection(shieldId,direction);
julientiron 1:9efe863db15e 263
julientiron 1:9efe863db15e 264 ComputeSpeedProfile(shieldId, shieldPrm[shieldId].stepsToTake);
julientiron 1:9efe863db15e 265
julientiron 1:9efe863db15e 266 /* Motor activation */
julientiron 1:9efe863db15e 267 StartMovement(shieldId);
julientiron 1:9efe863db15e 268 }
julientiron 0:cba942f8172a 269 }
julientiron 0:cba942f8172a 270
julientiron 0:cba942f8172a 271 /******************************************************//**
julientiron 0:cba942f8172a 272 * @brief Immediatly stops the motor and disable the power bridge
julientiron 0:cba942f8172a 273 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 274 * @retval None
julientiron 0:cba942f8172a 275 **********************************************************/
julientiron 1:9efe863db15e 276 void Easyspin::HardStop(uint8_t shieldId)
julientiron 0:cba942f8172a 277 {
julientiron 1:9efe863db15e 278 /* Disable corresponding PWM */
julientiron 1:9efe863db15e 279 PwmStop(shieldId);
julientiron 0:cba942f8172a 280
julientiron 1:9efe863db15e 281 /* Disable power stage */
julientiron 1:9efe863db15e 282 CmdDisable(shieldId);
julientiron 0:cba942f8172a 283
julientiron 1:9efe863db15e 284 /* Set inactive state */
julientiron 1:9efe863db15e 285 shieldPrm[shieldId].motionState = INACTIVE;
julientiron 1:9efe863db15e 286 shieldPrm[shieldId].commandExecuted = NO_CMD;
julientiron 1:9efe863db15e 287 shieldPrm[shieldId].stepsToTake = MAX_STEPS;
julientiron 0:cba942f8172a 288
julientiron 0:cba942f8172a 289 #ifdef _DEBUG_Easyspin
julientiron 1:9efe863db15e 290 Serial.println("Inactive\n");
julientiron 1:9efe863db15e 291 #endif
julientiron 0:cba942f8172a 292 }
julientiron 0:cba942f8172a 293
julientiron 0:cba942f8172a 294 /******************************************************//**
julientiron 0:cba942f8172a 295 * @brief Moves the motor of the specified number of steps
julientiron 0:cba942f8172a 296 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 297 * @param[in] direction FORWARD or BACKWARD
julientiron 0:cba942f8172a 298 * @param[in] stepCount Number of steps to perform
julientiron 0:cba942f8172a 299 * @retval None
julientiron 0:cba942f8172a 300 **********************************************************/
julientiron 0:cba942f8172a 301 void Easyspin::Move(uint8_t shieldId, dir_t direction, uint32_t stepCount)
julientiron 0:cba942f8172a 302 {
julientiron 1:9efe863db15e 303 /* Eventually deactivate motor */
julientiron 1:9efe863db15e 304 if (shieldPrm[shieldId].motionState != INACTIVE) {
julientiron 1:9efe863db15e 305 HardStop(shieldId);
julientiron 1:9efe863db15e 306 }
julientiron 1:9efe863db15e 307
julientiron 1:9efe863db15e 308 if (stepCount != 0) {
julientiron 1:9efe863db15e 309 shieldPrm[shieldId].stepsToTake = stepCount;
julientiron 1:9efe863db15e 310
julientiron 1:9efe863db15e 311 shieldPrm[shieldId].commandExecuted = MOVE_CMD;
julientiron 1:9efe863db15e 312
julientiron 1:9efe863db15e 313 shieldPrm[shieldId].currentPosition = ConvertPosition(CmdGetParam(shieldId,Easyspin_ABS_POS));
julientiron 1:9efe863db15e 314
julientiron 1:9efe863db15e 315 /* Direction setup */
julientiron 1:9efe863db15e 316 SetDirection(shieldId,direction);
julientiron 1:9efe863db15e 317
julientiron 1:9efe863db15e 318 ComputeSpeedProfile(shieldId, stepCount);
julientiron 1:9efe863db15e 319
julientiron 1:9efe863db15e 320 /* Motor activation */
julientiron 1:9efe863db15e 321 StartMovement(shieldId);
julientiron 1:9efe863db15e 322 }
julientiron 1:9efe863db15e 323 }
julientiron 1:9efe863db15e 324
julientiron 0:cba942f8172a 325
julientiron 1:9efe863db15e 326 /******************************************************//**
julientiron 1:9efe863db15e 327 * @brief Turn left or right with the specified angle
julientiron 1:9efe863db15e 328 * @param[in] rotation RIGHT or LEFT
julientiron 1:9efe863db15e 329 * @param[in] angle in degrees
julientiron 1:9efe863db15e 330 * @retval None
julientiron 1:9efe863db15e 331 **********************************************************/
julientiron 1:9efe863db15e 332 void Easyspin::Turn(rot_t rotation, uint16_t angle)
julientiron 1:9efe863db15e 333 {
julientiron 1:9efe863db15e 334 uint16_t nbStep = (10934*angle)/360;
julientiron 1:9efe863db15e 335 if(rotation==RIGHT) {
julientiron 1:9efe863db15e 336 Move(0, FORWARD, nbStep);
julientiron 1:9efe863db15e 337 Move(1, FORWARD, nbStep);
julientiron 1:9efe863db15e 338 } else {
julientiron 1:9efe863db15e 339 Move(0, BACKWARD, nbStep);
julientiron 1:9efe863db15e 340 Move(1, BACKWARD, nbStep);
julientiron 1:9efe863db15e 341 }
julientiron 1:9efe863db15e 342 }
julientiron 1:9efe863db15e 343
julientiron 1:9efe863db15e 344 /******************************************************//**
julientiron 1:9efe863db15e 345 * @brief Move forward or backward with the specified distance
julientiron 1:9efe863db15e 346 * @param[in] direction FORWARD or BACKWARD
julientiron 1:9efe863db15e 347 * @param[in] distance in cm
julientiron 1:9efe863db15e 348 * @retval None
julientiron 1:9efe863db15e 349 **********************************************************/
julientiron 1:9efe863db15e 350 void Easyspin::Move_cm(dir_t direction, uint16_t distance)
julientiron 1:9efe863db15e 351 {
julientiron 1:9efe863db15e 352 uint16_t nbStep = (10000 * distance)/61;
julientiron 1:9efe863db15e 353 if(direction==FORWARD) {
julientiron 1:9efe863db15e 354 Move(0, FORWARD, nbStep);
julientiron 1:9efe863db15e 355 Move(1, BACKWARD, nbStep);
julientiron 1:9efe863db15e 356 } else {
julientiron 1:9efe863db15e 357 Move(0, BACKWARD, nbStep);
julientiron 1:9efe863db15e 358 Move(1, FORWARD, nbStep);
julientiron 1:9efe863db15e 359 }
julientiron 0:cba942f8172a 360 }
julientiron 0:cba942f8172a 361
julientiron 0:cba942f8172a 362 /******************************************************//**
julientiron 0:cba942f8172a 363 * @brief Resets all Easyspin shields
julientiron 0:cba942f8172a 364 * @param None
julientiron 0:cba942f8172a 365 * @retval None
julientiron 0:cba942f8172a 366 **********************************************************/
julientiron 0:cba942f8172a 367 void Easyspin::ResetAllShields(void)
julientiron 0:cba942f8172a 368 {
julientiron 0:cba942f8172a 369 uint8_t loop;
julientiron 1:9efe863db15e 370
julientiron 1:9efe863db15e 371 for (loop = 0; loop < numberOfShields; loop++) {
julientiron 1:9efe863db15e 372 /* Stop movement and disable power stage*/
julientiron 1:9efe863db15e 373 HardStop(loop);
julientiron 1:9efe863db15e 374 }
julientiron 0:cba942f8172a 375 Reset();
julientiron 1:9efe863db15e 376 wait_us(20); // Reset pin must be forced low for at least 10us
julientiron 0:cba942f8172a 377 ReleaseReset();
julientiron 0:cba942f8172a 378 }
julientiron 0:cba942f8172a 379
julientiron 0:cba942f8172a 380 /******************************************************//**
julientiron 1:9efe863db15e 381 * @brief Runs the motor. It will accelerate from the min
julientiron 0:cba942f8172a 382 * speed up to the max speed by using the shield acceleration.
julientiron 0:cba942f8172a 383 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 384 * @param[in] direction FORWARD or BACKWARD
julientiron 0:cba942f8172a 385 * @retval None
julientiron 0:cba942f8172a 386 **********************************************************/
julientiron 0:cba942f8172a 387 void Easyspin::Run(uint8_t shieldId, dir_t direction)
julientiron 0:cba942f8172a 388 {
julientiron 1:9efe863db15e 389 /* Eventually deactivate motor */
julientiron 1:9efe863db15e 390 if (shieldPrm[shieldId].motionState != INACTIVE) {
julientiron 1:9efe863db15e 391 HardStop(shieldId);
julientiron 1:9efe863db15e 392 }
julientiron 1:9efe863db15e 393
julientiron 0:cba942f8172a 394 /* Direction setup */
julientiron 0:cba942f8172a 395 SetDirection(shieldId,direction);
julientiron 0:cba942f8172a 396
julientiron 0:cba942f8172a 397 shieldPrm[shieldId].commandExecuted = RUN_CMD;
julientiron 0:cba942f8172a 398
julientiron 0:cba942f8172a 399 /* Motor activation */
julientiron 1:9efe863db15e 400 StartMovement(shieldId);
julientiron 0:cba942f8172a 401 }
julientiron 0:cba942f8172a 402
julientiron 0:cba942f8172a 403 /******************************************************//**
julientiron 0:cba942f8172a 404 * @brief Changes the acceleration of the specified shield
julientiron 0:cba942f8172a 405 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 406 * @param[in] newAcc New acceleration to apply in pps^2
julientiron 0:cba942f8172a 407 * @retval true if the command is successfully executed, else false
julientiron 1:9efe863db15e 408 * @note The command is not performed is the shield is executing
julientiron 0:cba942f8172a 409 * a MOVE or GOTO command (but it can be used during a RUN command)
julientiron 0:cba942f8172a 410 **********************************************************/
julientiron 0:cba942f8172a 411 bool Easyspin::SetAcceleration(uint8_t shieldId,uint16_t newAcc)
julientiron 1:9efe863db15e 412 {
julientiron 1:9efe863db15e 413 bool cmdExecuted = false;
julientiron 1:9efe863db15e 414 if ((newAcc != 0)&&
julientiron 1:9efe863db15e 415 ((shieldPrm[shieldId].motionState == INACTIVE)||
julientiron 1:9efe863db15e 416 (shieldPrm[shieldId].commandExecuted == RUN_CMD))) {
julientiron 1:9efe863db15e 417 shieldPrm[shieldId].acceleration = newAcc;
julientiron 1:9efe863db15e 418 cmdExecuted = true;
julientiron 1:9efe863db15e 419 }
julientiron 1:9efe863db15e 420 return cmdExecuted;
julientiron 1:9efe863db15e 421 }
julientiron 0:cba942f8172a 422
julientiron 0:cba942f8172a 423 /******************************************************//**
julientiron 0:cba942f8172a 424 * @brief Changes the deceleration of the specified shield
julientiron 0:cba942f8172a 425 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 426 * @param[in] newDec New deceleration to apply in pps^2
julientiron 0:cba942f8172a 427 * @retval true if the command is successfully executed, else false
julientiron 1:9efe863db15e 428 * @note The command is not performed is the shield is executing
julientiron 0:cba942f8172a 429 * a MOVE or GOTO command (but it can be used during a RUN command)
julientiron 0:cba942f8172a 430 **********************************************************/
julientiron 0:cba942f8172a 431 bool Easyspin::SetDeceleration(uint8_t shieldId, uint16_t newDec)
julientiron 1:9efe863db15e 432 {
julientiron 1:9efe863db15e 433 bool cmdExecuted = false;
julientiron 1:9efe863db15e 434 if ((newDec != 0)&&
julientiron 1:9efe863db15e 435 ((shieldPrm[shieldId].motionState == INACTIVE)||
julientiron 1:9efe863db15e 436 (shieldPrm[shieldId].commandExecuted == RUN_CMD))) {
julientiron 1:9efe863db15e 437 shieldPrm[shieldId].deceleration = newDec;
julientiron 1:9efe863db15e 438 cmdExecuted = true;
julientiron 1:9efe863db15e 439 }
julientiron 1:9efe863db15e 440 return cmdExecuted;
julientiron 1:9efe863db15e 441 }
julientiron 0:cba942f8172a 442
julientiron 0:cba942f8172a 443 /******************************************************//**
julientiron 0:cba942f8172a 444 * @brief Set current position to be the Home position (ABS pos set to 0)
julientiron 0:cba942f8172a 445 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 446 * @retval None
julientiron 0:cba942f8172a 447 **********************************************************/
julientiron 0:cba942f8172a 448 void Easyspin::SetHome(uint8_t shieldId)
julientiron 0:cba942f8172a 449 {
julientiron 1:9efe863db15e 450 CmdSetParam(shieldId, Easyspin_ABS_POS, 0);
julientiron 0:cba942f8172a 451 }
julientiron 1:9efe863db15e 452
julientiron 0:cba942f8172a 453 /******************************************************//**
julientiron 1:9efe863db15e 454 * @brief Sets current position to be the Mark position
julientiron 0:cba942f8172a 455 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 456 * @retval None
julientiron 0:cba942f8172a 457 **********************************************************/
julientiron 0:cba942f8172a 458 void Easyspin::SetMark(uint8_t shieldId)
julientiron 0:cba942f8172a 459 {
julientiron 1:9efe863db15e 460 uint32_t mark = CmdGetParam(shieldId,Easyspin_ABS_POS);
julientiron 1:9efe863db15e 461 CmdSetParam(shieldId,Easyspin_MARK, mark);
julientiron 0:cba942f8172a 462 }
julientiron 0:cba942f8172a 463
julientiron 0:cba942f8172a 464 /******************************************************//**
julientiron 0:cba942f8172a 465 * @brief Changes the max speed of the specified shield
julientiron 0:cba942f8172a 466 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 467 * @param[in] newMaxSpeed New max speed to apply in pps
julientiron 0:cba942f8172a 468 * @retval true if the command is successfully executed, else false
julientiron 1:9efe863db15e 469 * @note The command is not performed is the shield is executing
julientiron 0:cba942f8172a 470 * a MOVE or GOTO command (but it can be used during a RUN command).
julientiron 0:cba942f8172a 471 **********************************************************/
julientiron 0:cba942f8172a 472 bool Easyspin::SetMaxSpeed(uint8_t shieldId, uint16_t newMaxSpeed)
julientiron 1:9efe863db15e 473 {
julientiron 1:9efe863db15e 474 bool cmdExecuted = false;
julientiron 1:9efe863db15e 475 if ((newMaxSpeed > Easyspin_MIN_PWM_FREQ)&&
julientiron 1:9efe863db15e 476 (newMaxSpeed <= Easyspin_MAX_PWM_FREQ) &&
julientiron 1:9efe863db15e 477 (shieldPrm[shieldId].minSpeed <= newMaxSpeed) &&
julientiron 1:9efe863db15e 478 ((shieldPrm[shieldId].motionState == INACTIVE)||
julientiron 1:9efe863db15e 479 (shieldPrm[shieldId].commandExecuted == RUN_CMD))) {
julientiron 1:9efe863db15e 480 shieldPrm[shieldId].maxSpeed = newMaxSpeed;
julientiron 1:9efe863db15e 481 cmdExecuted = true;
julientiron 1:9efe863db15e 482 }
julientiron 1:9efe863db15e 483 return cmdExecuted;
julientiron 1:9efe863db15e 484 }
julientiron 0:cba942f8172a 485
julientiron 0:cba942f8172a 486 /******************************************************//**
julientiron 0:cba942f8172a 487 * @brief Changes the min speed of the specified shield
julientiron 0:cba942f8172a 488 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 489 * @param[in] newMinSpeed New min speed to apply in pps
julientiron 0:cba942f8172a 490 * @retval true if the command is successfully executed, else false
julientiron 1:9efe863db15e 491 * @note The command is not performed is the shield is executing
julientiron 0:cba942f8172a 492 * a MOVE or GOTO command (but it can be used during a RUN command).
julientiron 0:cba942f8172a 493 **********************************************************/
julientiron 0:cba942f8172a 494 bool Easyspin::SetMinSpeed(uint8_t shieldId, uint16_t newMinSpeed)
julientiron 1:9efe863db15e 495 {
julientiron 1:9efe863db15e 496 bool cmdExecuted = false;
julientiron 1:9efe863db15e 497 if ((newMinSpeed >= Easyspin_MIN_PWM_FREQ)&&
julientiron 1:9efe863db15e 498 (newMinSpeed < Easyspin_MAX_PWM_FREQ) &&
julientiron 1:9efe863db15e 499 (newMinSpeed <= shieldPrm[shieldId].maxSpeed) &&
julientiron 1:9efe863db15e 500 ((shieldPrm[shieldId].motionState == INACTIVE)||
julientiron 1:9efe863db15e 501 (shieldPrm[shieldId].commandExecuted == RUN_CMD))) {
julientiron 1:9efe863db15e 502 shieldPrm[shieldId].minSpeed = newMinSpeed;
julientiron 1:9efe863db15e 503 cmdExecuted = true;
julientiron 1:9efe863db15e 504 }
julientiron 1:9efe863db15e 505 return cmdExecuted;
julientiron 1:9efe863db15e 506 }
julientiron 0:cba942f8172a 507
julientiron 0:cba942f8172a 508 /******************************************************//**
julientiron 0:cba942f8172a 509 * @brief Stops the motor by using the shield deceleration
julientiron 0:cba942f8172a 510 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 511 * @retval true if the command is successfully executed, else false
julientiron 0:cba942f8172a 512 * @note The command is not performed is the shield is in INACTIVE state.
julientiron 0:cba942f8172a 513 **********************************************************/
julientiron 0:cba942f8172a 514 bool Easyspin::SoftStop(uint8_t shieldId)
julientiron 1:9efe863db15e 515 {
julientiron 1:9efe863db15e 516 bool cmdExecuted = false;
julientiron 1:9efe863db15e 517 if (shieldPrm[shieldId].motionState != INACTIVE) {
julientiron 1:9efe863db15e 518 shieldPrm[shieldId].commandExecuted = SOFT_STOP_CMD;
julientiron 1:9efe863db15e 519 cmdExecuted = true;
julientiron 1:9efe863db15e 520 }
julientiron 1:9efe863db15e 521 return (cmdExecuted);
julientiron 0:cba942f8172a 522 }
julientiron 0:cba942f8172a 523
julientiron 0:cba942f8172a 524 /******************************************************//**
julientiron 0:cba942f8172a 525 * @brief Locks until the shield state becomes Inactive
julientiron 0:cba942f8172a 526 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 527 * @retval None
julientiron 0:cba942f8172a 528 **********************************************************/
julientiron 0:cba942f8172a 529 void Easyspin::WaitWhileActive(uint8_t shieldId)
julientiron 1:9efe863db15e 530 {
julientiron 0:cba942f8172a 531 /* Wait while motor is running */
julientiron 0:cba942f8172a 532 while (GetShieldState(shieldId) != INACTIVE);
julientiron 0:cba942f8172a 533 }
julientiron 0:cba942f8172a 534
julientiron 0:cba942f8172a 535 /******************************************************//**
julientiron 0:cba942f8172a 536 * @brief Issue the Disable command to the Easyspin of the specified shield
julientiron 0:cba942f8172a 537 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 538 * @retval None
julientiron 0:cba942f8172a 539 **********************************************************/
julientiron 0:cba942f8172a 540 void Easyspin::CmdDisable(uint8_t shieldId)
julientiron 0:cba942f8172a 541 {
julientiron 1:9efe863db15e 542 SendCommand(shieldId, Easyspin_DISABLE);
julientiron 0:cba942f8172a 543 }
julientiron 0:cba942f8172a 544
julientiron 0:cba942f8172a 545 /******************************************************//**
julientiron 0:cba942f8172a 546 * @brief Issues the Enable command to the Easyspin of the specified shield
julientiron 0:cba942f8172a 547 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 548 * @retval None
julientiron 0:cba942f8172a 549 **********************************************************/
julientiron 0:cba942f8172a 550 void Easyspin::CmdEnable(uint8_t shieldId)
julientiron 0:cba942f8172a 551 {
julientiron 1:9efe863db15e 552 SendCommand(shieldId, Easyspin_ENABLE);
julientiron 0:cba942f8172a 553 }
julientiron 0:cba942f8172a 554
julientiron 0:cba942f8172a 555 /******************************************************//**
julientiron 0:cba942f8172a 556 * @brief Issues the GetParam command to the Easyspin of the specified shield
julientiron 0:cba942f8172a 557 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 558 * @param[in] param Register adress (Easyspin_ABS_POS, Easyspin_MARK,...)
julientiron 0:cba942f8172a 559 * @retval Register value
julientiron 0:cba942f8172a 560 **********************************************************/
julientiron 0:cba942f8172a 561 uint32_t Easyspin::CmdGetParam(uint8_t shieldId, Easyspin_Registers_t param)
julientiron 0:cba942f8172a 562 {
julientiron 1:9efe863db15e 563 uint32_t i;
julientiron 1:9efe863db15e 564 uint32_t spiRxData;
julientiron 1:9efe863db15e 565 uint8_t maxArgumentNbBytes = 0;
julientiron 1:9efe863db15e 566 uint8_t spiIndex = numberOfShields - shieldId - 1;
julientiron 1:9efe863db15e 567 bool itDisable = false;
julientiron 1:9efe863db15e 568
julientiron 1:9efe863db15e 569 do {
julientiron 1:9efe863db15e 570 spiPreemtionByIsr = false;
julientiron 1:9efe863db15e 571 if (itDisable) {
julientiron 1:9efe863db15e 572 /* re-enable interrupts if disable in previous iteration */
julientiron 1:9efe863db15e 573 flag.enable_irq();
julientiron 1:9efe863db15e 574 itDisable = false;
julientiron 1:9efe863db15e 575 }
julientiron 1:9efe863db15e 576
julientiron 1:9efe863db15e 577 for (i = 0; i < numberOfShields; i++) {
julientiron 1:9efe863db15e 578 spiTxBursts[0][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 579 spiTxBursts[1][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 580 spiTxBursts[2][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 581 spiTxBursts[3][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 582 spiRxBursts[1][i] = 0;
julientiron 1:9efe863db15e 583 spiRxBursts[2][i] = 0;
julientiron 1:9efe863db15e 584 spiRxBursts[3][i] = 0;
julientiron 1:9efe863db15e 585 }
julientiron 1:9efe863db15e 586 switch (param) {
julientiron 1:9efe863db15e 587 case Easyspin_ABS_POS:
julientiron 1:9efe863db15e 588 ;
julientiron 1:9efe863db15e 589 case Easyspin_MARK:
julientiron 1:9efe863db15e 590 spiTxBursts[0][spiIndex] = ((uint8_t)Easyspin_GET_PARAM )| (param);
julientiron 1:9efe863db15e 591 maxArgumentNbBytes = 3;
julientiron 1:9efe863db15e 592 break;
julientiron 1:9efe863db15e 593 case Easyspin_EL_POS:
julientiron 1:9efe863db15e 594 ;
julientiron 1:9efe863db15e 595 case Easyspin_CONFIG:
julientiron 1:9efe863db15e 596 ;
julientiron 1:9efe863db15e 597 case Easyspin_STATUS:
julientiron 1:9efe863db15e 598 spiTxBursts[1][spiIndex] = ((uint8_t)Easyspin_GET_PARAM )| (param);
julientiron 1:9efe863db15e 599 maxArgumentNbBytes = 2;
julientiron 1:9efe863db15e 600 break;
julientiron 1:9efe863db15e 601 default:
julientiron 1:9efe863db15e 602 spiTxBursts[2][spiIndex] = ((uint8_t)Easyspin_GET_PARAM )| (param);
julientiron 1:9efe863db15e 603 maxArgumentNbBytes = 1;
julientiron 1:9efe863db15e 604 }
julientiron 1:9efe863db15e 605
julientiron 1:9efe863db15e 606 /* Disable interruption before checking */
julientiron 1:9efe863db15e 607 /* pre-emption by ISR and SPI transfers*/
julientiron 1:9efe863db15e 608 flag.disable_irq();
julientiron 1:9efe863db15e 609 itDisable = true;
julientiron 1:9efe863db15e 610 } while (spiPreemtionByIsr); // check pre-emption by ISR
julientiron 1:9efe863db15e 611
julientiron 1:9efe863db15e 612 for (i = Easyspin_CMD_ARG_MAX_NB_BYTES-1-maxArgumentNbBytes;
julientiron 1:9efe863db15e 613 i < Easyspin_CMD_ARG_MAX_NB_BYTES;
julientiron 1:9efe863db15e 614 i++) {
julientiron 1:9efe863db15e 615 WriteBytes(&spiTxBursts[i][0],
julientiron 1:9efe863db15e 616 &spiRxBursts[i][0]);
julientiron 0:cba942f8172a 617 }
julientiron 1:9efe863db15e 618
julientiron 1:9efe863db15e 619 spiRxData = ((uint32_t)spiRxBursts[1][spiIndex] << 16)|
julientiron 1:9efe863db15e 620 (spiRxBursts[2][spiIndex] << 8) |
julientiron 1:9efe863db15e 621 (spiRxBursts[3][spiIndex]);
julientiron 1:9efe863db15e 622
julientiron 1:9efe863db15e 623 /* re-enable interrupts after SPI transfers*/
julientiron 1:9efe863db15e 624 flag.enable_irq();
julientiron 1:9efe863db15e 625
julientiron 1:9efe863db15e 626 return (spiRxData);
julientiron 0:cba942f8172a 627 }
julientiron 0:cba942f8172a 628
julientiron 0:cba942f8172a 629 /******************************************************//**
julientiron 0:cba942f8172a 630 * @brief Issues the GetStatus command to the Easyspin of the specified shield
julientiron 0:cba942f8172a 631 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 632 * @retval Status Register value
julientiron 0:cba942f8172a 633 * @note Once the GetStatus command is performed, the flags of the status register
julientiron 0:cba942f8172a 634 * are reset. This is not the case when the status register is read with the
julientiron 0:cba942f8172a 635 * GetParam command (via the functions ReadStatusRegister or CmdGetParam).
julientiron 0:cba942f8172a 636 **********************************************************/
julientiron 0:cba942f8172a 637 uint16_t Easyspin::CmdGetStatus(uint8_t shieldId)
julientiron 0:cba942f8172a 638 {
julientiron 1:9efe863db15e 639 uint32_t i;
julientiron 1:9efe863db15e 640 uint16_t status;
julientiron 1:9efe863db15e 641 uint8_t spiIndex = numberOfShields - shieldId - 1;
julientiron 1:9efe863db15e 642 bool itDisable = false;
julientiron 1:9efe863db15e 643
julientiron 1:9efe863db15e 644 do {
julientiron 1:9efe863db15e 645 spiPreemtionByIsr = false;
julientiron 1:9efe863db15e 646 if (itDisable) {
julientiron 1:9efe863db15e 647 /* re-enable interrupts if disable in previous iteration */
julientiron 1:9efe863db15e 648 flag.enable_irq();
julientiron 1:9efe863db15e 649 itDisable = false;
julientiron 1:9efe863db15e 650 }
julientiron 0:cba942f8172a 651
julientiron 1:9efe863db15e 652 for (i = 0; i < numberOfShields; i++) {
julientiron 1:9efe863db15e 653 spiTxBursts[0][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 654 spiTxBursts[1][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 655 spiTxBursts[2][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 656 spiRxBursts[1][i] = 0;
julientiron 1:9efe863db15e 657 spiRxBursts[2][i] = 0;
julientiron 1:9efe863db15e 658 }
julientiron 1:9efe863db15e 659 spiTxBursts[0][spiIndex] = Easyspin_GET_STATUS;
julientiron 0:cba942f8172a 660
julientiron 1:9efe863db15e 661 /* Disable interruption before checking */
julientiron 1:9efe863db15e 662 /* pre-emption by ISR and SPI transfers*/
julientiron 1:9efe863db15e 663 flag.disable_irq();
julientiron 1:9efe863db15e 664 itDisable = true;
julientiron 1:9efe863db15e 665 } while (spiPreemtionByIsr); // check pre-emption by ISR
julientiron 0:cba942f8172a 666
julientiron 1:9efe863db15e 667 for (i = 0; i < Easyspin_CMD_ARG_NB_BYTES_GET_STATUS + Easyspin_RSP_NB_BYTES_GET_STATUS; i++) {
julientiron 1:9efe863db15e 668 WriteBytes(&spiTxBursts[i][0], &spiRxBursts[i][0]);
julientiron 1:9efe863db15e 669 }
julientiron 1:9efe863db15e 670 status = (spiRxBursts[1][spiIndex] << 8) | (spiRxBursts[2][spiIndex]);
julientiron 1:9efe863db15e 671
julientiron 1:9efe863db15e 672 /* re-enable interrupts after SPI transfers*/
julientiron 1:9efe863db15e 673 flag.enable_irq();
julientiron 1:9efe863db15e 674
julientiron 1:9efe863db15e 675 return (status);
julientiron 0:cba942f8172a 676 }
julientiron 0:cba942f8172a 677
julientiron 0:cba942f8172a 678 /******************************************************//**
julientiron 0:cba942f8172a 679 * @brief Issues the Nop command to the Easyspin of the specified shield
julientiron 0:cba942f8172a 680 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 681 * @retval None
julientiron 0:cba942f8172a 682 **********************************************************/
julientiron 0:cba942f8172a 683 void Easyspin::CmdNop(uint8_t shieldId)
julientiron 0:cba942f8172a 684 {
julientiron 1:9efe863db15e 685 SendCommand(shieldId, Easyspin_NOP);
julientiron 0:cba942f8172a 686 }
julientiron 0:cba942f8172a 687
julientiron 0:cba942f8172a 688 /******************************************************//**
julientiron 0:cba942f8172a 689 * @brief Issues the SetParam command to the Easyspin of the specified shield
julientiron 0:cba942f8172a 690 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 691 * @param[in] param Register adress (Easyspin_ABS_POS, Easyspin_MARK,...)
julientiron 0:cba942f8172a 692 * @param[in] value Value to set in the register
julientiron 0:cba942f8172a 693 * @retval None
julientiron 0:cba942f8172a 694 **********************************************************/
julientiron 0:cba942f8172a 695 void Easyspin::CmdSetParam(uint8_t shieldId,
julientiron 1:9efe863db15e 696 Easyspin_Registers_t param,
julientiron 1:9efe863db15e 697 uint32_t value)
julientiron 0:cba942f8172a 698 {
julientiron 1:9efe863db15e 699 uint32_t i;
julientiron 1:9efe863db15e 700 uint8_t maxArgumentNbBytes = 0;
julientiron 1:9efe863db15e 701 uint8_t spiIndex = numberOfShields - shieldId - 1;
julientiron 1:9efe863db15e 702 bool itDisable = false;
julientiron 1:9efe863db15e 703 do {
julientiron 1:9efe863db15e 704 spiPreemtionByIsr = false;
julientiron 1:9efe863db15e 705 if (itDisable) {
julientiron 1:9efe863db15e 706 /* re-enable interrupts if disable in previous iteration */
julientiron 1:9efe863db15e 707 flag.enable_irq();//interrupts();
julientiron 1:9efe863db15e 708 itDisable = false;
julientiron 1:9efe863db15e 709 }
julientiron 1:9efe863db15e 710 for (i = 0; i < numberOfShields; i++) {
julientiron 1:9efe863db15e 711 spiTxBursts[0][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 712 spiTxBursts[1][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 713 spiTxBursts[2][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 714 spiTxBursts[3][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 715 }
julientiron 1:9efe863db15e 716 switch (param) {
julientiron 1:9efe863db15e 717 case Easyspin_ABS_POS:
julientiron 1:9efe863db15e 718 ;
julientiron 1:9efe863db15e 719 case Easyspin_MARK:
julientiron 1:9efe863db15e 720 spiTxBursts[0][spiIndex] = param;
julientiron 1:9efe863db15e 721 spiTxBursts[1][spiIndex] = (uint8_t)(value >> 16);
julientiron 1:9efe863db15e 722 spiTxBursts[2][spiIndex] = (uint8_t)(value >> 8);
julientiron 1:9efe863db15e 723 maxArgumentNbBytes = 3;
julientiron 1:9efe863db15e 724 break;
julientiron 1:9efe863db15e 725 case Easyspin_EL_POS:
julientiron 1:9efe863db15e 726 ;
julientiron 1:9efe863db15e 727 case Easyspin_CONFIG:
julientiron 1:9efe863db15e 728 spiTxBursts[1][spiIndex] = param;
julientiron 1:9efe863db15e 729 spiTxBursts[2][spiIndex] = (uint8_t)(value >> 8);
julientiron 1:9efe863db15e 730 maxArgumentNbBytes = 2;
julientiron 1:9efe863db15e 731 break;
julientiron 1:9efe863db15e 732 default:
julientiron 1:9efe863db15e 733 spiTxBursts[2][spiIndex] = param;
julientiron 1:9efe863db15e 734 maxArgumentNbBytes = 1;
julientiron 1:9efe863db15e 735 }
julientiron 1:9efe863db15e 736 spiTxBursts[3][spiIndex] = (uint8_t)(value);
julientiron 1:9efe863db15e 737
julientiron 1:9efe863db15e 738 /* Disable interruption before checking */
julientiron 1:9efe863db15e 739 /* pre-emption by ISR and SPI transfers*/
julientiron 1:9efe863db15e 740 flag.disable_irq();
julientiron 1:9efe863db15e 741 itDisable = true;
julientiron 1:9efe863db15e 742 } while (spiPreemtionByIsr); // check pre-emption by ISR
julientiron 1:9efe863db15e 743
julientiron 1:9efe863db15e 744 /* SPI transfer */
julientiron 1:9efe863db15e 745 for (i = Easyspin_CMD_ARG_MAX_NB_BYTES-1-maxArgumentNbBytes;
julientiron 1:9efe863db15e 746 i < Easyspin_CMD_ARG_MAX_NB_BYTES;
julientiron 1:9efe863db15e 747 i++) {
julientiron 1:9efe863db15e 748 WriteBytes(&spiTxBursts[i][0],&spiRxBursts[i][0]);
julientiron 0:cba942f8172a 749 }
julientiron 1:9efe863db15e 750 /* re-enable interrupts after SPI transfers*/
julientiron 1:9efe863db15e 751 flag.enable_irq();
julientiron 0:cba942f8172a 752 }
julientiron 0:cba942f8172a 753
julientiron 0:cba942f8172a 754 /******************************************************//**
julientiron 0:cba942f8172a 755 * @brief Reads the Status Register value
julientiron 0:cba942f8172a 756 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 757 * @retval Status register valued
julientiron 1:9efe863db15e 758 * @note The status register flags are not cleared
julientiron 0:cba942f8172a 759 * at the difference with CmdGetStatus()
julientiron 0:cba942f8172a 760 **********************************************************/
julientiron 0:cba942f8172a 761 uint16_t Easyspin::ReadStatusRegister(uint8_t shieldId)
julientiron 0:cba942f8172a 762 {
julientiron 1:9efe863db15e 763 return (CmdGetParam(shieldId,Easyspin_STATUS));
julientiron 0:cba942f8172a 764 }
julientiron 0:cba942f8172a 765
julientiron 0:cba942f8172a 766 /******************************************************//**
julientiron 0:cba942f8172a 767 * @brief Releases the Easyspin reset (pin set to High) of all shields
julientiron 0:cba942f8172a 768 * @param None
julientiron 0:cba942f8172a 769 * @retval None
julientiron 0:cba942f8172a 770 **********************************************************/
julientiron 0:cba942f8172a 771 void Easyspin::ReleaseReset(void)
julientiron 1:9efe863db15e 772 {
julientiron 1:9efe863db15e 773 reset = 1;
julientiron 0:cba942f8172a 774 }
julientiron 0:cba942f8172a 775
julientiron 0:cba942f8172a 776 /******************************************************//**
julientiron 0:cba942f8172a 777 * @brief Resets the Easyspin (reset pin set to low) of all shields
julientiron 0:cba942f8172a 778 * @param None
julientiron 0:cba942f8172a 779 * @retval None
julientiron 0:cba942f8172a 780 **********************************************************/
julientiron 0:cba942f8172a 781 void Easyspin::Reset(void)
julientiron 0:cba942f8172a 782 {
julientiron 1:9efe863db15e 783 reset = 0;
julientiron 0:cba942f8172a 784 }
julientiron 0:cba942f8172a 785
julientiron 0:cba942f8172a 786 /******************************************************//**
julientiron 1:9efe863db15e 787 * @brief Set the stepping mode
julientiron 0:cba942f8172a 788 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 789 * @param[in] stepMod from full step to 1/16 microstep as specified in enum Easyspin_STEP_SEL_t
julientiron 0:cba942f8172a 790 * @retval None
julientiron 0:cba942f8172a 791 **********************************************************/
julientiron 0:cba942f8172a 792 void Easyspin::SelectStepMode(uint8_t shieldId, Easyspin_STEP_SEL_t stepMod)
julientiron 0:cba942f8172a 793 {
julientiron 1:9efe863db15e 794 uint8_t stepModeRegister;
julientiron 1:9efe863db15e 795
julientiron 1:9efe863db15e 796 /* Eventually deactivate motor */
julientiron 1:9efe863db15e 797 if (shieldPrm[shieldId].motionState != INACTIVE) {
julientiron 1:9efe863db15e 798 HardStop(shieldId);
julientiron 1:9efe863db15e 799 }
julientiron 0:cba942f8172a 800
julientiron 1:9efe863db15e 801 /* Read Step mode register and clear STEP_SEL field */
julientiron 1:9efe863db15e 802 stepModeRegister = (uint8_t)(0xF8 & CmdGetParam(shieldId,Easyspin_STEP_MODE)) ;
julientiron 1:9efe863db15e 803
julientiron 1:9efe863db15e 804 /* Apply new step mode */
julientiron 1:9efe863db15e 805 CmdSetParam(shieldId, Easyspin_STEP_MODE, stepModeRegister | (uint8_t)stepMod);
julientiron 1:9efe863db15e 806
julientiron 1:9efe863db15e 807 /* Reset abs pos register */
julientiron 1:9efe863db15e 808 SetHome(shieldId);
julientiron 0:cba942f8172a 809 }
julientiron 0:cba942f8172a 810
julientiron 0:cba942f8172a 811 /******************************************************//**
julientiron 1:9efe863db15e 812 * @brief Specifies the direction
julientiron 0:cba942f8172a 813 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 814 * @param[in] dir FORWARD or BACKWARD
julientiron 1:9efe863db15e 815 * @note The direction change is only applied if the shield
julientiron 0:cba942f8172a 816 * is in INACTIVE state
julientiron 0:cba942f8172a 817 * @retval None
julientiron 0:cba942f8172a 818 **********************************************************/
julientiron 0:cba942f8172a 819 void Easyspin::SetDirection(uint8_t shieldId, dir_t dir)
julientiron 0:cba942f8172a 820 {
julientiron 1:9efe863db15e 821 if (shieldPrm[shieldId].motionState == INACTIVE) {
julientiron 1:9efe863db15e 822 shieldPrm[shieldId].direction = dir;
julientiron 1:9efe863db15e 823
julientiron 1:9efe863db15e 824 switch (shieldId) {
julientiron 1:9efe863db15e 825 case 2:
julientiron 1:9efe863db15e 826 dir3 = dir;
julientiron 1:9efe863db15e 827 break;
julientiron 1:9efe863db15e 828 case 1:
julientiron 1:9efe863db15e 829 dir2 = dir;
julientiron 1:9efe863db15e 830 break;
julientiron 1:9efe863db15e 831 case 0:
julientiron 1:9efe863db15e 832 dir1 = dir;
julientiron 1:9efe863db15e 833 break;
julientiron 1:9efe863db15e 834 default:
julientiron 1:9efe863db15e 835 ;
julientiron 1:9efe863db15e 836 }
julientiron 0:cba942f8172a 837 }
julientiron 0:cba942f8172a 838 }
julientiron 0:cba942f8172a 839
julientiron 0:cba942f8172a 840 /******************************************************//**
julientiron 0:cba942f8172a 841 * @brief Gets the pointer to the Easyspin instance
julientiron 0:cba942f8172a 842 * @param None
julientiron 0:cba942f8172a 843 * @retval Pointer to the instance of Easyspin
julientiron 0:cba942f8172a 844 **********************************************************/
julientiron 0:cba942f8172a 845 class Easyspin* Easyspin::GetInstancePtr(void)
julientiron 0:cba942f8172a 846 {
julientiron 1:9efe863db15e 847 return (class Easyspin*)instancePtr;
julientiron 0:cba942f8172a 848 }
julientiron 0:cba942f8172a 849
julientiron 0:cba942f8172a 850 /******************************************************//**
julientiron 0:cba942f8172a 851 * @brief Handles the shield state machine at each ste
julientiron 0:cba942f8172a 852 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 853 * @retval None
julientiron 0:cba942f8172a 854 * @note Must only be called by the timer ISR
julientiron 0:cba942f8172a 855 **********************************************************/
julientiron 0:cba942f8172a 856 void Easyspin::StepClockHandler(uint8_t shieldId)
julientiron 0:cba942f8172a 857 {
julientiron 1:9efe863db15e 858 /* Set isr flag */
julientiron 1:9efe863db15e 859 isrFlag = true;
julientiron 1:9efe863db15e 860
julientiron 1:9efe863db15e 861 /* Incrementation of the relative position */
julientiron 1:9efe863db15e 862 shieldPrm[shieldId].relativePos++;
julientiron 1:9efe863db15e 863
julientiron 1:9efe863db15e 864 /* Periodically check that estimated position is correct */
julientiron 1:9efe863db15e 865 if ((shieldPrm[shieldId].commandExecuted != RUN_CMD) &&
julientiron 1:9efe863db15e 866 ((shieldPrm[shieldId].relativePos % 10) == 00)) {
julientiron 1:9efe863db15e 867 uint32_t AbsPos= ConvertPosition(CmdGetParam(shieldId,Easyspin_ABS_POS));
julientiron 1:9efe863db15e 868
julientiron 1:9efe863db15e 869 /* Correct estimated position if needed */
julientiron 1:9efe863db15e 870 if (AbsPos != 0) {
julientiron 1:9efe863db15e 871 if ((shieldPrm[shieldId].direction == FORWARD) &&
julientiron 1:9efe863db15e 872 (AbsPos != shieldPrm[shieldId].currentPosition + shieldPrm[shieldId].relativePos)) {
julientiron 0:cba942f8172a 873 #ifdef _DEBUG_Easyspin
julientiron 1:9efe863db15e 874 snprintf(EasyspinStrOut, DEBUG_BUFFER_SIZE, "F EstPos:%ld RealPos: %ld\n",shieldPrm[shieldId].relativePos,(AbsPos - shieldPrm[shieldId].currentPosition));
julientiron 1:9efe863db15e 875 Serial.println(EasyspinStrOut);
julientiron 1:9efe863db15e 876 #endif
julientiron 1:9efe863db15e 877 shieldPrm[shieldId].relativePos = AbsPos - shieldPrm[shieldId].currentPosition;
julientiron 1:9efe863db15e 878
julientiron 1:9efe863db15e 879 } else if ((shieldPrm[shieldId].direction == BACKWARD) &&
julientiron 1:9efe863db15e 880 (AbsPos != shieldPrm[shieldId].currentPosition - shieldPrm[shieldId].relativePos)) {
julientiron 0:cba942f8172a 881 #ifdef _DEBUG_Easyspin
julientiron 1:9efe863db15e 882 snprintf(EasyspinStrOut, DEBUG_BUFFER_SIZE, "B EstPos:%ld RealPos: %ld\n",shieldPrm[shieldId].relativePos,(AbsPos - shieldPrm[shieldId].currentPosition));
julientiron 1:9efe863db15e 883 Serial.println(EasyspinStrOut);
julientiron 1:9efe863db15e 884 #endif
julientiron 1:9efe863db15e 885 shieldPrm[shieldId].relativePos = shieldPrm[shieldId].currentPosition - AbsPos;
julientiron 1:9efe863db15e 886 }
julientiron 0:cba942f8172a 887 }
julientiron 0:cba942f8172a 888 }
julientiron 1:9efe863db15e 889
julientiron 1:9efe863db15e 890 switch (shieldPrm[shieldId].motionState) {
julientiron 1:9efe863db15e 891 case ACCELERATING: {
julientiron 1:9efe863db15e 892 if ((shieldPrm[shieldId].commandExecuted == SOFT_STOP_CMD)||
julientiron 1:9efe863db15e 893 ((shieldPrm[shieldId].commandExecuted != RUN_CMD)&&
julientiron 1:9efe863db15e 894 (shieldPrm[shieldId].relativePos == shieldPrm[shieldId].startDecPos))) {
julientiron 1:9efe863db15e 895 shieldPrm[shieldId].motionState = DECELERATING;
julientiron 1:9efe863db15e 896 shieldPrm[shieldId].accu = 0;
julientiron 0:cba942f8172a 897 #ifdef _DEBUG_Easyspin
julientiron 1:9efe863db15e 898 snprintf(EasyspinStrOut, DEBUG_BUFFER_SIZE, "Acc->Dec: speed: %u relativepos: %ld \n",shieldPrm[shieldId].speed,shieldPrm[shieldId].relativePos);
julientiron 1:9efe863db15e 899 Serial.println(EasyspinStrOut);
julientiron 1:9efe863db15e 900 #endif
julientiron 1:9efe863db15e 901 } else if ((shieldPrm[shieldId].speed >= shieldPrm[shieldId].maxSpeed)||
julientiron 1:9efe863db15e 902 ((shieldPrm[shieldId].commandExecuted != RUN_CMD)&&
julientiron 1:9efe863db15e 903 (shieldPrm[shieldId].relativePos == shieldPrm[shieldId].endAccPos))) {
julientiron 1:9efe863db15e 904 shieldPrm[shieldId].motionState = STEADY;
julientiron 0:cba942f8172a 905 #ifdef _DEBUG_Easyspin
julientiron 1:9efe863db15e 906 snprintf(EasyspinStrOut, DEBUG_BUFFER_SIZE, "Acc->Steady: speed: %u relativepos: %ld \n",shieldPrm[shieldId].speed,shieldPrm[shieldId].relativePos);
julientiron 1:9efe863db15e 907 Serial.println(EasyspinStrOut);
julientiron 1:9efe863db15e 908 #endif
julientiron 1:9efe863db15e 909 } else {
julientiron 1:9efe863db15e 910 bool speedUpdated = false;
julientiron 1:9efe863db15e 911 /* Go on accelerating */
julientiron 1:9efe863db15e 912 shieldPrm[shieldId].accu += ((uint32_t)shieldPrm[shieldId].acceleration << 16) / shieldPrm[shieldId].speed;
julientiron 1:9efe863db15e 913 while (shieldPrm[shieldId].accu >= (0X10000L)) {
julientiron 1:9efe863db15e 914 shieldPrm[shieldId].accu -= (0X10000L);
julientiron 1:9efe863db15e 915 shieldPrm[shieldId].speed +=1;
julientiron 1:9efe863db15e 916 speedUpdated = true;
julientiron 1:9efe863db15e 917 }
julientiron 1:9efe863db15e 918
julientiron 1:9efe863db15e 919 if (speedUpdated) {
julientiron 1:9efe863db15e 920 ApplySpeed(shieldId, shieldPrm[shieldId].speed);
julientiron 1:9efe863db15e 921 }
julientiron 1:9efe863db15e 922 }
julientiron 1:9efe863db15e 923 break;
julientiron 1:9efe863db15e 924 }
julientiron 1:9efe863db15e 925 case STEADY: {
julientiron 1:9efe863db15e 926 if ((shieldPrm[shieldId].commandExecuted == SOFT_STOP_CMD)||
julientiron 1:9efe863db15e 927 ((shieldPrm[shieldId].commandExecuted != RUN_CMD)&&
julientiron 1:9efe863db15e 928 (shieldPrm[shieldId].relativePos >= (shieldPrm[shieldId].startDecPos))) ||
julientiron 1:9efe863db15e 929 ((shieldPrm[shieldId].commandExecuted == RUN_CMD)&&
julientiron 1:9efe863db15e 930 (shieldPrm[shieldId].speed > shieldPrm[shieldId].maxSpeed))) {
julientiron 1:9efe863db15e 931 shieldPrm[shieldId].motionState = DECELERATING;
julientiron 1:9efe863db15e 932 shieldPrm[shieldId].accu = 0;
julientiron 1:9efe863db15e 933 } else if ((shieldPrm[shieldId].commandExecuted == RUN_CMD)&&
julientiron 1:9efe863db15e 934 (shieldPrm[shieldId].speed < shieldPrm[shieldId].maxSpeed)) {
julientiron 1:9efe863db15e 935 shieldPrm[shieldId].motionState = ACCELERATING;
julientiron 1:9efe863db15e 936 shieldPrm[shieldId].accu = 0;
julientiron 1:9efe863db15e 937 }
julientiron 1:9efe863db15e 938 break;
julientiron 0:cba942f8172a 939 }
julientiron 1:9efe863db15e 940 case DECELERATING: {
julientiron 1:9efe863db15e 941 if (((shieldPrm[shieldId].commandExecuted == SOFT_STOP_CMD)&&(shieldPrm[shieldId].speed <= shieldPrm[shieldId].minSpeed))||
julientiron 1:9efe863db15e 942 ((shieldPrm[shieldId].commandExecuted != RUN_CMD)&&
julientiron 1:9efe863db15e 943 (shieldPrm[shieldId].relativePos >= shieldPrm[shieldId].stepsToTake))) {
julientiron 1:9efe863db15e 944 /* Motion process complete */
julientiron 1:9efe863db15e 945 HardStop(shieldId);
julientiron 1:9efe863db15e 946 #ifdef _DEBUG_Easyspin
julientiron 1:9efe863db15e 947 snprintf(EasyspinStrOut, DEBUG_BUFFER_SIZE, "Dec->Stop: speed: %u relativepos: %ld \n",shieldPrm[shieldId].speed,shieldPrm[shieldId].relativePos );
julientiron 1:9efe863db15e 948 Serial.println(EasyspinStrOut);
julientiron 1:9efe863db15e 949 #endif
julientiron 1:9efe863db15e 950 } else if ((shieldPrm[shieldId].commandExecuted == RUN_CMD)&&
julientiron 1:9efe863db15e 951 (shieldPrm[shieldId].speed <= shieldPrm[shieldId].maxSpeed)) {
julientiron 1:9efe863db15e 952 shieldPrm[shieldId].motionState = STEADY;
julientiron 1:9efe863db15e 953 #ifdef _DEBUG_Easyspin
julientiron 1:9efe863db15e 954 snprintf(EasyspinStrOut, DEBUG_BUFFER_SIZE, "Dec->Steady: speed: %u relativepos: %ld \n",shieldPrm[shieldId].speed,shieldPrm[shieldId].relativePos);
julientiron 1:9efe863db15e 955 Serial.println(EasyspinStrOut);
julientiron 1:9efe863db15e 956 #endif
julientiron 1:9efe863db15e 957 } else {
julientiron 1:9efe863db15e 958 /* Go on decelerating */
julientiron 1:9efe863db15e 959 if (shieldPrm[shieldId].speed > shieldPrm[shieldId].minSpeed) {
julientiron 1:9efe863db15e 960 bool speedUpdated = false;
julientiron 1:9efe863db15e 961 shieldPrm[shieldId].accu += ((uint32_t)shieldPrm[shieldId].deceleration << 16) / shieldPrm[shieldId].speed;
julientiron 1:9efe863db15e 962 while (shieldPrm[shieldId].accu >= (0X10000L)) {
julientiron 1:9efe863db15e 963 shieldPrm[shieldId].accu -= (0X10000L);
julientiron 1:9efe863db15e 964 shieldPrm[shieldId].speed -=1;
julientiron 1:9efe863db15e 965 speedUpdated = true;
julientiron 1:9efe863db15e 966 }
julientiron 1:9efe863db15e 967 if (speedUpdated) {
julientiron 1:9efe863db15e 968 ApplySpeed(shieldId, shieldPrm[shieldId].speed);
julientiron 1:9efe863db15e 969 }
julientiron 1:9efe863db15e 970 }
julientiron 1:9efe863db15e 971 }
julientiron 1:9efe863db15e 972 break;
julientiron 1:9efe863db15e 973 }
julientiron 1:9efe863db15e 974 default: {
julientiron 1:9efe863db15e 975 break;
julientiron 1:9efe863db15e 976 }
julientiron 0:cba942f8172a 977 }
julientiron 1:9efe863db15e 978 /* Set isr flag */
julientiron 1:9efe863db15e 979 isrFlag = false;
julientiron 0:cba942f8172a 980 }
julientiron 0:cba942f8172a 981
julientiron 0:cba942f8172a 982 /******************************************************//**
julientiron 0:cba942f8172a 983 * @brief Updates the current speed of the shield
julientiron 0:cba942f8172a 984 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 985 * @param[in] newSpeed in pps
julientiron 0:cba942f8172a 986 * @retval None
julientiron 0:cba942f8172a 987 **********************************************************/
julientiron 0:cba942f8172a 988 void Easyspin::ApplySpeed(uint8_t shieldId, uint16_t newSpeed)
julientiron 0:cba942f8172a 989 {
julientiron 1:9efe863db15e 990 if (newSpeed < Easyspin_MIN_PWM_FREQ) {
julientiron 1:9efe863db15e 991 newSpeed = Easyspin_MIN_PWM_FREQ;
julientiron 1:9efe863db15e 992 }
julientiron 1:9efe863db15e 993 if (newSpeed > Easyspin_MAX_PWM_FREQ) {
julientiron 1:9efe863db15e 994 newSpeed = Easyspin_MAX_PWM_FREQ;
julientiron 1:9efe863db15e 995 }
julientiron 1:9efe863db15e 996
julientiron 1:9efe863db15e 997 shieldPrm[shieldId].speed = newSpeed;
julientiron 0:cba942f8172a 998
julientiron 1:9efe863db15e 999 switch (shieldId) {
julientiron 1:9efe863db15e 1000 case 0:
julientiron 1:9efe863db15e 1001 Pwm1SetFreq(newSpeed);
julientiron 1:9efe863db15e 1002 break;
julientiron 1:9efe863db15e 1003 case 1:
julientiron 1:9efe863db15e 1004 Pwm2SetFreq(newSpeed);
julientiron 1:9efe863db15e 1005 break;
julientiron 1:9efe863db15e 1006 case 2:
julientiron 1:9efe863db15e 1007 Pwm3SetFreq(newSpeed);
julientiron 1:9efe863db15e 1008 break;
julientiron 1:9efe863db15e 1009 default:
julientiron 1:9efe863db15e 1010 break; //ignore error
julientiron 1:9efe863db15e 1011 }
julientiron 0:cba942f8172a 1012 }
julientiron 0:cba942f8172a 1013
julientiron 0:cba942f8172a 1014 /******************************************************//**
julientiron 0:cba942f8172a 1015 * @brief Computes the speed profile according to the number of steps to move
julientiron 0:cba942f8172a 1016 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 1017 * @param[in] nbSteps number of steps to perform
julientiron 0:cba942f8172a 1018 * @retval None
julientiron 0:cba942f8172a 1019 * @note Using the acceleration and deceleration of the shield,
julientiron 0:cba942f8172a 1020 * this function determines the duration in steps of the acceleration,
julientiron 0:cba942f8172a 1021 * steady and deceleration phases.
julientiron 0:cba942f8172a 1022 * If the total number of steps to perform is big enough, a trapezoidal move
julientiron 0:cba942f8172a 1023 * is performed (i.e. there is a steady phase where the motor runs at the maximum
julientiron 0:cba942f8172a 1024 * speed.
julientiron 0:cba942f8172a 1025 * Else, a triangular move is performed (no steady phase: the maximum speed is never
julientiron 0:cba942f8172a 1026 * reached.
julientiron 0:cba942f8172a 1027 **********************************************************/
julientiron 0:cba942f8172a 1028 void Easyspin::ComputeSpeedProfile(uint8_t shieldId, uint32_t nbSteps)
julientiron 0:cba942f8172a 1029 {
julientiron 1:9efe863db15e 1030 uint32_t reqAccSteps;
julientiron 0:cba942f8172a 1031 uint32_t reqDecSteps;
julientiron 1:9efe863db15e 1032
julientiron 1:9efe863db15e 1033 /* compute the number of steps to get the targeted speed */
julientiron 1:9efe863db15e 1034 reqAccSteps = (shieldPrm[shieldId].maxSpeed - shieldPrm[shieldId].minSpeed);
julientiron 1:9efe863db15e 1035 reqAccSteps *= (shieldPrm[shieldId].maxSpeed + shieldPrm[shieldId].minSpeed);
julientiron 1:9efe863db15e 1036 reqDecSteps = reqAccSteps;
julientiron 1:9efe863db15e 1037 reqAccSteps /= (uint32_t)shieldPrm[shieldId].acceleration;
julientiron 1:9efe863db15e 1038 reqAccSteps /= 2;
julientiron 0:cba942f8172a 1039
julientiron 1:9efe863db15e 1040 /* compute the number of steps to stop */
julientiron 1:9efe863db15e 1041 reqDecSteps /= (uint32_t)shieldPrm[shieldId].deceleration;
julientiron 1:9efe863db15e 1042 reqDecSteps /= 2;
julientiron 1:9efe863db15e 1043
julientiron 1:9efe863db15e 1044 if(( reqAccSteps + reqDecSteps ) > nbSteps) {
julientiron 1:9efe863db15e 1045 /* Triangular move */
julientiron 1:9efe863db15e 1046 /* reqDecSteps = (Pos * Dec) /(Dec+Acc) */
julientiron 0:cba942f8172a 1047
julientiron 1:9efe863db15e 1048 reqDecSteps = ((uint32_t) shieldPrm[shieldId].deceleration * nbSteps) / (shieldPrm[shieldId].acceleration + shieldPrm[shieldId].deceleration);
julientiron 1:9efe863db15e 1049 if (reqDecSteps > 1) {
julientiron 1:9efe863db15e 1050 reqAccSteps = reqDecSteps - 1;
julientiron 1:9efe863db15e 1051 if(reqAccSteps == 0) {
julientiron 1:9efe863db15e 1052 reqAccSteps = 1;
julientiron 1:9efe863db15e 1053 }
julientiron 1:9efe863db15e 1054 } else {
julientiron 1:9efe863db15e 1055 reqAccSteps = 0;
julientiron 1:9efe863db15e 1056 }
julientiron 1:9efe863db15e 1057 shieldPrm[shieldId].endAccPos = reqAccSteps;
julientiron 1:9efe863db15e 1058 shieldPrm[shieldId].startDecPos = reqDecSteps;
julientiron 1:9efe863db15e 1059 } else {
julientiron 1:9efe863db15e 1060 /* Trapezoidal move */
julientiron 1:9efe863db15e 1061 /* accelerating phase to endAccPos */
julientiron 1:9efe863db15e 1062 /* steady phase from endAccPos to startDecPos */
julientiron 1:9efe863db15e 1063 /* decelerating from startDecPos to stepsToTake*/
julientiron 1:9efe863db15e 1064 shieldPrm[shieldId].endAccPos = reqAccSteps;
julientiron 1:9efe863db15e 1065 shieldPrm[shieldId].startDecPos = nbSteps - reqDecSteps - 1;
julientiron 0:cba942f8172a 1066 }
julientiron 0:cba942f8172a 1067 }
julientiron 0:cba942f8172a 1068
julientiron 0:cba942f8172a 1069 /******************************************************//**
julientiron 0:cba942f8172a 1070 * @brief Converts the ABS_POSITION register value to a 32b signed integer
julientiron 0:cba942f8172a 1071 * @param[in] abs_position_reg value of the ABS_POSITION register
julientiron 1:9efe863db15e 1072 * @retval operation_result 32b signed integer corresponding to the absolute position
julientiron 0:cba942f8172a 1073 **********************************************************/
julientiron 0:cba942f8172a 1074 int32_t Easyspin::ConvertPosition(uint32_t abs_position_reg)
julientiron 0:cba942f8172a 1075 {
julientiron 0:cba942f8172a 1076 int32_t operation_result;
julientiron 0:cba942f8172a 1077
julientiron 1:9efe863db15e 1078 if (abs_position_reg & Easyspin_ABS_POS_SIGN_BIT_MASK) {
julientiron 0:cba942f8172a 1079 /* Negative register value */
julientiron 0:cba942f8172a 1080 abs_position_reg = ~abs_position_reg;
julientiron 0:cba942f8172a 1081 abs_position_reg += 1;
julientiron 0:cba942f8172a 1082
julientiron 0:cba942f8172a 1083 operation_result = (int32_t) (abs_position_reg & Easyspin_ABS_POS_VALUE_MASK);
julientiron 0:cba942f8172a 1084 operation_result = -operation_result;
julientiron 1:9efe863db15e 1085 } else {
julientiron 0:cba942f8172a 1086 operation_result = (int32_t) abs_position_reg;
julientiron 0:cba942f8172a 1087 }
julientiron 0:cba942f8172a 1088 return operation_result;
julientiron 0:cba942f8172a 1089 }
julientiron 0:cba942f8172a 1090
julientiron 0:cba942f8172a 1091 /******************************************************//**
julientiron 0:cba942f8172a 1092 * @brief Handlers of the flag interrupt which calls the user callback (if defined)
julientiron 0:cba942f8172a 1093 * @param None
julientiron 0:cba942f8172a 1094 * @retval None
julientiron 0:cba942f8172a 1095 **********************************************************/
julientiron 0:cba942f8172a 1096 void Easyspin::FlagInterruptHandler(void)
julientiron 0:cba942f8172a 1097 {
julientiron 1:9efe863db15e 1098 if (flagInterruptCallback != NULL) {
julientiron 1:9efe863db15e 1099 /* Set isr flag */
julientiron 1:9efe863db15e 1100 isrFlag = true;
julientiron 1:9efe863db15e 1101
julientiron 1:9efe863db15e 1102 flagInterruptCallback();
julientiron 1:9efe863db15e 1103
julientiron 1:9efe863db15e 1104 /* Reset isr flag */
julientiron 1:9efe863db15e 1105 isrFlag = false;
julientiron 1:9efe863db15e 1106 }
julientiron 0:cba942f8172a 1107 }
julientiron 0:cba942f8172a 1108
julientiron 0:cba942f8172a 1109 /******************************************************//**
julientiron 0:cba942f8172a 1110 * @brief Sends a command without arguments to the Easyspin via the SPI
julientiron 0:cba942f8172a 1111 * @param[in] shieldId (from 0 to 2)
julientiron 1:9efe863db15e 1112 * @param[in] param Command to send
julientiron 0:cba942f8172a 1113 * @retval None
julientiron 0:cba942f8172a 1114 **********************************************************/
julientiron 0:cba942f8172a 1115 void Easyspin::SendCommand(uint8_t shieldId, uint8_t param)
julientiron 0:cba942f8172a 1116 {
julientiron 1:9efe863db15e 1117 uint8_t spiIndex = numberOfShields - shieldId - 1;
julientiron 1:9efe863db15e 1118 bool itDisable = false;
julientiron 1:9efe863db15e 1119
julientiron 1:9efe863db15e 1120 do {
julientiron 1:9efe863db15e 1121 spiPreemtionByIsr = false;
julientiron 1:9efe863db15e 1122 if (itDisable) {
julientiron 1:9efe863db15e 1123 /* re-enable interrupts if disable in previous iteration */
julientiron 1:9efe863db15e 1124 flag.enable_irq();
julientiron 1:9efe863db15e 1125 itDisable = false;
julientiron 1:9efe863db15e 1126 }
julientiron 0:cba942f8172a 1127
julientiron 1:9efe863db15e 1128 for (uint32_t i = 0; i < numberOfShields; i++) {
julientiron 1:9efe863db15e 1129 spiTxBursts[3][i] = Easyspin_NOP;
julientiron 1:9efe863db15e 1130 }
julientiron 1:9efe863db15e 1131 spiTxBursts[3][spiIndex] = param;
julientiron 1:9efe863db15e 1132
julientiron 1:9efe863db15e 1133 /* Disable interruption before checking */
julientiron 1:9efe863db15e 1134 /* pre-emption by ISR and SPI transfers*/
julientiron 1:9efe863db15e 1135 flag.disable_irq();
julientiron 1:9efe863db15e 1136 itDisable = true;
julientiron 1:9efe863db15e 1137 } while (spiPreemtionByIsr); // check pre-emption by ISR
julientiron 1:9efe863db15e 1138
julientiron 1:9efe863db15e 1139 WriteBytes(&spiTxBursts[3][0], &spiRxBursts[3][0]);
julientiron 1:9efe863db15e 1140
julientiron 1:9efe863db15e 1141 /* re-enable interrupts after SPI transfers*/
julientiron 1:9efe863db15e 1142 flag.enable_irq();
julientiron 0:cba942f8172a 1143 }
julientiron 0:cba942f8172a 1144
julientiron 0:cba942f8172a 1145 /******************************************************//**
julientiron 1:9efe863db15e 1146 * @brief Sets the registers of the Easyspin to their predefined values
julientiron 0:cba942f8172a 1147 * from Easyspin_target_config.h
julientiron 0:cba942f8172a 1148 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 1149 * @retval None
julientiron 0:cba942f8172a 1150 **********************************************************/
julientiron 0:cba942f8172a 1151 void Easyspin::SetRegisterToPredefinedValues(uint8_t shieldId)
julientiron 0:cba942f8172a 1152 {
julientiron 1:9efe863db15e 1153 CmdSetParam(shieldId,
julientiron 1:9efe863db15e 1154 Easyspin_ABS_POS,
julientiron 1:9efe863db15e 1155 0);
julientiron 1:9efe863db15e 1156 CmdSetParam(shieldId,
julientiron 1:9efe863db15e 1157 Easyspin_EL_POS,
julientiron 1:9efe863db15e 1158 0);
julientiron 1:9efe863db15e 1159 CmdSetParam(shieldId,
julientiron 1:9efe863db15e 1160 Easyspin_MARK,
julientiron 1:9efe863db15e 1161 0);
julientiron 1:9efe863db15e 1162 switch (shieldId) {
julientiron 1:9efe863db15e 1163 case 0:
julientiron 1:9efe863db15e 1164 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1165 Easyspin_TVAL,
julientiron 0:cba942f8172a 1166 Tval_Current_to_Par(Easyspin_CONF_PARAM_TVAL_SHIELD_0));
julientiron 1:9efe863db15e 1167 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1168 Easyspin_T_FAST,
julientiron 0:cba942f8172a 1169 (uint8_t)Easyspin_CONF_PARAM_TOFF_FAST_SHIELD_0 |
julientiron 0:cba942f8172a 1170 (uint8_t)Easyspin_CONF_PARAM_FAST_STEP_SHIELD_0);
julientiron 1:9efe863db15e 1171 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1172 Easyspin_TON_MIN,
julientiron 0:cba942f8172a 1173 Tmin_Time_to_Par(Easyspin_CONF_PARAM_TON_MIN_SHIELD_0));
julientiron 1:9efe863db15e 1174 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1175 Easyspin_TOFF_MIN,
julientiron 0:cba942f8172a 1176 Tmin_Time_to_Par(Easyspin_CONF_PARAM_TOFF_MIN_SHIELD_0));
julientiron 1:9efe863db15e 1177 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1178 Easyspin_OCD_TH,
julientiron 0:cba942f8172a 1179 Easyspin_CONF_PARAM_OCD_TH_SHIELD_0);
julientiron 1:9efe863db15e 1180 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1181 Easyspin_STEP_MODE,
julientiron 0:cba942f8172a 1182 (uint8_t)Easyspin_CONF_PARAM_STEP_SEL_SHIELD_0 |
julientiron 0:cba942f8172a 1183 (uint8_t)Easyspin_CONF_PARAM_SYNC_SEL_SHIELD_0);
julientiron 1:9efe863db15e 1184 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1185 Easyspin_ALARM_EN,
julientiron 0:cba942f8172a 1186 Easyspin_CONF_PARAM_ALARM_EN_SHIELD_0);
julientiron 1:9efe863db15e 1187 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1188 Easyspin_CONFIG,
julientiron 0:cba942f8172a 1189 (uint16_t)Easyspin_CONF_PARAM_CLOCK_SETTING_SHIELD_0 |
julientiron 0:cba942f8172a 1190 (uint16_t)Easyspin_CONF_PARAM_TQ_REG_SHIELD_0 |
julientiron 0:cba942f8172a 1191 (uint16_t)Easyspin_CONF_PARAM_OC_SD_SHIELD_0 |
julientiron 0:cba942f8172a 1192 (uint16_t)Easyspin_CONF_PARAM_SR_SHIELD_0 |
julientiron 0:cba942f8172a 1193 (uint16_t)Easyspin_CONF_PARAM_TOFF_SHIELD_0);
julientiron 1:9efe863db15e 1194 break;
julientiron 1:9efe863db15e 1195 case 1:
julientiron 1:9efe863db15e 1196 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1197 Easyspin_TVAL,
julientiron 0:cba942f8172a 1198 Tval_Current_to_Par(Easyspin_CONF_PARAM_TVAL_SHIELD_1));
julientiron 1:9efe863db15e 1199 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1200 Easyspin_T_FAST,
julientiron 0:cba942f8172a 1201 (uint8_t)Easyspin_CONF_PARAM_TOFF_FAST_SHIELD_1 |
julientiron 0:cba942f8172a 1202 (uint8_t)Easyspin_CONF_PARAM_FAST_STEP_SHIELD_1);
julientiron 1:9efe863db15e 1203 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1204 Easyspin_TON_MIN,
julientiron 0:cba942f8172a 1205 Tmin_Time_to_Par(Easyspin_CONF_PARAM_TON_MIN_SHIELD_1));
julientiron 1:9efe863db15e 1206 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1207 Easyspin_TOFF_MIN,
julientiron 0:cba942f8172a 1208 Tmin_Time_to_Par(Easyspin_CONF_PARAM_TOFF_MIN_SHIELD_1));
julientiron 1:9efe863db15e 1209 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1210 Easyspin_OCD_TH,
julientiron 0:cba942f8172a 1211 Easyspin_CONF_PARAM_OCD_TH_SHIELD_1);
julientiron 1:9efe863db15e 1212 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1213 Easyspin_STEP_MODE,
julientiron 0:cba942f8172a 1214 (uint8_t)Easyspin_CONF_PARAM_STEP_SEL_SHIELD_1 |
julientiron 0:cba942f8172a 1215 (uint8_t)Easyspin_CONF_PARAM_SYNC_SEL_SHIELD_1);
julientiron 1:9efe863db15e 1216 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1217 Easyspin_ALARM_EN,
julientiron 0:cba942f8172a 1218 Easyspin_CONF_PARAM_ALARM_EN_SHIELD_1);
julientiron 1:9efe863db15e 1219 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1220 Easyspin_CONFIG,
julientiron 0:cba942f8172a 1221 (uint16_t)Easyspin_CONF_PARAM_CLOCK_SETTING_SHIELD_1 |
julientiron 0:cba942f8172a 1222 (uint16_t)Easyspin_CONF_PARAM_TQ_REG_SHIELD_1 |
julientiron 0:cba942f8172a 1223 (uint16_t)Easyspin_CONF_PARAM_OC_SD_SHIELD_1 |
julientiron 0:cba942f8172a 1224 (uint16_t)Easyspin_CONF_PARAM_SR_SHIELD_1 |
julientiron 0:cba942f8172a 1225 (uint16_t)Easyspin_CONF_PARAM_TOFF_SHIELD_1);
julientiron 1:9efe863db15e 1226 break;
julientiron 1:9efe863db15e 1227 case 2:
julientiron 1:9efe863db15e 1228 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1229 Easyspin_TVAL,
julientiron 0:cba942f8172a 1230 Tval_Current_to_Par(Easyspin_CONF_PARAM_TVAL_SHIELD_2));
julientiron 1:9efe863db15e 1231 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1232 Easyspin_T_FAST,
julientiron 0:cba942f8172a 1233 (uint8_t)Easyspin_CONF_PARAM_TOFF_FAST_SHIELD_2 |
julientiron 0:cba942f8172a 1234 (uint8_t)Easyspin_CONF_PARAM_FAST_STEP_SHIELD_2);
julientiron 1:9efe863db15e 1235 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1236 Easyspin_TON_MIN,
julientiron 0:cba942f8172a 1237 Tmin_Time_to_Par(Easyspin_CONF_PARAM_TON_MIN_SHIELD_2));
julientiron 1:9efe863db15e 1238 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1239 Easyspin_TOFF_MIN,
julientiron 0:cba942f8172a 1240 Tmin_Time_to_Par(Easyspin_CONF_PARAM_TOFF_MIN_SHIELD_2));
julientiron 1:9efe863db15e 1241 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1242 Easyspin_OCD_TH,
julientiron 0:cba942f8172a 1243 Easyspin_CONF_PARAM_OCD_TH_SHIELD_2);
julientiron 1:9efe863db15e 1244 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1245 Easyspin_STEP_MODE,
julientiron 0:cba942f8172a 1246 (uint8_t)Easyspin_CONF_PARAM_STEP_SEL_SHIELD_2 |
julientiron 0:cba942f8172a 1247 (uint8_t)Easyspin_CONF_PARAM_SYNC_SEL_SHIELD_2);
julientiron 1:9efe863db15e 1248 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1249 Easyspin_ALARM_EN,
julientiron 0:cba942f8172a 1250 Easyspin_CONF_PARAM_ALARM_EN_SHIELD_2);
julientiron 1:9efe863db15e 1251 CmdSetParam(shieldId,
julientiron 0:cba942f8172a 1252 Easyspin_CONFIG,
julientiron 0:cba942f8172a 1253 (uint16_t)Easyspin_CONF_PARAM_CLOCK_SETTING_SHIELD_2 |
julientiron 0:cba942f8172a 1254 (uint16_t)Easyspin_CONF_PARAM_TQ_REG_SHIELD_2 |
julientiron 0:cba942f8172a 1255 (uint16_t)Easyspin_CONF_PARAM_OC_SD_SHIELD_2 |
julientiron 0:cba942f8172a 1256 (uint16_t)Easyspin_CONF_PARAM_SR_SHIELD_2 |
julientiron 0:cba942f8172a 1257 (uint16_t)Easyspin_CONF_PARAM_TOFF_SHIELD_2);
julientiron 1:9efe863db15e 1258 break;
julientiron 1:9efe863db15e 1259 default:
julientiron 1:9efe863db15e 1260 ;
julientiron 1:9efe863db15e 1261 }
julientiron 0:cba942f8172a 1262 }
julientiron 0:cba942f8172a 1263
julientiron 0:cba942f8172a 1264 /******************************************************//**
julientiron 1:9efe863db15e 1265 * @brief Sets the registers of the Easyspin to their predefined values
julientiron 0:cba942f8172a 1266 * from Easyspin_target_config.h
julientiron 0:cba942f8172a 1267 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 1268 * @retval None
julientiron 0:cba942f8172a 1269 **********************************************************/
julientiron 0:cba942f8172a 1270 void Easyspin::WriteBytes(uint8_t *pByteToTransmit, uint8_t *pReceivedByte)
julientiron 0:cba942f8172a 1271 {
julientiron 1:9efe863db15e 1272 CS = 0;
julientiron 1:9efe863db15e 1273 for (uint32_t i = 0; i < numberOfShields; i++) {
julientiron 1:9efe863db15e 1274 *pReceivedByte = spi.write(*pByteToTransmit);
julientiron 1:9efe863db15e 1275 pByteToTransmit++;
julientiron 1:9efe863db15e 1276 pReceivedByte++;
julientiron 1:9efe863db15e 1277 }
julientiron 1:9efe863db15e 1278 CS = 1;
julientiron 1:9efe863db15e 1279 if (isrFlag) {
julientiron 1:9efe863db15e 1280 spiPreemtionByIsr = true;
julientiron 1:9efe863db15e 1281 }
julientiron 0:cba942f8172a 1282 }
julientiron 0:cba942f8172a 1283
julientiron 0:cba942f8172a 1284 /******************************************************//**
julientiron 0:cba942f8172a 1285 * @brief Initialises the PWM uses by the specified shield
julientiron 0:cba942f8172a 1286 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 1287 * @retval None
julientiron 1:9efe863db15e 1288 * @note Shield 0 uses PW1 based on timer 1
julientiron 0:cba942f8172a 1289 * Shield 1 uses PWM 2 based on timer 2
julientiron 0:cba942f8172a 1290 * Shield 2 uses PWM3 based timer 0
julientiron 0:cba942f8172a 1291 **********************************************************/
julientiron 0:cba942f8172a 1292 void Easyspin::PwmInit(uint8_t shieldId)
julientiron 0:cba942f8172a 1293 {
julientiron 1:9efe863db15e 1294 switch (shieldId) {
julientiron 1:9efe863db15e 1295 case 0:
julientiron 1:9efe863db15e 1296 /* PWM1 uses timer 1 */
julientiron 1:9efe863db15e 1297 /* Initialise timer by setting waveform generation mode
julientiron 1:9efe863db15e 1298 to PWM phase and Frequency correct: mode = 8
julientiron 1:9efe863db15e 1299 (WGM10 = 0, WGM11 = 0, WGM12 = 0, WGM13 = 1) */
julientiron 1:9efe863db15e 1300
julientiron 1:9efe863db15e 1301 /* Stop timer1 by clearing CSS bits and set WGM13 and WGM12 */
julientiron 1:9efe863db15e 1302 //TCCR1B = 0x10;
julientiron 1:9efe863db15e 1303
julientiron 1:9efe863db15e 1304 /* Set WGM10 and WGM11 */
julientiron 1:9efe863db15e 1305 //TCCR1A = 0x00;
julientiron 1:9efe863db15e 1306
julientiron 1:9efe863db15e 1307 /* Disable Timer1 interrupt */
julientiron 1:9efe863db15e 1308 //TIMSK1 = 0;
julientiron 1:9efe863db15e 1309 //pwm1.period_us(400);
julientiron 1:9efe863db15e 1310 //pwm1.pulsewidth_us(200);
julientiron 1:9efe863db15e 1311
julientiron 1:9efe863db15e 1312 break;
julientiron 1:9efe863db15e 1313 case 1:
julientiron 1:9efe863db15e 1314 /* PWM2 uses timer 2 */
julientiron 1:9efe863db15e 1315 /* Initialise timer by setting waveform generation mode
julientiron 1:9efe863db15e 1316 to PWM phase correct: mode = 5
julientiron 1:9efe863db15e 1317 (WGM0 = 1, WGM21 = 0, WGM22 = 1) */
julientiron 1:9efe863db15e 1318
julientiron 1:9efe863db15e 1319 /* Stop timer2 by clearing CSS bits and set WGM22 */
julientiron 1:9efe863db15e 1320 //TCCR2B = 0x08;
julientiron 1:9efe863db15e 1321
julientiron 1:9efe863db15e 1322 /* Set WGM20 and WGM21 */
julientiron 1:9efe863db15e 1323 //TCCR2A = 0x01;
julientiron 1:9efe863db15e 1324
julientiron 1:9efe863db15e 1325 /* Disable Timer2 interrupt */
julientiron 1:9efe863db15e 1326 //TIMSK2 = 0;
julientiron 1:9efe863db15e 1327 //pwm2.period_us(500);
julientiron 1:9efe863db15e 1328 //pwm2.pulsewidth_us(100);
julientiron 1:9efe863db15e 1329 break;
julientiron 0:cba942f8172a 1330
julientiron 0:cba942f8172a 1331
julientiron 1:9efe863db15e 1332 case 2:
julientiron 1:9efe863db15e 1333 /* PWM3 uses timer 0 */
julientiron 1:9efe863db15e 1334 /* !!!!! Caution: Calling this configuration will break */
julientiron 1:9efe863db15e 1335 /* all default Arduino's timing functions as delay(),millis()... */
julientiron 1:9efe863db15e 1336
julientiron 1:9efe863db15e 1337 /* Initialise timer by setting waveform generation mode
julientiron 1:9efe863db15e 1338 to PWM phase correct: mode = 5
julientiron 1:9efe863db15e 1339 (WGM0 = 1, WGM21 = 0, WGM22 = 1) */
julientiron 1:9efe863db15e 1340
julientiron 1:9efe863db15e 1341 /* Stop timer0 by clearing CSS bits and set WGM22 */
julientiron 1:9efe863db15e 1342 //TCCR0B = 0x08;
julientiron 1:9efe863db15e 1343
julientiron 1:9efe863db15e 1344 /* Set WGM00 and WGM01 */
julientiron 1:9efe863db15e 1345 //TCCR0A = 0x01;
julientiron 1:9efe863db15e 1346
julientiron 1:9efe863db15e 1347 /* Disable Timer0 interrupt */
julientiron 1:9efe863db15e 1348 //TIMSK0 = 0;
julientiron 1:9efe863db15e 1349 //pwm3.period_ms(10);
julientiron 1:9efe863db15e 1350 //pwm3.pulsewidth_ms(1);
julientiron 1:9efe863db15e 1351 break;
julientiron 1:9efe863db15e 1352 default:
julientiron 1:9efe863db15e 1353 break;//ignore error
julientiron 1:9efe863db15e 1354 }
julientiron 1:9efe863db15e 1355 }
julientiron 1:9efe863db15e 1356
julientiron 1:9efe863db15e 1357 /******************************************************//**
julientiron 1:9efe863db15e 1358 * @brief Ticker1
julientiron 1:9efe863db15e 1359 * @param[in]
julientiron 1:9efe863db15e 1360 * @retval
julientiron 1:9efe863db15e 1361 **********************************************************/
julientiron 1:9efe863db15e 1362 void Easyspin::tick1()
julientiron 1:9efe863db15e 1363 {
julientiron 1:9efe863db15e 1364 class Easyspin* instancePtr = Easyspin::GetInstancePtr();
julientiron 1:9efe863db15e 1365 pwm1 = !pwm1;
julientiron 1:9efe863db15e 1366 if (instancePtr != NULL) {
julientiron 1:9efe863db15e 1367 if (instancePtr->GetShieldState(0) != INACTIVE) {
julientiron 1:9efe863db15e 1368 instancePtr->StepClockHandler(0);
julientiron 1:9efe863db15e 1369 }
julientiron 1:9efe863db15e 1370 }
julientiron 1:9efe863db15e 1371 }
julientiron 1:9efe863db15e 1372
julientiron 1:9efe863db15e 1373 /******************************************************//**
julientiron 1:9efe863db15e 1374 * @brief Ticker2
julientiron 1:9efe863db15e 1375 * @param[in]
julientiron 1:9efe863db15e 1376 * @retval
julientiron 1:9efe863db15e 1377 **********************************************************/
julientiron 1:9efe863db15e 1378 void Easyspin::tick2()
julientiron 1:9efe863db15e 1379 {
julientiron 1:9efe863db15e 1380 class Easyspin* instancePtr = Easyspin::GetInstancePtr();
julientiron 1:9efe863db15e 1381 pwm2 = !pwm2;
julientiron 1:9efe863db15e 1382 if (instancePtr != NULL) {
julientiron 1:9efe863db15e 1383 if (instancePtr->GetShieldState(1) != INACTIVE) {
julientiron 1:9efe863db15e 1384 instancePtr->StepClockHandler(1);
julientiron 1:9efe863db15e 1385 }
julientiron 1:9efe863db15e 1386 }
julientiron 0:cba942f8172a 1387 }
julientiron 0:cba942f8172a 1388
julientiron 0:cba942f8172a 1389 /******************************************************//**
julientiron 0:cba942f8172a 1390 * @brief Sets the frequency of PWM1 used by shield 0
julientiron 0:cba942f8172a 1391 * @param[in] newFreq in Hz
julientiron 0:cba942f8172a 1392 * @retval None
julientiron 0:cba942f8172a 1393 * @note The frequency is directly the current speed of the shield
julientiron 0:cba942f8172a 1394 **********************************************************/
julientiron 0:cba942f8172a 1395 void Easyspin::Pwm1SetFreq(uint16_t newFreq)
julientiron 0:cba942f8172a 1396 {
julientiron 1:9efe863db15e 1397 uint16_t us;
julientiron 1:9efe863db15e 1398 us = (1000000 / (newFreq * 2));
julientiron 1:9efe863db15e 1399 ticker1.attach_us(this, &Easyspin::tick1, us);
julientiron 0:cba942f8172a 1400 }
julientiron 0:cba942f8172a 1401
julientiron 0:cba942f8172a 1402 /******************************************************//**
julientiron 0:cba942f8172a 1403 * @brief Sets the frequency of PWM2 used by shield 1
julientiron 0:cba942f8172a 1404 * @param[in] newFreq in Hz
julientiron 0:cba942f8172a 1405 * @retval None
julientiron 0:cba942f8172a 1406 * @note The frequency is directly the current speed of the shield
julientiron 0:cba942f8172a 1407 **********************************************************/
julientiron 0:cba942f8172a 1408 void Easyspin::Pwm2SetFreq(uint16_t newFreq)
julientiron 0:cba942f8172a 1409 {
julientiron 1:9efe863db15e 1410 uint16_t us;
julientiron 1:9efe863db15e 1411 us = (1000000 / (newFreq * 2));
julientiron 1:9efe863db15e 1412 ticker2.attach_us(this, &Easyspin::tick2, us);
julientiron 0:cba942f8172a 1413 }
julientiron 0:cba942f8172a 1414
julientiron 0:cba942f8172a 1415 /******************************************************//**
julientiron 0:cba942f8172a 1416 * @brief Sets the frequency of PWM3 used by shield 2
julientiron 0:cba942f8172a 1417 * @param[in] newFreq in Hz
julientiron 0:cba942f8172a 1418 * @retval None
julientiron 0:cba942f8172a 1419 * @note The frequency is directly the current speed of the shield
julientiron 0:cba942f8172a 1420 **********************************************************/
julientiron 0:cba942f8172a 1421 void Easyspin::Pwm3SetFreq(uint16_t newFreq)
julientiron 0:cba942f8172a 1422 {
julientiron 1:9efe863db15e 1423
julientiron 0:cba942f8172a 1424 }
julientiron 0:cba942f8172a 1425
julientiron 0:cba942f8172a 1426 /******************************************************//**
julientiron 0:cba942f8172a 1427 * @brief Stops the PWM uses by the specified shield
julientiron 0:cba942f8172a 1428 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 1429 * @retval None
julientiron 0:cba942f8172a 1430 **********************************************************/
julientiron 0:cba942f8172a 1431 void Easyspin::PwmStop(uint8_t shieldId)
julientiron 0:cba942f8172a 1432 {
julientiron 1:9efe863db15e 1433 switch (shieldId) {
julientiron 1:9efe863db15e 1434 case 0:
julientiron 1:9efe863db15e 1435 ticker1.detach();
julientiron 1:9efe863db15e 1436 break;
julientiron 1:9efe863db15e 1437 case 1:
julientiron 1:9efe863db15e 1438 ticker2.detach();
julientiron 1:9efe863db15e 1439 break;
julientiron 1:9efe863db15e 1440 case 2:
julientiron 1:9efe863db15e 1441 ticker3.detach();
julientiron 1:9efe863db15e 1442 break;
julientiron 1:9efe863db15e 1443 default:
julientiron 1:9efe863db15e 1444 break;//ignore error
julientiron 1:9efe863db15e 1445 }
julientiron 0:cba942f8172a 1446 }
julientiron 0:cba942f8172a 1447
julientiron 0:cba942f8172a 1448 /******************************************************//**
julientiron 0:cba942f8172a 1449 * @brief Sets the parameters of the shield to predefined values
julientiron 0:cba942f8172a 1450 * from Easyspin_target_config.h
julientiron 0:cba942f8172a 1451 * @param None
julientiron 0:cba942f8172a 1452 * @retval None
julientiron 0:cba942f8172a 1453 **********************************************************/
julientiron 0:cba942f8172a 1454 void Easyspin::SetShieldParamsToPredefinedValues(void)
julientiron 0:cba942f8172a 1455 {
julientiron 1:9efe863db15e 1456 shieldPrm[0].acceleration = Easyspin_CONF_PARAM_ACC_SHIELD_0;
julientiron 1:9efe863db15e 1457 shieldPrm[0].deceleration = Easyspin_CONF_PARAM_DEC_SHIELD_0;
julientiron 1:9efe863db15e 1458 shieldPrm[0].maxSpeed = Easyspin_CONF_PARAM_MAX_SPEED_SHIELD_0;
julientiron 1:9efe863db15e 1459 shieldPrm[0].minSpeed = Easyspin_CONF_PARAM_MIN_SPEED_SHIELD_0;
julientiron 1:9efe863db15e 1460
julientiron 1:9efe863db15e 1461 shieldPrm[1].acceleration = Easyspin_CONF_PARAM_ACC_SHIELD_1;
julientiron 1:9efe863db15e 1462 shieldPrm[1].deceleration = Easyspin_CONF_PARAM_DEC_SHIELD_1;
julientiron 1:9efe863db15e 1463 shieldPrm[1].maxSpeed = Easyspin_CONF_PARAM_MAX_SPEED_SHIELD_1;
julientiron 1:9efe863db15e 1464 shieldPrm[1].minSpeed = Easyspin_CONF_PARAM_MIN_SPEED_SHIELD_1;
julientiron 1:9efe863db15e 1465
julientiron 1:9efe863db15e 1466 shieldPrm[2].acceleration = Easyspin_CONF_PARAM_ACC_SHIELD_2;
julientiron 1:9efe863db15e 1467 shieldPrm[2].deceleration = Easyspin_CONF_PARAM_DEC_SHIELD_2;
julientiron 1:9efe863db15e 1468 shieldPrm[2].maxSpeed = Easyspin_CONF_PARAM_MAX_SPEED_SHIELD_2;
julientiron 1:9efe863db15e 1469 shieldPrm[2].minSpeed = Easyspin_CONF_PARAM_MIN_SPEED_SHIELD_2;
julientiron 1:9efe863db15e 1470
julientiron 1:9efe863db15e 1471 for (uint8_t i = 0; i < numberOfShields; i++) {
julientiron 1:9efe863db15e 1472 SetRegisterToPredefinedValues(i);
julientiron 1:9efe863db15e 1473 }
julientiron 0:cba942f8172a 1474 }
julientiron 0:cba942f8172a 1475
julientiron 0:cba942f8172a 1476 /******************************************************//**
julientiron 0:cba942f8172a 1477 * @brief Initialises the bridge parameters to start the movement
julientiron 0:cba942f8172a 1478 * and enable the power bridge
julientiron 0:cba942f8172a 1479 * @param[in] shieldId (from 0 to 2)
julientiron 0:cba942f8172a 1480 * @retval None
julientiron 0:cba942f8172a 1481 **********************************************************/
julientiron 1:9efe863db15e 1482 void Easyspin::StartMovement(uint8_t shieldId)
julientiron 0:cba942f8172a 1483 {
julientiron 1:9efe863db15e 1484 /* Enable Easyspin powerstage */
julientiron 1:9efe863db15e 1485 CmdEnable(shieldId);
julientiron 0:cba942f8172a 1486
julientiron 1:9efe863db15e 1487 if (shieldPrm[shieldId].endAccPos != 0) {
julientiron 1:9efe863db15e 1488 shieldPrm[shieldId].motionState = ACCELERATING;;
julientiron 1:9efe863db15e 1489 } else {
julientiron 1:9efe863db15e 1490 shieldPrm[shieldId].motionState = DECELERATING;
julientiron 1:9efe863db15e 1491 }
julientiron 0:cba942f8172a 1492
julientiron 1:9efe863db15e 1493 shieldPrm[shieldId].accu = 0;
julientiron 1:9efe863db15e 1494 shieldPrm[shieldId].relativePos = 0;
julientiron 1:9efe863db15e 1495 ApplySpeed(shieldId, shieldPrm[shieldId].minSpeed);
julientiron 0:cba942f8172a 1496 #ifdef _DEBUG_Easyspin
julientiron 1:9efe863db15e 1497 snprintf(EasyspinStrOut, DEBUG_BUFFER_SIZE, "Stop->Acc: speed: %u relPos: %ld\n", shieldPrm[shieldId].minSpeed, shieldPrm[shieldId].relativePos) ;
julientiron 1:9efe863db15e 1498 Serial.println(EasyspinStrOut);
julientiron 1:9efe863db15e 1499 #endif
julientiron 0:cba942f8172a 1500 }
julientiron 0:cba942f8172a 1501
julientiron 0:cba942f8172a 1502 /******************************************************//**
julientiron 1:9efe863db15e 1503 * @brief Converts mA in compatible values for TVAL register
julientiron 0:cba942f8172a 1504 * @param[in] Tval
julientiron 0:cba942f8172a 1505 * @retval TVAL values
julientiron 0:cba942f8172a 1506 **********************************************************/
julientiron 0:cba942f8172a 1507 inline uint8_t Easyspin::Tval_Current_to_Par(double Tval)
julientiron 0:cba942f8172a 1508 {
julientiron 1:9efe863db15e 1509 return ((uint8_t)(((Tval - 31.25)/31.25)+0.5));
julientiron 0:cba942f8172a 1510 }
julientiron 0:cba942f8172a 1511
julientiron 0:cba942f8172a 1512 /******************************************************//**
julientiron 1:9efe863db15e 1513 * @brief Convert time in us in compatible values
julientiron 0:cba942f8172a 1514 * for TON_MIN register
julientiron 0:cba942f8172a 1515 * @param[in] Tmin
julientiron 0:cba942f8172a 1516 * @retval TON_MIN values
julientiron 0:cba942f8172a 1517 **********************************************************/
julientiron 0:cba942f8172a 1518 inline uint8_t Easyspin::Tmin_Time_to_Par(double Tmin)
julientiron 0:cba942f8172a 1519 {
julientiron 1:9efe863db15e 1520 return ((uint8_t)(((Tmin - 0.5)*2)+0.5));
julientiron 0:cba942f8172a 1521 }