mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-20 01:58:32 -04:00
Extend FX16 functionality.
This commit is contained in:
parent
46c3268670
commit
269de4b1e7
3 changed files with 155 additions and 91 deletions
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue