Allow M18 to turn off selected motors
authorJim Morris <morris@wolfman.com>
Sun, 16 Oct 2016 04:05:22 +0000 (21:05 -0700)
committerJim Morris <morris@wolfman.com>
Sun, 16 Oct 2016 04:05:22 +0000 (21:05 -0700)
src/libs/StepperMotor.cpp
src/modules/robot/Robot.cpp
src/modules/utils/motordrivercontrol/MotorDriverControl.cpp

index cee458d..287d348 100644 (file)
@@ -51,7 +51,15 @@ void StepperMotor::on_halt(void *argument)
 
 void StepperMotor::on_enable(void *argument)
 {
-    enable(argument != nullptr);
+    // argument is a uin32_t where bit0 is on or off, and bit 1:X, 2:Y, 3:Z, 4:A, 5:B, 6:C etc
+    // for now if bit0 is 1 we turn all on, if 0 we turn all off otherwise we turn selected axis off
+    uint32_t bm= (uint32_t)argument;
+    if(bm == 0x01) {
+        enable(true);
+
+    }else if(bm == 0 || ((bm&0x01) == 0 && ((bm&(0x02<<index)) != 0)) ) {
+        enable(false);
+    }
 }
 
 void StepperMotor::change_steps_per_mm(float new_steps)
index f4e9fc8..706566c 100644 (file)
@@ -519,7 +519,19 @@ void Robot::on_gcode_received(void *argument)
                 THEKERNEL->call_event(ON_ENABLE, (void*)1); // turn all enable pins on
                 break;
 
-            case 18: // this used to support parameters, now it ignores them
+            case 18: // this allows individual motors to be turned off, no parameters falls through to turn all off
+                if(gcode->get_num_args() > 0) {
+                    // bitmap of motors to turn off, where bit 1:X, 2:Y, 3:Z, 4:A, 5:B, 6:C
+                    uint32_t bm= 0;
+                    for (int i = 0; i < n_motors; ++i) {
+                        char axis= (i <= Z_AXIS ? 'X'+i : 'A'+(i-3));
+                        if(gcode->has_letter(axis)) bm |= (0x02<<i); // set appropriate bit
+                    }
+                    THEKERNEL->conveyor->wait_for_idle();
+                    THEKERNEL->call_event(ON_ENABLE, (void *)bm);
+                    break;
+                }
+                // fall through
             case 84:
                 THEKERNEL->conveyor->wait_for_idle();
                 THEKERNEL->call_event(ON_ENABLE, nullptr); // turn all enable pins off
index 3e270fc..62b1b47 100644 (file)
@@ -189,8 +189,18 @@ bool MotorDriverControl::config_module(uint16_t cs)
 // This may cause the initial step to be missed if on-idle is delayed too much but we can't do SPI in an interrupt
 void MotorDriverControl::on_enable(void *argument)
 {
-    enable_event= true;
-    enable_flg= (argument != nullptr);
+    // argument is a uin32_t where bit0 is on or off, and bit 1:X, 2:Y, 3:Z, 4:A, 5:B, 6:C etc
+    // for now if bit0 is 1 we turn all on, if 0 we turn all off otherwise we turn selected axis off
+    uint32_t i= (designator >= 'X' || designator <= 'Z') ? designator-'X' : designator-'A'+3;
+    uint32_t bm= (uint32_t)argument;
+    if(bm == 0x01) {
+        enable_event= true;
+        enable_flg= true;
+
+    }else if(bm == 0 || ( (bm&0x01) == 0 && (bm&(0x02<<i)) != 0 )) {
+        enable_event= true;
+        enable_flg= false;
+    }
 }
 
 void MotorDriverControl::on_idle(void *argument)