Sei sulla pagina 1di 33

ES_Configure.

h
/****************************************************************************
Module
ES_Configure.h
Description
This file contains macro definitions that are edited by the user to
adapt the Events and Services framework to a particular application.
*****************************************************************************/
#ifndef CONFIGURE_H
#define CONFIGURE_H
/****************************************************************************/
#define MAX_NUM_SERVICES 16
/****************************************************************************/
#define NUM_SERVICES 2
/****************************************************************************/
// These are the definitions for Service 0
// the header file with the public function prototypes
#define SERV_0_HEADER "SPECTRE_Comm.h"
// the name of the Init function
#define SERV_0_INIT InitSPECTRE_Comm
// the name of the run function
#define SERV_0_RUN RunSPECTRE_Comm
// How big should this services Queue be?
#define SERV_0_QUEUE_SIZE 5
/****************************************************************************/
// These are the definitions for Service 1
#if NUM_SERVICES > 1
// the header file with the public function prototypes
#define SERV_1_HEADER "SPECTRE_Control.h"
// the name of the Init function
#define SERV_1_INIT InitSPECTRE_Control
// the name of the run function
#define SERV_1_RUN RunSPECTRE_Control
// How big should this services Queue be?
#define SERV_1_QUEUE_SIZE 3
#endif
/****************************************************************************/
// Name/define the events of interest
// Universal events occupy the lowest entries, followed by user-defined events
typedef enum { ES_NO_EVENT = 0,
ES_ERROR, /* used to indicate an error from the service */
ES_INIT,
/* used to transition from initial pseudo-state */
ES_TIMEOUT, /* signals that the timer has expired */
EV_BUTTON_PRESSED,
EV_BYTE_RECEIVED,
EV_MSG_RECEIVED,
EV_STARTED_RECEIVING,
EV_SEND_DATA,
EV_BALLOON_POPPED,
EV_UNPAIR } ES_EventTyp_t ;

/****************************************************************************/
#define EVENT_CHECK_HEADER "EventCheckers.h"
/****************************************************************************/
#define EVENT_CHECK_LIST CheckForButton
/****************************************************************************/
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define

TIMER_UNUSED ((pPostFunc)0)
TIMER0_RESP_FUNC PostSPECTRE_Comm
TIMER1_RESP_FUNC PostSPECTRE_Comm
TIMER2_RESP_FUNC PostSPECTRE_Comm
TIMER3_RESP_FUNC PostSPECTRE_Control
TIMER4_RESP_FUNC PostSPECTRE_Control
TIMER5_RESP_FUNC PostSPECTRE_Control
TIMER6_RESP_FUNC TIMER_UNUSED
TIMER7_RESP_FUNC TIMER_UNUSED
TIMER8_RESP_FUNC TIMER_UNUSED
TIMER9_RESP_FUNC TIMER_UNUSED
TIMER10_RESP_FUNC TIMER_UNUSED
TIMER11_RESP_FUNC TIMER_UNUSED
TIMER12_RESP_FUNC TIMER_UNUSED
TIMER13_RESP_FUNC TIMER_UNUSED
TIMER14_RESP_FUNC PostSPECTRE_Comm
TIMER15_RESP_FUNC PostSPECTRE_Comm

/****************************************************************************/
#define
#define
#define
#define
#define
#define
#define
#define

TxTimer 0
CommTimeout 1
RxTimeout 2
TxRxDebounce 14
TestTimer 15
StatusTimer 3
PopperTimer 4
BalloonPoppedAddressTimer 5

#endif /* CONFIGURE_H */

Startup.S
; <<< Use Configuration Wizard in Context Menu >>>
;******************************************************************************
;
; startup_rvmdk.S - Startup code for use with Keil's uVision.
;
; Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
; Software License Agreement
;
; Texas Instruments (TI) is supplying this software for use solely and
; exclusively on TI's microcontroller products. The software is owned by
; TI and/or its suppliers, and is protected under applicable copyright
; laws. You may not combine this software with "viral" open-source
; software in order to form a larger program.
;
; THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
; NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
; NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
; A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
; CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
; DAMAGES, FOR ANY REASON WHATSOEVER.
;
; This is part of revision 2.1.0.12573 of the EK-TM4C123GXL Firmware Package.
;
;******************************************************************************
;******************************************************************************
;
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
;******************************************************************************
Stack
EQU
0x00000800
;******************************************************************************
;
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
;******************************************************************************
Heap
EQU
0x00000000
;******************************************************************************
;
; Allocate space for the stack.
;
;******************************************************************************
AREA
STACK, NOINIT, READWRITE, ALIGN=3
StackMem
SPACE
Stack
__initial_sp
;******************************************************************************
;
; Allocate space for the heap.
;
;******************************************************************************
AREA
HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
HeapMem
SPACE
Heap
__heap_limit
;******************************************************************************

;
; Indicate that the code in this file preserves 8-byte alignment of the stack.
;
;******************************************************************************
PRESERVE8
;******************************************************************************
;
; Place code into the reset code section.
;
;******************************************************************************
AREA
RESET, CODE, READONLY
THUMB
;******************************************************************************
;
; External declarations for the interrupt handlers used by the application.
;
;******************************************************************************
EXTERN SysTickIntHandler
EXTERN ResponseFunc
EXTERN BalloonMonitorISR
;
EXTERN UARTStdioIntHandler
;******************************************************************************
;
; The vector table.
;
;******************************************************************************
EXPORT __Vectors
__Vectors
DCD
StackMem + Stack
; Top of Stack
DCD
Reset_Handler
; Reset Handler
DCD
NmiSR
; NMI Handler
DCD
FaultISR
; Hard Fault Handler
DCD
IntDefaultHandler
; The MPU fault handler
DCD
IntDefaultHandler
; The bus fault handler
DCD
IntDefaultHandler
; The usage fault handler
DCD
0
; Reserved
DCD
0
; Reserved
DCD
0
; Reserved
DCD
0
; Reserved
DCD
IntDefaultHandler
; SVCall handler
DCD
IntDefaultHandler
; Debug monitor handler
DCD
0
; Reserved
DCD
IntDefaultHandler
; The PendSV handler
DCD
SysTickIntHandler
; The SysTick handler
DCD
IntDefaultHandler
; GPIO Port A
DCD
IntDefaultHandler
; GPIO Port B
DCD
IntDefaultHandler
; GPIO Port C
DCD
IntDefaultHandler
; GPIO Port D
DCD
IntDefaultHandler
; GPIO Port E
DCD
IntDefaultHandler
; UART0 Rx and Tx
DCD
ResponseFunc
; UART1 Rx and Tx
DCD
IntDefaultHandler
; SSI0 Rx and Tx
DCD
IntDefaultHandler
; I2C0 Master and Slave
DCD
IntDefaultHandler
; PWM Fault
DCD
IntDefaultHandler
; PWM Generator 0
DCD
IntDefaultHandler
; PWM Generator 1
DCD
IntDefaultHandler
; PWM Generator 2
DCD
IntDefaultHandler
; Quadrature Encoder 0
DCD
IntDefaultHandler
; ADC Sequence 0
DCD
IntDefaultHandler
; ADC Sequence 1
DCD
IntDefaultHandler
; ADC Sequence 2

DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD

IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
0
0
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
0
0
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
BalloonMonitorISR
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
0
0
0
0
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
0
0
0
0
0
0
0
0
0

;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;

