Vous êtes sur la page 1sur 35

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 3
/****************************************************************************/
// These are the definitions for Service 0
// the header file with the public function prototypes
#define SERV_0_HEADER "MI6_Comm.h"
// the name of the Init function
#define SERV_0_INIT InitMI6_Comm
// the name of the run function
#define SERV_0_RUN RunMI6_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 "MI6_Control.h"
// the name of the Init function
#define SERV_1_INIT InitMI6_Control
// the name of the run function
#define SERV_1_RUN RunMI6_Control
// How big should this services Queue be?
#define SERV_1_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 2
#if NUM_SERVICES > 2
// the header file with the public function prototypes
#define SERV_2_HEADER "Analog_Control.h"
// the name of the Init function
#define SERV_2_INIT InitAnalog_Control
// the name of the run function
#define SERV_2_RUN RunAnalog_Control
// How big should this services Queue be?
#define SERV_2_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_PAIR_BUTTON_PRESSED,
EV_BYTE_RECEIVED,
EV_MSG_RECEIVED,
EV_STARTED_RECEIVING,
EV_SEND_REQUEST,
EV_PAIR_ACKNOWLEDGED,
EV_POP_BALLOON,
EV_SEND_DATA,
EV_RESET_BUTTON_PRESSED,
EV_BRAKE_BUTTON_PRESSED,
EV_BRAKE_BUTTON_RELEASED,
EV_SEND_NEXT_BYTE } ES_EventTyp_t ;
/****************************************************************************/
// This is the name of the Event checking function header file.
#define EVENT_CHECK_HEADER "EventCheckers.h"
/****************************************************************************/
// This is the list of event checking functions
#define EVENT_CHECK_LIST
CheckForButton,CheckForHatchetSwing,CheckForUnpair,CheckForBrakeButton
/****************************************************************************/
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define

TIMER_UNUSED ((pPostFunc)0)
TIMER0_RESP_FUNC PostMI6_Comm
TIMER1_RESP_FUNC PostMI6_Comm
TIMER2_RESP_FUNC PostMI6_Comm
TIMER3_RESP_FUNC PostMI6_Control
TIMER4_RESP_FUNC PostMI6_Control
TIMER5_RESP_FUNC PostMI6_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 PostMI6_Control
TIMER14_RESP_FUNC PostMI6_Comm
TIMER15_RESP_FUNC PostAnalog_Control

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

TxTimer 0
CommTimeout 1
RxTimeout 2
TxTimeout 3
StatusTimeout 4
BalloonPopTimer 5
AnalogTimer
15
TestTimer 14
DebounceTimer 13

#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 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
IntDefaultHandler
; ADC Sequence 3

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
0
0
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
0
0
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
0
0
0
0
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
IntDefaultHandler
0
0
0
0
0
0
0
0
0
0

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

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
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

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
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
void
bool
bool
bool
bool

InitializeEventCheckers( void );
CheckForButton(void);
CheckForHatchetSwing(void);
CheckForUnpair( void );
CheckForBrakeButton( 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
//Modular Variables
static uint8_t LastUnpairState;
static uint8_t CurrentUnpairState;
static uint8_t InitialBrakeButtonState = 0;
static uint8_t LastBrakeButtonState = 0;
void InitializeEventCheckers( void ){
LastUnpairState = (HWREG( GPIO_PORTD_BASE + (GPIO_O_DATA + ALL_BITS) ) &
BIT1HI);
InitialBrakeButtonState = (HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA+ALL_BITS)) &
BIT0HI);
LastBrakeButtonState = InitialBrakeButtonState;
}
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_PAIR_BUTTON_PRESSED; // Set the EventType to
EV_BUTTON_PRESSED
PostMI6_Control(ButtonPressed);
// Post the event to the MI6_Comm module
ReturnVal = true;
}
LastButtonState = CurrentButtonState;
// Update the value of LastButtonState
return ReturnVal;
}

bool CheckForHatchetSwing(void)
{
static uint8_t LastHatchetState = 0;
uint8_t CurrentHatchetState;
bool ReturnVal = false;
CurrentHatchetState = (HWREG(GPIO_PORTB_BASE+(GPIO_O_DATA+ALL_BITS)) &
BIT3HI);
// Mask Port B with input of interest, in this case pin PB3 corresponding
to hatchet popping input
){

if ( (CurrentHatchetState != LastHatchetState) && (CurrentHatchetState != 0)


// If the pin state has changed, and is now not low
ES_Event Hatchet;
Hatchet.EventType = EV_POP_BALLOON;
PostMI6_Control(Hatchet);
ReturnVal = true;
}
LastHatchetState = CurrentHatchetState;
return ReturnVal;

}
bool CheckForUnpair(void){
bool ReturnVal = false;
CurrentUnpairState = (HWREG( GPIO_PORTD_BASE + (GPIO_O_DATA + ALL_BITS) ) &
BIT1HI);
if(CurrentUnpairState != LastUnpairState){
ES_Event ButtonPressed;
// Create ButtonPressed event
ButtonPressed.EventType = EV_RESET_BUTTON_PRESSED;
// Set the EventType
to EV_BUTTON_PRESSED
PostMI6_Control(ButtonPressed);
// Post the event to the MI6_Comm module
ReturnVal = true;
}
LastUnpairState = CurrentUnpairState;
return ReturnVal;
}
bool CheckForBrakeButton( void ){
uint8_t CurrentBrakeButtonState;
bool ReturnVal = false;
InitialBrakeButtonState = QueryInitialBrakeButtonState();
CurrentBrakeButtonState = (HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA+ALL_BITS)) &
BIT0HI);
// Read in the value at pin PD0
if ( (CurrentBrakeButtonState != LastBrakeButtonState) &&
(CurrentBrakeButtonState != InitialBrakeButtonState) ){
ES_Event BrakeButtonPressed;
BrakeButtonPressed.EventType = EV_BRAKE_BUTTON_PRESSED;
PostMI6_Control(BrakeButtonPressed);
ReturnVal = true;
}
if ( (CurrentBrakeButtonState != LastBrakeButtonState) &&
(CurrentBrakeButtonState == InitialBrakeButtonState) ){
ES_Event BrakeButtonReleased;

BrakeButtonReleased.EventType = EV_BRAKE_BUTTON_RELEASED;
PostMI6_Control(BrakeButtonReleased);
ReturnVal = true;
}
LastBrakeButtonState = CurrentBrakeButtonState;
return ReturnVal;
}

