Académique Documents
Professionnel Documents
Culture Documents
What/Why
-------Created
*/
/*
*****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
/* include header files for the framework and this service
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "ES_DeferRecall.h"
#include "ES_ShortTimer.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
"inc/hw_memmap.h"
"inc/hw_types.h"
"inc/hw_gpio.h"
"inc/hw_sysctl.h"
"driverlib/sysctl.h"
"driverlib/pin_map.h" // Define PART_TM4C123GH6PM in project
"driverlib/gpio.h"
"driverlib/timer.h"
"driverlib/interrupt.h"
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
TRACK2 0x00000002
TRACK3 0x00000004
TRACK4 0x00000008
TRACK5 0x00000010
TRACK6 0x00000020
TRACK7 0x00000040
TRACK8 0x00000080
TRACK9 0x00000100
TRACK10 0x00000200
TRACK11 0x00000400
TRACK12 0x00000800
TRACK13 0x00001000
TRACK14 0x00002000
TRACK15 0x00004000
TRACK16 0x00008000
TRACK17 0x00010000 //change to volume up?
TRACK18 0x00020000 //change to volume down?
ALLZEROS 0x00000000 //to reset pins to zero after an activation
//Module variables
//************************************
static uint8_t MyPriority; //the priority of the Audio service
static bool noInterrupts = false; //if true, don't allow tracks to interrupt
the current track
//************************************
//Helper Functions
static void SR_Write3Bytes(uint32_t trackToPlay);
static void SR_Shift1Byte(uint8_t byteToShift);
static void SR_StoreAllBytes(void);
//************************************
/****************************************************************************
Function
InitializeAudio
Parameters
uint8_t Priority = the priority of this module, needed for the posting
service.
Returns
Returns
bool = a bool indicating if the event was successfully posted
to the ES framework (true) or not (false)
Description
Notes
Author
Robert Carrera, 11/13/2016
****************************************************************************/
bool PostAudioService( ES_Event ThisEvent ){
return ES_PostToService(MyPriority, ThisEvent);
}
/****************************************************************************
Function
RunAudio
Parameters
ES_Event ThisEvent - an event pulled off the queue of the
Audio service, that should be responded to
Returns
ES_Event = an event indicating if the run function was
successfully executed (true if ES_NO_EVENT is returned)
Description
The main run function for the Audio module
Notes
Calls SR_Write3Bytes
Author
Robert Carrera, 11/13/2016
****************************************************************************/
ES_Event RunAudio(ES_Event ThisEvent){
ES_Event newEvent; //return value
newEvent.EventType = ES_NO_EVENT; //assume no errors+--+++++++++++++++
+++++++++
uint32_t trackToPlay = 0;
static uint32_t trackToPlay2 = 0; //a second track to play when a
second track timer expires
if(ThisEvent.EventType == ES_OPEN){ //if the curtains have opened
trackToPlay = TRACK1; //play the main theme that plays
throughout the story. It should be several minutes long.
}else if (ThisEvent.EventType == ES_WIND){ //if the wind is blowing
and triggers a wind event
//printf("ES_WIND event received by audio");
trackToPlay = TRACK2; //play a wind sound effect.
//may want to also control volume based on wind speed
} else if (ThisEvent.EventType == ES_LIGHTNING){ //if the wind is
blowing fast enough to trigger a lightning event
//printf("ES_LIGHTNING event received by audio");
trackToPlay = TRACK5; //play a lightning sound effect.
noInterrupts = true; // we don't want the lightning to
be interrupted immediately by ongoing wind events or other lightning events
SR_Write3Bytes(trackToPlay); //we'll send the track to play
directly to circumvent the fact that noInterrupts is true
uint16_t AudioTimeout = 2000; //how long to wait until we kill
track [ms]
ES_Timer_InitTimer(AUDIO_KILLTIMER, AudioTimeout); //set timer
to kill track
} else if (ThisEvent.EventType == ES_PLANTGROWN){ //if a plant has
detected the sun and grows
trackToPlay = TRACK7; //play a growing plant sound effect.
uint16_t AudioTimeout = 1200; //how long to wait until we kill
track [ms]
ES_Timer_InitTimer(AUDIO_KILLTIMER, AudioTimeout); //set timer
to kill track
} else if(ThisEvent.EventType == ES_GROW){ //if the wind scene is over
//printf("ES_GROW event received by audio");
trackToPlay = TRACK3; //play heavy rain.
uint16_t secondTrackTime = 2000; //how long to wait until we
interrupt the first track with the second track [ms]
ES_Timer_InitTimer(AUDIO_SECONDTRACKTIMER, secondTrackTime);
//Initialize the second track to interrupt this one
trackToPlay2 = TRACK6; //transition to a light fading rain,
after second track timer expires
} else if (ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam
== AUDIO_KILLTIMER){ //if a kill audio timer has timed out
SR_Write3Bytes(ALLZEROS); //kill any audio playing
track (zero)
command
Returns
none
Description
Sends the track command, specified as the first 18 bits of the
uint32_t trackToPlay,
to the appropriate Audio shift registers (3 daisy-chained
shift registers). Posts in the appropriate order,
with the 8 MSBs sent to the SRs first, then the next 8 MSBs,
and finally the last 8 MSBs.
Notes
Calls the function SR_Write1Byte
Author
Robert Carrera, 11/13/2016
****************************************************************************/
static void SR_Write3Bytes(uint32_t trackToPlay){
uint32_t shiftFirstByte = 16;
uint32_t shiftSecondByte = 8;
uint8_t firstByteMask = 0xff;
uint32_t firstByteIn;
uint32_t secondByteIn;
uint32_t thirdByteIn;
firstByteIn = trackToPlay >> shiftFirstByte;
secondByteIn = trackToPlay >> shiftSecondByte;
thirdByteIn = (trackToPlay & firstByteMask);
//printf("first byte: %x\n\r", firstByteIn);
//printf("second byte: %x\n\r", secondByteIn);
//printf("third byte: %x\n\r", thirdByteIn);
//Below I should write 3 bytes to the shift register. May want another
helper function below that writes
registers.
Notes
Lowers the REGISTER clock before writing, but does NOT raise the REGISTER
clock. Must
call SR_StoreAllBytes to write the loaded bytes onto the SR
output pins.
Author
Robert Carrera, 11/13/2016
****************************************************************************/
static void SR_Shift1Byte(uint8_t byteToShift){
uint8_t BitCounter; //loop variable, represents number of passed in
bits at end of current loop
uint8_t shiftMSBToLSB = 7; //amount to shift to get MSB to LSB
position
uint8_t LocalRegisterImage = byteToShift; // save a local copy
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) &= REGISTERLO; //turn
register (store) low before shifting in data
uint8_t MSBmask = 0x80; //create a mask to isolate the MSB in our 8bit input NewValue
uint8_t MSB; //will store the MSB, which will be shifted out
// shift out the data while pulsing the serial clock
for(BitCounter = 1; BitCounter<9; BitCounter = BitCounter+1) {// pass
in a bit to the SR for each value of i
// Isolate the MSB of NewValue, put it into the LSB position
and output
MSB = (LocalRegisterImage & MSBmask) >> shiftMSBToLSB; //get
the current MSB
//printf("MSB: %d", MSB);
if (MSB == 0){ //if the current MSB was LO
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) &=
DATALO; //turn Data LO
}
else{ //if the current MSB was HI
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) |=
DATAHI; //turn Data HI
}
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) |= SHIFTHI;
//put SCLK HI
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) &= SHIFTLO;
//put SCLK LO
LocalRegisterImage = LocalRegisterImage<<1; //shift the bits
left so we have a new MSB
}
}
/****************************************************************************
Function
SR_StoreAllBytes
Parameters
none
Returns
none
Description
Raises the REGISTER clock pin to latch any data on the shift
registers.
Notes
//************************************