Skip to content

Commit 4146a7b

Browse files
committed
I2CCommander supports new FOCMotorStatus
1 parent fe7a3ab commit 4146a7b

File tree

3 files changed

+27
-36
lines changed

3 files changed

+27
-36
lines changed

src/comms/i2c/I2CCommander.cpp

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,6 @@ void I2CCommander::addMotor(FOCMotor* motor){
2323

2424

2525

26-
I2CCommander_Motor_Status I2CCommander::getMotorStatus(uint8_t motorNum){
27-
if (motorNum<numMotors){
28-
if (motors[motorNum]->zero_electric_angle==NOT_SET) // TODO detect open-loop uninitialized state!
29-
return I2CCommander_Motor_Status::MOT_UNINITIALIZED;
30-
if (motors[motorNum]->enabled==0)
31-
return I2CCommander_Motor_Status::MOT_DISABLED;
32-
if (motors[motorNum]->shaft_velocity >= I2CCOMMANDER_MIN_VELOCITY_FOR_MOTOR_MOVING)
33-
return I2CCommander_Motor_Status::MOT_MOVING;
34-
return I2CCommander_Motor_Status::MOT_IDLE;
35-
}
36-
return I2CCommander_Motor_Status::MOT_UNKNOWN;
37-
};
38-
39-
40-
4126

4227
bool I2CCommander::readBytes(void* valueToSet, uint8_t numBytes){
4328
if (_wire->available()>=numBytes){
@@ -85,7 +70,17 @@ void I2CCommander::onRequest(){
8570

8671

8772

73+
/*
74+
Reads values from I2C bus and updates the motor's values.
75+
76+
Currently this isn't really thread-safe, but works ok in practice on 32-bit MCUs.
8877
78+
Do not use on 8-bit architectures where the 32 bit writes may not be atomic!
79+
80+
Plan to make this safe: the writes should be buffered, and not actually executed
81+
until in the main loop by calling commander->run();
82+
the run() method disables interrupts while the updates happen.
83+
*/
8984
bool I2CCommander::receiveRegister(uint8_t motorNum, uint8_t registerNum, int numBytes) {
9085
int val;
9186
float floatval;
@@ -230,7 +225,23 @@ bool I2CCommander::receiveRegister(uint8_t motorNum, uint8_t registerNum, int nu
230225

231226

232227

228+
/*
229+
Reads values from motor/sensor and writes them to I2C bus. Intended to be run
230+
from the Wire.onRequest interrupt.
231+
232+
Assumes atomic 32 bit reads. On 8-bit arduino this assumption does not hold and this
233+
code is not safe on those platforms. You might read "half-written" floats.
234+
235+
A solution might be to maintain a complete set of shadow registers in the commander
236+
class, and update them in the run() method (which runs with interrupts off). Not sure
237+
of the performance impact of all those 32 bit read/writes though. In any case, since
238+
I use only 32 bit MCUs I'll leave it as an excercise to the one who needs it. ;-)
233239
240+
On 32 bit platforms the implication is that reads will occur atomically, so data will
241+
be intact, but they can occur at any time during motor updates, so different values might
242+
not be in a fully consistent state (i.e. phase A current might be from the current iteration
243+
but phase B current from the previous iteration).
244+
*/
234245
bool I2CCommander::sendRegister(uint8_t motorNum, uint8_t registerNum) {
235246
// read the current register
236247
switch(registerNum) {
@@ -239,8 +250,7 @@ bool I2CCommander::sendRegister(uint8_t motorNum, uint8_t registerNum) {
239250
_wire->write((uint8_t)lastcommandregister);
240251
_wire->write((uint8_t)lastcommanderror+1);
241252
for (int i=0;(i<numMotors && i<28); i++) { // at most 28 motors, so we can fit in one packet
242-
uint8_t status = (uint8_t)getMotorStatus(i);
243-
_wire->write(status);
253+
_wire->write(motors[motorNum]->motor_status);
244254
}
245255
break;
246256
case REG_MOTOR_ADDRESS:

src/comms/i2c/I2CCommander.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ class I2CCommander {
2626
void onReceive(int numBytes);
2727
void onRequest();
2828

29-
I2CCommander_Motor_Status getMotorStatus(uint8_t motorNum);
30-
3129
protected:
3230
void writeFloat(float value);
3331
bool readBytes(void* valueToSet, uint8_t numBytes);

src/comms/i2c/I2CCommanderRegisters.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,6 @@ typedef enum : uint8_t {
6262

6363

6464

65-
// TODO stati are work in progress. For example, it would be good to differentiate between not moving because stalled,
66-
// and not moving because target set-point has been reached. It would be good to be able to track initialization state
67-
// and error state.
68-
typedef enum : uint8_t {
69-
MOT_UNINITIALIZED = 0x00, // Motor is not initialized
70-
MOT_INITIALIZING = 0x01, // TODO - this status is not used at the moment, can't detect it
71-
72-
MOT_DISABLED = 0x02, // motor is disabled
73-
MOT_IDLE = 0x03, // motor is enabled, but not moving (current_velocity==target==0 in velocity mode,
74-
// or position==target in position mode)
75-
MOT_MOVING = 0x04, // motor is moving
76-
77-
MOT_ERROR = 0x05, // TODO - motor is disabled because an error has occurred
78-
MOT_INIT_FAILED = 0x0F, // motor initialization failed
79-
MOT_UNKNOWN = 0xFF // incorrect motor number
80-
} I2CCommander_Motor_Status;
81-
8265

8366

8467
#endif

0 commit comments

Comments
 (0)