Brandon Dyer
Published

UARK Senior Design Project: BLDC Motor Controller

This project consists of designing a motor controller that will operate a 48V, 1hp BLDC hub motor.

IntermediateFull instructions providedOver 1 day1,115
UARK Senior Design Project: BLDC Motor Controller

Things used in this project

Software apps and online services

Code Composer Studio
Texas Instruments Code Composer Studio

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

Gerber and drill files

Gerber and Drill files used to fabricate PCB

Board file

Allegro .brd file used to generate Gerber and drill files

Bill of Materials

BOM for the components used in the project

Texas Instruments References and Datasheets

PDF References for TI components and software, as well as links to the different datasheets used in the project.

Schematics

Schematic changes

This schematic reflects changes made to the board but were not made to the PCB layout software

PSPICE Schematic

PSPICE schematic netlisted to PCB layout

PSPICE Library

PSPICE component library used with PSPICE .opj file

Main Flowchart

Main software flowchart not including ISR

Hall ISR

Hall Sensor Interrupt Service Routine

Must Read

Must read before beginning project

Schematic

This is the schematic used on the PCB layout. Changes can be made via PCB editing software or on the physical board

Code

Main Code

C/C++
This is the main.c file used for the project software in Code Composer Studio
/*
Date:5/1/18
Revision 6
Written By: Brandon Dyer

Description:
1. PWM on High side and turn on/off low side
2. PWM freq = 16kHz
3. Using ADC to manipulate LEDs to indicate direction
    blue on=fwd, orange on=rev, blue and orange off= neutral
4. Using ADC to control motor speed forward and backwards
5. This code has been successful in running the motor in both directions using POT on SPEED1 input
6. This is a modified version of rev5 code to fix the reverse mode (did not work in rev5)
*/

//----------------------Start of Code-----------------------------
//###########################################################################
//
// FILE:    Example_2803xGpioSetup.c
//
// TITLE:   GPIO Toggle Test example
//
// Included Files
//
#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

//
// Defines that select the example to compile in.  
// Only one example should be set as 1 the rest should be set as 0.
//
// Global Variables
volatile Uint16 direction;   //forward=1, reverse=0
volatile Uint16 dutyMax;      //max duty cycle
volatile Uint16 rampMid;      //middle ramp compare point
volatile Uint16 pwmMax;     //max pwm pulse width
volatile Uint16 maxCount;    //max period for ePWM
volatile Uint16 speed1;     //ADC result for SPEED1 potentiometer reading

//Define Macros
#define Reverse 0;
#define Forward 1;