ADMulti.h
#ifndef ADMULTI
#define ADMULTI
// ADMulti.h
// Setup up ADC0 to convert up to 4 channels using SS2
#include <stdint.h>
// initialize the A/D converter to convert on 1-4 channels
void ADC_MultiInit(uint8_t HowMany);
//------------ADC_MultiRead-----------// Triggers A/D conversion and waits for result
// Input: none
// Output: up to 4 12-bit result of ADC conversions
// software trigger, busy-wait sampling, takes about 18.6uS to execute
// data returned by reference
// lowest numbered converted channel is in data[0]
void ADC_MultiRead(uint32_t data[4]);
#endif

ADMulti.c
#include
#include
#include
#include
#include

<stdint.h>
"inc/hw_gpio.h"
"inc/hw_types.h"
"inc/hw_memmap.h"
"inc/tm4c123gh6pm.h"

#include "ADMulti.h"
static const uint32_t HowMany2Mask[4] = {0x01,0x03,0x07,0x0F};
// this mapping puts PE0 as resuult 0, PE1 as result 1...
static const uint32_t HowMany2Mux[4] = {0x03,0x023,0x123,0x0123};
static const uint32_t HowMany2CTL[4] = {ADC_SSCTL2_END0|ADC_SSCTL2_IE0,
ADC_SSCTL2_END1|ADC_SSCTL2_IE1,
ADC_SSCTL2_END2|ADC_SSCTL2_IE2,
ADC_SSCTL2_END3|ADC_SSCTL2_IE3};
static uint8_t NumChannelsConverting;
// initialize the A/D converter to convert on 1-4 channels
void ADC_MultiInit(uint8_t HowMany){
volatile uint32_t delay;
uint8_t index = HowMany-1; // index into the HowMany2Mask array
// first sanity check on the HowMany parameter
if ( (0 == HowMany) || (4 < HowMany))
return;
NumChannelsConverting = HowMany;
SYSCTL_RCGCADC_R |= 0x00000001; // 1) activate ADC0
SYSCTL_RCGCGPIO_R |= SYSCTL_RCGCGPIO_R4; // 1) activate clock for Port E
delay = SYSCTL_RCGCGPIO_R;
// 2) allow time for clock to stabilize
delay = SYSCTL_RCGCGPIO_R;
GPIO_PORTE_DIR_R &= ~HowMany2Mask[index];
// 3) make PE0, PE1, PE2, PE3 input
GPIO_PORTE_AFSEL_R |= HowMany2Mask[index];
// 4) enable alternate function on
PE0 - PE3
GPIO_PORTE_DEN_R &= ~HowMany2Mask[index];
// 5) disable digital I/O on PE0
- PE3
GPIO_PORTE_AMSEL_R |= HowMany2Mask[index];
// 6) enable analog functionality
on PE4 PE5
ADC0_PC_R &= ~0xF;
// 8) clear max sample rate field
ADC0_PC_R |= 0x1;
//
configure for 125K samples/sec
ADC0_SSPRI_R = 0x3210;
// 9) Sequencer 3 is lowest priority
ADC0_ACTSS_R &= ~0x0004;
// 10) disable sample sequencer 2
ADC0_EMUX_R &= ~0x0F00;
// 11) seq2 is software trigger
ADC0_SSMUX2_R = HowMany2Mux[index];
// 12) set channels for SS2
ADC0_SSCTL2_R = HowMany2CTL[index];
// 13) set which sample is last
ADC0_IM_R &= ~0x0004;
// 14) disable SS2 interrupts
ADC0_ACTSS_R |= 0x0004;
// 15) enable sample sequencer 2
}
//------------ADC_MultiRead-----------// Triggers A/D conversion and waits for result
// Input: none
// Output: up to 4 12-bit result of ADC conversions
// software trigger, busy-wait sampling, takes about 18.6uS to execute
// data returned by reference
// lowest numbered converted channel is in data[0]
void ADC_MultiRead(uint32_t data[4]){
uint8_t i;

ADC0_PSSI_R = 0x0004;
while((ADC0_RIS_R&0x04)==0)
{};
for (i=0; i< NumChannelsConverting;
data[i] = ADC0_SSFIFO2_R&0xFFF;
}
ADC0_ISC_R = 0x0004;
}

