Spectre
Spectre
Spectre
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"
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
);
);
);
);
);
);
);
);
// 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;
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;
//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();
}
}
}
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
}
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
//
hi
//
lo
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 ) >>
}
}
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 );
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 ------------------------------*/