// Function Prototype
void ADC_Setup(void);
void delay_loop(void);
void Gpio_select(void);
void LED_BLINK(void);
void configure_ePWM1(void);
void configure_ePWM2(void);
void configure_ePWM3(void);
void configure_ePWM4(void);
void configure_ePWM5(void);
void configure_ePWM6(void);
void sector1(void);
void sector2(void);
void sector3(void);
void sector4(void);
void sector5(void);
void sector6(void);
__interrupt void xint1_ISR(void);
__interrupt void xint2_ISR(void);
__interrupt void xint3_ISR(void);
//
// Main
//
void main(void)
{


//memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, &RamfuncsLoadEnd - &RamfuncsLoadStart);


    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2803x_SysCtrl.c file.
    //
     InitSysCtrl();

    //
    // Step 2. Initialize GPIO:
    // This example function is found in the DSP2803x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //The Tables below show how to configure GPIOA and GPIOB

    //            _______________________________________________________________________________
    //           |                          GPIOB MUX Functions                                  |
    //  ---------|===============================================================================|
    // Bit Value:|   xx    |    xx    |   xx    |   00(I)  |   00(I) |   00(I)|   00(N) |   00(N)|
    //      GPIO:|   47    |    46    |   45    |   44     |   43    |   42   |   41    |   40   |
    //  Function:|  RSVD   |   RSVD   |  RSVD   |   SW2    |  GPIO   |  GPIO  |  GPIO   |  GPIO  |
    //  ---------|---------|----------|---------|----------|---------|--------|---------|--------|
    // Bit Value:|   00(N) |    00    |   00    |   00     |   00    |   00(O)|   00(O) |   00(O)| Note: GPIO32 is also ADCSOCAO
    //      GPIO:|   39    |    38    |   37    |   36     |   35    |   34   |   33    |   32   |       and may need to be set to [11]
    //  Function:|  GPIO   |JTAG_TCK  |JTAG_TDO |JTAG_TMS  |JTAG_TDI |EN_GATE |  GPIO   |  GPIO  |       ; all NC pins are set to outputs
    //  -----------------------------------------------------------------------------------------
    //             GPBMUX=0x000000 (This is zero by default anyways)  and GPBDIR=0000 0011 1000 0111=0x0387



    //            _______________________________________________________________________________
    //           |                             GPIOA MUX1 Functions                              |
    //           |===============================================================================|
    // Bit Value:|   00(I) |   00(O) |   00(I) |   10     |   00(I)  |  01    |  00(N)|    01    |
    //      GPIO:|   15    |   14    |   13    |   12     |   11     |  10    |  09   |    08    |
    //  Function:| FAULT   | BL_LED  |  OCTW   |SCITXDA   |Xint3_H3  |PWM1A_AH| GPIO  | PWM2A_AL |
    //  ---------|---------|---------|---------|----------|----------|--------|-------|----------|
    // Bit Value:|  00(N)  |   01    |   10    |   01     |   10     |  01    |  00(N)|    01    |
    //      GPIO:|  07     |   06    |   05    |   04     |   03     |  02    |  01   |    00    |
    //  Function:| GPIO    |PWM3A_BH |SPISIMOA |PWM4A_BL  |SPISOMIA  |PWM5A_CH| GPIO  |  PWM6A_CL|
    //  -----------------------------------------------------------------------------------------
    //              GPAMUX1=0x02111991  and  GPADIR=0100 0010 1000 0010=0x4282  bits 15-0     Note:  All NC pins are set to outputs

    //            _______________________________________________________________________________
    //           |                          GPIOA MUX2 Functions                                 |
    //  ---------|===============================================================================|
    // Bit Value:|   01    |    01   |    00(N)|    01    |    00(I) |  00(N) |  00(N)|     00(O)|
    //      GPIO:|   31    |    30   |    29   |    28    |    27    |   26   |   25  |     24   |
    //  Function:| CANTXA  |  CANRXA |   GPIO  |  SCIRXDA |  Xint2_H2|  GPIO  |  GPIO |   OR_LED |
    //  ---------|---------|---------|---------|----------|----------|--------|-------|----------|
    // Bit Value:|  00(I)  |   00(O) |   00(O) |   00(O)  |   01     |  01    |  00(O)|    00(I) |
    //      GPIO:|  23     |   22    |   21    |   20     |   19     |  18    |  17   |    16    |
    //  Function:|Xint1_H1 | RS_CAN  | RED_LED |  GN_LED  | nSPISTEA | SPICLKA| DC_CAL|    SW1   |
    //  -----------------------------------------------------------------------------------------
    //              GPAMUX2=0x51000050    and     GPADIR=0010 0111 0111 0010=0x2772  bits 31-16      --> Note: Total value in GPADIR=0x27724282

    //           _______________________________________________________________________________
    //          |                                  Analog MUX                                   |
    //          |                      (Default to ADC inputs at reset)                         |
    // ---------|===============================================================================|
    //   ADC_IN:|   B7    |    B6   |    B5   |    B4    |    B3   |   B2    |   B1   |    B0   |
    // Function:|NOT USED |NOT USED |NOT USED | NOT USED |NOT USED |NOT USED |NOT USED|NOT USED |
    // ---------|---------|---------|---------|----------|---------|---------|--------|---------|
    //   ADC_IN:|   A7    |    A6   |    A5   |    A4    |    A3   |   A2    |   A1   |    A0   |
    // Function:| SPEED2  | NOT USED|  SPEED1 | NOT USED |   SO_3  |  SO_2   |  SO_1  |NOT USED |
    // -----------------------------------------------------------------------------------------

    // Initialize GPIO MUX Functions and Data Directions
    InitGpio();


    // Initialize External Interrupts
    EALLOW;                                     // allow access to protected registers
    GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 23;  // XINT1 is GPIO23
    GpioIntRegs.GPIOXINT2SEL.bit.GPIOSEL = 27;  // XINT2 is GPIO27
    GpioIntRegs.GPIOXINT3SEL.bit.GPIOSEL = 11;  // XINT3 is GPIO11
    EDIS;                                       // disable access to protected registers

    //
    // Configure XINT1
    //
    XIntruptRegs.XINT1CR.bit.POLARITY = 11;     // Interrupt on Rising and Falling edge for Hall1
    XIntruptRegs.XINT2CR.bit.POLARITY = 11;     // Interrupt on Rising and Falling edge for Hall2
    XIntruptRegs.XINT3CR.bit.POLARITY = 11;     // Interrupt on Rising and Falling edge for Hall3

    //
    // Enable XINT1 and XINT2
    //
    XIntruptRegs.XINT1CR.bit.ENABLE = 1;        // Enable XINT1 = Hall1
    XIntruptRegs.XINT2CR.bit.ENABLE = 1;        // Enable XINT2 = Hall2
    XIntruptRegs.XINT3CR.bit.ENABLE = 1;        // Enable XINT3 = Hall3

    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
    DINT;

    // Initialize PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP2803x_PieCtrl.c file.
    //
    InitPieCtrl();

    // Disable CPU interrupts and clear all CPU interrupt flags:
    //
    IER = 0x0000;
    IFR = 0x0000;


    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP2803x_DefaultIsr.c.
    // This function is found in DSP2803x_PieVect.c.

    //  Map ISR addresses to the PIE Vector Table
    InitPieVectTable();
    EALLOW;                                  // This is needed to write to EALLOW protected registers
    PieVectTable.XINT1 = &xint1_ISR;         // Map External Interrupt 1 ISR address to PIE vector table
    PieVectTable.XINT2 = &xint2_ISR;         // Map External Interrupt 2 ISR address to PIE vector table
    PieVectTable.XINT3 = &xint3_ISR;         // Map External Interrupt 3 ISR address to PIE vector table
    EDIS;                                    // This is needed to disable write to EALLOW protected registers

    // Step 4. Initialize all the Device Peripherals:
    //
    //initialize ADC registers
    ADC_Setup();
    // Initialize ePWM1-ePWM6
    // All modules start with 0% duty cycle
    // Only ePWMxA is used for each ePWMx module
    //
    EALLOW;                                  // allow access to Sys Ctrl Regs
    SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;  // enable ePWM1 clock
    SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1;  // enable ePWM2 clock
    SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1;  // enable ePWM3 clock
    SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1;  // enable ePWM4 clock
    SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1;  // enable ePWM5 clock
    SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1;  // enable ePWM6 clock
    SysCtrlRegs.PCLKCR0.bit.SPIAENCLK  = 1;  // enable SPIA clock
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC  = 0;  // Must turn off global clock sync before initializing ePWM modules
    delay_loop();                            // Allow time for clock sync to turn off
    delay_loop();
    speed1=0;                                // Initialize SPEED1 value
    maxCount=1875;                           // Initialize PWM TBCTR Period (PWM_Freq = 30MHz/maxCount)
    pwmMax=190;                              // PWM pulse goes high at pwmMax (Using Down-Count mode) duty cycle = pwmMax/maxCount
    direction=2;                             // initialize direction to neutral rotation
    configure_ePWM1();                       // Configure ePWM1 (forced LOW)
    configure_ePWM2();                       // Configure ePWM2 (forced LOW)
    configure_ePWM3();                       // Configure ePWM3 (forced LOW)
    configure_ePWM4();                       // Configure ePWM4 (forced LOW)
    configure_ePWM5();                       // Configure ePWM5 (forced LOW)
    configure_ePWM6();                       // Configure ePWM6 (forced LOW)
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;   // Must turn on global clock sync to enable ePWM modules
    EDIS;                                    // disable access to System Control Registers

    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;       // Enable the PIE block
    PieCtrlRegs.PIEIER1.bit.INTx4 = 1;       // Enable PIE Group 1 INT4
    PieCtrlRegs.PIEIER1.bit.INTx5 = 1;       // Enable PIE Group 1 INT5
    PieCtrlRegs.PIEIER12.bit.INTx1 = 1;      // Enable the PIE Group 12 INT1
    IER |= M_INT1;                           // Enable CPU INT1
    EINT;                                    // Enable Global Interrupts

    //---------------------- Main code for running motor controller-----------------------------------


    GpioDataRegs.GPBSET.bit.GPIO34=1;   //Enable DRV8301
    delay_loop();                       //allow time for DRV8301 to power up
    delay_loop();

    // setup spi regs for DRV8301
    //       Bit  15           WR=0, R=1
    //       Bits 14:11        address
    //       Bits 10:0         data
    //
        //Ctrl Reg 1: Gate Driver Control
        //Gate Current: 1.7A                                bits[1-0]  =00
        //Gate Reset:   Normal mode                         bits[2]    =0
        //PWM Mode:     6PWM                                bits[3]    =0
        //OCP Mode:     Current Limit                       bits[5-4]  =00
        //OC ADJ SET    0.403/.0137 = 29A                  bits[10-6]  =10000
        //address                                           bits[14-11]=0010
        //write                                             bits[15]   =0
        SpiaRegs.SPITXBUF = 0x1400; //        0001 0100 0000 0000
        delay_loop();
        //SpiaRegs.SPIDAT = 0x1400;

        //Ctrl Reg 2: Current Shunt Amp and Misc Ctrl
        //OCTW Mode:     Report OT at nOCTW pin         bits[1-0]  =01
        //Gain:          G = 20V/V                      bits[3-2]  =01
        //DC CAL1:       Shunt amp connected to load    bits[4]    =0
        //DC CAL2:       Shunt amp connected to load    bits[5]    =0
        //OC TOFF:       Cycle by Cycle                 bits[6]    =0
        //reserved                                      bits[10-7] =0000
        //address                                       bits[14-11]=0011
        //write                                         bits[15]   =0
        SpiaRegs.SPITXBUF = 0x1805; // binary 0001 1000 0000 0101
        delay_loop();
        //SpiaRegs.SPIDAT = 0x1805;

     GpioDataRegs.GPASET.bit.GPIO20 = 1;  //Green LED is on


while(1)
{
    if (GpioDataRegs.GPADAT.bit.GPIO16==0)
    {
        GpioDataRegs.GPASET.bit.GPIO14=1;
    }
    else
    {
        GpioDataRegs.GPACLEAR.bit.GPIO14=1;
    }


    // Checking for OCTW and FAULT events on DRV8301 OCTW and FAULT pins
    if(GpioDataRegs.GPADAT.bit.GPIO13==0)
    {
       GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;  //disable Driver
       GpioDataRegs.GPASET.bit.GPIO24 = 1;    //Orange LED on if OCTW event
    }
    else
    {
       GpioDataRegs.GPBSET.bit.GPIO34 = 1;    //enable Driver
       GpioDataRegs.GPACLEAR.bit.GPIO24 = 1;  //Orange LED off, no OCTW event
    }
    if(GpioDataRegs.GPADAT.bit.GPIO15==0)
    {
       GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;   //disable Driver
       GpioDataRegs.GPASET.bit.GPIO21 = 1;     //Red LED on if FAULT event

       //turn off all PWM signals on FAULT event
       EPwm1Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AH LOW
       EPwm2Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AL LOW
       EPwm3Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BH LOW
       EPwm4Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BL LOW
       EPwm5Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CH LOW
       EPwm6Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CL LOW

    }
    else
    {
        GpioDataRegs.GPBSET.bit.GPIO34 = 1;     //enable Driver
        GpioDataRegs.GPACLEAR.bit.GPIO21 = 1;   //Red LED off, no FAULT event
    }

    //Sampling ADC5 (Speed1 input) to determine speed desired
    AdcRegs.ADCSOCFRC1.bit.SOC5 = 1;

    while(AdcRegs.ADCSOCFLG1.bit.SOC5!=0)
    {
    //wait for conversion to complete
    }
    //Store Results of ADC
    speed1=AdcResult.ADCRESULT5;

    //Use ADC value to initialize CMPA (pwmMax) counter value used for duty cycle
    //initialize duty cycle when moving backwards
    if(speed1<=1500)
    {
        direction=0;
        pwmMax=1500-speed1;
        GpioDataRegs.GPACLEAR.bit.GPIO14=1;     //turn on blue LED
        GpioDataRegs.GPASET.bit.GPIO24=1;       //turn off orange LED
    }
    //deadband zone: turn off all FETs
    if(speed1>1500 && speed1<2200)
    {
        direction=2;
        GpioDataRegs.GPACLEAR.bit.GPIO24=1;         //turn of blue LED
        GpioDataRegs.GPACLEAR.bit.GPIO14=1;         //turn off orange LED
        EPwm1Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AH LOW
        EPwm2Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AL LOW
        EPwm3Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BH LOW
        EPwm4Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BL LOW
        EPwm5Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CH LOW
        EPwm6Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CL LOW
    }
    //initialize duty cycle when moving forwards
    if(speed1>=2200)
    {
        direction=1;
        pwmMax=speed1-2200;
        GpioDataRegs.GPACLEAR.bit.GPIO24=1;     //turn off orange LED
        GpioDataRegs.GPASET.bit.GPIO14=1;       //turn on blue LED
    }
    //set max and min duty cycle:  min=10% and max=80%
    if(pwmMax<200)
        pwmMax=200;
    if(pwmMax>1500)
        pwmMax>1500;


//This section starts stationary motor by polling rotor position, at which point the Hall interrupts take over
//
if(direction==0)
{
    //if rotor is in sector 1
    if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
            sector4();


    //if rotor is in sector 2
    if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==0)
            sector5();


    //if rotor is in sector 3
    if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
            sector6();


    //if rotor is in sector 4
    if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
            sector1();


    //if rotor is in sector 5
    if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==1)
            sector2();


    //if rotor is in sector 6
    if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
            sector3();
}

