Professional Documents
Culture Documents
Module
ISR.c
Revision
1.0.1
Description
This is a template file for implementing flat state machines under the
Gen2 Events and Services Framework.
Notes
History
When Who What/Why
-------------- --- --------
01/15/12 11:12 jec revisions for Gen2 framework
11/07/11 11:26 jec made the queue static
10/30/11 17:59 jec fixed references to CurrentEvent in RunTemplateSM()
10/23/11 18:20 jec began conversion from SMTemplate.c (02/20/07 rev)
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
/* include header files for this state machine as well as any machines at the
next lower level in the hierarchy that are sub-machines to this machine
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "PWMService.h"
// the common headers for C99 types
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "ES_Port.h"
#include "termio.h"
#include "BITDEFS.H"
Returns
Description
Intializes the necessary hardware and software for Input Capture Response interrupt
Notes
Author
J. Edward Carryer, 10/23/11, 18:55
****************************************************************************/
void InitInputCapturePeriod(void)
{
// start by enabling the clock to the timer (Wide Timer 1,3,5)
HWREG(SYSCTL_RCGCWTIMER) |= SYSCTL_RCGCWTIMER_R1;
HWREG(SYSCTL_RCGCWTIMER) |= SYSCTL_RCGCWTIMER_R3;
HWREG(SYSCTL_RCGCWTIMER) |= SYSCTL_RCGCWTIMER_R5;
// enable the clock to Port C and Port D
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R2;
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R3;
// kill a few cycles to let the clock get going
while ((HWREG(SYSCTL_PRWTIMER) & SYSCTL_PRWTIMER_R1) != SYSCTL_PRWTIMER_R1)
{}
while ((HWREG(SYSCTL_PRWTIMER) & SYSCTL_PRWTIMER_R3) != SYSCTL_PRWTIMER_R3)
{}
while ((HWREG(SYSCTL_PRWTIMER) & SYSCTL_PRWTIMER_R5) != SYSCTL_PRWTIMER_R5)
{}
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R2) != SYSCTL_PRGPIO_R2)
{}
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R3) != SYSCTL_PRGPIO_R3)
{}
// Now Set up the port to do the capture (clock was enabled earlier)
// start by setting the alternate function for Port C bit 4 (WT0CCP0)
HWREG(GPIO_PORTC_BASE + GPIO_O_AFSEL) |= BIT6HI;
HWREG(GPIO_PORTC_BASE + GPIO_O_AFSEL) |= BIT7HI;
HWREG(GPIO_PORTD_BASE + GPIO_O_AFSEL) |= BIT2HI;
HWREG(GPIO_PORTD_BASE + GPIO_O_AFSEL) |= BIT3HI;
// HWREG(GPIO_PORTD_BASE + GPIO_O_AFSEL) |= BIT6HI;
// Then, map bit 4's alternate function to WT0CCP0
// 7 is the mux value to select WT0CCP0, 16 to shift it over to the
// right nibble for bit 4 (4 bits/nibble * 4 bits)
HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL) = (HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL) &
0xfff0ffff) + (7 << 24);
HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL) = (HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL) &
0xfff0ffff) + (7 << 28);
HWREG(GPIO_PORTD_BASE + GPIO_O_PCTL) = (HWREG(GPIO_PORTD_BASE + GPIO_O_PCTL) &
0xfff0ffff) + (7 << 8);
HWREG(GPIO_PORTD_BASE + GPIO_O_PCTL) = (HWREG(GPIO_PORTD_BASE + GPIO_O_PCTL) &
0xfff0ffff) + (7 << 12);
// HWREG(GPIO_PORTD_BASE + GPIO_O_PCTL) = (HWREG(GPIO_PORTD_BASE + GPIO_O_PCTL) &
0xfff0ffff) + (7 << 24);
// Enable pin on Port C for digital I/O
HWREG(GPIO_PORTC_BASE + GPIO_O_DEN) |= (BIT6HI | BIT7HI);
HWREG(GPIO_PORTD_BASE + GPIO_O_DEN) |= (BIT2HI | BIT3HI);
// make pin 4 on Port C into an input
HWREG(GPIO_PORTC_BASE + GPIO_O_DIR) &= (BIT7LO & BIT6LO);
HWREG(GPIO_PORTD_BASE + GPIO_O_DIR) &= (BIT2LO & BIT3LO);
// back to the timer to enable a local capture interrupt
HWREG(WTIMER1_BASE + TIMER_O_IMR) |= TIMER_IMR_CAEIM;
HWREG(WTIMER1_BASE + TIMER_O_IMR) |= TIMER_IMR_CBEIM;
HWREG(WTIMER3_BASE + TIMER_O_IMR) |= TIMER_IMR_CAEIM;
HWREG(WTIMER3_BASE + TIMER_O_IMR) |= TIMER_IMR_CBEIM;
// HWREG(WTIMER5_BASE + TIMER_O_IMR) |= TIMER_IMR_CAEIM;
void InitPeriodicInt(void)
{
// start by enabling the clock to the timer (Wide Timer 1)
HWREG(SYSCTL_RCGCWTIMER) |= SYSCTL_RCGCWTIMER_R5;
// wait for the clock to get going
while ((HWREG(SYSCTL_PRWTIMER) & SYSCTL_PRWTIMER_R5) != SYSCTL_PRWTIMER_R5)
{}
// make sure that timer (Timer A)is disabled before configuring
HWREG(WTIMER5_BASE + TIMER_O_CTL) &= ~TIMER_CTL_TAEN;
// set it up in 32bit wide (individual, not concatenated) mode
HWREG(WTIMER5_BASE + TIMER_O_CFG) = TIMER_CFG_16_BIT;
// set up timer A in periodic mode so that itrepeats the time-outs
HWREG(WTIMER5_BASE + TIMER_O_TAMR) = (HWREG(WTIMER5_BASE + TIMER_O_TAMR) &
~TIMER_TAMR_TAMR_M) | TIMER_TAMR_TAMR_PERIOD;
// set timeout to 2 mS
HWREG(WTIMER5_BASE + TIMER_O_TAILR) = TicksPerMS * 2;
// enable a local timeout interrupt
HWREG(WTIMER5_BASE + TIMER_O_IMR) |= TIMER_IMR_TATOIM;
// HWREG(NVIC_PRI24) = (HWREG(NVIC_PRI24) & ~NVIC_PRI24_INTA_M) |
NVIC_PRI24_INTA_S;
// enable the Timer A in Wide Timer 1 interrupt in the NVIC
// it is interrupt number 96 so appears in EN3 at bit 0
HWREG(NVIC_EN3) |= BIT8HI;
// make sure interrupts are enabled globally
// __enable_irq();
// now kick the timer offby enabling it and enabling the timer to
// stall while stopped by the debugger
HWREG(WTIMER5_BASE + TIMER_O_CTL) |= (TIMER_CTL_TAEN |
TIMER_CTL_TASTALL);
}
/****************************************************************************
Function
InputCaptureResponse
Parameters
Returns
Description
Calculates the period between two encoder signals
Notes
Author
J. Edward Carryer, 10/23/11, 19:25
****************************************************************************/
void InputCaptureResponseLeftEnc(void)
{
uint32_t ThisCapture;
// start by clearing the source of the interrupt, the input capture event
HWREG(WTIMER1_BASE + TIMER_O_ICR) = TIMER_ICR_CAECINT;
// now grab the captured value and calculate the period
ThisCapture = HWREG(WTIMER1_BASE + TIMER_O_TAR);
PeriodLeftEnc = ThisCapture - LastCaptureLeftEnc;
void InputCaptureResponseRightEnc(void)
{
uint32_t ThisCapture;
// start by clearing the source of the interrupt, the input capture event
HWREG(WTIMER1_BASE + TIMER_O_ICR) = TIMER_ICR_CBECINT;
// now grab the captured value and calculate the period
ThisCapture = HWREG(WTIMER1_BASE + TIMER_O_TBR);
PeriodRightEnc = ThisCapture - LastCaptureRightEnc;
if (PeriodRightEnc > MINSPEED_PERIOD)
{
PeriodRightEnc = MINSPEED_PERIOD;
}
if (PeriodRightEnc < MAXSPEED_PERIOD)
{
PeriodRightEnc = MAXSPEED_PERIOD;
}
// update LastCapture to prepare for the next edge
LastCaptureRightEnc = ThisCapture;
}
void InputCaptureResponseW3TA(void)
{
uint32_t ThisCapture;
// start by clearing the source of the interrupt, the input capture event
HWREG(WTIMER3_BASE + TIMER_O_ICR) = TIMER_ICR_CAECINT;
// now grab the captured value and calculate the period
ThisCapture = HWREG(WTIMER3_BASE + TIMER_O_TAR);
PeriodW3TA = ThisCapture - LastCaptureW3TA;
// update LastCapture to prepare for the next edge
//printf("\n\rPeriod in W3TA is %d", PeriodW3TA);
LastCaptureW3TA = ThisCapture;
}
void InputCaptureResponseW3TB(void)
{
uint32_t ThisCapture;
// start by clearing the source of the interrupt, the input capture event
HWREG(WTIMER3_BASE + TIMER_O_ICR) = TIMER_ICR_CBECINT;
// now grab the captured value and calculate the period
ThisCapture = HWREG(WTIMER3_BASE + TIMER_O_TBR);
PeriodW3TB = ThisCapture - LastCaptureW3TB;
// update LastCapture to prepare for the next edge
//printf("\n\rPeriod in W3TB is %d", PeriodW3TB);
LastCaptureW3TB = ThisCapture;
}
void ControlResponse(void)
{
// start by clearing the source of the interrupt
HWREG(WTIMER5_BASE + TIMER_O_ICR) = TIMER_ICR_TATOCINT;
LeftLastError = LeftRPMError;
// SetDutyPB4((LeftNewDuty));
//duty_pterm = RightPropGain*RightRPMError;
//printf("P term Duty %f \r\n", QueryDutyPterm());
RightNewDuty = RightPropGain * RightRPMError + RightIntegTerm;
CurrentPB1 = HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) & BIT1HI;
if (RightNewDuty > 100)
{
RightNewDuty = 100;
}
else if (RightNewDuty < 0)
{
RightNewDuty = 0;
}
if (CurrentPB1)
{
RightNewDuty = 100 - RightNewDuty;
}
// printf("\n\r Left Target is %d and Left Actual is
%d",LeftTargetRPM,LeftCurrentRPM);
// printf("\n\r Right Target is %d and Right Actual is
%d",RightTargetRPM,RightCurrentRPM);
RightLastError = RightRPMError;
// SetDutyPB5((RightNewDuty));
}
/****************************************************************************/
/***************************************************************************
private functions
***************************************************************************/
uint32_t QueryPeriodW1TA(void)
{
return PeriodLeftEnc;
}
uint32_t QueryPeriodW3TA(void)
{
return PeriodW3TA;
}
uint32_t QueryPeriodW5TA(void)
{
return PeriodW5TA;
}
uint32_t QueryPeriodW1TB(void)
{
return PeriodRightEnc;
}
uint32_t QueryPeriodW3TB(void)
{
return PeriodW3TB;
}
uint8_t QuerySpeedLeft(void)
{
return LeftCurrentRPM;
}
uint8_t QuerySpeedRight(void)
{
return RightCurrentRPM;
}