ADC Sequence 3
Watchdog timer
Timer 0 subtimer A
Timer 0 subtimer B
Timer 1 subtimer A
Timer 1 subtimer B
Timer 2 subtimer A
Timer 2 subtimer B
Analog Comparator 0
Analog Comparator 1
Analog Comparator 2
System Control (PLL, OSC, BO)
FLASH Control
GPIO Port F
GPIO Port G
GPIO Port H
; UART2 Rx and Tx
SSI1 Rx and Tx
Timer 3 subtimer A
Timer 3 subtimer B
I2C1 Master and Slave
Quadrature Encoder 1
CAN0
CAN1
Reserved
Reserved
Hibernate
USB0
PWM Generator 3
uDMA Software Transfer
uDMA Error
ADC1 Sequence 0
ADC1 Sequence 1
ADC1 Sequence 2
ADC1 Sequence 3
Reserved
Reserved
GPIO Port J
GPIO Port K
GPIO Port L
SSI2 Rx and Tx
SSI3 Rx and Tx
UART3 Rx and Tx
UART4 Rx and Tx
UART5 Rx and Tx
UART6 Rx and Tx
UART7 Rx and Tx
Reserved
Reserved
Reserved
Reserved
I2C2 Master and Slave
I2C3 Master and Slave
Timer 4 subtimer A
Timer 4 subtimer B
Reserved
Reserved
Reserved
Reserved
Reserved
Reserved
Reserved
Reserved
Reserved

DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD

0
0
0
0
0
0
0
0
0
0
0
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
0
0
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
0
0
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler

;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;

Reserved
Reserved
Reserved
Reserved
Reserved
Reserved
Reserved
Reserved
Reserved
Reserved
Reserved
Timer 5 subtimer A
Timer 5 subtimer B
Wide Timer 0 subtimer A
Wide Timer 0 subtimer B
Wide Timer 1 subtimer A
Wide Timer 1 subtimer B
Wide Timer 2 subtimer A
Wide Timer 2 subtimer B
Wide Timer 3 subtimer A
Wide Timer 3 subtimer B
Wide Timer 4 subtimer A
Wide Timer 4 subtimer B
Wide Timer 5 subtimer A
Wide Timer 5 subtimer B
FPU
Reserved
Reserved
I2C4 Master and Slave
I2C5 Master and Slave
GPIO Port M
GPIO Port N
Quadrature Encoder 2
Reserved
Reserved
GPIO Port P (Summary or P0)
GPIO Port P1
GPIO Port P2
GPIO Port P3
GPIO Port P4
GPIO Port P5
GPIO Port P6
GPIO Port P7
GPIO Port Q (Summary or Q0)
GPIO Port Q1
GPIO Port Q2
GPIO Port Q3
GPIO Port Q4
GPIO Port Q5
GPIO Port Q6
GPIO Port Q7
GPIO Port R
GPIO Port S
PWM 1 Generator 0
PWM 1 Generator 1
PWM 1 Generator 2
PWM 1 Generator 3
PWM 1 Fault

;******************************************************************************
;
; This is the code that gets called when the processor first starts execution
; following a reset event.
;

;******************************************************************************
EXPORT Reset_Handler
Reset_Handler
;
; Enable the floating-point unit. This must be done here to handle the
; case where main() uses floating-point and the function prologue saves
; floating-point registers (which will fault if floating-point is not
; enabled). Any configuration of the floating-point unit using
; DriverLib APIs must be done here prior to the floating-point unit
; being enabled.
;
; Note that this does not use DriverLib since it might not be included
; in this project.
;
MOVW
R0, #0xED88
MOVT
R0, #0xE000
LDR
R1, [R0]
ORR
R1, #0x00F00000
STR
R1, [R0]
;
; Call the C library enty point that handles startup. This will copy
; the .data section initializers from flash to SRAM and zero fill the
; .bss section.
;
IMPORT __main
B
__main
;******************************************************************************
;
; This is the code that gets called when the processor receives a NMI. This
; simply enters an infinite loop, preserving the system state for examination
; by a debugger.
;
;******************************************************************************
NmiSR
B
NmiSR
;******************************************************************************
;
; This is the code that gets called when the processor receives a fault
; interrupt. This simply enters an infinite loop, preserving the system state
; for examination by a debugger.
;
;******************************************************************************
FaultISR
B
FaultISR
;******************************************************************************
;
; This is the code that gets called when the processor receives an unexpected
; interrupt. This simply enters an infinite loop, preserving the system state
; for examination by a debugger.
;
;******************************************************************************
IntDefaultHandler
B
IntDefaultHandler
;******************************************************************************
;
; Make sure the end of this section is aligned.
;
;******************************************************************************
ALIGN

;******************************************************************************
;
; Some code in the normal code section for initializing the heap and stack.
;
;******************************************************************************
AREA
|.text|, CODE, READONLY
;******************************************************************************
;
; The function expected of the C library startup code for defining the stack
; and heap memory locations. For the C library version of the startup code,
; provide this function so that the C library initialization code can find out
; the location of the stack and heap.
;
;******************************************************************************
IF :DEF: __MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR
R0, =HeapMem
LDR
R1, =(StackMem + Stack)
LDR
R2, =(HeapMem + Heap)
LDR
R3, =StackMem
BX
LR
ENDIF
;******************************************************************************
;
; Make sure the end of this section is aligned.
;
;******************************************************************************
ALIGN
;******************************************************************************
;
; Tell the assembler that we're done.
;
;******************************************************************************
END

EventCheckers.h
/****************************************************************************
Module
EventCheckers.h
Description
header file for the event checking functions
*****************************************************************************/
#ifndef EventCheckers_H
#define EventCheckers_H
// prototypes for event checkers
bool CheckForButton(void);
#endif /* EventCheckers_H */

EventCheckers.c
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include
#include
#include
#include
#include

"inc/hw_types.h"
"inc/hw_memmap.h"
"driverlib/sysctl.h"
"driverlib/gpio.h"
"inc/hw_gpio.h"

#include
#include
#include
#include
#include
#include

"ES_Configure.h"
"ES_Events.h"
"ES_PostList.h"
"ES_ServiceHeaders.h"
"ES_Port.h"
"EventCheckers.h"

#define ALL_BITS (0xff<<2)


#define BUTTON_DOWN 0
bool CheckForButton(void)
{
static uint8_t LastButtonState = 0;
uint8_t CurrentButtonState;
bool ReturnVal = false;
CurrentButtonState = HWREG( GPIO_PORTF_BASE + (GPIO_O_DATA + ALL_BITS) ) &
BIT4HI;
// Mask Port F with the input of interest, in this case pin PF4
corresponding to the button
if ( (CurrentButtonState != LastButtonState) &&
(CurrentButtonState == BUTTON_DOWN) )
// Check if the button state has
changed since last sample, and is now low
{
ES_Event ButtonPressed;
// Create ButtonPressed event
ButtonPressed.EventType = EV_BUTTON_PRESSED;
// Set the EventType to
EV_BUTTON_PRESSED
PostSPECTRE_Comm(ButtonPressed);
// Post the event to the Lab_10 module
ReturnVal = true;
}
LastButtonState = CurrentButtonState;
// Update the value of LastButtonState
return ReturnVal;
}

PWM.h
#ifndef PWM_H
#define PWM_H
#include "ES_Types.h"
void InitPWM(void);
void SetDuty( uint32_t DutyCycleRight, uint32_t RightDirection, uint32_t
DutyCycleLeft, uint32_t LeftDirection );
void FlagHi(void);
void FlagLo(void);
void PopperHi(void);
void PopperLo(void);
#endif // end PWM.h file

PWM.c
#include
#include
#include
#include
#include
#include

"inc/hw_memmap.h"
"inc/hw_gpio.h"
"inc/hw_pwm.h"
"inc/hw_sysctl.h"
"inc/hw_types.h"
"bitdefs.h"

#include "PWM.h"
#include "GeneralBase.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include

<stdint.h>
<stdbool.h>
<stdio.h>
"inc/hw_types.h"
"inc/hw_memmap.h"
"driverlib/sysctl.h"
"driverlib/gpio.h"
"driverlib/interrupt.h"
"utils/uartstdio.h"

#include
#include
#include
#include

"ES_Configure.h"
"ES_Framework.h"
"termio.h"
"ES_Port.h"

#define clrScrn()
printf("\x1b[2J")
#define goHome() printf("\x1b[1,1H")
#define clrLine() printf("\x1b[K")
/* Module defines
* VALUE TO BE SET WITH ELECTRICAL TIME CONSTANT
* PWMTicksPerMS: 40,000 ticks per mS assumes a 40Mhz clock and we are using SysClk/32
for PWM
* PeriodIn10US is in tens of microseconds
*/
#define PWMTicksPer10US (40000/32)/100 // with the divide by 100, this is actually
PWM ticks per 10s of uSeconds
#define PeriodIn10US 15
#define ServoPeriodIn10US 2000
#define LiftPeriodIn10US 2000
#define ServoPeriodHi 150
#define ServoPeriodLo 250
#define BitsPerNibble 4
#define ALL_BITS (0xff<<2)
#define
#define
#define
#define