if(direction==1)
{
    //if rotor is in sector 1
    if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
            sector1();


    //if rotor is in sector 2
    if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==0)
            sector2();


    //if rotor is in sector 3
    if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
            sector3();


    //if rotor is in sector 4
    if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
            sector4();


    //if rotor is in sector 5
    if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==1)
            sector5();


    //if rotor is in sector 6
    if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
            sector6();
}


}

    return;
}
//==================================================================================================================
//----------------------The rest of code defines the functions declared in code---------------------
//
//delay_loop
//
void delay_loop()
{
    double      i;
    for (i = 0; i < 20000; i++)
    {
        
    }
}

void sector1(void)
{

    EPwm2Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AL LOW
    EPwm6Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CL LOW
    EPwm3Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BH LOW
    EPwm5Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CH LOW

    EPwm4Regs.AQCSFRC.bit.CSFA = AQ_SET;        //Force BL HIGH
    EPwm1Regs.CMPA.half.CMPA   = pwmMax;        //turn on AH max pwm
    EPwm1Regs.AQCSFRC.bit.CSFA = 0;             //disable forced LOW state on AH
}

void sector2(void)
{

    EPwm2Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AL LOW
    EPwm4Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BL LOW
    EPwm3Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BH LOW
    EPwm5Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CH LOW

    EPwm6Regs.AQCSFRC.bit.CSFA = AQ_SET;        //Force CL HIGH
    EPwm1Regs.CMPA.half.CMPA   = pwmMax;        //turn on AH max pwm
    EPwm1Regs.AQCSFRC.bit.CSFA = 0;             //disable forced LOW state on AH


}

void sector3(void)
{

    EPwm2Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force AL LOW
    EPwm4Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force BL LOW
    EPwm1Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force AH LOW
    EPwm5Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force CH LOW

    EPwm6Regs.AQCSFRC.bit.CSFA = AQ_SET;         //Force CL HIGH
    EPwm3Regs.CMPA.half.CMPA   = pwmMax;         //turn on BH max pwm
    EPwm3Regs.AQCSFRC.bit.CSFA = 0;              //disable forced LOW state on BH


}

void sector4(void)
{

    EPwm4Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force BL LOW
    EPwm6Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force CL LOW
    EPwm1Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force AH LOW
    EPwm5Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force CH LOW

    EPwm2Regs.AQCSFRC.bit.CSFA = AQ_SET;         //Force AL HIGH
    EPwm3Regs.CMPA.half.CMPA   = pwmMax;         //turn on BH max pwm
    EPwm3Regs.AQCSFRC.bit.CSFA = 0;              //disable forced LOW state on BH


}

void sector5(void)
{

    EPwm4Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force BL LOW
    EPwm6Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force CL LOW
    EPwm1Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force AH LOW
    EPwm3Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force BH LOW

    EPwm2Regs.AQCSFRC.bit.CSFA = AQ_SET;         //Force AL HIGH
    EPwm5Regs.CMPA.half.CMPA   = pwmMax;         //turn on CH max pwm
    EPwm5Regs.AQCSFRC.bit.CSFA = 0;              //disable forced LOW state on CH


}

void sector6(void)
{

    EPwm2Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force AL LOW
    EPwm6Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force CL LOW
    EPwm1Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force AH LOW
    EPwm3Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;       //Force BH LOW

    EPwm4Regs.AQCSFRC.bit.CSFA = AQ_SET;         //Force BL HIGH
    EPwm5Regs.CMPA.half.CMPA   = pwmMax;         //turn on CH max pwm
    EPwm5Regs.AQCSFRC.bit.CSFA = 0;              //disable forced LOW state on CH


}

//
//----------------------------Start PWM Initialization Functions-----------------------------------------
void configure_ePWM1(void)
{
    EPwm1Regs.TBPRD                 = maxCount;         //PWM period in clock counts (clock freq = 30MHz)
    EPwm1Regs.TBCTL.bit.PRDLD       = 0;                //TBPRD loaded from shadow reg when TBCTR = 0
//    EPwm1Regs.TBPHS.half.TBPHS      = 0;                // Set Phase register to zero
    EPwm1Regs.TBCTL.bit.PHSEN       = 0;                //Do not load TBCTR from phase reg
    EPwm1Regs.TBCTL.bit.PRDLD       = TB_SHADOW;
    EPwm1Regs.TBCTL.bit.CTRMODE     = TB_COUNT_DOWN;    //Down-count mode enabled
//    EPwm1Regs.TBCTL.bit.SYNCOSEL    = TB_CTR_ZERO;
    EPwm1Regs.CMPA.half.CMPA        = pwmMax;           //CMPA event occurs at TBCTR = pwmMax
    EPwm1Regs.CMPCTL.bit.SHDWAMODE  = CC_SHADOW;        //CMPA value buffered via shadow reg
    EPwm1Regs.CMPCTL.bit.LOADAMODE  = CC_CTR_ZERO;      //Load CMPA from shadow reg when CTR = 0
    EPwm1Regs.AQCTLA.bit.CBD        = 0;                //Disable CBD event
    EPwm1Regs.AQCTLA.bit.CBU        = 0;                //Disable CBU event
    EPwm1Regs.AQCTLA.bit.CAU        = 0;                //Disable CAU event
    EPwm1Regs.AQCTLA.bit.CAD        = AQ_SET;           //Set on CAD event
    EPwm1Regs.AQCTLA.bit.PRD        = 0;                //do nothing when TBCTR = Period
    EPwm1Regs.AQCTLA.bit.ZRO        = AQ_CLEAR;         //Clear EPWMxA when TBCTR = 0
    EPwm1Regs.AQCSFRC.bit.CSFA      = AQ_CLEAR;         //Force EPWMxA continuously LOW (must be set to zero to disable)

}

void configure_ePWM2(void)
{
    EPwm2Regs.TBPRD                 = maxCount;         //PWM period in clock counts (clock freq = 30MHz)
    EPwm2Regs.TBCTL.bit.PRDLD       = 0;                //TBPRD loaded from shadow reg when TBCTR = 0
//    EPwm2Regs.TBPHS.half.TBPHS      = 0;                // Set Phase register to zero
    EPwm2Regs.TBCTL.bit.PHSEN       = 0;                //Do not load TBCTR from phase reg
    EPwm2Regs.TBCTL.bit.PRDLD       = TB_SHADOW;
    EPwm2Regs.TBCTL.bit.CTRMODE     = TB_COUNT_DOWN;    //Down-count mode enabled
//    EPwm2Regs.TBCTL.bit.SYNCOSEL    = TB_CTR_ZERO;
    EPwm2Regs.CMPA.half.CMPA        = pwmMax;           //CMPA event occurs at TBCTR = pwmMax
    EPwm2Regs.CMPCTL.bit.SHDWAMODE  = CC_SHADOW;        //CMPA value buffered via shadow reg
    EPwm2Regs.CMPCTL.bit.LOADAMODE  = CC_CTR_ZERO;      //Load CMPA from shadow reg when CTR = 0
    EPwm2Regs.AQCTLA.bit.CBD        = 0;                //Disable CBD event
    EPwm2Regs.AQCTLA.bit.CBU        = 0;                //Disable CBU event
    EPwm2Regs.AQCTLA.bit.CAU        = 0;                //Disable CAU event
    EPwm2Regs.AQCTLA.bit.CAD        = 0;                //Disable CAD event
    EPwm2Regs.AQCTLA.bit.PRD        = 0;                //do nothing when TBCTR = Period
    EPwm2Regs.AQCTLA.bit.ZRO        = AQ_CLEAR;         //Clear EPWMxA when TBCTR = 0
    EPwm2Regs.AQCSFRC.bit.CSFA      = AQ_CLEAR;         //Force EPWMxA continuously LOW (must be set to zero to disable)

}

void configure_ePWM3(void)
{
    EPwm3Regs.TBPRD                 = maxCount;         //PWM period in clock counts (clock freq = 30MHz)
    EPwm3Regs.TBCTL.bit.PRDLD       = 0;                //TBPRD loaded from shadow reg when TBCTR = 0
//    EPwm3Regs.TBPHS.half.TBPHS      = 0;                // Set Phase register to zero
    EPwm3Regs.TBCTL.bit.PHSEN       = 0;                //Do not load TBCTR from phase reg
    EPwm3Regs.TBCTL.bit.PRDLD       = TB_SHADOW;
    EPwm3Regs.TBCTL.bit.CTRMODE     = TB_COUNT_DOWN;    //Down-count mode enabled
//    EPwm3Regs.TBCTL.bit.SYNCOSEL    = TB_CTR_ZERO;
    EPwm3Regs.CMPA.half.CMPA        = pwmMax;           //CMPA event occurs at TBCTR = pwmMax
    EPwm3Regs.CMPCTL.bit.SHDWAMODE  = CC_SHADOW;        //CMPA value buffered via shadow reg
    EPwm3Regs.CMPCTL.bit.LOADAMODE  = CC_CTR_ZERO;      //Load CMPA from shadow reg when CTR = 0
    EPwm3Regs.AQCTLA.bit.CBD        = 0;                //Disable CBD event
    EPwm3Regs.AQCTLA.bit.CBU        = 0;                //Disable CBU event
    EPwm3Regs.AQCTLA.bit.CAU        = 0;                //Disable CAU event
    EPwm3Regs.AQCTLA.bit.CAD        = AQ_SET;                //SET CAD event
    EPwm3Regs.AQCTLA.bit.PRD        = 0;                //do nothing when TBCTR = Period
    EPwm3Regs.AQCTLA.bit.ZRO        = AQ_CLEAR;         //Clear EPWMxA when TBCTR = 0
    EPwm3Regs.AQCSFRC.bit.CSFA      = AQ_CLEAR;         //Force EPWMxA continuously LOW (must be set to zero to disable)

}

