/***************************************************************************
Download.c
****************************************************************************/
#include "Download.h"
/*--------------------------
Module Constants -----------------------------*/
const static char diskWait_ms
= 2; //max switch bounce time
const static int downloadWait_ms = 750; //wait
time per LED for DL progress
const static int blinkTime_ms = 250; //blink
time (on and off) while LEDS are blinking
/*-------------------------
Module Definitions ----------------------------*/
typedef enum { NOT_STARTED,
RUNNING,
STOPPED,
COMPLETED,
BLINKING
} DL_STATE_t; //internal state representation
/*--------------------------
Module Variables -----------------------------*/
static char waitingOnDiskEject; //Used to ensure disk is reinserted before
download begins
static DL_STATE_t myState; //Internal
state
static char diskIn; //Disk status (in or out)
static char downloadProgress; //Number between 0 and 8
static char blinkStatus; //When in blink mode, indicates if the
LEDs are on or off
static unsigned int lastUpdateDLTime; //Used
to update download progress
static unsigned int lastDiskTime; //Used
to update disk status (debounce the switch)
static unsigned int lastBlinkTime; //Used to update blinking of the LEDs when in blink mode
/*--------------------------
Module Functions -----------------------------*/
static void advanceDisplay(void); //Advances LED progress bar to indicate
download status
static void pulseShift(void); //Pulses the shift line for the
shift register
static void checkDiskStatus(void);
//Reads the disk switch with debouncing software
/*----------------------------
Module Code --------------------------------*/
void initDownload(void) {
unsigned int myTime;
myState
= NOT_STARTED; //Initialize
internal download state
diskIn
= !(PTM & BIT0HI); //Read disk status
if (diskIn) //If
disk starts in, can’t start download until it
waitingOnDiskEject
= 1;
//is ejected and then reinserted
else
waitingOnDiskEject
= 0;
downloadProgress
= 0; //Reset download progress
variable
blinkStatus
= 0; //When blinking, the LEDs will first turn on
myTime
= TMRS12_GetTime(); //Update all the
timer variables with the current time
lastUpdateDLTime
= myTime; //this
needs to be done to make the timing algorithms work
lastDiskTime
= myTime;
lastBlinkTime
= myTime;
clearDownloadDisplay(); //turn off
all LEDs
}
void resetDownload(void) {
initDownload(); //reset
download is just a wrapper for initDownload
}
char isDiskIn(void) {
checkDiskStatus(); //read disk status with debouncing
software
return (diskIn);
}
void clearDownloadDisplay(void)
{
int
i;
//clear out shift register
with all zeros
for (i=0; i<10; i++)
{
PTAD = PTAD & BIT6LO;
pulseShift();
}
}
DOWNLOAD_EVENT_t checkDownloadEvents(void) {
unsigned int myTime = TMRS12_GetTime();
checkDiskStatus(); //read disk
status with debouncing software
//state machine using internal state
switch(myState) {
case NOT_STARTED:
if(diskIn) {
if (!waitingOnDiskEject) {
myState = RUNNING;
downloadProgress = 1;
advanceDisplay();
lastUpdateDLTime = myTime;
return
DOWNLOAD_STARTED_EVENT;
}
else {
blinkDownloadLEDs();
return
DOWNLOAD_NO_EVENT;
}
}
else {
waitingOnDiskEject
= 0;
blinkDownloadLEDs();
return
DOWNLOAD_NO_EVENT;
}
break;
case RUNNING:
if(diskIn) {
//check if enough time has passed to
progress progress bar (LEDs)
if((myTime - lastUpdateDLTime) > downloadWait_ms) {
lastUpdateDLTime
= myTime;
downloadProgress++;
advanceDisplay();
//if all 8 LEDs are already lit up, download
is complete
if(downloadProgress > 8) {
myState = COMPLETED;
return
DOWNLOAD_COMPLETE_EVENT;
}
}
}
else {
//if disk isn’t in, download cannot progress
myState
= STOPPED;
return
DOWNLOAD_STOPPED_EVENT;
}
break;
case STOPPED:
if(diskIn) {
lastUpdateDLTime
= myTime;
myState
= RUNNING;
return
DOWNLOAD_STARTED_EVENT;
}
break;
case COMPLETED:
//once the download is complete, just
blink LEDs
blinkDownloadLEDs();
return
DOWNLOAD_COMPLETE_EVENT;
break;
}
return
DOWNLOAD_NO_EVENT;
}
void blinkDownloadLEDs(void)
{
char i = 0;
unsigned int myTime = TMRS12_GetTime();
//check if enough time has passed for the LEDs to be blinked (switch from on
to off or vise versa)
if ((myTime - lastBlinkTime) > blinkTime_ms) {
lastBlinkTime
= myTime;
//fill shift register with zeros or ones
for (i=0; i<8; i++)
{
if (blinkStatus)
PTAD = PTAD & BIT6LO;
else
PTAD = PTAD | BIT6HI;
pulseShift();
}
blinkStatus
= !blinkStatus;
}
}
static void checkDiskStatus(void)
{
unsigned int myTime = TMRS12_GetTime();
//update diskIn if diskWait_ms worth of time has passed (debounce)
if ((myTime - lastDiskTime) > diskWait_ms) {
diskIn
= !(PTM & BIT0HI);
lastDiskTime
= myTime;
}
}
static void advanceDisplay(void)
{
//load a 1 into the shift register (turns on
the next LED)
PTAD = PTAD | BIT6HI;
pulseShift();
}
static void pulseShift(void) {
int
j=0;
PTAD = PTAD & BIT7LO;
for (j=0; j<100;
j++) {
}
PTAD = PTAD | BIT7HI;
}