// 1) initiate SS2
// 2) wait for conversion(s) to complete
i++){
// 3) read result, one at a time
// 4) acknowledge completion, clear int

Analog_Control.h
/****************************************************************************
Header file for template service
based on the Gen 2 Events and Services Framework
****************************************************************************/
#ifndef Analog_Control_H
#define Analog_Control_H
#include "ES_Types.h"
// Public Function Prototypes
bool InitAnalog_Control ( uint8_t Priority );
bool PostAnalog_Control( ES_Event ThisEvent );
ES_Event RunAnalog_Control( ES_Event ThisEvent );
int8_t QueryThrust( void );
int8_t QueryTurn( void );
uint8_t QueryPotentiometer( void );
#endif /* Analog_Control_H */

Analog_Control.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
#include
#include
#include

"MI6_Comm.h"
"MI6_Control.h"
"Analog_Control.h"
"ADMulti.h"

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


#define ALL_BITS (0xff<<2)
/*---------------------------- Module Functions ---------------------------*/
void InitStateLEDs( void );
void SetStateLEDs( void );
void ClearStateLEDs( void );
/*---------------------------- Module Variables ---------------------------*/
static uint8_t MyPriority;
uint32_t AnalogArray[4];
int8_t Thrust;
int8_t Turn;
static uint8_t Potentiometer_Reading;
static bool LEDsON = false;
/*------------------------------ Module Code ------------------------------*/
bool InitAnalog_Control ( uint8_t Priority )
{
ES_Event ThisEvent;
MyPriority = Priority;
//Initialize ADC for 2 analog inputs
ADC_MultiInit(4);
//Initialize LEDs for states
InitStateLEDs();
//Read initial values
ADC_MultiRead(AnalogArray);
ES_Timer_InitTimer(AnalogTimer, 500);

//Set Timer for 500ms

// post the initial transition event


ThisEvent.EventType = ES_INIT;
if (ES_PostToService( MyPriority, ThisEvent) == true)
{
return true;
}else
{
return false;
}
}
bool PostAnalog_Control( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
ES_Event RunAnalog_Control( ES_Event ThisEvent )
{
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
if(ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam == AnalogTimer){
//Read analog values
ADC_MultiRead(AnalogArray);
Thrust = (uint8_t)(AnalogArray[1]>>4) - 128;
Turn = (uint8_t)(AnalogArray[0]>>4) - 128;
Potentiometer_Reading = 1 + AnalogArray[3]/340;
if (Potentiometer_Reading > 12){
Potentiometer_Reading = 12;
}
if(QueryPaired()){
//Don't Change State LEDs unless none are on.
if(LEDsON == false){
SetStateLEDs();
LEDsON = true;
}
}
else{
if(LEDsON){
ClearStateLEDs();
LEDsON = false;
}
else{
SetStateLEDs();
//Set State LEDs
LEDsON = true;
}
}
if(Thrust <= 10 && Thrust >= -10){
Thrust = 0;
}
if(Turn <= 10 && Turn >= -10){
Turn = 0;
}
//Reset Timer
ES_Timer_InitTimer(AnalogTimer, 200);
}
return ReturnEvent;

//Set Timer for 200ms

}
int8_t QueryThrust( void ){
return Thrust;
}
int8_t QueryTurn( void ){
return Turn;
}
uint8_t QueryPotentiometer( void ){
return Potentiometer_Reading;
}
void InitStateLEDs( void ){
//Initialize State LEDs
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R0;
while((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R0) != SYSCTL_PRGPIO_R0);
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R2;
while((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R2) != SYSCTL_PRGPIO_R2);
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R4;
while((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R4) != SYSCTL_PRGPIO_R4);
//A initialization
HWREG(GPIO_PORTA_BASE +GPIO_O_DEN) |= (BIT2HI | BIT3HI | BIT4HI | BIT5HI |
BIT6HI | BIT7HI);
HWREG(GPIO_PORTA_BASE +GPIO_O_DIR) |= (BIT2HI | BIT3HI | BIT4HI | BIT5HI |
BIT6HI | BIT7HI);
//C initialization
HWREG(GPIO_PORTC_BASE +GPIO_O_DEN) |= (BIT4HI | BIT5HI | BIT6HI | BIT7HI);
HWREG(GPIO_PORTC_BASE +GPIO_O_DIR) |= (BIT4HI | BIT5HI | BIT6HI | BIT7HI);
//E initialization
HWREG(GPIO_PORTE_BASE +GPIO_O_DEN) |= (BIT4HI | BIT5HI);
HWREG(GPIO_PORTE_BASE +GPIO_O_DIR) |= (BIT4HI | BIT5HI);
}
void SetStateLEDs( void ){
HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + ALL_BITS)) &= (BIT2LO & BIT3LO & BIT4LO
& BIT5LO & BIT6LO & BIT7LO);
HWREG(GPIO_PORTC_BASE + (GPIO_O_DATA + ALL_BITS)) &= (BIT4LO & BIT5LO & BIT6LO
& BIT7LO);
HWREG(GPIO_PORTE_BASE + (GPIO_O_DATA + ALL_BITS)) &= (BIT4LO & BIT5LO);
switch(Potentiometer_Reading){
case 1:
HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + ALL_BITS)) |= BIT2HI;
break;
case 2:
HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + ALL_BITS)) |= BIT3HI;
break;
case 3:
HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + ALL_BITS)) |= BIT4HI;
break;
case 4:
HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + ALL_BITS)) |= BIT5HI;
break;
case 5:
HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + ALL_BITS)) |= BIT6HI;