PROP_RIGHT_DIR BIT4HI
PROP_LEFT_DIR BIT5HI
PROP_RIGHT_PWM BIT6HI
PROP_LEFT_PWM BIT7HI

// InitPWM initializes 2 PWM modules, PWM0 and PWM1


void InitPWM(void){
// enable the clock to Port B
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R1;
int dummy=HWREG(SYSCTL_RCGCGPIO);
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R3;
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R4;

// enable clock to Port D


// enable clock to Port E

// Enable pins 4 - 7 on Port B for digital I/O


HWREG(GPIO_PORTB_BASE+GPIO_O_DEN) |= (BIT7HI | BIT6HI | BIT5HI | BIT4HI);
HWREG(GPIO_PORTD_BASE+GPIO_O_DEN) |= (BIT0HI | BIT1HI);
HWREG(GPIO_PORTE_BASE+GPIO_O_DEN) |= (BIT5HI | BIT4HI | BIT3HI);
// make pins 4 - 7 on Port B into outputs
HWREG(GPIO_PORTB_BASE+GPIO_O_DIR) |= (BIT7HI |BIT6HI | BIT5HI | BIT4HI);
HWREG(GPIO_PORTD_BASE+GPIO_O_DIR) |= (BIT0HI |BIT1HI);
HWREG(GPIO_PORTE_BASE+GPIO_O_DIR) |= (BIT5HI | BIT4HI | BIT3HI);
// set to 1
HWREG(GPIO_PORTB_BASE+(GPIO_O_DATA+ALL_BITS)) |=
| BIT7HI);

(BIT4HI | BIT5HI | BIT6HI

volatile uint32_t Dummy; // use volatile to avoid over-optimization


// start by enabling the clock to the PWM Modules (PWM0 and PWM1)
HWREG(SYSCTL_RCGCPWM) |= SYSCTL_RCGCPWM_R0;
HWREG(SYSCTL_RCGCPWM) |= SYSCTL_RCGCPWM_R1;
// Select the PWM clock as System Clock/32
// gives you a lower resolution, not as many clock ticks (no need for 25 ns
resolution)
HWREG(SYSCTL_RCC) = (HWREG(SYSCTL_RCC) & ~SYSCTL_RCC_PWMDIV_M) |
(SYSCTL_RCC_USEPWMDIV | SYSCTL_RCC_PWMDIV_32);
// make sure that the PWM module clock has gotten going
while ((HWREG(SYSCTL_PRPWM) & SYSCTL_PRPWM_R0) != SYSCTL_PRPWM_R0);
while ((HWREG(SYSCTL_PRPWM) & SYSCTL_PRPWM_R1) != SYSCTL_PRPWM_R1);
// disable the PWM while initializing
HWREG( PWM0_BASE+PWM_O_0_CTL ) = 0;
HWREG( PWM0_BASE+PWM_O_1_CTL ) = 0;
HWREG( PWM1_BASE+PWM_O_0_CTL ) = 0;
HWREG( PWM1_BASE+PWM_O_1_CTL ) = 0;
// program generators A to go to 0 at rising compare A, 1 on falling compare
A
HWREG( PWM0_BASE+PWM_O_0_GENA) =
(PWM_0_GENA_ACTCMPAU_ZERO | PWM_0_GENA_ACTCMPAD_ONE
HWREG( PWM0_BASE+PWM_O_1_GENA) =
(PWM_1_GENA_ACTCMPAU_ZERO | PWM_1_GENA_ACTCMPAD_ONE
HWREG( PWM1_BASE+PWM_O_0_GENA) =
(PWM_0_GENA_ACTCMPAU_ZERO | PWM_0_GENA_ACTCMPAD_ONE
HWREG( PWM1_BASE+PWM_O_1_GENA) =
(PWM_1_GENA_ACTCMPAU_ZERO | PWM_1_GENA_ACTCMPAD_ONE

);
);
);
);

// program generators B to go to 0 at rising compare B, 1 on falling compare


B
HWREG( PWM0_BASE+PWM_O_0_GENB) =
(PWM_0_GENA_ACTCMPBU_ZERO | PWM_0_GENA_ACTCMPBD_ONE
HWREG( PWM0_BASE+PWM_O_1_GENB) =
(PWM_1_GENA_ACTCMPBU_ZERO | PWM_1_GENA_ACTCMPBD_ONE
HWREG( PWM1_BASE+PWM_O_0_GENB) =
(PWM_0_GENA_ACTCMPBU_ZERO | PWM_0_GENA_ACTCMPBD_ONE
HWREG( PWM1_BASE+PWM_O_1_GENB) =
(PWM_1_GENA_ACTCMPBU_ZERO | PWM_1_GENA_ACTCMPBD_ONE

);
);
);
);

// Set the PWM period. Since we are counting both up & down, we initialize
// the load register to 1/2 the desired total period
HWREG( PWM0_BASE+PWM_O_0_LOAD) = ((PeriodIn10US * PWMTicksPer10US))>>1;
HWREG( PWM1_BASE+PWM_O_0_LOAD) = ((LiftPeriodIn10US * PWMTicksPer10US))>>1;

HWREG( PWM1_BASE+PWM_O_1_LOAD) = ((ServoPeriodIn10US * PWMTicksPer10US))>>1;


// Set the initial Duty cycle on A to 50% by programming the compare value
// to 1/2 the period to count up (or down)
HWREG( PWM0_BASE+PWM_O_0_CMPA) = ((PeriodIn10US * PWMTicksPer10US))>>3;
HWREG( PWM1_BASE+PWM_O_0_CMPA) = ((LiftPeriodIn10US * PWMTicksPer10US));
HWREG( PWM1_BASE+PWM_O_1_CMPA) = ((ServoPeriodLo* PWMTicksPer10US))>>1;
// Set the initial Duty cycle on B to 50% by programming the compare value
// to 1/2 the period
HWREG( PWM0_BASE+PWM_O_0_CMPB) = ((PeriodIn10US * PWMTicksPer10US))>>2;
HWREG( PWM1_BASE+PWM_O_0_CMPB) = ((LiftPeriodIn10US * PWMTicksPer10US))>>5;
HWREG( PWM1_BASE+PWM_O_1_CMPB) = ((ServoPeriodHi* PWMTicksPer10US))>>1;
// set changes to the PWM output Enables to be locally synchronized to a
// zero count
HWREG(PWM0_BASE+PWM_O_ENUPD) = (HWREG(PWM0_BASE+PWM_O_ENUPD) &
~(PWM_ENUPD_ENUPD0_M | PWM_ENUPD_ENUPD1_M | PWM_ENUPD_ENUPD2_M |
PWM_ENUPD_ENUPD3_M)) |
(PWM_ENUPD_ENUPD0_LSYNC | PWM_ENUPD_ENUPD1_LSYNC | PWM_ENUPD_ENUPD2_LSYNC |
PWM_ENUPD_ENUPD3_LSYNC);
HWREG(PWM1_BASE+PWM_O_ENUPD) = (HWREG(PWM1_BASE+PWM_O_ENUPD) &
~(PWM_ENUPD_ENUPD0_M | PWM_ENUPD_ENUPD1_M | PWM_ENUPD_ENUPD2_M |
PWM_ENUPD_ENUPD3_M)) |
(PWM_ENUPD_ENUPD0_LSYNC | PWM_ENUPD_ENUPD1_LSYNC | PWM_ENUPD_ENUPD2_LSYNC |
PWM_ENUPD_ENUPD3_LSYNC);
// enable the PWM outputs
HWREG( PWM0_BASE+PWM_O_ENABLE) |= (PWM_ENABLE_PWM1EN | PWM_ENABLE_PWM0EN);
HWREG( PWM0_BASE+PWM_O_ENABLE) |= (PWM_ENABLE_PWM2EN | PWM_ENABLE_PWM3EN);
HWREG( PWM1_BASE+PWM_O_ENABLE) |= (PWM_ENABLE_PWM0EN | PWM_ENABLE_PWM1EN);
HWREG( PWM1_BASE+PWM_O_ENABLE) |= (PWM_ENABLE_PWM2EN | PWM_ENABLE_PWM3EN);
// now configure the Port B pins to be PWM outputs
// start by selecting the alternate function for PB4 - 7
HWREG(GPIO_PORTB_BASE+GPIO_O_AFSEL) |= (BIT7HI | BIT6HI); // | BIT5HI | BIT4HI);
HWREG(GPIO_PORTD_BASE+GPIO_O_AFSEL) |= (BIT0HI | BIT1HI);
// select
alternate function for D0 and D1
HWREG(GPIO_PORTE_BASE+GPIO_O_AFSEL) |= (BIT5HI | BIT4HI);
// select
alternate function for E4 and E5
HWREG(GPIO_PORTB_BASE+GPIO_O_PCTL) =
(HWREG(GPIO_PORTB_BASE+GPIO_O_PCTL) & 0x0000ffff) + (4<<(7*BitsPerNibble)) +
(4<<(6*BitsPerNibble));
// map PWM mode 0 to pins B6 and B7
HWREG(GPIO_PORTD_BASE+GPIO_O_PCTL) =
(HWREG(GPIO_PORTD_BASE+GPIO_O_PCTL) & 0x0000ffff) + (5<<(0*BitsPerNibble)) +
(5<<(1*BitsPerNibble));
// map PWM mode 1 to pins D0 and D1
HWREG(GPIO_PORTE_BASE+GPIO_O_PCTL) =
(HWREG(GPIO_PORTE_BASE+GPIO_O_PCTL) & 0x0000ffff) + (5<<(5*BitsPerNibble)) +
(5<<(4*BitsPerNibble));
// map PWM mode 1 to pins E4 and E5
// set the up/down count mode
HWREG(PWM0_BASE+ PWM_O_0_CTL)
HWREG(PWM0_BASE+ PWM_O_1_CTL)
HWREG(PWM1_BASE+ PWM_O_0_CTL)
HWREG(PWM1_BASE+ PWM_O_1_CTL)

