You are on page 1of 3

/****************************************************************************

Module
BeaconIRCaptureModule.c

SET UP FOR WIDE TIMER 1 PORT 1


THIS CORRESPONDS to PC7.
Revision
1.0.1

Description
Listens for IR events
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
#include "BeaconIRInputCaptureModule.h"
// Hardware
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_pwm.h"
#include "inc/hw_nvic.h"
#include "inc/hw_timer.h"

// Event & Services Framework


#include "ES_Configure.h"
#include "ES_Framework.h"
#include "ES_DeferRecall.h"
#include "ES_ShortTimer.h"
#include "PWM16Tiva.h"
#include "MasterSM.h"

/*----------------------------- Module Defines ----------------------------*/


#define TICKS_PER_US (40)
#define TOLERANCE_PERCENT (.01)
#define REQUIRED_CONSEC_PULSES (10)
/*---------------------------- Module Functions ---------------------------*/
/* prototypes for private functions for this service.They should be functions
relevant to the behavior of this service
*/

/*------------------------------ Module Code ------------------------------*/


/****************************************************************************/

static uint32_t NumConsecutivePulses = 0;


static uint32_t lastCount = 0;
static bool OnBeacon = false;
static uint32_t mostRecentPerioduS = 0;
static uint32_t newCount;
static uint32_t BeaconPeriodUS = 0;
static uint32_t tolerance = 0;

//THIS IS THE ISR FOR THE TIMER


void BeaconIRISR(void)
{
//clear interrupt source
HWREG(WTIMER1_BASE + TIMER_O_ICR) = TIMER_ICR_CAECINT;
//grab event time from value register
newCount = HWREG(WTIMER1_BASE + TIMER_O_TAR);
//calculate ticks between events
mostRecentPerioduS = (newCount - lastCount) / TICKS_PER_US;
//printf("%d\r\n", mostRecentPerioduS);
//if period is within tolerance of period (in microseconds) then increment how many
good pulses we have.
if ((mostRecentPerioduS + tolerance > BeaconPeriodUS) && (mostRecentPerioduS -
tolerance < BeaconPeriodUS))
{
NumConsecutivePulses++;
}
//otherwise reset number of consecutive good pulses.
else
{
NumConsecutivePulses = 0;
}
// if number of consecutive good pulses gets high enough, tell the main service
that we've found the beacon
if (NumConsecutivePulses == REQUIRED_CONSEC_PULSES)
{
NumConsecutivePulses = 0;
ES_Event_t FoundIR;
FoundIR.EventType = FOUND_IR;
PostMasterSM(FoundIR);
//TODO: MAKE SURE WE"RE POSTING TO CORRECT STATEMACHINE
OnBeacon = true;
}
//store new tick count as old value.
lastCount = newCount;
}

void InitBeaconIRInputCaptureModule(void)
{
// enable wide timer 1 subtimer A which corresponds to PC6.
// enable wide timer 1 subtimer A which corresponds to PC6.
// enable wide timer 1 subtimer A which corresponds to PC6.
HWREG(SYSCTL_RCGCWTIMER) |= SYSCTL_RCGCWTIMER_R1;
// this will output/listen to pin pc4 (the first available pin)
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R2;
// disable timer
HWREG(WTIMER1_BASE + TIMER_O_CTL) &= ~TIMER_CTL_TAEN;
// make sure it's in 32bit long mode, this concatenates two 16bit timers.
HWREG(WTIMER1_BASE + TIMER_O_CFG) = TIMER_CFG_16_BIT;
//make roll-over of timer equal to the roll-over or 32bit int for simplicity/time
subtraction
HWREG(WTIMER1_BASE + TIMER_O_TAILR) = 0xffffffff;
// Set wide timer A to capture mode (TAMR=3, TAAMS = 0),
// store the edge time in the value register (TACMR = 1) and make it count up(TACDIR
= 1)
HWREG(WTIMER1_BASE + TIMER_O_TAMR) = (HWREG(WTIMER1_BASE + TIMER_O_TAMR) &
~TIMER_TAMR_TAAMS) | (TIMER_TAMR_TACDIR | TIMER_TAMR_TACMR | TIMER_TAMR_TAMR_CAP);
// To listen to rising edges, set TAEVENT bits in CTL register to clear
HWREG(WTIMER1_BASE + TIMER_O_CTL) &= ~TIMER_CTL_TAEVENT_M;

//tell PC6 that it will have an alternative function


HWREG(GPIO_PORTC_BASE + GPIO_O_AFSEL) |= BIT6HI;
//make bit 6's alternate function WT0CCP0. This requires writing 7 to it.
// so wrtie 7 shifted 24 times as it must be shifted 6 times * 4bits

//TODO: IS THIS SHIFTING RIGHT?


HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL) = (HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL) &
0xf0ffffff) + (7 << 24);

//enable pin c to be digital I/O


HWREG(GPIO_PORTC_BASE + GPIO_O_DEN) |= BIT6HI;
//MAke digital input
HWREG(GPIO_PORTC_BASE + GPIO_O_DIR) &= BIT6LO;
//turn local inteerrupt capture on
//HWREG(WTIMER1_BASE + TIMER_O_IMR) |= TIMER_IMR_CAEIM;
// enable interrupt in NVIC, it's bit 0 as it's event 96
HWREG(NVIC_EN3) |= BIT0HI;
// enable interrupts globally
__enable_irq();
// now enable timer and make sure ticks goes slowly when debugging.
HWREG(WTIMER1_BASE + TIMER_O_CTL) |= (TIMER_CTL_TAEN | TIMER_CTL_TASTALL);

printf("Initializign BeaconIR input capture\n\r");


}

void DisableBeaconIR()
{
HWREG(WTIMER1_BASE + TIMER_O_IMR) &= ~TIMER_IMR_CAEIM;
}

void EnableBeaconIR(uint32_t BeaconPeriod_us)


{
printf("enabling interrupt!!\r\n");
BeaconPeriodUS = BeaconPeriod_us;
tolerance = BeaconPeriodUS * TOLERANCE_PERCENT;
HWREG(WTIMER1_BASE + TIMER_O_IMR) |= TIMER_IMR_CAEIM;
}

You might also like