break;
case 6:
HWREG(GPIO_PORTA_BASE
break;
case 7:
HWREG(GPIO_PORTC_BASE
break;
case 8:
HWREG(GPIO_PORTC_BASE
break;
case 9:
HWREG(GPIO_PORTC_BASE
break;
case 10:
HWREG(GPIO_PORTC_BASE
break;
case 11:
HWREG(GPIO_PORTE_BASE
break;
case 12:
HWREG(GPIO_PORTE_BASE
break;

+ (GPIO_O_DATA + ALL_BITS)) |= BIT7HI;


+ (GPIO_O_DATA + ALL_BITS)) |= BIT4HI;
+ (GPIO_O_DATA + ALL_BITS)) |= BIT5HI;
+ (GPIO_O_DATA + ALL_BITS)) |= BIT6HI;
+ (GPIO_O_DATA + ALL_BITS)) |= BIT7HI;
+ (GPIO_O_DATA + ALL_BITS)) |= BIT4HI;
+ (GPIO_O_DATA + ALL_BITS)) |= BIT5HI;

}
}
void ClearStateLEDs( void ){
HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + ALL_BITS)) &= (BIT2LO & BIT3LO
& BIT4LO & BIT5LO & BIT6LO & BIT7LO);
HWREG(GPIO_PORTC_BASE + (GPIO_O_DATA + ALL_BITS)) &= (BIT4LO & BIT5LO
& BIT6LO & BIT7LO);
HWREG(GPIO_PORTE_BASE + (GPIO_O_DATA + ALL_BITS)) &= (BIT4LO & BIT5LO);
}

MI6_Comm.h
/****************************************************************************
Header file for template service
based on the Gen 2 Events and Services Framework
****************************************************************************/
#ifndef MI6_Comm_H
#define MI6_Comm_H
#include "ES_Types.h"
// Public Function Prototypes
bool InitMI6_Comm ( uint8_t Priority );
bool PostMI6_Comm( ES_Event ThisEvent );
ES_Event RunMI6_Comm( ES_Event ThisEvent );
void EnableTransmit( void );
void ResponseFunc( void );
void TransmitRequest( void );
void RecordAddress( void );
void TransmitControl( void );
bool CheckForPaired( void );
bool CheckForStatus( void );
typedef enum {OPEN,PROCESSING} Comm_State;
#endif /* MI6_Comm_H */

MI6_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
#include
#include
#include

"MI6_Comm.h"
"MI6_Control.h"
"Analog_Control.h"
"EventCheckers.h"

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


#define MY_ADDRESS 0x00
#define ALL_BITS (0xff<<2)
#define MAINTAIN_BRAKE 1
#define CLEAR_BRAKE 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 );
/*---------------------------- Module Variables ---------------------------*/
static uint8_t MyPriority;
static uint8_t RecTempMessage; //Temporary variable to read in UART DR
static int RecMesLen = 8; //Length of the message that was just read in
static int RecMsgCounter = 0;//Counter to keep track when receiving
static uint8_t RecMsgSum = 0;//Running sum variable to keep the check sum
static uint8_t RecMsg[20];//Variable to store received data
static bool TransmitPossible = true;
static int TxMesLen = 8;//Length of the message to be transmitted
static int TxMsgCounter = 0;//Counter to keep track when transmitting
static uint8_t TxMsgSum = 0;//Running sum variable to keep the check sum
static uint8_t TxMsg[20];//Variable to store the transmitted data
static char SpectreAddress[] = {0x00,0x00};//Address of the spectre that we are
linked to
static uint8_t RequestingSPECTRE = 1;
//SPECTRE that we are requesting to link
to (based on potentiometer)
//State variable
static Comm_State CurrentState;//Current State of the Comm module

static Comm_State NextState;//Next State of the Comm module