and enable the PWM


|= (PWM_0_CTL_MODE
|= (PWM_1_CTL_MODE
|= (PWM_0_CTL_MODE
|= (PWM_1_CTL_MODE

printf("InitPWM Successful \n\r");

generator
| PWM_0_CTL_ENABLE);
| PWM_1_CTL_ENABLE);
| PWM_0_CTL_ENABLE);
| PWM_1_CTL_ENABLE);

}
/* SetDuty
* return type: void
* parameters: four uint32_t that correspond to the desired duty cycle and direction
for each motor
* function: set PWM duty cycle for Port B pin 6 and 7
* note: DutyCycleRight refers to PWM to the right motor, and DutyCycleLeft to the
left motor
* If we desire the angular velocity of each motor to be forward, then RightDirection
and LeftDirection bits
*
will be 1
*/
void SetDuty( uint32_t DutyCycleRight, uint32_t RightDirectionBit, uint32_t
DutyCycleLeft, uint32_t LeftDirectionBit ){
if (RightDirectionBit == 1){
HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) |= BIT4HI;
}
else{
HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) &= ~BIT4HI;
}
if (LeftDirectionBit == 1){
HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) |= BIT5HI;
}
else{
HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) &= ~BIT5HI;
}
if( DutyCycleRight == 0){
HWREG( PWM0_BASE+PWM_O_0_CMPA ) = (PeriodIn10US *
PWMTicksPer10US*2)/100>>1;
} else {
HWREG( PWM0_BASE+PWM_O_0_CMPA ) = (PeriodIn10US *
PWMTicksPer10US*DutyCycleRight)/100>>1;
}
if( DutyCycleLeft == 0){
HWREG( PWM0_BASE+PWM_O_0_CMPB ) = (PeriodIn10US *
PWMTicksPer10US*2)/100>>1;
} else {
HWREG( PWM0_BASE+PWM_O_0_CMPB ) = (PeriodIn10US *
PWMTicksPer10US*DutyCycleLeft)/100>>1;
}
}
//Electromechanical display lo
void FlagLo(){
HWREG( PWM1_BASE+PWM_O_1_CMPA) = ((ServoPeriodLo* PWMTicksPer10US))>>1;
}
//Electromechanical display hi
void FlagHi(){
HWREG( PWM1_BASE+PWM_O_1_CMPA) = ((ServoPeriodHi* PWMTicksPer10US))>>1;
}
//Popper Hi
void PopperHi(){
HWREG(GPIO_PORTE_BASE + (GPIO_O_DATA + ALL_BITS)) |= BIT3HI;
HWREG( PWM1_BASE+PWM_O_1_CMPB) = ((ServoPeriodHi *
PWMTicksPer10US))>>1;
}

//Popper Lo
void PopperLo(){
HWREG(GPIO_PORTE_BASE + (GPIO_O_DATA + ALL_BITS)) &= ~BIT3HI;
HWREG( PWM1_BASE+PWM_O_1_CMPB) = ((ServoPeriodLo * PWMTicksPer10US))>>1;
}

SPECTRE_Comm.h
/****************************************************************************
Header file for template service
based on the Gen 2 Events and Services Framework
****************************************************************************/
#ifndef SPECTRE_Comm_H
#define SPECTRE_Comm_H
#include "ES_Types.h"
// Public Function Prototypes
bool InitSPECTRE_Comm ( uint8_t Priority );
bool PostSPECTRE_Comm( ES_Event ThisEvent );
ES_Event RunSPECTRE_Comm( ES_Event ThisEvent );
void ResponseFunc( void );
void BalloonMonitorISR( void );
void TransmitAcknowledge( void );
void RecordAddress( void );
void TransmitStatus( void );
bool CheckForPairingAttempt ( void );
bool CheckForControl ( void );
uint8_t QueryRecMsg(int Idx );
void ResetBalloonPoppedAddress( void );
typedef enum {OPEN,PROCESSING} Comm_State;
#endif /* SPECTRE_Comm_H */

SPECTRE_Comm.c
#include
#include
#include
#include

<stdint.h>
<stdbool.h>
<stdio.h>
<stdlib.h>

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

"inc/hw_types.h"
"inc/hw_memmap.h"
"driverlib/sysctl.h"
"driverlib/gpio.h"
"driverlib/interrupt.h"
"inc/hw_uart.h"
"inc/hw_gpio.h"
"inc/hw_sysctl.h"
"inc/hw_timer.h"
"inc/hw_nvic.h"

#include
#include
#include
#include
#include

"ES_Configure.h"
"ES_Framework.h"
"uartstdio.h"
"ES_Port.h"
"termio.h"

#include "SPECTRE_Comm.h"
#include "SPECTRE_Control.h"
/*----------------------------- Module Defines ----------------------------*/
#define MY_ADDRESS 0x05
#define ALL_BITS (0xff<<2)
/*---------------------------- Module Functions ---------------------------*/
void InitializeIO( void );
void InitializeUART( void );
void FirstByteTransmit( void );
void ByteTransmit ( void );
void InitializeMsgHelpers(char TempMessage);
void ProcessMessage( void );
void FreeMsgHelpers( void );
void InitializeBalloonUART( void );
/*---------------------------- Module Variables ---------------------------*/
static uint8_t MyPriority;
static uint8_t RecTempMessage;
static uint8_t RecTempMessageBalloon;
static int RecMesLen = 8;
static int RecMsgCounter = 0;
static uint8_t RecMsgSum = 0;
static uint8_t LastPoppedBalloonMessage;
static
static
static
static

int TxMesLen = 8;
int TxMsgCounter = 0;
uint8_t TxMsgSum = 0;
bool TransmitPossible = true;

static uint8_t MI6Address[2];


