Contains code to drive a small brushed DC motor with a Freescale FRDM-17510 MPC17510 H-bridge driver evaluation board, and a Freedom FRDM-KL25Z. Configures the KL25Z as USB HID device and requres a GUI on the PC.

Dependencies:   USBDevice mbed

Fork of LVHB DC Motor Drive by Freescale

This program uses a Freescale FRDM-KL25 and FRDM-17510 Motor control board. It configures the KL25 as a USB HID device and is intended to work with a GUI which is downloaded from Freescale. (where is the link to this GUI?)

There is a list of Analog Tools that mention mbed software support here: http://www.freescale.com/webapp/sps/site/overview.jsp?code=ANALOGTOOLBOX&tid=vanAnalogTools

main.cpp

Committer:
bdbohn
Date:
2014-11-12
Revision:
0:41c74fead7a9

File content as of revision 0:41c74fead7a9:

#include "mbed.h"
#include "USBHID.h"

// We declare a USBHID device.
// HID In/Out Reports are 64 Bytes long
// Vendor ID (VID):     0x15A2
// Product ID (PID):    0x0138
// Serial Number:       0x0001
USBHID hid(64, 64, 0x15A2, 0x0138, 0x0001, true);

//Setup Digital Outputs for the LEDs on the FRDM
DigitalOut red_led(LED1);
DigitalOut green_led(LED2);
DigitalOut blue_led(LED3);

//Setup PWM and Digital Outputs from FRDM-KL25Z to FRDM-17510
PwmOut IN1(PTD4); // Pin IN1 input to MPC17510 (FRDM PIN Name)
PwmOut IN2(PTA12); // Pin IN2 input to MPC17510 (FRDM PIN Name)
DigitalOut EN(PTC7); // Pin EN input to MPC17510 (FRDM PIN Name)
DigitalOut GINB(PTC0); // Pin GIN_B input to MPC17510 (FRDM PIN Name)
DigitalOut READY(PTC5); // Pin READY input to Motor Control Board (FRDM PIN Name)

//Variables
int pwm_freq_lo;
int pwm_freq_hi;
int frequencyHz;
int storedFreq;
int storedDuty;
int runstop = 0;
int runStopChange;
int direction = 1;
int directionChange;
int braking;
int brakingChange;
int dutycycle;
int motorState = 0;
int ramptime = 0;

//storage for send and receive data
HID_REPORT send_report;
HID_REPORT recv_report;

bool initflag = true;

// USB COMMANDS
// These are sent from the PC
#define WRITE_LED       0x20
#define WRITE_GEN_EN  0x40
#define WRITE_DUTY_CYCLE  0x50
#define WRITE_PWM_FREQ  0x60
#define WRITE_RUN_STOP  0x70
#define WRITE_DIRECTION  0x71
#define WRITE_BRAKING  0x90
#define WRITE_RESET  0xA0


// MOTOR STATES
#define STOP            0x00
#define RUN             0x02
#define RESET           0x05

// LED CONSTANTS
#define LEDS_OFF        0x00
#define RED             0x01
#define GREEN           0x02
#define BLUE            0x03
#define READY_LED       0x04

// LOGICAL CONSTANTS
#define OFF             0x00
#define ON              0x01

//Functions
void set_PWM_Freq(int freq);
void set_Duty_Cycle(int dutycycle);