/*------------------------------ Module Code ------------------------------*/
bool InitMI6_Comm ( uint8_t Priority )
{
ES_Event ThisEvent;
MyPriority = Priority;
InitializeIO();//Initialize the necessary io pins
InitializeUART();//Initialize the uart module
InitializeEventCheckers(); //Initialize EventChecker Variables
CurrentState = OPEN; // Set the current state open for tx
// post the initial transition event
ThisEvent.EventType = ES_INIT;
if (ES_PostToService( MyPriority, ThisEvent) == true)
{
return true;
}else
{
return false;
}
}
bool PostMI6_Comm( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
ES_Event RunMI6_Comm( ES_Event ThisEvent )
{
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
NextState = CurrentState;
if (CurrentState == OPEN){//Else if the current state is open
if( ThisEvent.EventType == EV_SEND_DATA ){
// If a
BUTTON_PRESSED event is detected or
we've received a SEND_DATA event
if (TransmitPossible == true){
FirstByteTransmit(); //Start the byte transmit process
}
}
else if( ThisEvent.EventType == EV_SEND_NEXT_BYTE ){ // If we've
received a TxTimer request
TxMsgCounter++; //Update the txmsgcounter that keeps track of
bytes transmitted
ByteTransmit(); //Transmit a byte
}
else if( ThisEvent.EventType == EV_STARTED_RECEIVING){//If we've received a
started receiving event, enter the processing state
NextState = PROCESSING; //Set the state to processing
}
else if ( (ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam ==
TestTimer) ){
//If we recived a dummy timeout
TransmitControl();//Send the control values
ES_Timer_InitTimer( TestTimer, 200 );//Restart the dummy timer
}
}

else if (CurrentState == PROCESSING){

//If we are in the processing state

if( ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam ==


RxTimeout){//If we've received a timeout and it's from not having received anything
before msg completely received
NextState = OPEN; //Return to the open state
FreeMsgHelpers(); //Clear the receive helper variables
}
else if(ThisEvent.EventType == EV_MSG_RECEIVED){//If we've received a message
NextState = OPEN;//Set the next state to be open
ProcessMessage();//Process the message
}
if ( (ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam ==
TestTimer) ){//If we recived a dummy timeout
ES_Timer_InitTimer( TestTimer, 20 );//Restart the dummy timer
}
}
CurrentState = NextState;//Set the current state to the next state
return ReturnEvent;
}
/***************************************************************************
private functions
***************************************************************************/
void InitializeIO(){//Function to initialize the IO pins
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R1;// Enable the clock to Port B
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_PORTB_BASE+GPIO_O_DEN) |= (BIT3HI); // Enable Port B pin PB3 to
be digital I/O
HWREG(GPIO_PORTB_BASE+GPIO_O_DIR) &= (BIT3LO); // Enable Port B pin PB3 to
be input
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) &= (BIT0LO & BIT1LO & BIT2LO);
// 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_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTF_BASE+GPIO_O_CR) = BIT0HI;
HWREG(GPIO_PORTF_BASE+GPIO_O_DEN) |= (BIT0HI | BIT1HI | BIT2HI | BIT3HI |
BIT4HI);
// Enable Port F pins PF3-4 to be digital I/O
HWREG(GPIO_PORTF_BASE+GPIO_O_DIR) |= (BIT1HI | BIT2HI | BIT3HI);
// Enable Port F pin PF3 to be output
HWREG(GPIO_PORTF_BASE+(ALL_BITS+GPIO_O_DATA)) &= (BIT3LO);
// Set pin PF3 low
HWREG(GPIO_PORTF_BASE+GPIO_O_DIR) &= (BIT4LO & BIT0LO);
// Enable Port F pin PF4 and PF0 to be input
HWREG(GPIO_PORTF_BASE+GPIO_O_PUR) |= (BIT4HI | BIT0HI);
// Enable pull up resistor for F4 and F0
}

void InitializeUART(){//Function to initialize the UART


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);
// 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_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 EnableTransmit( void ){
// Function created to meter transmissions only
when an Acknowledged message received upon last transmission
TransmitPossible = true;
}
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(){//Function to handle RX interrupts
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)){
//If the
first byte is 0x7e and we are at the 0 index of RecMsgCounter
ES_Event NewEvent;
//Create a new event New Event of type
StartedReceiving and post to MI6Comm's queue
NewEvent.EventType = EV_STARTED_RECEIVING;
PostMI6_Comm(NewEvent);
ES_Timer_InitTimer(RxTimeout,100); //Start an RxTimeout of
100ms (timeout for intramessage reception)
RecMsgCounter += 1;
//Update RecMsgCounter
}
else if ((RecMsgCounter == 1) && (RecTempMessage == 0x00)){ //If the
second byte is 0x00 and we are at the 1 index of RecMsgCounter
RecMsgCounter += 1;
//Update RecMsgCounter
ES_Timer_StopTimer(RxTimeout);
//Stop the RxTimeout Timer
ES_Timer_InitTimer(RxTimeout,100); //Start the RxTimeout Timer
}
else if (RecMsgCounter == 2){ //If we are on the second byte
InitializeMsgHelpers(RecTempMessage);
//Initialize the msg
helpers variables
RecMsgCounter += 1;
//Update the RecMsgCounter
ES_Timer_StopTimer(RxTimeout);
//Stop the RxTimeout Timer
ES_Timer_InitTimer(RxTimeout,100); //Stop the RxTimeout Timer
}
else if ((RecMsgCounter > 2) && (RecMsgCounter < RecMesLen+3)){
//Take in all bytes until we have hit the upper RecMessage length (+3 because
we don't include the 1st 3 bytes (0x73 and length))
RecMsg[RecMsgCounter-3] = RecTempMessage; //Store the
TempMessage in the next index of RecMsg
RecMsgCounter += 1;
//Update the RecMsgCounter
ES_Timer_StopTimer(RxTimeout);
//Stop the RxTimeout Timer
ES_Timer_InitTimer(RxTimeout,100); //Start the Rxtimeout timer
}