static uint8_t RecMsg[20];
static uint8_t TxMsg[20];
static bool MindControlled;
static uint8_t AddressWhenBalloonPopped[2] = {0,0};

//State variable
static Comm_State CurrentState;
static Comm_State NextState;
/*------------------------------ Module Code ------------------------------*/
bool InitSPECTRE_Comm ( uint8_t Priority )
{
ES_Event ThisEvent;
MyPriority = Priority;
InitializeIO();
InitializeUART();
InitializeBalloonUART();
MindControlled = false;
// post the initial transition event
ThisEvent.EventType = ES_INIT;
if (ES_PostToService( MyPriority, ThisEvent) == true)
{
return true;
}else
{
return false;
}
}
bool PostSPECTRE_Comm( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
ES_Event RunSPECTRE_Comm( ES_Event ThisEvent )
{
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
NextState = CurrentState;
if (CurrentState == OPEN){
if ( (ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam ==
TestTimer) ){
TransmitStatus();
ES_Timer_InitTimer( TestTimer, 200 );
}
if( ThisEvent.EventType == EV_BUTTON_PRESSED){
TransmitStatus();
}
if(ThisEvent.EventType == EV_SEND_DATA){

// If a BUTTON_PRESSED event
is detected

if (TransmitPossible == true){
FirstByteTransmit(); //Start the byte transmit process
}
}
else if( ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam ==
TxTimer){
TxMsgCounter++;
ByteTransmit();
}

else if( ThisEvent.EventType == EV_STARTED_RECEIVING){


NextState = PROCESSING;
}
}
else if (CurrentState == PROCESSING){
if ( (ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam ==
TestTimer) ){
ES_Timer_InitTimer( TestTimer, 30 );
}
else if( ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam ==
RxTimeout){
NextState = OPEN;
FreeMsgHelpers();
}
else if(ThisEvent.EventType == EV_MSG_RECEIVED){
NextState = OPEN;
ProcessMessage();
}
}
CurrentState = NextState;
return ReturnEvent;
}
/***************************************************************************
private functions
***************************************************************************/
void InitializeIO(){
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R3;// Enable the clock to Port D
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R4;// Enable the clock to Port E
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R5;// Enable the clock to Port F
while((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R5) != SYSCTL_PRGPIO_R5);
// Wait for the GPIO module clock to be ready on Port F
HWREG(GPIO_PORTD_BASE+GPIO_O_DEN) |= (BIT0HI | BIT1HI | BIT2HI);
// Enable Port D pins PD0-2 to be digital I/O
HWREG(GPIO_PORTD_BASE+GPIO_O_DIR) |= (BIT0HI | BIT1HI | BIT2HI);
// Enable Port D pins PD0-2 to be outputs
HWREG(GPIO_PORTE_BASE+GPIO_O_DEN) |= (BIT0HI | BIT1HI | BIT2HI | BIT3HI |
BIT4HI);
// Enable Port E pins PE0-4 to be digital I/O
HWREG(GPIO_PORTE_BASE+GPIO_O_DIR) &= (BIT0LO & BIT1LO & BIT2LO & BIT3LO &
BIT4LO);
// Enable Port E pins PE0-4 to be inputs
HWREG(GPIO_PORTF_BASE+GPIO_O_DEN) |= (BIT1HI | BIT3HI | BIT4HI);
// Enable Port F pins PF1, PF3-4 to be digital I/O
HWREG(GPIO_PORTF_BASE+GPIO_O_DIR) |= (BIT1HI | BIT3HI);
// Enable Port F pins PF1, PF3 to be outputs
HWREG(GPIO_PORTF_BASE+(ALL_BITS+GPIO_O_DATA)) &= (BIT3LO);
// Set pin PF3 low
HWREG(GPIO_PORTF_BASE+GPIO_O_DIR) &= (BIT4LO);
// Enable Port F pin PF4 to be input
HWREG(GPIO_PORTF_BASE+GPIO_O_PUR) |= BIT4HI;
// Enable pull up resistor for F4
}
void InitializeUART(){
HWREG(GPIO_PORTF_BASE+(ALL_BITS+GPIO_O_DATA)) |= BIT3HI;// Set pin PF3 hi
HWREG(SYSCTL_RCGCUART) |= SYSCTL_RCGCUART_R1;
// Enable the clock to UART1
while((HWREG(SYSCTL_PRUART) & SYSCTL_PRUART_R1 ) != SYSCTL_RCGCUART_R1);
// Wait for the UART module clock to be ready on UART 1
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R1;
// Enable the clock to Port B for the Tx and Rx lines
while((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R1) != SYSCTL_PRGPIO_R1);
// Wait for the GPIO module clock to be ready on Port B
HWREG(GPIO_PORTB_BASE +GPIO_O_DEN) |= (BIT0HI | BIT1HI | BIT3HI);

// Enable Port B pins PB0-1 to be digital I/O


HWREG(GPIO_PORTB_BASE +GPIO_O_DIR) &= (BIT0LO);
// Enable Port B pin
PB0 to be input
HWREG(GPIO_PORTB_BASE +GPIO_O_DIR) |= (BIT1HI);
// Enable Port B pin
PB1 to be output
HWREG(GPIO_PORTB_BASE +GPIO_O_DIR) |= (BIT3HI);
// Enable Port B pin
PB3 to be ouput (for pump)
HWREG(GPIO_PORTB_BASE+GPIO_O_PUR) |= BIT1HI;
// Enable pull up
resistor for B1
HWREG(GPIO_PORTB_BASE +GPIO_O_ODR) |= (BIT1HI);
// Enable Port B pin
PB1 to be open-drain (to handle transmission line contention without damage to pins)
HWREG(GPIO_PORTB_BASE+GPIO_O_AFSEL) |= (BIT1HI | BIT0HI);
// Select the alternate function for the UART pins
// Configure the PCMn bits to assign UART pins
HWREG(GPIO_PORTB_BASE+GPIO_O_PCTL) = (HWREG(GPIO_PORTB_BASE+GPIO_O_PCTL) &
0xffffff00) + (1 << 0) + (1 << 4);
// Assign pin PB0 to be Rx line and PB1
to be Tx
HWREG(UART1_BASE+UART_O_CTL) &= (~UART_CTL_UARTEN);
// Disable the UART
HWREG(UART1_BASE+UART_O_IBRD) = 0x00;
// Clear the integer portion of the baud rate generator
HWREG(UART1_BASE+UART_O_IBRD) |= 0x104;
// Write a value of 260 to the integer baud rate generator (desired baud rate
of 9600)
HWREG(UART1_BASE+UART_O_FBRD) = 0x00;
// Clear the fractional portion of the baud rate generator
HWREG(UART1_BASE+UART_O_FBRD) |= 0x1B;
// Write a value of 27 (27.16) to the fractional portion of the baud rate
generator (desired baud rate of 9600)
HWREG(UART1_BASE+UART_O_LCRH) |= UART_LCRH_WLEN_8;
// Select an 8-bit
word length on the transmission
HWREG(UART1_BASE+UART_O_CTL) |= ((UART_CTL_RXE | UART_CTL_TXE) &
~UART_CTL_HSE);
// Enable transmit and receive, and disable high-speed
transmission
HWREG(NVIC_EN0) = BIT6HI;
// Enable the interrupt for UART1 in the NVIC
__enable_irq();
// Globally enable interrupts
HWREG(UART1_BASE+UART_O_ICR) |= (UART_ICR_RXIC | UART_ICR_TXIC); // Clear
any interrupts that may exist
HWREG(UART1_BASE+UART_O_IM) |= UART_IM_RXIM;
// Enable the interrupt mask for UART1
HWREG(UART1_BASE+UART_O_IM) |= UART_IM_TXIM;
// Enable the interrupt mask for UART2
HWREG(UART1_BASE+UART_O_CTL) |= UART_CTL_UARTEN;
// Enable UART1 by setting the UARTEN bit
}
void FirstByteTransmit(){
HWREG(UART1_BASE+UART_O_DR) = TxMsg[TxMsgCounter];
TxMsgCounter++;
HWREG(UART1_BASE+UART_O_IM) |= UART_IM_TXIM;
}
void ByteTransmit(){//Function transmit bytes
if (TxMsgCounter <= TxMesLen - 1){//If we are less than the index of the last
byte
HWREG(UART1_BASE+UART_O_DR) = TxMsg[TxMsgCounter];
TxMsgCounter++;
}
else{
TransmitPossible = false;
TxMsgCounter = 0;
HWREG(UART1_BASE+UART_O_IM) &= (~UART_IM_TXIM);
// Enable the interrupt mask for UART2

}
}
void ResponseFunc(){
if ((HWREG(UART1_BASE+UART_O_MIS) & UART_MIS_TXMIS) == UART_MIS_TXMIS){
HWREG(UART1_BASE+UART_ICR_TXIC) |= (UART_ICR_TXIC);
ByteTransmit();
}
else if ((HWREG(UART1_BASE+UART_O_MIS) & UART_MIS_RXMIS) == UART_MIS_RXMIS){
HWREG(UART1_BASE+UART_ICR_RXIC) |= (UART_ICR_RXIC);
// Clear the source of the interrupt
RecTempMessage = HWREG(UART1_BASE+UART_O_DR);
// Save the byte received in the receiver buffer
if ((RecMsgCounter == 0) && (RecTempMessage == 0x7E)){
ES_Event NewEvent;
NewEvent.EventType = EV_STARTED_RECEIVING;
PostSPECTRE_Comm(NewEvent);
ES_Timer_InitTimer(RxTimeout,200);
RecMsgCounter += 1;
}
else if ((RecMsgCounter == 1) && (RecTempMessage == 0x00)){
RecMsgCounter += 1;
ES_Timer_StopTimer(RxTimeout);
ES_Timer_InitTimer(RxTimeout,200);
}
else if (RecMsgCounter == 2){
InitializeMsgHelpers(RecTempMessage);
RecMsgCounter += 1;
ES_Timer_StopTimer(RxTimeout);
ES_Timer_InitTimer(RxTimeout,100);
}
else if ((RecMsgCounter > 2) && (RecMsgCounter < RecMesLen+3)){
RecMsg[RecMsgCounter-3] = RecTempMessage;
RecMsgCounter += 1;
ES_Timer_StopTimer(RxTimeout);
ES_Timer_InitTimer(RxTimeout,100);
}
if (RecMsgCounter == (RecMesLen + 3)){
ES_Timer_StopTimer(RxTimeout);
ES_Event NewEvent;
NewEvent.EventType = EV_MSG_RECEIVED;
PostSPECTRE_Comm(NewEvent);
}
}
}
void InitializeMsgHelpers(char TempMessage){
RecMesLen = ((uint8_t) TempMessage) + 1;
}
void ProcessMessage(){
for (int i = 0; i < RecMesLen-1; i++){
RecMsgSum += (uint8_t) RecMsg[i];
}
if(RecMsg[0] == 0x89){
if(RecMsg[2] == 0x00){
TransmitPossible = true;
}
else if (RecMsg[2] == 0x01){
TransmitPossible = true;
ES_Timer_StopTimer(StatusTimer);// Stop the status timeout timer
ES_Timer_InitTimer(StatusTimer,1000);
// Restart the status

timeout timer
ES_Event NewEvent;//Post Send date event to Spectre comm
NewEvent.EventType = EV_SEND_DATA;
PostSPECTRE_Comm(NewEvent);
}
}
else if (RecMsgSum == ((0xff-RecMsg[RecMesLen-1]))&& (RecMsg[0] != 0x89)){
TransmitPossible = true;
ES_Event NewEvent;
NewEvent.EventType = EV_MSG_RECEIVED;
PostSPECTRE_Control(NewEvent);
}
FreeMsgHelpers();
}
void FreeMsgHelpers(){
RecMsgCounter = 0;
RecMsgSum = 0;
}
void TransmitAcknowledge( void ){
TxMesLen = 11;
TxMsg[0] = 0x7E; //Start delimiter of XBEE message
TxMsg[1] = 0x00; //MSB (msglen)
TxMsg[2] = 0x07; //LSB (msglen)
TxMsg[3] = 0x01; //XBEE API (Send Packet)
TxMsg[4] = 0xED; //MESSAGE ID
TxMsg[5] = MI6Address[0]; //MSB OF DESTINATION
TxMsg[6] = MI6Address[1]; //LSB OF DESTINATION
TxMsg[7] = 0x00; //BROADCAST PAN ID
TxMsg[8] = 0x02; //ACKNOWLEDGE PAIR HEADER
TxMsg[9] = 0x01; //PAIRING SUCCESSFULL
TxMsgSum = 0;
for (int i = 3; i < TxMesLen-1; i++){
TxMsgSum += TxMsg[i];
}
TxMsg[TxMesLen-1] = 0xFF - (char)TxMsgSum;
TxMsgCounter = 0;
ES_Event NewEvent;
NewEvent.EventType = EV_SEND_DATA;
PostSPECTRE_Comm(NewEvent);
}
void RecordAddress( void ){
MI6Address[0] = RecMsg[4];
MI6Address[1] = RecMsg[5];
}
void TransmitStatus( void ){
TxMesLen = 11;
TxMsg[0] = 0x7E; //Start delimiter of XBEE message
TxMsg[1] = 0x00; //MSB (msglen)
TxMsg[2] = 0x07; //LSB (msglen)
TxMsg[3] = 0x01; //XBEE API (Send Packet)
TxMsg[4] = 0xED; //MESSAGE ID
TxMsg[5] = MI6Address[0]; //MSB OF DESTINATION
TxMsg[6] = MI6Address[1]; //LSB OF DESTINATION
TxMsg[7] = 0x00; //BROADCAST PAN ID
TxMsg[8] = 0x04; //STATUS HEADER

if(~MindControlled){
TxMsg[9] = 0x00; //Not Mind Controlled
}
else if(MindControlled){
TxMsg[9] = 0x01; //Mind Controlled
}
TxMsgSum = 0;
for (int i = 3; i < TxMesLen-1; i++){
TxMsgSum += TxMsg[i];
}
TxMsg[TxMesLen-1] = 0xFF - (char)TxMsgSum;
TxMsgCounter = 0;
ES_Event NewEvent;
NewEvent.EventType = EV_SEND_DATA;
PostSPECTRE_Comm(NewEvent);
}
bool CheckForPairingAttempt( void ){
if(RecMsg[5] == 0x01 && RecMsg[6] == MY_ADDRESS){
MI6Address[0] = RecMsg[1];
MI6Address[1] = RecMsg[2];
if( (MI6Address[0] == AddressWhenBalloonPopped[0]) && (MI6Address[1] ==
AddressWhenBalloonPopped[1]) ){
return false;
}
else{
return true;
}
}
return false;
}
bool CheckForControl( void ){
if((RecMsg[5] == 0x03) && (RecMsg[1] == MI6Address[0]) && (RecMsg[2] ==
MI6Address[1])){
return true;
}
return false;
}
uint8_t QueryRecMsg(int Idx ){
return RecMsg[Idx]; //Return the data at a particular index of the message that
we just received
}
void InitializeBalloonUART(){
HWREG(SYSCTL_RCGCUART) |= SYSCTL_RCGCUART_R3;
// Enable the clock to UART2
while((HWREG(SYSCTL_PRUART) & SYSCTL_PRUART_R3 ) != SYSCTL_RCGCUART_R3);
// Wait for the UART module clock to be ready on UART 2
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R2;
// Enable the clock to Port
D for the Tx and Rx lines
while((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R2) != SYSCTL_PRGPIO_R2);
// Wait for the GPIO module clock to be ready on Port D
HWREG(GPIO_PORTC_BASE +GPIO_O_DEN) |= (BIT6HI | BIT7HI);
// Enable Port
D pins PD6 to be digital I/O
HWREG(GPIO_PORTC_BASE +GPIO_O_DIR) &= (BIT6LO);
// Enable Port D pin PD6 to be input
HWREG(GPIO_PORTC_BASE +GPIO_O_DIR) |= (BIT7HI);
HWREG(GPIO_PORTC_BASE+GPIO_O_AFSEL) |= BIT6HI;
// Select the alternate function for the UART pins
// Configure the PCMn bits to assign UART pins

HWREG(GPIO_PORTC_BASE+GPIO_O_PCTL) = (HWREG(GPIO_PORTC_BASE+GPIO_O_PCTL) &


0x00ffffff) + (1 << 24) + (1<<28);
// Assign pin PD6 to be Rx line
HWREG(UART3_BASE+UART_O_CTL) &= (~UART_CTL_UARTEN);
// Disable the UART
HWREG(UART3_BASE+UART_O_IBRD) = 0x00;
// Clear the integer portion of the baud rate generator
HWREG(UART3_BASE+UART_O_IBRD) |= 0x104;
// Write a value of 260 to the integer baud rate generator (desired baud rate
of 9600)
HWREG(UART3_BASE+UART_O_FBRD) = 0x00;
// Clear the fractional portion of the baud rate generator
HWREG(UART3_BASE+UART_O_FBRD) |= 0x1B;
// Write a value of 27 (27.16) to the fractional portion of the baud rate
generator (desired baud rate of 9600)
HWREG(UART3_BASE+UART_O_LCRH) |= UART_LCRH_WLEN_8;
// Select an 8-bit
word length on the transmission
HWREG(UART3_BASE+UART_O_CTL) |= ((UART_CTL_RXE | UART_CTL_TXE) &
~UART_CTL_HSE);
// Enable transmit and receive, and disable high-speed
transmission
HWREG(NVIC_EN1) = BIT27HI;
// Enable the interrupt for UART1 in the NVIC
__enable_irq();
// Globally enable interrupts
HWREG(UART3_BASE+UART_O_ICR) |= (UART_ICR_RXIC | UART_ICR_TXIC); // Clear
any interrupts that may exist
HWREG(UART3_BASE+UART_O_IM) |= UART_IM_RXIM;
// Enable the interrupt mask
for UART2
HWREG(UART3_BASE+UART_O_CTL) |= UART_CTL_UARTEN;
// Enable UART2 by
setting the UARTEN bit
}
void BalloonMonitorISR(){
HWREG(UART3_BASE+UART_ICR_RXIC) |= (UART_ICR_RXIC);

// Clear the source of


the interrupt
RecTempMessageBalloon = HWREG(UART3_BASE+UART_O_DR); // Save the byte
received in the receiver buffer
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT;
static int InitialPass = 0;
if (InitialPass == 0 ){
LastPoppedBalloonMessage = HWREG(UART3_BASE+UART_O_DR);
InitialPass = 1;
}
else if( RecTempMessageBalloon == 0x55 || RecTempMessageBalloon == 0xAA){

if((LastPoppedBalloonMessage == 0xAA) && (RecTempMessageBalloon ==


0x55) ){ // if the message is different from our last state, and it's popped
ReturnEvent.EventType = EV_BALLOON_POPPED;
PostSPECTRE_Control(ReturnEvent);
MindControlled = true;
// Set the state of mind controlled
to be true
ES_Timer_InitTimer( BalloonPoppedAddressTimer, 10000 );
// Set a timer for 10 seconds where the SPECTRE is not able to reconnect to
MI6 that controlled it when ballon was popped
AddressWhenBalloonPopped[0] = MI6Address[0];
// Store
the address of the MI6 in control when balloon was popped
AddressWhenBalloonPopped[1] = MI6Address[1];
// Store
the address of the MI6 in control when balloon was popped
}
LastPoppedBalloonMessage = RecTempMessageBalloon;
}
return;

}
void ResetBalloonPoppedAddress( void ){
// Function to reset the address of
the MI6 in control when the balloon was popped
AddressWhenBalloonPopped[0] = 0;
// Reset the high byte to zero
AddressWhenBalloonPopped[1] = 0;
// Reset the low byte to zero
}
/*------------------------------- Footnotes -------------------------------*/
/*------------------------------ End of file ------------------------------*/

