Software apps and online services | ||||||
![]() |
| |||||
Hand tools and fabrication machines | ||||||
![]() |
| |||||
This project was a Senior Design project that me and my team members, Duncan Starr and Grant Reed, had completed while attending the University of Arkansas in Fayetteville, AR. Thanks to the technical expertise of Mr. Saunders, Dr. Spieshoeffer, Dr. Lewelling, Texas Instruments E2E forum respondees, and others, this project was successful.
The sole purpose of this project is to design a motor controller that can operate the six individual hub motors that will be used to drive a rover. Each motor is operated by its own individual motor controller but will use CAN communications to communicate with the other individual motor controllers. The motor controller is designed to operate a 1hp Brushless DC (BLDC) motor with a maximum operating voltage and current of 48V and +/-25A respectively. One main focus of this project was to use mostly Texas Instruments (TI) components and software. The speed and direction of the motor will be controlled by a potentiometer that is connecting to a steering lever (much like what is used in a zero-turn mower).
The video below shows the motor being operated using a potentiometer and the motor controller, and the image below shows the three phase voltage output of the motor controller as it is operating the BLDC motor in the forward direction.
/*
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 textNo preview (download only).
//###########################################################################
//
// 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
//
//###########################################################################
//
// 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
//
//###########################################################################
//
// 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
//






Comments