if (RecMsgCounter == (RecMesLen + 3)){


//If we've reached the
length of our message
ES_Timer_StopTimer(RxTimeout);
//Stop the RxTimeout timer
ES_Event NewEvent;
//Create an Event NewEvent of type
EV_MSG_Received and post to the Comm
NewEvent.EventType = EV_MSG_RECEIVED;
PostMI6_Comm(NewEvent);
}
}
}
void InitializeMsgHelpers(char TempMessage){//Initialize variables that store
message data
RecMesLen = ((uint8_t) TempMessage) + 1;
}
void ProcessMessage(){//Process the message that we just read in
for (int i = 0; i < RecMesLen-1; i++){//Function to calculate the checksum
RecMsgSum += (uint8_t) RecMsg[i];
}
static int msgnum = 0;
msgnum++;
if ((RecMsgSum == (0xff-RecMsg[RecMesLen-1])) && (RecMsg[3] != 0x89)){//Check
the check sum of the data we received
TransmitPossible = true;
ES_Event NewEvent;
NewEvent.EventType = EV_MSG_RECEIVED;
PostMI6_Control(NewEvent);
}
else if ((RecMsgSum == (0xff-RecMsg[RecMesLen-1])) && (RecMsg[0] == 0x89) &&
(RecMsg[2] == 0x00)){
TransmitPossible = true;
}
else if ((RecMsgSum == (0xff-RecMsg[RecMesLen-1])) && (RecMsg[0] == 0x89) &&
(RecMsg[2] == 0x01 || RecMsg[2] == 0x02 || RecMsg[2] == 0x03)){
TransmitPossible = true;
ES_Timer_StopTimer(StatusTimeout); // Stop the status timeout timer
ES_Timer_InitTimer(StatusTimeout,1000);
// Restart the status
timeout timer
ES_Timer_StopTimer(TxTimeout);
// Stop the tx timeout timer
ES_Timer_InitTimer(TxTimeout,200); // Restart the tx timeout timer
ES_Event NewEvent;//Post Send date event to MI6 comm
NewEvent.EventType = EV_SEND_DATA;
PostMI6_Comm(NewEvent);
}
else{
printf("CHECKSUM ERROR \n\r");
}
FreeMsgHelpers();//Free Msg helper variables (clear/reset them)
}
void FreeMsgHelpers(){//Reset the Msg helper variables
RecMsgCounter = 0;//Set RecMsgCounter to 0
RecMsgSum = 0;//Set check sum to 0x00
}
void TransmitRequest( void ){//Function to transmit a request (same for all transmits
exc
TxMesLen = 11;
TxMsg[0] = 0x7E; //Start delimiter of XBEE message
TxMsg[1] = 0x00; //MSB (msglen)
TxMsg[2] = 0x07; //LSB (msglen)

TxMsg[3]
TxMsg[4]
TxMsg[5]
TxMsg[6]
TxMsg[7]
TxMsg[8]
TxMsg[9]

=
=
=
=
=
=
=

0x01; //XBEE API (Send Packet)


0xED; //MESSAGE ID
0xff; //MSB OF DESTINATION
0xff; //LSB OF DESTINATION
0x00; //BROADCAST PAN ID
0x01; //REQUEST PAIR HEADER
QueryPotentiometer(); //REQUEST SEQUENCE

TxMsgSum = 0;//Do
for (int i = 3; i
TxMsgSum +=
}
TxMsg[TxMesLen-1]

the check sum calculation for what we are sending out


< TxMesLen-1; i++){
TxMsg[i];
= 0xFF - (char)TxMsgSum;//Set the last byte to be the
checksum

TxMsgCounter = 0;//Set the counter back to 0


ES_Event NewEvent;//Post Send date event to MI6 comm
NewEvent.EventType = EV_SEND_DATA;
PostMI6_Comm(NewEvent);
}
void RecordAddress( void ){//Store the current spectre's address
SpectreAddress[0] = RecMsg[1];//spectre address msb
SpectreAddress[1] = RecMsg[2];//spectre address lsb
}
void TransmitControl( void ){
TxMesLen = 16;
TxMsg[0] = 0x7E; //Start delimiter of XBEE message
TxMsg[1] = 0x00; //MSB (msglen)
TxMsg[2] = 0x0C; //LSB (msglen)
TxMsg[3] = 0x01; //XBEE API (Send Packet)
TxMsg[4] = 0xED; //MESSAGE ID
TxMsg[5] = SpectreAddress[0]; //MSB OF DESTINATION
TxMsg[6] = SpectreAddress[1]; //LSB OF DESTINATION
TxMsg[7] = 0x00; //BROADCAST PAN ID
TxMsg[8] = 0x03; //REQUEST CONTROL HEADER
TxMsg[9] = (int8_t)QueryThrust(); //THRUST (cast to be signed value)
TxMsg[10] = (int8_t)QueryTurn(); //ORIENT (cast to be signed value)
TxMsg[11] = ReturnActionByte(); //ACTION
TxMsg[12] = 0x05; //EXA
TxMsg[13] = 0x05; //EXB
TxMsg[14] = 0x05; //EXC
ClearActionByte( MAINTAIN_BRAKE ); // Clear whatever actions we just
transmitted
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;
PostMI6_Comm(NewEvent);
}
bool CheckForPaired(){//Check to see if we have successfully paired
if ((RecMsg[6] == 0x01) && (RecMsg[5] == 0x02)){//byte 9 of RecMsg is the

success bit of a RecMsg, and byte 8 is the acknowledge header


SpectreAddress[0] = RecMsg[1];
SpectreAddress[1] = RecMsg[2];
return true;
}
return false;
}
bool CheckForStatus(){//Check to see if we have received a status message from the
spectre
if (( (RecMsg[6] == 0x00) || (RecMsg[6] == 0x01) ) && (RecMsg[5] == 0x04) &&
(RecMsg[1] == SpectreAddress[0]) && (RecMsg[2] == SpectreAddress[1])){//byte 9 of
recmsg is the free/mind-control bit, byte 8 is the status header
and then bytes 4 & 5 make sure that we are reading from the spectre
of the right address
return true;//return true if match
}
return false;//else return false
}
/*------------------------------- Footnotes -------------------------------*/
/*------------------------------ End of file ------------------------------*/

MI6_Control.h
/****************************************************************************
Header file for template service
based on the Gen 2 Events and Services Framework
****************************************************************************/
#ifndef MI6_Control_H
#define MI6_Control_H
#include "ES_Types.h"
// Public Function Prototypes
bool InitMI6_Control ( uint8_t Priority );
bool PostMI6_Control( ES_Event ThisEvent );
ES_Event RunMI6_Control( ES_Event ThisEvent );
void ClearActionByte( uint8_t KeepBrake );
uint8_t ReturnActionByte( void );
bool QueryPaired( void );
uint8_t QueryInitialBrakeButtonState( void );
typedef enum { REQUESTING, PAIRED } Control_State;
#endif /* MI6_Control_H */

MI6_Control.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 "Analog_Control.h"
#include "MI6_Control.h"
#include "MI6_Comm.h"
/*----------------------------- Module Defines ----------------------------*/
#define ALL_BITS (0xff<<2)
#define POP 1
#define BRAKE 2
#define STOP_BRAKE 3
#define UNPAIR 4
#define MAINTAIN_BRAKE 1
#define CLEAR_BRAKE 2
/*---------------------------- Module Functions ---------------------------*/
void SetActionByte( uint8_t ActionToDo );
/*---------------------------- Module Variables ---------------------------*/
static uint8_t MyPriority; // My priority
static uint8_t ActionByte;
static uint8_t BalloonPopStatus;
static uint8_t InitialBrakeButtonState = 0;
//State variable
static Control_State CurrentState; // The Current State of Control module
static Control_State NextState; // The Next State of Control module
static bool Paired = false;
//Used to Query if Paired or Not
static bool Debouncing = false;
//Debounce the button.
/*------------------------------ Module Code ------------------------------*/
bool InitMI6_Control ( uint8_t Priority )
{
ES_Event ThisEvent;
MyPriority = Priority;
ActionByte = 0;
InitialBrakeButtonState = (HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA+ALL_BITS)) &
BIT0HI);
// Initialize the InitialBrakeButtonState variable to state of pin PD0
CurrentState = REQUESTING; // Setting the current state of control module to