SPECTRE_Control.h
/****************************************************************************
Header file for template service
based on the Gen 2 Events and Services Framework
****************************************************************************/
#ifndef SPECTRE_Control_H
#define SPECTRE_Control_H
#include "ES_Types.h"
// Public Function Prototypes
bool InitSPECTRE_Control( uint8_t Priority );
bool PostSPECTRE_Control( ES_Event ThisEvent );
ES_Event RunSPECTRE_Control( ES_Event ThisEvent );
typedef enum {SEARCHING,PAIRED,MINDCONTROLLED} Spectre_State;
typedef enum {WIMPY,HEFTY} Balloon_Popper_State;
#endif /* SPECTRE_Control_H */

SPECTRE_Control.c
#include
#include
#include
#include
#include

<stdint.h>
<stdbool.h>
<stdio.h>
<stdlib.h>
<math.h>

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

"inc/hw_types.h"
"inc/hw_memmap.h"
"driverlib/sysctl.h"
"driverlib/gpio.h"
"driverlib/interrupt.h"
"inc/hw_uart.h"
"inc/hw_gpio.h"
"inc/hw_sysctl.h"
"inc/hw_timer.h"
"inc/hw_nvic.h"
"inc/hw_pwm.h"

#include
#include
#include
#include
#include

"ES_Configure.h"
"ES_Framework.h"
"uartstdio.h"
"ES_Port.h"
"termio.h"