void configure_ePWM4(void)
{
    EPwm4Regs.TBPRD                 = maxCount;         //PWM period in clock counts (clock freq = 30MHz)
    EPwm4Regs.TBCTL.bit.PRDLD       = 0;                //TBPRD loaded from shadow reg when TBCTR = 0
//    EPwm4Regs.TBPHS.half.TBPHS      = 0;                // Set Phase register to zero
    EPwm4Regs.TBCTL.bit.PHSEN       = 0;                //Do not load TBCTR from phase reg
    EPwm4Regs.TBCTL.bit.PRDLD       = TB_SHADOW;
    EPwm4Regs.TBCTL.bit.CTRMODE     = TB_COUNT_DOWN;    //Down-count mode enabled
//    EPwm4Regs.TBCTL.bit.SYNCOSEL    = TB_CTR_ZERO;
    EPwm4Regs.CMPA.half.CMPA        = pwmMax;           //CMPA event occurs at TBCTR = pwmMax
    EPwm4Regs.CMPCTL.bit.SHDWAMODE  = CC_SHADOW;        //CMPA value buffered via shadow reg
    EPwm4Regs.CMPCTL.bit.LOADAMODE  = CC_CTR_ZERO;      //Load CMPA from shadow reg when CTR = 0
    EPwm4Regs.AQCTLA.bit.CBD        = 0;                //Disable CBD event
    EPwm4Regs.AQCTLA.bit.CBU        = 0;                //Disable CBU event
    EPwm4Regs.AQCTLA.bit.CAU        = 0;                //Disable CAU event
    EPwm4Regs.AQCTLA.bit.CAD        = 0;                //Disable CAD event
    EPwm4Regs.AQCTLA.bit.PRD        = 0;                //do nothing when TBCTR = Period
    EPwm4Regs.AQCTLA.bit.ZRO        = AQ_CLEAR;         //Clear EPWMxA when TBCTR = 0
    EPwm4Regs.AQCSFRC.bit.CSFA      = AQ_CLEAR;         //Force EPWMxA continuously LOW (must be set to zero to disable)

}

void configure_ePWM5(void)
{
    EPwm5Regs.TBPRD                 = maxCount;         //PWM period in clock counts (clock freq = 30MHz)
    EPwm5Regs.TBCTL.bit.PRDLD       = 0;                //TBPRD loaded from shadow reg when TBCTR = 0
//    EPwm5Regs.TBPHS.half.TBPHS      = 0;                // Set Phase register to zero
    EPwm5Regs.TBCTL.bit.PHSEN       = 0;                //Do not load TBCTR from phase reg
    EPwm5Regs.TBCTL.bit.PRDLD       = TB_SHADOW;
    EPwm5Regs.TBCTL.bit.CTRMODE     = TB_COUNT_DOWN;    //Down-count mode enabled
//    EPwm5Regs.TBCTL.bit.SYNCOSEL    = TB_CTR_ZERO;
    EPwm5Regs.CMPA.half.CMPA        = pwmMax;           //CMPA event occurs at TBCTR = pwmMax
    EPwm5Regs.CMPCTL.bit.SHDWAMODE  = CC_SHADOW;        //CMPA value buffered via shadow reg
    EPwm5Regs.CMPCTL.bit.LOADAMODE  = CC_CTR_ZERO;      //Load CMPA from shadow reg when CTR = 0
    EPwm5Regs.AQCTLA.bit.CBD        = 0;                //Disable CBD event
    EPwm5Regs.AQCTLA.bit.CBU        = 0;                //Disable CBU event
    EPwm5Regs.AQCTLA.bit.CAU        = 0;                //Disable CAU event
    EPwm5Regs.AQCTLA.bit.CAD        = AQ_SET;           //SET on CAD event
    EPwm5Regs.AQCTLA.bit.PRD        = 0;                //do nothing when TBCTR = Period
    EPwm5Regs.AQCTLA.bit.ZRO        = AQ_CLEAR;         //Clear EPWMxA when TBCTR = 0
    EPwm5Regs.AQCSFRC.bit.CSFA      = AQ_CLEAR;         //Force EPWMxA continuously LOW (must be set to zero to disable)

}

void configure_ePWM6(void)
{
    EPwm6Regs.TBPRD                 = maxCount;         //PWM period in clock counts (clock freq = 30MHz)
    EPwm6Regs.TBCTL.bit.PRDLD       = 0;                //TBPRD loaded from shadow reg when TBCTR = 0
//    EPwm6Regs.TBPHS.half.TBPHS      = 0;               // Set Phase register to zero
    EPwm6Regs.TBCTL.bit.PHSEN       = 0;                //Do not load TBCTR from phase reg
    EPwm6Regs.TBCTL.bit.PRDLD       = TB_SHADOW;
    EPwm6Regs.TBCTL.bit.CTRMODE     = TB_COUNT_DOWN;    //Down-count mode enabled
//    EPwm6Regs.TBCTL.bit.SYNCOSEL    = TB_CTR_ZERO;
    EPwm6Regs.CMPA.half.CMPA        = pwmMax;           //CMPA event occurs at TBCTR = pwmMax
    EPwm6Regs.CMPCTL.bit.SHDWAMODE  = CC_SHADOW;        //CMPA value buffered via shadow reg
    EPwm6Regs.CMPCTL.bit.LOADAMODE  = CC_CTR_ZERO;      //Load CMPA from shadow reg when CTR = 0
    EPwm6Regs.AQCTLA.bit.CBD        = 0;                //Disable CBD event
    EPwm6Regs.AQCTLA.bit.CBU        = 0;                //Disable CBU event
    EPwm6Regs.AQCTLA.bit.CAU        = 0;                //Disable CAU event
    EPwm6Regs.AQCTLA.bit.CAD        = 0;                //Disable CAD event
    EPwm6Regs.AQCTLA.bit.PRD        = 0;                //do nothing when TBCTR = Period
    EPwm6Regs.AQCTLA.bit.ZRO        = AQ_CLEAR;         //Clear EPWMxA when TBCTR = 0
    EPwm6Regs.AQCSFRC.bit.CSFA      = AQ_CLEAR;         //Force EPWMxA continuously LOW (must be set to zero to disable)
}


//---------------------------------End PWM Initialization Functions------------------------------------------

/*Truth Table for Hall-to-Case relationship
  WHERE PHASE A=GREEN, PHASE B=YELLOW, PHASE C=BLUE
  WHERE HALL1=GPIO23, HALL2=GPIO27, HALL3=GPIO11

 SECTOR| HALL1(GREEN) | HALL2(YELLOW) | HALL3(BLUE) || ePWM1A(AH) | ePWM2A(AL) | ePWM3A(BH) | ePWM4A(BL) | ePWM5A(CH) | ePWM6A(CL) |
 ======|==============|===============|=============||============|============|============|============|============|============|
 sec 1 |      1       |        0      |      1      ||      1     |      0     |      0     |      1     |      0     |      0     |
 ------|--------------|---------------|-------------||------------|------------|------------|------------|------------|------------|
 sec 2 |      1       |        0      |      0      ||      1     |      0     |      0     |      0     |      0     |      1     |
 ------|--------------|---------------|-------------||------------|------------|------------|------------|------------|------------|
 sec 3 |      1       |        1      |      0      ||      0     |      0     |      1     |      0     |      0     |      1     |
 ------|--------------|---------------|-------------||------------|------------|------------|------------|------------|------------|
 sec 4 |      0       |        1      |      0      ||      0     |      1     |      1     |      0     |      0     |      0     |
 ------|--------------|---------------|-------------||------------|------------|------------|------------|------------|------------|
 sec 5 |      0       |        1      |      1      ||      0     |      1     |      0     |      0     |      1     |      0     |
-------|--------------|---------------|-------------||------------|------------|------------|------------|------------|------------|
 sec 6 |      0       |        0      |      1      ||      0     |      0     |      0     |      1     |      1     |      0     |
 ------|--------------|---------------|-------------||------------|------------|------------|------------|------------|------------|

*/