REQUESTING
// post the initial transition event
ThisEvent.EventType = ES_INIT;
if (ES_PostToService( MyPriority, ThisEvent) == true)
{
return true;
}else
{
return false;
}
}
bool PostMI6_Control( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
ES_Event RunMI6_Control( ES_Event ThisEvent )
{
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
NextState = CurrentState;
if (CurrentState == REQUESTING){ //Check to see if we are in a requesting state
if( (ThisEvent.EventType == EV_SEND_REQUEST || ThisEvent.EventType ==
EV_PAIR_BUTTON_PRESSED) && Debouncing == false){
// If a SEND_REQUEST event
is detected
ClearActionByte( CLEAR_BRAKE );
TransmitRequest(); //Broadcast a control request
ES_Timer_InitTimer( DebounceTimer, 50);
Debouncing = true;
}

BIT2HI);

else if( ThisEvent.EventType == EV_PAIR_ACKNOWLEDGED ){


// If a
PAIR_ACKNOWLEDGED event is detected
RecordAddress(); // Record the address of the paired spectre
NextState = PAIRED; // Set the next state to paired
ES_Timer_InitTimer( TxTimeout, 200 ); // Start the 5Hz tx timeout
ES_Timer_InitTimer( StatusTimeout, 1000); // Start the 1Hz
timeout timer
HWREG(GPIO_PORTF_BASE + (ALL_BITS+GPIO_O_DATA)) |= (BIT1HI |
//Turn LED from Green to WHITE
Paired = true;
//Now Paired
}
else if( ThisEvent.EventType == EV_MSG_RECEIVED){ // If a message was
received
if (CheckForPaired() == true){//Check to see if we successfully
paired (only thing we care about here)
ES_Event NewEvent;//Post event EV_PAIR_ACKNOWLEDGED to the
Control state machine
NewEvent.EventType = EV_PAIR_ACKNOWLEDGED;
PostMI6_Control(NewEvent);
}
}

else if( (ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam


== DebounceTimer) ){
Debouncing = false;

}
}
else if (CurrentState == PAIRED){//Check to see if we are in a paired state
if( (ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam ==
TxTimeout) ){ // If there's a timeout event and it's a tx timeout (5Hz timer)
TransmitControl(); //Transmit control values
ES_Timer_InitTimer( TxTimeout, 200 ); // Reset the Tx Timer
}
else if( ThisEvent.EventType == EV_RESET_BUTTON_PRESSED){
NextState = REQUESTING; //Set the next state to requesting
ES_Timer_StopTimer(StatusTimeout); //Stop the 1 Hz timer
ES_Timer_StopTimer(TxTimeout);//Stop the txtimeout
ES_Timer_StopTimer(TxTimer);//Stop the txtimer
SetActionByte( UNPAIR );
//Transmit an unpair
command to the SPECTRE
HWREG(GPIO_PORTF_BASE + (ALL_BITS+GPIO_O_DATA)) &= ~(BIT1HI |
BIT2HI);
//Change LED back to Green
Paired = false; //No Longer Paired
EnableTransmit(); //Allow transmit
InitialBrakeButtonState =
(HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA+ALL_BITS)) & BIT0HI);
// Re-initialize the
InitialBrakeButtonState
}
else if( (ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam
== DebounceTimer) ){
Debouncing = false;
}
else if( (ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam
== StatusTimeout) ){ // If there's a timeout event and it's a status timeout (1Hz
timer)
ES_Timer_StopTimer(TxTimeout); //Stop the tx timer
NextState = REQUESTING; //Set the next state to requesting
HWREG(GPIO_PORTF_BASE + (ALL_BITS+GPIO_O_DATA)) &= ~(BIT1HI |
BIT2HI);
//Change LED back to Green
Paired = false; //No Longer Paired
EnableTransmit(); //Allow transmit
InitialBrakeButtonState =
(HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA+ALL_BITS)) & BIT0HI);
// Re-initialize the
InitialBrakeButtonState
}
else if( (ThisEvent.EventType == EV_POP_BALLOON) && (BalloonPopStatus
== 0) ){//If we detect a balloon pop event and the status is 0
BalloonPopStatus = 1; //Set the status to 1
SetActionByte( POP );
ES_Timer_InitTimer( BalloonPopTimer, 2000 ); //Init a balloon pop
timer so that we don't pop more than twice in 2 s
}
else if( (ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam
== BalloonPopTimer) ){ // If we have a timeout event and the timer is the Balloon
pop timer
BalloonPopStatus = 0; //Set the balloon pop status to 0

}
else if( ThisEvent.EventType == EV_MSG_RECEIVED){//If we have received
a message
if (CheckForStatus() == true){ //Check to see if it's a status
message
ES_Timer_StopTimer( StatusTimeout ); //Stop the timeout
timer if it passes
ES_Timer_InitTimer( StatusTimeout, 1000 ); //Start the
timeout timer for 1 second
}
}
else if( ThisEvent.EventType == EV_BRAKE_BUTTON_PRESSED ){
SetActionByte( BRAKE );
// Set the brake bit of the Action
byte to be transmitted
}
else if( ThisEvent.EventType == EV_BRAKE_BUTTON_RELEASED ){
SetActionByte( STOP_BRAKE ); // Clear the brake bit of the
Action byte to be transmitted
}
}
CurrentState = NextState; //Update the current state
return ReturnEvent;
}
void SetActionByte( uint8_t ActionToDo ){ //Function to set bits in the Action byte
(unpair, brake, pop)
if ( ActionToDo == POP ){
ActionByte = ActionByte | BIT0HI;
}
else{
ActionByte = ActionByte & BIT0LO;
}
if ( ActionToDo == BRAKE ){
ActionByte = ActionByte | BIT1HI;
}
else if ( ActionToDo == STOP_BRAKE ){
ActionByte = ActionByte & BIT1LO;
}
if ( ActionToDo == UNPAIR ){
ActionByte = ActionByte | BIT7HI;
}
else{
ActionByte = ActionByte & BIT7LO;
}
}
void ClearActionByte( uint8_t KeepBrake ){
if ( KeepBrake == MAINTAIN_BRAKE ){
ActionByte = ActionByte & BIT1HI;

// If we wish to maintain the brake


bit setting
// Mask the variable with the brake
bit set hi

}
else if ( KeepBrake == CLEAR_BRAKE ){

// If we wish to clear the unpair,

pop, AND brake bits


ActionByte = 0x00;
// Clear the entire ActionByte variable
}
ActionByte = ActionByte & BIT1HI;
// Clear all bits upon
transmission with the exception of the brake bit, which is changed upon
an EV_BRAKE_BUTTON_RELEASED event
}
uint8_t ReturnActionByte( void ){

// Function to return the Action byte


being transmitted

return ActionByte;
}
bool QueryPaired( void ){
return Paired;
}
uint8_t QueryInitialBrakeButtonState( void ){
return InitialBrakeButtonState;
}
/*------------------------------- Footnotes -------------------------------*/
/*------------------------------ End of file ------------------------------*/

Vous aimerez peut-être aussi