#include "SPECTRE_Comm.h"
#include "SPECTRE_Control.h"
#include "PWM.h"
/*----------------------------- Module Defines ----------------------------*/
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define

ALL_BITS (0xff<<2)
LEFT_OPEN 1
RIGHT_OPEN 1
LEFT_CLOSED 0
RIGHT_CLOSED 0
FORWARD_LOWER 7855
FORWARD_UPPER 20945
BRAKE_LOWER -28800
BRAKE_UPPER -2620
RIGHT_LOWER -2620
RIGHT_UPPER 7855
ZERO_MAGNITUDE 12000
NONZERO_MAGNITUDE 13000
FULL_LIFT 1
BRAKE_LIFT 2
NO_LIFT 0

/*---------------------------- Module Functions ---------------------------*/


static void PopBalloon( void );
static void SetLift( int Toggle );
static void LogControl( void );
static void SetThrust( int Toggle );
static void SetBrakes( void );
void CheckForUnpair( void );
int16_t ThrustOrientationAngle( double x, double y );
uint16_t ThrustOrientationMagnitude( double x, double y );
/*---------------------------- Module Variables ---------------------------*/
static uint8_t MyPriority;
//State variable
static Spectre_State CurrentState;

static Spectre_State NextState;


static Balloon_Popper_State BalloonPopperState;
static int8_t Thrust;
static int8_t Orient;
static uint8_t Action = 0;
/*------------------------------ Module Code ------------------------------*/
bool InitSPECTRE_Control ( uint8_t Priority )
{
ES_Event ThisEvent;
MyPriority = Priority;
CurrentState = SEARCHING; //Set the initial state to searching
InitPWM();//Initialize our pwm module
SetLift( NO_LIFT );
SetThrust(0);//Set the initial fan speeds to 0
FlagLo();//Set the flag to be low
BalloonPopperState = WIMPY;//Set the initial balloon popper state to be WIMPY
PopperLo();//Make the necessary pins and PWM cycles to reflect a wimpy balloon
popper
HWREG(GPIO_PORTF_BASE+(ALL_BITS+GPIO_O_DATA)) |= BIT1HI;
HWREG(GPIO_PORTF_BASE+(ALL_BITS+GPIO_O_DATA)) &= BIT3LO;

//
hi
//
lo

Set pin PF1


(red LED)
Set pin PF3
(green LED)

// post the initial transition event


ThisEvent.EventType = ES_INIT;
if (ES_PostToService( MyPriority, ThisEvent) == true)
{
return true;
}else
{
return false;
}
}
bool PostSPECTRE_Control( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
ES_Event RunSPECTRE_Control( ES_Event ThisEvent )
{
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
NextState = CurrentState;
if(CurrentState == SEARCHING){
if(ThisEvent.EventType == EV_MSG_RECEIVED){
if(CheckForPairingAttempt()){
NextState = PAIRED; // Set the next state to be paired
TransmitAcknowledge(); //Begin by transmitting the
acknolwedge back to the MI6
HWREG(GPIO_PORTF_BASE+(ALL_BITS+GPIO_O_DATA)) |= BIT3HI;
// Set pin PF3 hi (green LED)
HWREG(GPIO_PORTF_BASE+(ALL_BITS+GPIO_O_DATA)) &= BIT1LO;
// Set pin PF1 lo (red LED)
SetLift(FULL_LIFT);//Set the lift fan to be hi
FlagHi();//Activate the electromechanical identifier
ES_Timer_InitTimer( StatusTimer , 1000 );//Initialize the

status timer
}
}
if( (ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam ==
BalloonPoppedAddressTimer) ){
ResetBalloonPoppedAddress();
}
}
if(CurrentState == PAIRED){
if(ThisEvent.EventType == EV_MSG_RECEIVED){
if(CheckForControl()){//Check to see if we received a control
message
LogControl();//Log the control message that we just
received
TransmitStatus();//Transmit our status back to the MI6
ES_Timer_InitTimer( StatusTimer , 1000 );//Re-initialize
the StatusTimer
}
}
if( (ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam ==
StatusTimer)
|| (ThisEvent.EventType == EV_BALLOON_POPPED)
|| (ThisEvent.EventType == EV_UNPAIR) ){//If a
timeout from the status timer
NextState = SEARCHING;//Set the next state to be searching
HWREG(GPIO_PORTF_BASE+(ALL_BITS+GPIO_O_DATA)) |= BIT1HI;
// Set pin PF1 hi (red LED)
HWREG(GPIO_PORTF_BASE+(ALL_BITS+GPIO_O_DATA)) &= BIT3LO;
// Set pin PF3 lo (green LED)
SetLift(NO_LIFT);//Set the lift fan to be low
SetThrust(0);//Set the thrust to be low
FlagLo();//Set the flag to be low
ES_Timer_StopTimer(PopperTimer);//Stop the popper timer
BalloonPopperState = WIMPY;//Set the balloon state to be WIMPY
PopperLo();//Set the popper low (inactive)
}
if(ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam ==
PopperTimer){//If we receive a timeout from the popper
BalloonPopperState = WIMPY;//Set the balloon state to be wimpy
PopperLo();//Deactivate the popper
}
if( (ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam ==
BalloonPoppedAddressTimer) ){
ResetBalloonPoppedAddress();
}
}
CurrentState = NextState;//Set the next state to the current state
return ReturnEvent;
}
void SetLift( int Toggle ){//Function to handle lift toggling
//Check to see if we want lift
if (Toggle == FULL_LIFT){
HWREG( PWM1_BASE+PWM_O_ENABLE ) |= PWM_ENABLE_PWM0EN; // Enable PWM
to PD0
HWREG( PWM1_BASE+PWM_O_0_CMPA ) = (HWREG( PWM1_BASE+PWM_O_0_LOAD ) >>
1) + (HWREG( PWM1_BASE+PWM_O_0_LOAD ) >> 2) + (HWREG( PWM1_BASE+PWM_O_0_LOAD ) >>

3) + (HWREG( PWM1_BASE+PWM_O_0_LOAD ) >> 4);


// Set pin PD0 duty cycle to 100%
}
else if ( Toggle == BRAKE_LIFT ){
HWREG( PWM1_BASE+PWM_O_ENABLE ) |= PWM_ENABLE_PWM0EN; // Enable PWM
to PD0
HWREG( PWM1_BASE+PWM_O_0_CMPA ) = HWREG( PWM1_BASE+PWM_O_0_LOAD )>>2;
// Set pin PD0 duty cycle to 25%
}
else{
HWREG( PWM1_BASE+PWM_O_0_CMPA ) = 0;
// Set duty cycle to 0%
HWREG( PWM1_BASE+PWM_O_ENABLE ) &= ~PWM_ENABLE_PWM0EN;
// Disable PWM to PD0
}
}

void PopBalloon( void ){


if (((Action & BIT0HI) == BIT0HI) && (BalloonPopperState == WIMPY)){//If we
receive an action message and the popper is wimpy
PopperHi();//Set the popper hi
BalloonPopperState = HEFTY;//Set the popper state to hefty
ES_Timer_InitTimer(PopperTimer,2000);//Initialize the popper timer for
2 s
}
}
void SetBrakes( void ){
if ((Action & BIT1HI) == BIT1HI){//If we receive an action message to break
SetLift( BRAKE_LIFT );
}
}
void CheckForUnpair( void ){
if ((Action & BIT7HI) == BIT7HI){

// If the unpair bit is set in the action


byte
ES_Event UnpairEvent;
// Generate an event to post to the
SPECTRE_Control module to unpair
UnpairEvent.EventType = EV_UNPAIR;
PostSPECTRE_Control( UnpairEvent );

}
}
void LogControl( void ){//Function to handle control
Thrust = (int8_t) QueryRecMsg(6); //Read in the thrust data to thrust variable
(byte 6)
Orient = (int8_t) QueryRecMsg(7); //Read in the orient data to orient variable
(byte 7)
SetThrust(1); //Set the thrust value by passing 1 to the function
Action = QueryRecMsg(8); //Read in the action data
PopBalloon(); //Call the balloon pop function
SetBrakes();
CheckForUnpair();
}
void SetThrust( int Toggle ){ //Function to control thrust and direction
static uint8_t LeftDrive;//Declaration for left motor pwm duty cycle
static uint8_t RightDrive;//Declaration for right motor pwm duty cycle
static uint8_t LeftDir;//Declaration for left motor direction of spin
static uint8_t RightDir;//Declaration for right motor direction of spin
uint16_t magnitude = ThrustOrientationMagnitude( (double) Thrust, (double)
Orient );

int16_t angle = ThrustOrientationAngle( (double) Orient, (double) Thrust );


if (Toggle == 1){
if ( magnitude < ZERO_MAGNITUDE ){
SetLift( FULL_LIFT );
LeftDrive = 2;
RightDrive = 2;
LeftDir = 0;
RightDir = 0;
}
else if ( magnitude > NONZERO_MAGNITUDE ){
if ( (angle > FORWARD_LOWER) && (angle < FORWARD_UPPER) ){
SetLift( FULL_LIFT );
LeftDrive = 50;
RightDrive = 50;
LeftDir = 0;
RightDir = 0;
}
else if ( (angle < RIGHT_UPPER) && (angle > RIGHT_LOWER) ){
SetLift( FULL_LIFT );
LeftDrive = 0;
RightDrive = 50;
LeftDir = 0;
RightDir = 0;
}
else if ( (angle < BRAKE_UPPER) && (angle > BRAKE_LOWER) ){
SetLift( BRAKE_LIFT ); // Brake the SPECTRE by cutting
power to lift fan
LeftDrive = 2;
RightDrive = 2;
LeftDir = 0;
RightDir = 0;
}
else{
SetLift( FULL_LIFT );
LeftDrive = 50;
RightDrive = 0;
LeftDir = 0;
RightDir = 0;
}
}
}
else{
SetLift( NO_LIFT );
LeftDrive = 2;
RightDrive = 2;
LeftDir = 0;
RightDir = 0;
}
SetDuty(LeftDrive, LeftDir, RightDrive, RightDir);
// Apply the drive
conditions (Direction bit of 0 corresponds to forward drive)
}
int16_t ThrustOrientationAngle( double x, double y ){

double angle = 0;
angle = 10000 * atan2( y, x );
// Multiply the floating point
number by 10000 to gain resolution when cast as a uint16 without
creating rollover
return (int16_t) angle;
}
uint16_t ThrustOrientationMagnitude( double x, double y ){
double magnitude = 0;
magnitude = 500 * sqrt( x*x + y*y );
// Multiply the floating
point number by 500 to gain resolution when cast as a uint16 without
creating rollover
return (uint16_t) magnitude;
}
/*------------------------------- Footnotes -------------------------------*/
/*------------------------------ End of file ------------------------------*/

Potrebbero piacerti anche