int main() 
{
    send_report.length = 64;
    recv_report.length = 64;
    
    red_led     = 1;        // Red LED = OFF
    green_led   = 1;        // Green LED = OFF
    blue_led    = 0;        // Blue LED = ON
    
    motorState = RESET;
    initflag = true;
    
    IN1.period(1);          //initially set period to 1 second
    IN2.period(1);

    IN1.write(0);           //set PWM percentage to 0
    IN2.write(0);

    
    while(1) 
    {
        //try to read a msg
        if(hid.readNB(&recv_report)) 
        {
            if(initflag == true)
            {
                initflag = false;
                blue_led = 1;               //turn off blue LED
            }
            switch(recv_report.data[0])     //byte 0 of recv_report.data is command
            {
//-----------------------------------------------------------------------------------------------------------------
//          COMMAND PARSER
//-----------------------------------------------------------------------------------------------------------------
////////
                case WRITE_LED:
                    switch(recv_report.data[1])
                    {
                        case LEDS_OFF:
                            red_led = 1;
                            green_led = 1;
                            blue_led = 1;
                            break;
                        case RED:
                            if(recv_report.data[2] == 1){red_led = 0;} else {red_led = 1;}
                            break;
                        case GREEN:
                            if(recv_report.data[2] == 1){green_led = 0;} else {green_led = 1;}
                            break; 
                        case BLUE:
                            if(recv_report.data[2] == 1){blue_led = 0;} else {blue_led = 1;}
                            break;     
                         default:
                            break;
                            
                        
                    }// End recv report data[1]
                    break;
  ////////                    

  ////////              
                 case  WRITE_DUTY_CYCLE:
                    dutycycle = recv_report.data[1];
                    set_Duty_Cycle(dutycycle);
                    break;
////////                
                 case  WRITE_PWM_FREQ:                      //PWM frequency can be larger than 1 byte
                    pwm_freq_lo = recv_report.data[1];      //so we have to re-assemble the number
                    pwm_freq_hi = recv_report.data[2] * 100;
                    frequencyHz = pwm_freq_lo + pwm_freq_hi;
                    set_PWM_Freq(frequencyHz);
                    break;
////////                
                case  WRITE_RUN_STOP:
                    if(recv_report.data[1] == 1)
                    {
                        if(runstop != 1)
                        {
                            red_led = 1;
                            blue_led = 1;
                            green_led = 0;
                            READY = 1;
                            runstop = 1;
                            runStopChange = 1;
                            motorState = RUN;
                            frequencyHz = storedFreq;
                            set_PWM_Freq(frequencyHz);
                            dutycycle = storedDuty;
                            set_Duty_Cycle(dutycycle);
                        }
 
                    }
                    else
                    {
                        if(runstop != 0)
                        {
                            runstop = 0;
                            runStopChange = 1;
                            motorState = STOP;
                            red_led = 0;
                            green_led = 1;
                            blue_led = 1;                          
                           storedFreq = frequencyHz;
                           storedDuty = dutycycle;
                           READY = 0;
                        }
                    }
                     break;
////////                
                case  WRITE_DIRECTION:
 
 
                    if(recv_report.data[1] == 1)
                    {
                        if(direction != 1)
                        {
                            direction = 1;
                            directionChange = 1;
                        }
                    }
                    else
                    {
                        if(direction != 0)
                        {
                            direction = 0;
                            directionChange = 1;
                         }
                    }                    
                    break;
////////
                case  WRITE_BRAKING:
                    if(recv_report.data[1] == 1)
                    {
                            braking = 1;
                    }
                    else
                    {
                            braking = 0;
                    }
                    break;
////////                
                default:
                    break;
            }// End Switch recv report data[0]

//-----------------------------------------------------------------------------------------------------------------
//      end command parser    
//-----------------------------------------------------------------------------------------------------------------
            
            send_report.data[0] = recv_report.data[0];      // Echo Command
            send_report.data[1] = recv_report.data[1];      // Echo Subcommand 1
            send_report.data[2] = recv_report.data[2];      // Echo Subcommand 2
            send_report.data[3] = 0x00;
            send_report.data[4] = 0x00;
            send_report.data[5] = 0x00;
            send_report.data[6] = 0x00;
            send_report.data[7] = 0x00;
              
            //Send the report
            hid.send(&send_report);
        }// End If(hid.readNB(&recv_report))
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//End of USB message handling        
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//************************************************************************************************************************
// This is handling of PWM, braking, direction
//***********************************************************************************************************************/

        switch (motorState)
        {
            case STOP:
             READY = 0;                                

                if(braking == 1)
                {
                    EN = 0;                  
                    IN1.period(1);
                    IN2.period(1);
                    IN1.write(0);
                    IN2.write(0);    
                }
                else
                {
                    EN = 0;
                    IN1.period(1);
                    IN2.period(1);                 
                    IN1.write(0);
                    IN2.write(0);  
                    EN = 1;                    
                }
                break;
             
            case RUN:
                if(runStopChange != 0)
                {
                    READY = 1;                    
                    EN = 1;
                    directionChange = 0;
                    runStopChange = 0;
                    set_PWM_Freq(frequencyHz);
                    set_Duty_Cycle(dutycycle);
                }    
                break;
                
            case RESET:
                IN1.write(0.0);
                IN2.write(0.0);    
                IN1.period(0.0);                            
                IN2.period(0.0);                
                runStopChange = false;
                motorState = STOP;                
                break;
                
        }// end switch motorState
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////       
     }// End While Loop
 }// End Main  


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void set_PWM_Freq(int freq)
{
        storedFreq = freq;
        float period = 1.0/freq;
        
        if(direction == 1)
        {
            IN1.period(period);
            IN2.period(0.0);  
        }
        else
        {
            IN1.period(0.0);
            IN2.period(period);  
        }
}
            
void set_Duty_Cycle(int dc)
{
    storedDuty = dc;
    if(direction == 1)
    {
        red_led = 0;
        green_led = 1;
        IN1.write(float(dc/100.0));
        IN2.write(0);
    }
    else
    {
        red_led = 1;
        green_led = 0;
        IN2.write(float(dc/100.00));
        IN1.write(0);
    }
}