//-----------------------------Start Interrupt Service Routines-----------------------------------------------
__interrupt void xint1_ISR(void)
{

    //start ADC conversion
    AdcRegs.ADCSOCFRC1.bit.SOC5 = 1;
    while(AdcRegs.ADCSOCFLG1.bit.SOC5!=0)
    {
    //waiting for results
    }
    //Store Results of ADC
    speed1=AdcResult.ADCRESULT5;

    //set CMPA value when moving backward
    if(speed1<=1500)
    {
        direction = 0;
        pwmMax=1500-speed1;
    }

    //set CMPA value for when moving forward
    if(speed1>=2200)
    {
        direction = 1;
        pwmMax=speed1-2200;
    }

    //turn off all FETs if not moving forwards/backwards
    else
    {
        direction = 2;
        EPwm1Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AH LOW
        EPwm2Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AL LOW
        EPwm3Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BH LOW
        EPwm4Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BL LOW
        EPwm5Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CH LOW
        EPwm6Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CL LOW
    }

    //set max and min CMPA values for duty cycle:  200=10% and 1500=80%
    if(pwmMax<200)
        pwmMax=200;
    if(pwmMax>1500)
        pwmMax=1500;

    //choose next state based on previous state and direction
    if(direction==0)
    {
        //if rotor is in sector 1
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector4();


        //if rotor is in sector 2
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector5();


        //if rotor is in sector 3
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector6();


        //if rotor is in sector 4
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector1();


        //if rotor is in sector 5
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector2();


        //if rotor is in sector 6
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector3();
    }

    if(direction==1)
    {
        //if rotor is in sector 1
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector1();


        //if rotor is in sector 2
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector2();


        //if rotor is in sector 3
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector3();


        //if rotor is in sector 4
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector4();


        //if rotor is in sector 5
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector5();


        //if rotor is in sector 6
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector6();
    }

    // Acknowledge this interrupt to get more from group 1
    //
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

//
// xint2_isr -
//
__interrupt void xint2_ISR(void)
{

    //start ADC conversion
    AdcRegs.ADCSOCFRC1.bit.SOC5 = 1;
    while(AdcRegs.ADCSOCFLG1.bit.SOC5!=0)
    {
    //waiting for results
    }
    //Store Results of ADC
    speed1=AdcResult.ADCRESULT5;

    //set CMPA value when moving backward
    if(speed1<=1500)
    {
        direction = 0;
        pwmMax=1500-speed1;
    }

    //set CMPA value for when moving forward
    if(speed1>=2200)
    {
        direction = 1;
        pwmMax=speed1-2200;
    }

    //turn off all FETs if not moving forwards/backwards
    else
    {
        direction = 2;
        EPwm1Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AH LOW
        EPwm2Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AL LOW
        EPwm3Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BH LOW
        EPwm4Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BL LOW
        EPwm5Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CH LOW
        EPwm6Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CL LOW
    }

    //set max and min CMPA values for duty cycle:  200=10% and 1500=80%
    if(pwmMax<200)
        pwmMax=200;
    if(pwmMax>1500)
        pwmMax=1500;

    //choose next state based on previous state and direction
    if(direction==0)
    {
        //if rotor is in sector 1
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector4();


        //if rotor is in sector 2
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector5();


        //if rotor is in sector 3
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector6();


        //if rotor is in sector 4
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector1();


        //if rotor is in sector 5
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector2();


        //if rotor is in sector 6
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector3();
    }

    if(direction==1)
    {
        //if rotor is in sector 1
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector1();


        //if rotor is in sector 2
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector2();


        //if rotor is in sector 3
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector3();


        //if rotor is in sector 4
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector4();


        //if rotor is in sector 5
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector5();


        //if rotor is in sector 6
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector6();
    }

    // Acknowledge this interrupt to get more from group 1
    //
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

__interrupt void xint3_ISR(void)
{

    //start ADC conversion
    AdcRegs.ADCSOCFRC1.bit.SOC5 = 1;
    while(AdcRegs.ADCSOCFLG1.bit.SOC5!=0)
    {
    //waiting for results
    }
    //Store Results of ADC
    speed1=AdcResult.ADCRESULT5;

    //set CMPA value when moving backward
    if(speed1<=1500)
    {
        direction = 0;
        pwmMax=1500-speed1;
    }

    //set CMPA value for when moving forward
    if(speed1>=2200)
    {
        direction = 1;
        pwmMax=speed1-2200;
    }

    //turn off all FETs if not moving forwards/backwards
    else
    {
        direction = 2;
        EPwm1Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AH LOW
        EPwm2Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force AL LOW
        EPwm3Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BH LOW
        EPwm4Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force BL LOW
        EPwm5Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CH LOW
        EPwm6Regs.AQCSFRC.bit.CSFA = AQ_CLEAR;      //Force CL LOW
    }

    //set max and min CMPA values for duty cycle:  200=10% and 1500=80%
    if(pwmMax<200)
        pwmMax=200;
    if(pwmMax>1500)
        pwmMax=1500;

    //choose next state based on previous state and direction
    if(direction==0)
    {
        //if rotor is in sector 1
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector4();


        //if rotor is in sector 2
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector5();


        //if rotor is in sector 3
        if(GpioDataRegs.GPADAT.bit.GPIO23==1 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector6();


        //if rotor is in sector 4
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==0)
                sector1();


        //if rotor is in sector 5
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==1 && GpioDataRegs.GPADAT.bit.GPIO11==1)
                sector2();


        //if rotor is in sector 6
        if(GpioDataRegs.GPADAT.bit.GPIO23==0 && GpioDataRegs.GPADAT.bit.GPIO27==0 && GpioDataRegs.GPADAT.bit.GPIO11==1)
...

This file has been truncated, please download it to see its full contents.

HALL AND PHASE SIGNAL PROGRESSIONS.xlsx

Plain text
This file illustrates how the hall sensors related to the phase voltage of the motor used in this project. Note that the hall sensor progressions may be different with your motor. The tables indicate what MOSFETs are turned on for each different sector, relating back to the different sectorx() functions used in the software main.c.
No preview (download only).

DSP2803x_Gpio.c

C/C++
GPIO pin configuration initialization
//###########################################################################
//
// FILE:	DSP2803x_Gpio.c
//
// TITLE:	DSP2803x General Purpose I/O Initialization & Support Functions.
//
//###########################################################################
// $TI Release: F2803x Support Library v2.01.00.00 $
// $Release Date: Thu Dec  7 18:49:31 CST 2017 $
// $Copyright:
// Copyright (C) 2009-2017 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################

//
// Included Files
//
#include "DSP2803x_Device.h"     // DSP2803x Headerfile Include File
#include "DSP2803x_Examples.h"   // DSP2803x Examples Include File

//
// InitGpio - This function initializes the Gpio to a known (default) state.
//
// For more details on configuring GPIO's as peripheral functions,
// refer to the individual peripheral examples and/or GPIO setup example.
//
void 
InitGpio(void)
{
    EALLOW;

    //
    // Each GPIO pin can be:
    // a) a GPIO input/output
    // b) peripheral function 1
    // c) peripheral function 2
    // d) peripheral function 3
    // By default, all are GPIO Inputs
    //


    //            _______________________________________________________________________________
    //           |                          GPIOB MUX Functions                                  |
    //  ---------|===============================================================================|
    // Bit Value:|   xx    |    xx    |   xx    |   00(I)  |   00(I) |   00(I)|   00(N) |   00(N)|
    //      GPIO:|   47    |    46    |   45    |   44     |   43    |   42   |   41    |   40   |
    //  Function:|  RSVD   |   RSVD   |  RSVD   |   SW2    |  GPIO   |  GPIO  |  GPIO   |  GPIO  |
    //  ---------|---------|----------|---------|----------|---------|--------|---------|--------|
    // Bit Value:|   00(N) |    00    |   00    |   00     |   00    |   00(O)|   00(O) |   00(O)| Note: GPIO32 is also ADCSOCAO
    //      GPIO:|   39    |    38    |   37    |   36     |   35    |   34   |   33    |   32   |       and may need to be set to [11]
    //  Function:|  GPIO   |JTAG_TCK  |JTAG_TDO |JTAG_TMS  |JTAG_TDI |EN_GATE |  GPIO   |  GPIO  |       ; all NC pins are set to outputs
    //  -----------------------------------------------------------------------------------------
    //             GPBMUX=0x000000 (This is zero by default anyways)  and GPBDIR=0000 0011 1000 0111=0x0387
    //


    //            _______________________________________________________________________________
    //           |                             GPIOA MUX1 Functions                              |
    //           |===============================================================================|
    // Bit Value:|   00(I) |   00(O) |   00(I) |   10     |   00(I)  |  01    |  00(N)|    01    |
    //      GPIO:|   15    |   14    |   13    |   12     |   11     |  10    |  09   |    08    |
    //  Function:| FAULT   | BL_LED  |  OCTW   |SCITXDA   |Xint3_H3  |PWM1A_AH| GPIO  | PWM2A_AL |
    //  ---------|---------|---------|---------|----------|----------|--------|-------|----------|
    // Bit Value:|  00(N)  |   01    |   10    |   01     |   10     |  01    |  00(N)|    01    |
    //      GPIO:|  07     |   06    |   05    |   04     |   03     |  02    |  01   |    00    |
    //  Function:| GPIO    |PWM3A_BH |SPISIMOA |PWM4A_BL  |SPISOMIA  |PWM5A_CH| GPIO  |  PWM6A_CL|
    //  -----------------------------------------------------------------------------------------
    //              GPAMUX1=0x02111991  and  GPADIR=0100 0010 1000 0010=0x4282  bits 15-0     Note:  All NC pins are set to outputs
    // settings for 3PWM and no RS-232 or CAN:  GPAMUX1=0x00101890 and GPADIR=0x5282

    //            _______________________________________________________________________________
    //           |                          GPIOA MUX2 Functions                                 |
    //  ---------|===============================================================================|
    // Bit Value:|   01    |    01   |    00(N)|    01    |    00(I) |  00(N) |  00(N)|     00(O)|
    //      GPIO:|   31    |    30   |    29   |    28    |    27    |   26   |   25  |     24   |
    //  Function:| CANTXA  |  CANRXA |   GPIO  |  SCIRXDA |  Xint2_H2|  GPIO  |  GPIO |   OR_LED |
    //  ---------|---------|---------|---------|----------|----------|--------|-------|----------|
    // Bit Value:|  00(I)  |   00(O) |   00(O) |   00(O)  |   01     |  01    |  00(O)|    00(I) |
    //      GPIO:|  23     |   22    |   21    |   20     |   19     |  18    |  17   |    16    |
    //  Function:|Xint1_H1 | RS_CAN  | RED_LED |  GN_LED  | nSPISTEA | SPICLKA| DC_CAL|    SW1   |
    //  -----------------------------------------------------------------------------------------
    //              GPAMUX2=0x51000050    and     GPADIR=0010 0111 0111 0010=0x2772  bits 31-16      --> Note: Total value in GPADIR=0x27724282
    // setting for 3PWM and no RS-232 or CAN:  GPAMUX2=0x00000050 and GPADIR=0xF772

    //           _______________________________________________________________________________
    //          |                                  Analog MUX                                   |
    //          |                      (Default to ADC inputs at reset)                         |
    // ---------|===============================================================================|
    //   ADC_IN:|   B7    |    B6   |    B5   |    B4    |    B3   |   B2    |   B1   |    B0   |
    // Function:|NOT USED |NOT USED |NOT USED | NOT USED |NOT USED |NOT USED |NOT USED|NOT USED |
    // ---------|---------|---------|---------|----------|---------|---------|--------|---------|
    //   ADC_IN:|   A7    |    A6   |    A5   |    A4    |    A3   |   A2    |   A1   |    A0   |
    // Function:| SPEED2  | NOT USED|  SPEED1 | NOT USED |   SO_3  |  SO_2   |  SO_1  |NOT USED |
    // -----------------------------------------------------------------------------------------






    GpioCtrlRegs.GPAMUX1.all = 0x02111991;   // GPIO functionality GPIO0-GPIO15
    //GpioCtrlRegs.GPAMUX1.all = 0x00101890;     //No comms other than SPI and setup for 3PWM instead 6PWM
    GpioCtrlRegs.GPAMUX2.all = 0x51000050;   // GPIO functionality GPIO16-GPIO31
    //GpioCtrlRegs.GPAMUX2.all = 0x00000050;     //No comms other than SPI and setup for 3PWM instead 6PWM
    GpioCtrlRegs.GPBMUX1.all = 0x0000;         // GPIO functionality GPIO32-GPIO44

    //
    // Dig.IO funct. applies to AIO2,4,6,10,12,14
    //
    GpioCtrlRegs.AIOMUX1.all = 0x0000;     

    GpioCtrlRegs.GPADIR.all = 0x27724282;   // Set direction of GPIOA pins based on table above
    //GpioCtrlRegs.GPADIR.all = 0xF7725282;     // GPIO direction when using no ext. comms and 3PWM instead of 6PWM
    GpioCtrlRegs.GPBDIR.all = 0x0387;        // Set direction of GPIOB pins based on table above
    GpioCtrlRegs.AIODIR.all = 0x0000;        // AIO2,4,6,19,12,14 are digital inputs

    //
    // Each input can have different qualification
    // a) input synchronized to SYSCLKOUT
    // b) input qualified by a sampling window
    // c) input sent asynchronously (valid for peripheral inputs only)
    //
    GpioCtrlRegs.GPAQSEL1.all = 0x0000;    // GPIO0-GPIO15 Synch to SYSCLKOUT
    GpioCtrlRegs.GPAQSEL2.all = 0x0000;    // GPIO16-GPIO31 Synch to SYSCLKOUT
    GpioCtrlRegs.GPBQSEL1.all = 0x0000;    // GPIO32-GPIO44 Synch to SYSCLKOUT

    //
    // Pull-ups can be enabled
    //
    GpioCtrlRegs.GPAPUD.all = 0x0000;      // Pullup's enabled GPIO0-GPIO31
    GpioCtrlRegs.GPBPUD.all = 0x0000;      // Pullup's enabled GPIO32-GPIO44

    // -----------------------------SPI Configurations----------------------------------------


    // Set qualification for selected pins to asynch only
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 2;  // Configure GPIO5 as SPISIMOA
    GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 2;  // Configure GPIO3 as SPISOMIA
    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA


    SpiaRegs.SPICCR.bit.SPISWRESET = 0;      // Force SPIA to reset state
    SpiaRegs.SPICCR.bit.SPICHAR = 0xF;       // 16 bit SPI
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;     // Data output one half period after rising clock edge when phase=0
    SpiaRegs.SPICTL.bit.CLK_PHASE = 0;       // Set Phase to zero
    SpiaRegs.SPICTL.bit.OVERRUNINTENA = 0;   // Disable data overrun flag
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;    // Set as Master
    SpiaRegs.SPICTL.bit.TALK = 1;            // Allow data transmission
    SpiaRegs.SPICTL.bit.SPIINTENA = 0;       // Disable SPI interrupt
    SpiaRegs.SPIBRR = 127;                   // Set Bit Rate to LSPCLK/10
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;      // Force SPIA out of reset state
    SpiaRegs.SPIPRI.bit.FREE = 1;            // Set so breakpoints don't disturb xmission

    GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 3;     // Asynch input GPIO5 (SPISIMOA)
    GpioCtrlRegs.GPAQSEL1.bit.GPIO3 = 3;     // Asynch input GPIO3 (SPISOMIA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3;    // Asynch input GPIO18 (SPICLKA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3;    // Asynch input GPIO19 (SPISTEA)

    EDIS;
    GpioDataRegs.GPACLEAR.all = 0xFFFFFFFF;// Clear all GPIO1-GPIO31 outputs
    GpioDataRegs.GPBCLEAR.all = 0xFFFFFFFF;// Clear all GPIO32-GPIO44 outputs


}

//
// End of file
//

DSP2803x_Spi.c

C/C++
SPI configuration
//###########################################################################
//
// FILE:   DSP2803x_Spi.c
//
// TITLE:  DSP2803x SPI Initialization & Support Functions.
//
//###########################################################################
// $TI Release: F2803x Support Library v2.01.00.00 $
// $Release Date: Thu Dec  7 18:49:31 CST 2017 $
// $Copyright:
// Copyright (C) 2009-2017 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################

//
// Included Files
//
#include "DSP2803x_Device.h"     // DSP2803x Headerfile Include File
#include "DSP2803x_Examples.h"   // DSP2803x Examples Include File

//
// InitSPI -This function initializes the SPI(s) to a known state.
//
void 
InitSpi(void)
{
    //
    // Initialize SPI-A
    //
}

//
// InitSpiGpio - This function initializes GPIO pins to function as SPI pins
//
// Each GPIO pin can be configured as a GPIO pin or up to 3 different
// peripheral functional pins. By default all pins come up as GPIO
// inputs after reset.
//
// Caution:
// For each SPI peripheral
// Only one GPIO pin should be enabled for SPISOMO operation.
// Only one GPIO pin should be enabled for SPISOMI operation.
// Only one GPIO pin should be enabled for SPICLK  operation.
// Only one GPIO pin should be enabled for SPISTE  operation.
// Comment out other unwanted lines.
//
void 
InitSpiGpio()
{

    InitSpiaGpio();
#if DSP28_SPIB
    InitSpibGpio();
#endif
}

//
// InitSpiaGpio - Initialize SPIA GPIOs
//
void 
InitSpiaGpio()
{
    EALLOW;

    //
    // Enable internal pull-up for the selected pins
    // Pull-ups can be enabled or disabled by the user.
    // This will enable the pullups for the specified pins.
    // Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;   //Enable pull-up on GPIO16 (SPISIMOA)
    //GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0;   //Enable pull-up on GPIO5 (SPISIMOA)
    GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;   //Enable pull-up on GPIO17 (SPISOMIA)
    //GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0;  // Enable pull-up on GPIO3 (SPISOMIA)
    GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;   // Enable pull-up on GPIO18 (SPICLKA)
    GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;   // Enable pull-up on GPIO19 (SPISTEA)

    //
    // Set qualification for selected pins to asynch only
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3;   //Asynch input GPIO16 (SPISIMOA)
    //GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 3;  //Asynch input GPIO5 (SPISIMOA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3;   // Asynch input GPIO17 (SPISOMIA)
    //GpioCtrlRegs.GPAQSEL1.bit.GPIO3 = 3;  // Asynch input GPIO3 (SPISOMIA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3;   // Asynch input GPIO18 (SPICLKA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3;   // Asynch input GPIO19 (SPISTEA)

    //
    // Configure SPI-A pins using GPIO regs
    // This specifies which of the possible GPIO pins will be SPI functional 
    // pins. Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
    //GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 2;  // Configure GPIO5 as SPISIMOA
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
    //GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 2;  // Configure GPIO3 as SPISOMIA
    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA

    EDIS;
}

#if DSP28_SPIB
//
// InitSpibGpio - Initialize SPIB GPIOs
//
void 
InitSpibGpio()
{
    EALLOW;

    //
    // Enable internal pull-up for the selected pins
    // Pull-ups can be enabled or disabled disabled by the user.
    // This will enable the pullups for the specified pins.
    // Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0;   //Enable pull-up on GPIO12 (SPISIMOB)
    //GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0; //Enable pull-up on GPIO24 (SPISIMOB)

    GpioCtrlRegs.GPAPUD.bit.GPIO13 = 0;   //Enable pull-up on GPIO13 (SPISOMIB)
    //GpioCtrlRegs.GPAPUD.bit.GPIO25 = 0; //Enable pull-up on GPIO25 (SPISOMIB)

    GpioCtrlRegs.GPAPUD.bit.GPIO14 = 0;    //Enable pull-up on GPIO14 (SPICLKB)
    //GpioCtrlRegs.GPAPUD.bit.GPIO26 = 0;  //Enable pull-up on GPIO26 (SPICLKB)

    GpioCtrlRegs.GPAPUD.bit.GPIO15 = 0;    //Enable pull-up on GPIO15 (SPISTEB)
    //GpioCtrlRegs.GPAPUD.bit.GPIO27 = 0;  //Enable pull-up on GPIO27 (SPISTEB)

    //
    // Set qualification for selected pins to asynch only
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 3;   // Asynch input GPIO12 (SPISIMOB)
    //GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 3;  // Asynch input GPIO24 (SPISIMOB)

    GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 3;   // Asynch input GPIO13 (SPISOMIB)
    //GpioCtrlRegs.GPAQSEL2.bit.GPIO25 = 3;  // Asynch input GPIO25 (SPISOMIB)

    GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 3;   // Asynch input GPIO14 (SPICLKB)
    //GpioCtrlRegs.GPAQSEL2.bit.GPIO26 = 3;  // Asynch input GPIO26 (SPICLKB)

    GpioCtrlRegs.GPAQSEL1.bit.GPIO15 = 3;   // Asynch input GPIO15 (SPISTEB)
    //GpioCtrlRegs.GPAQSEL2.bit.GPIO27 = 3;   // Asynch input GPIO27 (SPISTEB)

    //
    // Configure SPI-B pins using GPIO regs
    // This specifies which of the possible GPIO pins will be SPI functional 
    // pins. Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 3;    // Configure GPIO12 as SPISIMOB
    //GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 3;   // Configure GPIO24 as SPISIMOB

    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 3;    // Configure GPIO13 as SPISOMIB
    //GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 3;   // Configure GPIO25 as SPISOMIB

    GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 3;    // Configure GPIO14 as SPICLKB
    //GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 3;   // Configure GPIO26 as SPICLKB

    GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 3;    // Configure GPIO15 as SPISTEB
    //GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 3;   // Configure GPIO27 as SPISTEB

    EDIS;
}
#endif 

//
// End of file
//

DSP2803x_SysCtrl.c

C/C++
Configure System controls
//###########################################################################
//
// FILE:   DSP2803x_SysCtrl.c
//
// TITLE:  DSP2803x Device System Control Initialization & Support Functions.
//
// DESCRIPTION:  Example initialization of system resources.
//
//###########################################################################
// $TI Release: F2803x Support Library v2.01.00.00 $
// $Release Date: Thu Dec  7 18:49:31 CST 2017 $
// $Copyright:
// Copyright (C) 2009-2017 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################

//
// Included Files
//
#include "DSP2803x_Device.h"     // Headerfile Include File
#include "DSP2803x_Examples.h"   // Examples Include File

//
// Functions that will be run from RAM need to be assigned to
// a different section.  This section will then be mapped to a load and
// run address using the linker cmd file.
//
//  *IMPORTANT*
//  IF RUNNING FROM FLASH, PLEASE COPY OVER THE SECTION "ramfuncs"  FROM FLASH
//  TO RAM PRIOR TO CALLING InitSysCtrl(). THIS PREVENTS THE MCU FROM THROWING 
//  AN EXCEPTION WHEN A CALL TO DELAY_US() IS MADE. 
//
#pragma CODE_SECTION(InitFlash, "ramfuncs");

//
// InitSysCtrl - This function initializes the System Control registers
// to a known state.
//
// - Disables the watchdog
// - Set the PLLCR for proper SYSCLKOUT frequency
// - Set the pre-scaler for the high and low frequency peripheral clocks
// - Enable the clocks to the peripherals
//
void 
InitSysCtrl(void)
{
    //
    // Disable the watchdog
    //
    DisableDog();

    //
    //                                  *IMPORTANT*
    // The Device_cal function, which copies the ADC & oscillator calibration
    // values from TI reserved OTP into the appropriate trim registers, occurs
    // automatically in the Boot ROM. If the boot ROM code is bypassed during
    // the debug process, the following function MUST be called for the ADC and
    // oscillators to function according to specification. The clocks to the 
    // ADC MUST be enabled before calling this function.
    // See the device data manual and/or the ADC Reference
    // Manual for more information.
    //
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // Enable ADC peripheral clock
    (*Device_cal)();
    SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 0; // Return ADC clock to original state
    EDIS;

    //
    // Select Internal Oscillator 1 as Clock Source (default), and turn off
    // all unused clocks to conserve power.
    //

    //---------------
    IntOsc1Sel();


    //
    // Initialize the PLL control: PLLCR and CLKINDIV
    // DSP28_PLLCR and DSP28_CLKINDIV are defined in DSP2803x_Examples.h
    //
    InitPll(DSP28_PLLCR,DSP28_DIVSEL);
    
    //
    // Initialize the peripheral clocks
    //
    InitPeripheralClocks();
}

//
// InitFlash - This function initializes the Flash Control registers
//                   CAUTION
// This function MUST be executed out of RAM. Executing it
// out of OTP/Flash will yield unpredictable results
//
void 
InitFlash(void)
{
    EALLOW;
    
    //
    // Enable Flash Pipeline mode to improve performance
    // of code executed from Flash.
    //
    FlashRegs.FOPT.bit.ENPIPE = 1;

    //
    //                CAUTION
    // Minimum waitstates required for the flash operating
    // at a given CPU rate must be characterized by TI.
    // Refer to the datasheet for the latest information.
    //

    //
    // Set the Paged Waitstate for the Flash
    //
    FlashRegs.FBANKWAIT.bit.PAGEWAIT = 2;

    //
    // Set the Random Waitstate for the Flash
    //
    FlashRegs.FBANKWAIT.bit.RANDWAIT = 2;

    //
    // Set the Waitstate for the OTP
    //
    FlashRegs.FOTPWAIT.bit.OTPWAIT = 3;

    //
    //                CAUTION
    // ONLY THE DEFAULT VALUE FOR THESE 2 REGISTERS SHOULD BE USED
    //
    FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF;
    FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF;
    EDIS;

    //
    // Force a pipeline flush to ensure that the write to
    // the last register configured occurs before returning.
    //
    __asm(" RPT #7 || NOP");
}

//
// ServiceDog - This function resets the watchdog timer.
// Enable this function for using ServiceDog in the application
//
void 
ServiceDog(void)
{
    EALLOW;
    SysCtrlRegs.WDKEY = 0x0055;
    SysCtrlRegs.WDKEY = 0x00AA;
    EDIS;
}

//
// DisableDog - This function disables the watchdog timer.
//
void 
DisableDog(void)
{
    EALLOW;
    SysCtrlRegs.WDCR= 0x0068;
    EDIS;
}

//
// InitPll - This function initializes the PLLCR register.
//
void 
InitPll(Uint16 val, Uint16 divsel)
{
   volatile Uint16 iVol;

   //
   // Make sure the PLL is not running in limp mode
   //
   if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
   {
        EALLOW;
        
        //
        // OSCCLKSRC1 failure detected. PLL running in limp mode.
        // Re-enable missing clock logic.
        //
        SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1;
        EDIS;
        
        //
        // Replace this line with a call to an appropriate
        // SystemShutdown(); function.
        __asm("        ESTOP0");     // Uncomment for debugging purposes
    }

    //
    // DIVSEL MUST be 0 before PLLCR can be changed from
    // 0x0000. It is set to 0 by an external reset XRSn
    // This puts us in 1/4
    //
    if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
    {
        EALLOW;
        SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
        EDIS;
    }

    //
    // Change the PLLCR
    //
    if (SysCtrlRegs.PLLCR.bit.DIV != val)
    {
        EALLOW;
        
        //
        // Before setting PLLCR turn off missing clock detect logic
        //
        SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
        SysCtrlRegs.PLLCR.bit.DIV = val;
        EDIS;

        //
        // Optional: Wait for PLL to lock.
        //
        // During this time the CPU will switch to OSCCLK/2 until
        // the PLL is stable.  Once the PLL is stable the CPU will
        // switch to the new PLL value.
        //
        // This time-to-lock is monitored by a PLL lock counter.
        //
        // Code is not required to sit and wait for the PLL to lock.
        // However, if the code does anything that is timing critical,
        // and requires the correct clock be locked, then it is best to
        // wait until this switching has completed.
        //
        
        //
        // Wait for the PLL lock bit to be set.
        //

        //
        // The watchdog should be disabled before this loop, or fed within
        // the loop via ServiceDog().
        //

        //
        // Uncomment to disable the watchdog
        //
        DisableDog();

        while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
        {
            //
            // Uncomment to service the watchdog
            //
            // ServiceDog();
        }

        EALLOW;
        SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
        EDIS;
    }

    //
    // If switching to 1/2
    //
    if((divsel == 1)||(divsel == 2))
    {
        EALLOW;
        SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
        EDIS;
    }

    //
    // If switching to 1/1
    // * First go to 1/2 and let the power settle
    //   The time required will depend on the system, this is only an example
    // * Then switch to 1/1
    //
    if(divsel == 3)
    {
        EALLOW;
        SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
        DELAY_US(50L);
        SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
        EDIS;
    }
}

//
// InitPeripheralClocks - This function initializes the clocks to the 
// peripheral modules. First the high and low clock prescalers are set
// Second the clocks are enabled to each peripheral.
// To reduce power, leave clocks to unused peripherals disabled
//
// Note: If a peripherals clock is not enabled then you cannot
// read or write to the registers for that peripheral
//
void 
InitPeripheralClocks(void)
{
    EALLOW;

    //
    // LOSPCP prescale register settings, normally it will be set 
    // to default values
    //
    //GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3;  // GPIO18 = XCLKOUT
    SysCtrlRegs.LOSPCP.all = 0x0002;

    //
    // XCLKOUT to SYSCLKOUT ratio.  By default XCLKOUT = 1/4 SYSCLKOUT
    //
    SysCtrlRegs.XCLK.bit.XCLKOUTDIV=2;

    //
    // Peripheral clock enables set for the selected peripherals.
    // If you are not using a peripheral leave the clock off
    // to save on power.
    //
    // Note: not all peripherals are available on all 2803x derivates.
    // Refer to the datasheet for your particular device.
    //
    // This function is not written to be an example of efficient code.
    //
    SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;      // ADC
    SysCtrlRegs.PCLKCR3.bit.COMP1ENCLK = 1;    // COMP1
    SysCtrlRegs.PCLKCR3.bit.COMP2ENCLK = 1;    // COMP2
    SysCtrlRegs.PCLKCR3.bit.COMP3ENCLK = 1;    // COMP3
    SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1;    // eCAP1
    SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1;      // eCAN-A
    SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1;    // eQEP1
    SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;    // ePWM1
    SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1;    // ePWM2
    SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1;    // ePWM3
    SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1;    // ePWM4
    SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1;    // ePWM5
    SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1;    // ePWM6
    SysCtrlRegs.PCLKCR1.bit.EPWM7ENCLK = 1;    // ePWM7
    SysCtrlRegs.PCLKCR0.bit.HRPWMENCLK = 0;    // HRPWM
    SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 0;     // I2C
    SysCtrlRegs.PCLKCR0.bit.LINAENCLK = 0;     // LIN-A
    SysCtrlRegs.PCLKCR3.bit.CLA1ENCLK = 0;     // CLA1
    SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;     // SCI-A
    SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;     // SPI-A
    SysCtrlRegs.PCLKCR0.bit.SPIBENCLK = 0;     // SPI-B
    SysCtrlRegs.PCLKCR2.bit.HRCAP1ENCLK = 0;
    SysCtrlRegs.PCLKCR2.bit.HRCAP2ENCLK = 0;

    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;     // Enable TBCLK within the ePWM

    EDIS;
}

//
// CsmUnlock - This function unlocks the CSM. User must replace 0xFFFF's 
// with current password for the DSP. Returns 1 if unlock is successful.
//
#define SYSCTRL_CSM_STATUS_FAIL          0
#define SYSCTRL_CSM_STATUS_SUCCESS       1
Uint16
CsmUnlock()
{
    volatile Uint16 temp;

    //
    // Load the key registers with the current password. The 0xFFFF's are dummy
    // passwords.  User should replace them with the correct password for the 
    // DSP.
    //
    EALLOW;
    CsmRegs.KEY0 = 0xFFFF;
    CsmRegs.KEY1 = 0xFFFF;
    CsmRegs.KEY2 = 0xFFFF;
    CsmRegs.KEY3 = 0xFFFF;
    CsmRegs.KEY4 = 0xFFFF;
    CsmRegs.KEY5 = 0xFFFF;
    CsmRegs.KEY6 = 0xFFFF;
    CsmRegs.KEY7 = 0xFFFF;
    EDIS;

    //
    // Perform a dummy read of the password locations
    // if they match the key values, the CSM will unlock
    //
    temp = CsmPwl.PSWD0;
    temp = CsmPwl.PSWD1;
    temp = CsmPwl.PSWD2;
    temp = CsmPwl.PSWD3;
    temp = CsmPwl.PSWD4;
    temp = CsmPwl.PSWD5;
    temp = CsmPwl.PSWD6;
    temp = CsmPwl.PSWD7;

    //
    // If the CSM unlocked, return succes, otherwise return
    // failure.
    //
    if (CsmRegs.CSMSCR.bit.SECURE == 0)
    {
        return SYSCTRL_CSM_STATUS_SUCCESS;
    }   
    else 
    {
        return SYSCTRL_CSM_STATUS_FAIL;   
    }

}

//
// IntOsc1Sel - This function switches to Internal Oscillator 1 and turns off
// all other clock sources to minimize power consumption
//
void 
IntOsc1Sel (void) 
{
    EALLOW;
    SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;
    SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL=0;      // Clk Src = INTOSC1
    SysCtrlRegs.CLKCTL.bit.XCLKINOFF=1;         // Turn off XCLKIN
    SysCtrlRegs.CLKCTL.bit.XTALOSCOFF=1;        // Turn off XTALOSC
    SysCtrlRegs.CLKCTL.bit.INTOSC2OFF=1;        // Turn off INTOSC2
    EDIS;
}

//
// IntOsc2Sel - This function switches to Internal oscillator 2 from 
// External Oscillator and turns off all other clock sources to minimize 
// power consumption
// NOTE: If there is no external clock connection, when switching from
//       INTOSC1 to INTOSC2, EXTOSC and XLCKIN must be turned OFF prior
//       to switching to internal oscillator 1
//
void 
IntOsc2Sel (void) 
{
    EALLOW;
    SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 0;     // Turn on INTOSC2
    SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 1;      // Turn off XCLKIN
    SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 1;     // Turn off XTALOSC
    SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 1;  // Switch to INTOSC2    
    
    SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1;   // Switch to Int. Oscillator 2
    SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0;    // Clock Watchdog off (INTOSC1)
    SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;     // Leave INTOSC1 on
    EDIS;
}

//
// XtalOscSel - This function switches to External CRYSTAL oscillator and turns
// off all other clock sources to minimize power consumption. This option may 
// not be available on all device packages
//
void 
XtalOscSel (void)  
{
    EALLOW;
    SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 0;     // Turn on XTALOSC
    DELAY_US(1000L);                           // 1mS delay to ensure crystal
                                               // oscillator is up and running.
                                               // Adjust as needed. 
    SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 1;      // Turn off XCLKIN
    SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 0;  // Switch to external clock
    
    //
    // Switch INTOSC1 to INTOSC2/ext clk
    //
    SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1;
    
    SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0;    // Clock Watchdog off of INTOSC1
    SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1;     // Turn off INTOSC2
    SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;     // Leave INTOSC1 on
    EDIS;
}

//
// ExtOscSel - This function switches to External oscillator and turns off all 
// other clock sources to minimize power consumption.
//
void 
ExtOscSel (void)
{
    EALLOW;
    
    //
    // 1-GPIO19 = XCLKIN, 0-GPIO38 = XCLKIN
    //
    SysCtrlRegs.XCLK.bit.XCLKINSEL = 1;
    
    SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 1;   //Turn on XTALOSC
    SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 0;    //Turn on XCLKIN
    SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 0; //Switch to external clock
    
    //
    // Switch INTOSC1 to INTOSC2/ext clk
    //
    SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1;
    
    SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0;   //Clock Watchdog off of INTOSC1
    SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1;    //Turn off INTOSC2
    SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;    //Leave INTOSC1 on
    EDIS;
}

//
// End of file
//

Software Instructions.docx

Plain text
Read before using Code Composer Studio
No preview (download only).

Credits

Brandon Dyer
1 project • 3 followers
Thanks to Texas Instrument Inc., Duncan Starr, Grant Reed, Robert Saunders, Dr. Kevin Lewelling , Arkansas Space Grant Consortium, and University of Arkansas (Fayetteville).

Comments