Microduino

Dependencies:   mbed

Fork of BalanceCar by Li Weiyi

Microduino_Stepper_PWM.cpp

Committer:
lixianyu
Date:
2016-06-07
Revision:
2:99785a1007a4
Child:
3:c6caae712d5d

File content as of revision 2:99785a1007a4:

// Microduino_Stepper.cpp
//
// Copyright (C) 2009-2013 Shenyang
// $Id: Microduino_Stepper.cpp,v 1.00 2016/04/07 $

#include "Microduino_Stepper_PWM.h"
extern Timer g_Timer;
extern Serial mpc;
DigitalOut gSteperE(PIN_EN);
Ticker g_Ticker;
static Stepper_t steppers[MAX_STEPPERS] = {
    {false,NULL},{false,NULL},{false,NULL},{false,NULL}
};

uint8_t StepperCount = 0;

// Some debugging assistance

void stepperAllEnable()
{
    //digitalWrite(PIN_EN, LOW);
    gSteperE = 0;
}

void stepperAllDisable()
{
    //digitalWrite(PIN_EN, HIGH);
    gSteperE = 1;
}

#if 0
static inline void handle_interrupts()
{
    for(uint8_t channel=0; channel < MAX_STEPPERS; channel++) {
        if(steppers[channel].isActive)
            steppers[channel].stepper->computeStep();
    }
}
#endif

#if 0
static void initISR()
{
#if defined(_useTimer1)
    cli();
    TCCR1A = 0;
    TCCR1B = _BV(WGM12)|_BV(CS11);
    OCR1A = TIMER_COMP;
    TCNT1 = 0;
    TIMSK1 = _BV(OCIE1A);
    sei();
#endif
    pinMode(PIN_EN, OUTPUT);
    stepperAllEnable();
}

#if defined(_useTimer1)
ISR(TIMER1_COMPA_vect)
{
    handle_interrupts();
}
#endif
#endif

static void timerHandle()
{
    for (uint8_t channel=0; channel < MAX_STEPPERS; channel++) {
        if(steppers[channel].isActive)
            steppers[channel].stepper->computeStep();
    }
}

static bool isTimerActive()
{
    for(uint8_t channel=0; channel <MAX_STEPPERS ; channel++) {
        if(steppers[channel].isActive == true)
            return  true;
    }
    return false;
}
/****************** end of static functions ******************************/

Stepper::Stepper(PinName dirPin, PinName stepPin)
{
    if(StepperCount < MAX_STEPPERS) {
        this->stepperIndex = StepperCount++;
    } else {
        this->stepperIndex = INVALID_STEPPER;
    }
    gpio_init_out(&dirOUT, dirPin);
    
    period = PERIOD_MIN;
    pwmout_init(&pwmStep, stepPin);
    pwmout_period_us(&pwmStep, period);
    pwmout_pulsewidth_us(&pwmStep, 2);
    speed = 0;
    
    steppers[this->stepperIndex].isActive = false;
}

uint8_t Stepper::begin()
{
    if (this->stepperIndex < MAX_STEPPERS) {
        setMaxAccel(DEFAULT_ACCEL);
        if (isTimerActive() == false) {
            //initISR();
            //pinMode(PIN_EN, OUTPUT);
            //g_Ticker.attach_us(&timerHandle, 40);
            stepperAllEnable();
            //mpc.printf("isTimerActive==false\r\n");
        }
        steppers[this->stepperIndex].isActive = true;
        steppers[this->stepperIndex].stepper = this;
        //pwmout_pulsewidth_us(&pwmStep, 1); // Stepper will work.
    }
    return this->stepperIndex;
}

extern long map(long x, long in_min, long in_max, long out_min, long out_max);
#define constrain(x,a,b) ((x) < (a) ? (a) : ((x) > (b) ? (b) : (x)))
void Stepper::setSpeed(int16_t _speed)
{
    //mpc.printf("Enter setSpeed(%d)\r\n", _speed);
    speed += constrain((_speed-speed), -(int16_t)maxAccel, (int16_t)maxAccel);
    if (speed == 0) {
        //pwmout_pulsewidth_us(&pwmStep, 0);
        stepperAllDisable();
        return;
    } else if (speed > 0) {
        gpio_write(&dirOUT, 0);
        period = map(speed, 1, 1200, PERIOD_MAX, PERIOD_MIN);
        //pwmout_period_us(&pwmStep, period);
    }
    else {
        gpio_write(&dirOUT, 1);
        period = map(speed, -1200, -1, PERIOD_MIN, PERIOD_MAX);
        pwmout_period_us(&pwmStep, period);
    }
    //stepperAllEnable();
    //pwmout_period_us(&pwmStep, period);
    //mpc.printf("speed : %d, period : %d\r\n", speed, period);
}

void Stepper::setMaxAccel(uint16_t _accel)
{
    maxAccel = _accel;
}

int16_t Stepper::getSpeed()
{
    return  speed;
}

uint16_t Stepper::getMaxAccel()
{
    return  maxAccel;
}

#if 0
void Stepper::computeStep()
{
    counter++;
    if(counter > period) {
        counter = 0;
        if(period > 0) {
            //PIN_SET(stepPin);
            gpio_write(&stepOUT, 1);
            //delayMicroseconds(1);
            wait_us(1);
            //PIN_CLR(stepPin);
            gpio_write(&stepOUT, 0);
        }
    }
}
#endif