Drive a stepper motor using A4988 with asynchronous. No wait() function.

Revision:
0:26fa30c35f74
Child:
1:0f8209567b7d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AsyncStepper.cpp	Thu Jul 12 01:27:04 2018 +0000
@@ -0,0 +1,111 @@
+// -*- coding:utf-8-unix -*-
+/*!
+  @file   AsyncStepper.cpp
+  
+  @brief  Drive a stepper motor using A4988 with asynchronous.
+  
+  @author	T.Kawamura
+  @version	1.0
+  @date		2018-07-12	T.Kawamura	Written for C++/mbed.
+  @see
+  Copyright (C) 2018 Takuma Kawamura.
+  Released under the MIT license.
+  http://opensource.org/licenses/mit-license.php
+*/
+#include "AsyncStepper.hpp"
+
+AsyncStepper::AsyncStepper( PinName enablePin, PinName stepPin, PinName dirPin, uint32_t rpm, stepMode_e stepMode, PinName ms1Pin, PinName ms2Pin, PinName ms3Pin, uint32_t oneRotationFullSteps, stopMode_e stopMode ) : stepMode( stepMode ), ms1Pin( ms1Pin ), ms2Pin( ms2Pin ), ms3Pin( ms3Pin ), oneRotationFullSteps( oneRotationFullSteps ), stopMode( stopMode ), halfPulseCount( 0 ), currentMaxStepCount( 0 ), stopPulseOut( true )
+{
+  ticker = new Ticker();
+  enableOut = new DigitalOut( enablePin );
+  stepOut = new DigitalOut( stepPin );
+  dirOut = new DigitalOut( dirPin );
+  if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) {
+    stepModeBus = new BusOut( ms1Pin, ms2Pin, ms3Pin );
+    stepModeBus->write( stepMode );
+  }
+  enableOut->write( 1 );
+  stepOut->write( 0 );
+  dirOut->write( 0 );
+  
+  oneRotationSteps = oneRotationFullSteps * ( stepMode + 1 );
+  pulseWidth_us = (uint64_t)( 30000000 / ( rpm * oneRotationSteps ) );
+  ticker->attach_us( callback(this, &AsyncStepper::ISR_PULSEOUT), pulseWidth_us );
+}
+
+AsyncStepper::~AsyncStepper()
+{
+  delete ticker;
+  delete enableOut;
+  delete stepOut;
+  delete dirOut;
+  if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) {
+    delete stepModeBus;
+  }
+}
+
+void AsyncStepper::ISR_PULSEOUT( void )
+{
+  if ( !stopPulseOut ) {
+    stepOut->write( !stepOut->read() );
+
+    if ( ++halfPulseCount / 2 > currentMaxStepCount ) {
+      if ( stopMode == FREE ) {
+        AsyncStepper::Disable();
+      }
+      halfPulseCount = 0;
+      stopPulseOut = true;
+    }
+  }
+  
+  return;
+}
+
+void AsyncStepper::SetRPM( uint32_t rpm )
+{
+  ticker->detach();
+  oneRotationSteps = oneRotationFullSteps * ( stepMode + 1 );
+  pulseWidth_us = (uint64_t)( 30000000 / ( rpm * oneRotationSteps ) );
+  ticker->attach_us( callback(this, &AsyncStepper::ISR_PULSEOUT), pulseWidth_us );
+  
+  return;
+}
+
+void AsyncStepper::SetStepMode( stepMode_e stepMode )
+{
+  if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) {
+    stepModeBus->write( stepMode );
+  }
+  
+  return;
+}
+
+void AsyncStepper::Enable( void )
+{
+  enableOut->write( 0 );
+  
+  return;
+}
+
+void AsyncStepper::Disable( void )
+{
+  enableOut->write( 1 );
+  
+  return;
+}
+
+bool AsyncStepper::IsStopping( void )
+{
+  return stopPulseOut;
+}
+
+void AsyncStepper::Rotate( direction_e direction, uint32_t steps )
+{
+  dirOut->write( direction );
+  
+  AsyncStepper::Enable();
+  currentMaxStepCount = steps;
+  stopPulseOut = false;
+  
+  return;
+}