You are on page 1of 7

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

Module
SRPWM.c
Description
This service keeps track of each shift register output and its PWM signal
Notes
History
When
Who
What/Why
-------------- ---------11/12/16 02:03 rdb
created it for ME218A project
****************************************************************************/
#include "SRPWM.h"
/*---------------------------- Module Variables ---------------------------*/
// with the introduction of Gen2, we need a module level Priority variable
static uint8_t MyPriority;
// Array holding information for the shift register "strings" we are using for
PWMs
static uint8_t SRStrings[] = { SRPWM_SR_STRING_0, SRPWM_SR_STRING_1,
SRPWM_SR_STRING_2 }; // up to 2 strings in current implementation
// Array holding the current pulse width value of every output pin on our shift
registers
static uint8_t CurrPulseWidth[] = { 0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,

0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0 }; // Array to keep track of the pulse
width in each LED
// Delay time constraining our PWM frequency
static uint16_t DelayTime = 200;
/****************************************************************************
Function
Init_SRPWMService
Parameters
uint8_t Priotity the priority of this service
Returns

bool whether initialization was successful

Description

Initializes SRPWM module

Author
R. D. Born 11/29/16
****************************************************************************/
bool Init_SRPWMService(uint8_t Priority)
{
printf("Initializing SRPWM\n\r");
// Initialize shift register hardware
SRPWM_HWInit();
// Set priority of this service
MyPriority = Priority;
// Initialize short timer and start it off counting
ES_ShortTimerInit(MyPriority, SHORT_TIMER_UNUSED );
ES_ShortTimerStart(TIMER_A, DelayTime);

// Return success
return true;

bool Post_SRPWMService(ES_Event ThisEvent)


{
return ES_PostToService( MyPriority, ThisEvent);
}
/****************************************************************************
Function
Run_SRPWMService
Parameters

ES_Event ThisEvent the event we need to handle


Returns

ES_Event the returned event (default: ES_NO_EVENT)

Description
Handles all the events posted to the SRPWM queue
Author
R. D. Born 11/29/16
****************************************************************************/
ES_Event Run_SRPWMService(ES_Event ThisEvent)
{
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
static int PW_ctr = 0;
uint8_t val = 0;
uint8_t PW_idx = 0;
uint8_t NewPW = 0;
switch(ThisEvent.EventType)
{
case ES_SHORT_TIMEOUT:
// DO FOR EACH shift register string
for(uint8_t SRStr = 0; SRStr < NUM_SR_STRINGS_PWM; SRStr++)
{
// DO FOR EACH shift register in this string
for(uint8_t ShiftReg = NUM_SR_PER_STRING; ShiftReg > 0 ;
ShiftReg--)
{
// DO FOR EACH output in this shift register
for(uint8_t output = NUM_OUTPUTS_PER_SR; output >
0 ; output--)
{
// IF we've been high for the whole pulse
width
//
Pull output low
// ELSE
//
Pull output high

CurrSRString
- 1)

*
*

// Current index calculations...


//
CurrSRString
= SRStr
//
CurrSR
=
NUM_SR_PER_STRING
+
(NUM_SR_PER_STR - ShiftReg
//

CurrOutput
+

//

idx

NUM_OUTPUTS_PER_SR
output

= CurrSR

CurrOutput

uint8_t idx = ((SRStr*NUM_SR_PER_STRING) +


(ShiftReg - 1))*NUM_OUTPUTS_PER_SR + (output - 1);
// Set value of current output as
appropriate (HIGH or LOW)

if(PW_ctr >= CurrPulseWidth[idx])


{
val &= ~(1 << (output - 1));
}
else

{
}

val |= (1 << (output - 1));

// Write to shift register


SR_Write(SRStrings[SRStr], val);
// Reset value to be written next time
val = 0;
}

// Post to shift register string


SR_Post(SRStrings[SRStr]);

// Increment pulse width counter modulo MAX_PULSE_WIDTH


PW_ctr = (PW_ctr + 1)%MAX_PULSE_WIDTH;
// Start the timer
ES_ShortTimerStart(TIMER_A, DelayTime);
break;
case CHANGE_PULSEWIDTH:
// Extract PW_idx and NewPW from ThisEvent.EventParam
PW_idx = ExtractIdx(ThisEvent.EventParam);
NewPW = ExtractPW(ThisEvent.EventParam);
// Make sure PW_idx and NewPW are valid
if(PW_idx >
(NUM_SR_STRINGS_PWM*NUM_SR_PER_STRING*NUM_OUTPUTS_PER_SR))
{
// Do nothing
printf("WARNING: requested PWM is out of range, nothing
will be changed\n\r");
break;
}
// IF NewPW width is greater than maximum allowed pulse width
if(NewPW > MAX_PULSE_WIDTH)
{
// Set the new pulse with to the max
printf("WARNING: New pulse width is larger than the
maximum allowed, it will be set to the maximum value of %d\n\r",
MAX_PULSE_WIDTH);
NewPW = MAX_PULSE_WIDTH;
}
SR_SetPWM(NewPW, PW_idx);
break;
default:
break;
}
return ReturnEvent;

/****************************************************************************
Function
SR_SetPWM
Parameters
uint8_t PulseWidth new pulse width to set OutputPin to
uint8_t OutputPin pin whose pulse width we are changing
Returns

Description

Changes the pulse width (i.e. duty cycle) on OutputPin

Author
R. D. Born 11/29/16
****************************************************************************/
void SR_SetPWM(uint8_t PulseWidth, uint8_t OutputPin)
{
// Set the current pulse width of OutputPin to PulseWidth
CurrPulseWidth[OutputPin] = PulseWidth;
}
/****************************************************************************
Function
SRPWM_HWInit
Parameters
Returns
Description
Initializes hardware associated with SRPWM module
Author
R. D. Born 11/29/16
****************************************************************************/
void SRPWM_HWInit(void)
{
SR_Init();
}
/****************************************************************************
Function
GetPW
Parameters
uint8_t PW_idx the index of the pin whose pulse width we want
Returns

uint8_t the pulse width at the requested pin

Description
Polls the requested pin for its pulse width (i.e. duty cycle)
Author
R. D. Born 11/29/16
****************************************************************************/
uint8_t GetPW(uint8_t PW_idx)
{
// IF PW_idx is not valid
if(PW_idx > (NUM_SR_STRINGS_PWM*NUM_SR_PER_STRING*NUM_OUTPUTS_PER_SR))
{
// Do nothing
printf("WARNING: requested PWM is out of range, cannot retrieve a
value, returning 0\n\r");
return 0;
}
// Return the current pulse width at PW_idx
return CurrPulseWidth[PW_idx];
}
/****************************************************************************
Function

Encode_Idx_PW
Parameters
parameter

uint8_t PW pulse width, to be encoded for event parameter


uint8_t PW_idx index of output pin, to be encoded for event

Returns
uint16_t encoded event parameter
Description

Encodes the pulse width we wish to set a certain output pin to so

that

both the pulse width and the output pin's index can be included as
information with a single event.

Author
R. D. Born 11/29/16
****************************************************************************/
uint16_t Encode_Idx_PW(uint8_t PW, uint8_t PW_idx)
{
// Shift PW_idx left 8 bits
return (PW | (PW_idx << 8));
}
/****************************************************************************
Function
ExtractIdx
Parameters

uint16_t Param event parameter from which to extract the output pin

index
Returns

uint8_t the output pin index encoded in Param

Description
Decodes an event parameter to retrieve the index of the output pin

whose

pulse width we would like to change.


Author
R. D. Born 11/29/16
****************************************************************************/
static uint8_t ExtractIdx(uint16_t Param)
{
// Return the 8 most significant bits of Param
uint8_t ReturnVal = (Param >> 8) & 0xff;
return ReturnVal;
}
/****************************************************************************
Function
ExtractPW
Parameters
uint16_t Param event parameter from which to extract the new pulse

width

Returns
uint8_t the pulse width encoded in Param
Description

Decodes an event parameter to retrieve the new pulse width we would


like to change an output pin to.
Author
R. D. Born 11/29/16
****************************************************************************/
static uint8_t ExtractPW(uint16_t Param)
{
// Return the 8 least significant bits of Param
uint8_t ReturnVal = (Param >> 0) & 0xff;
return ReturnVal;
}