Professional Documents
Culture Documents
Module
MotorEncoders.c
Description
This module implements encoder close loop drive
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
/* include header files for the framework and this service
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "ES_DeferRecall.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h" // Define PART_TM4C123GH6PM in project
#include "driverlib/gpio.h"
#include "termio.h"
#include "hw_nvic.h"
#include "hw_pwm.h"
#include "hw_timer.h"
#include "MotorEncoders.h"
#include "MotorDrive.h"
#include "MasterSM.h"
#define BitsPerNibble 4
#define PRI_A_SHIFT 4
#define PRI_B_SHIFT 12
#define PRI_C_SHIFT 20
#define PRI_D_SHIFT 28
/******************************************************************/
// handles encoder pulses from the left motor
void LeftEncoderResponse(void)
{
// clear source of the interrupt
HWREG(WTIMER0_BASE + TIMER_O_ICR) = TIMER_ICR_CAECINT;
// update LastEdge
LastEncoderEdge[0] = ThisEncoderEdge[0];
// Increment count
EncoderCount[0]++;
// restart oneshot
RestartLeftStopShot();
NewEdge[0] = true;
}
/******************************************************************/
// handles encoder pulses from the right motor
void RightEncoderResponse(void)
{
// clear source of the interrupt
HWREG(WTIMER0_BASE + TIMER_O_ICR) = TIMER_ICR_CBECINT;
// update LastEdge
LastEncoderEdge[1] = ThisEncoderEdge[1];
// Increment count
EncoderCount[1]++;
// restart oneshot
RestartRightStopShot();
NewEdge[1] = true;
}
/******************************************************************/
// handles the left one shot interrupt
void LeftStopShotResponse(void)
{
// clear the source of the interrupt
HWREG(WTIMER3_BASE + TIMER_O_ICR) = TIMER_ICR_TATOCINT;
// set RPM to 0
ActRPM[0] = 0;
//printf("Left \r\n");
if (Driving[0])
{
Driving[0] = false;
ES_Event_t NewEvent;
NewEvent.EventType = LEFT_BUMPER_HIT;
PostMasterSM(NewEvent);
}
/******************************************************************/
// handles the right one shot interrupt
void RightStopShotResponse(void)
{
// clear the source of the interrupt
HWREG(WTIMER3_BASE + TIMER_O_ICR) = TIMER_ICR_TBTOCINT;
// set RPM to 0
ActRPM[1] = 0;
//printf("Right \r\n");
if (Driving[1])
{
Driving[1] = false;
ES_Event_t NewEvent;
NewEvent.EventType = RIGHT_BUMPER_HIT;
PostMasterSM(NewEvent);
}
/******************************************************************/
// Initializes timer subsystem to do input capture for Both Encoders
void InitBothEncoderCapture(void)
{
// enable clock to WideTimer 0
HWREG(SYSCTL_RCGCWTIMER) |= SYSCTL_RCGCWTIMER_R0;
// enable the clock to port C
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R2;
// kick off the timer by enabling and enable timer stall during debug TODO removed
enable TIMER_CTL_TAEN TIMER_CTL_TBEN
HWREG(WTIMER0_BASE + TIMER_O_CTL) |= (TIMER_CTL_TAEN | TIMER_CTL_TASTALL);
HWREG(WTIMER0_BASE + TIMER_O_CTL) |= (TIMER_CTL_TBEN | TIMER_CTL_TBSTALL);
}
// set timout
HWREG(WTIMER3_BASE + TIMER_O_TAILR) = OneShotTimeout;
HWREG(WTIMER3_BASE + TIMER_O_TBILR) = OneShotTimeout;
// kick off the timer by enabling and enable timer stall during debug
HWREG(WTIMER3_BASE + TIMER_O_CTL) |= (TIMER_CTL_TAEN | TIMER_CTL_TASTALL);
HWREG(WTIMER3_BASE + TIMER_O_CTL) |= (TIMER_CTL_TBEN | TIMER_CTL_TBSTALL);
}
/****************************************************************************/
//Initialize periodic timer interrupt for control law
void InitPIControl(void)
{
// get clock speed
ClockSpeed = SysCtlClockGet();
// enable clock to WideTimer 4
HWREG(SYSCTL_RCGCWTIMER) |= SYSCTL_RCGCWTIMER_R4;
while ((HWREG(SYSCTL_PRWTIMER) & SYSCTL_PRWTIMER_R4) != SYSCTL_PRWTIMER_R4)
{}
// set timout
HWREG(WTIMER4_BASE + TIMER_O_TAILR) = CONTROL_INTERVAL;
// kick off the timer by enabling and enable timer stall during debug
HWREG(WTIMER4_BASE + TIMER_O_CTL) |= (TIMER_CTL_TAEN | TIMER_CTL_TASTALL);
}
/****************************************************************************/
void PIControlResponse(void)
{
// clear the source of the interrupt
HWREG(WTIMER4_BASE + TIMER_O_ICR) = TIMER_ICR_TATOCINT;
/****************************************************************************/
// use to turn on Encoder Control of the Motors
void EnableEncoderControl(void)
{
// Resets Encoder count
EncoderCount[0] = 0;
EncoderCount[1] = 0;
/****************************************************************************/
// use to turn off Encoder Control of the Motors
void DisableEncoderControl(void)
{
// disables Encoder control
HWREG(WTIMER4_BASE + TIMER_O_CTL) &= (~TIMER_CTL_TAEN);
}
/****************************************************************************/
// distance is in inches
void SetDistanceLimit(uint16_t Distance)
{
//turn on distance control
limit = true;
/****************************************************************************/
// angle is in degrees
void SetAngleLimit(uint16_t Angle)
{
//turn on distance control
limit = true;
/****************************************************************************/
// no limit on the number of encoder counts
void DisableLimit(void)
{
//turn off distance control
limit = false;
}
/****************************************************************************/
void SetLeftRPM(uint8_t RPM, uint8_t Dir)
{
Direction[0] = Dir;
if (RPM)
{
Driving[0] = true;
}
else
{
Driving[0] = false;
}
SetRPM[0] = RPM;
}
/****************************************************************************/
void SetRightRPM(uint8_t RPM, uint8_t Dir)
{
Direction[1] = Dir;
if (RPM)
{
Driving[1] = true;
}
else
{
Driving[1] = false;
}
SetRPM[1] = RPM;
}
/***************************************************************************
private functions
***************************************************************************/
/******************************************************************/
//restart the Left One Shot timer
static void RestartLeftStopShot(void)
{
// disable wide timer 3/A
HWREG(WTIMER3_BASE + TIMER_O_CTL) &= ~TIMER_CTL_TAEN;
// kick off the timer by enabling and enable timer stall during debug
HWREG(WTIMER3_BASE + TIMER_O_CTL) |= (TIMER_CTL_TAEN);
}
/******************************************************************/
// restart the Right One Shot timer
static void RestartRightStopShot(void)
{
// disable wide timer 3/B
HWREG(WTIMER3_BASE + TIMER_O_CTL) &= ~TIMER_CTL_TBEN;
// kick off the timer by enabling and enable timer stall during debug
HWREG(WTIMER3_BASE + TIMER_O_CTL) |= (TIMER_CTL_TBEN);
}