Extend FX16 functionality.

This commit is contained in:
Richard Barry 2009-01-31 12:56:33 +00:00
parent 46c3268670
commit 269de4b1e7
3 changed files with 155 additions and 91 deletions

View file

@ -51,14 +51,9 @@
#include "task.h"
#include "semphr.h"
#define diceMIN 1
#define diceMAX 6
#define diceRUN_MIN 600000L
#define diceRUN_MAX 1200000L
#define diceDELAY_BETWEEN_RANDOM_NUMBERS_ms ( 20 )
#define diceRUN_TIME ( 2000 / diceDELAY_BETWEEN_RANDOM_NUMBERS_ms )
#define diceSTATE_STOPPED 0
#define diceSTATE_STARTUP 1
#define diceSTATE_RUNNING 2
#define diceEND_DELAY ( 5000 / portTICK_RATE_MS )
@ -80,61 +75,72 @@ extern volatile unsigned char *pucDisplayOutput[ 2 ];
void vDiceTask( void *pvParameters )
{
char cDiceState = diceSTATE_STOPPED;
unsigned char ucDiceValue, ucIndex;
unsigned long ulDiceRunTime, ulDiceDelay, ulDiceDelayReload;
extern void vToggleFlashTaskSuspendState( void );
unsigned long ulDiceRunTime;
extern void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks );
/* Two instances of this task are created so the task parameter is used
to pass in an index that allows this task to know which file scope variables
it should use. Cast this index into a usable type. */
ucIndex = ( unsigned char ) pvParameters;
/* A binary semaphore is used to signal button push events. Create the
semaphore before it is used. */
vSemaphoreCreateBinary( xSemaphores[ ucIndex ] );
srand( ( unsigned char ) diceRUN_MIN );
/* Make sure the semaphore starts in the wanted state - no button pushes
pending. This call will just clear any button pushes that are latched.
Passing in 0 as the block time means the call will not wait for any further
button pushes. */
prvButtonHit( ucIndex, 0 );
/* Seed the random number generator. */
srand( ( unsigned char ) diceRUN_TIME );
for( ;; )
{
switch( cDiceState )
/* Wait for a button push. This task will enter the Blocked state
(will not run again) until after a button has been pushed. */
prvButtonHit( ucIndex, portMAX_DELAY );
/* The next line will only execute after a button has been pushed -
initialise the variable used to shake the dice. */
ulDiceRunTime = diceRUN_TIME;;
/* Suspend the flash tasks so this task has exclusive access to the
display. */
vSuspendFlashTasks( ucIndex, pdTRUE );
while( ulDiceRunTime > 0 )
{
case diceSTATE_STOPPED:
ulDiceRunTime--;
prvButtonHit( ucIndex, portMAX_DELAY );
ulDiceRunTime = diceRUN_MIN;
cDiceState = diceSTATE_RUNNING;
ulDiceDelay = 1;
ulDiceDelayReload = 1;
cDiceState = diceSTATE_RUNNING;
if( ucIndex == 0 )
{
vToggleFlashTaskSuspendState();
}
/* Generate and display a random number. */
ucDiceValue = rand() % 6 + 1;
dice7SEG_Value( ucIndex ) = ( dice7SEG_Value( ucIndex ) | 0xf7 ) & cDisplaySegments[ ucIndex ][ ucDiceValue ];
break;
/* Block/sleep for a very short time before generating the next
random number. */
vTaskDelay( diceDELAY_BETWEEN_RANDOM_NUMBERS_ms / portTICK_RATE_MS );
}
case diceSTATE_RUNNING:
/* Wait for a short time before resuming (un-suspending) the flash
task. The flash tasks are only restarted if a button is not pushed
during this delay - if a button is pushed then the dice are shaken
again.
ulDiceRunTime--;
ulDiceDelay--;
First...clear any button pushes that are already pending. Again a
block time of zero is used so the function does not wait for any
pushes. */
prvButtonHit( ucIndex, 0 );
if( !ulDiceDelay )
{
ucDiceValue = rand() % 6 + 1;
dice7SEG_Value( ucIndex ) = ( dice7SEG_Value( ucIndex ) | 0xf7 ) & cDisplaySegments[ ucIndex ][ ucDiceValue ];
ulDiceDelayReload = ulDiceDelayReload + 100;
ulDiceDelay = ulDiceDelayReload;
}
if( ulDiceRunTime == 0 )
{
dice7SEG_Value( ucIndex ) = ( dice7SEG_Value( ucIndex ) | 0xf7 ) & cDisplaySegments[ ucIndex ][ rand() % 6 + 1 ];
cDiceState = diceSTATE_STOPPED;
if( ucIndex == 0 )
{
vTaskDelay( diceEND_DELAY );
*pucDisplayOutput[ ucIndex ] = 0xff;
vToggleFlashTaskSuspendState();
}
}
break;
/* Second...peek the semaphore. This task will block/sleep until a
button is pushed again, but because the peek function is used a
button being pushed will unblock the task but remain pending. */
if( xQueuePeek( xSemaphores[ ucIndex ], NULL, diceEND_DELAY ) == pdFALSE )
{
*pucDisplayOutput[ ucIndex ] = 0xff;
vSuspendFlashTasks( ucIndex, pdFALSE );
}
}
}