Extend FX16 functionality.

pull/4/head
Richard Barry 16 years ago
parent 0e91b60a7d
commit 4e1b587af3

@ -47,41 +47,64 @@
licensing and training services.
*/
/*
* Defines the 'dice' tasks as described at the top of main.c
*/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#define diceDELAY_BETWEEN_RANDOM_NUMBERS_ms ( 20 )
#define diceRUN_TIME ( 2000 / diceDELAY_BETWEEN_RANDOM_NUMBERS_ms )
#define diceEND_DELAY ( 5000 / portTICK_RATE_MS )
/* Delays used within the dice functionality. All delays are defined in milliseconds. */
#define diceDELAY_BETWEEN_RANDOM_NUMBERS_ms ( 20 / portTICK_RATE_MS )
#define diceSHAKE_TIME ( ( 2000 / portTICK_RATE_MS ) / diceDELAY_BETWEEN_RANDOM_NUMBERS_ms )
#define diceSHORT_PAUSE_BEFORE_SHAKE ( 1000 / portTICK_RATE_MS )
#define diceDELAY_WHILE_DISPLAYING_RESULT ( 5000 / portTICK_RATE_MS )
#define dice7SEG_Value( x ) *( pucDisplayOutput[ x ] )
/* Macro to access the display ports. */
#define dice7SEG_Value( x ) ( *( pucDisplayOutput[ x ] ) )
/* Checks the semaphore use to communicate button push events. A block time
can be specified - this is the time to wait for a button push to occur should
one have not already occurred. */
#define prvButtonHit( ucIndex, xTicksToWait ) xSemaphoreTake( xSemaphores[ ucIndex ], xTicksToWait )
/* Defines the outputs required for each digit on the display. */
static const char cDisplaySegments[ 2 ][ 11 ] =
{
{ 0x48, 0xeb, 0x8c, 0x89, 0x2b, 0x19, 0x18, 0xcb, 0x08, 0x09, 0xf7 },
{ 0xa0, 0xf3, 0xc4, 0xc1, 0x93, 0x89, 0x88, 0xe3, 0x80, 0x81, 0x7f }
{ 0x48, 0xeb, 0x8c, 0x89, 0x2b, 0x19, 0x18, 0xcb, 0x08, 0x09, 0xf7 }, /* Left display. */
{ 0xa0, 0xf3, 0xc4, 0xc1, 0x93, 0x89, 0x88, 0xe3, 0x80, 0x81, 0x7f } /* Right display. */
};
/* The semaphores used to communicate button push events between the button
input interrupt handlers and the dice tasks. Two dice tasks are created so two
semaphores are required. */
static xSemaphoreHandle xSemaphores[ 2 ] = { 0 };
/* Defines the ports used to write to the display. This variable is defined in
partest.c, which contains the LED set/clear/toggle functions. */
extern volatile unsigned char *pucDisplayOutput[ 2 ];
/*-----------------------------------------------------------*/
/*
* Defines the 'dice' tasks as described at the top of main.c
*/
void vDiceTask( void *pvParameters )
{
unsigned char ucDiceValue, ucIndex;
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. */
to pass in a constant that indicates whether this task is controlling
the left side or right side display. The constant is used as an index
into the arrays defined at file scope within this file. */
ucIndex = ( unsigned char ) pvParameters;
/* A binary semaphore is used to signal button push events. Create the
@ -91,12 +114,18 @@ extern void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks );
/* 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. */
button pushes but instead return immediately. */
prvButtonHit( ucIndex, 0 );
/* Seed the random number generator. */
srand( ( unsigned char ) diceRUN_TIME );
srand( ( unsigned char ) diceSHAKE_TIME );
/* Start the task proper. A loop will be performed each time a button is
pushed. The task will remain in the blocked state (sleeping) until a
button is pushed. */
for( ;; )
{
/* Wait for a button push. This task will enter the Blocked state
@ -104,13 +133,21 @@ extern void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks );
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;;
initialise the variable used to control the time the dice is shaken
for. */
ulDiceRunTime = diceSHAKE_TIME;
/* Suspend the flash tasks so this task has exclusive access to the
display. */
vSuspendFlashTasks( ucIndex, pdTRUE );
/* Clear the display and pause for a short time, before starting to
shake. */
*pucDisplayOutput[ ucIndex ] = 0xff;
vTaskDelay( diceSHORT_PAUSE_BEFORE_SHAKE );
/* Keep generating and displaying random numbers until the shake time
expires. */
while( ulDiceRunTime > 0 )
{
ulDiceRunTime--;
@ -121,31 +158,33 @@ extern void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks );
/* Block/sleep for a very short time before generating the next
random number. */
vTaskDelay( diceDELAY_BETWEEN_RANDOM_NUMBERS_ms / portTICK_RATE_MS );
vTaskDelay( diceDELAY_BETWEEN_RANDOM_NUMBERS_ms );
}
/* 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.
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. */
/* Clear any button pushes that are pending because a button bounced, or
was pressed while the dice were shaking. Again a block time of zero is
used so the function does not wait for any pushes but instead returns
immediately. */
prvButtonHit( ucIndex, 0 );
/* 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 );
}
/* Delay for a short while to display the dice shake result. Use a queue
peek here instead of a vTaskDelay() allows the delay to be interrupted by
a button push. If a button is pressed xQueuePeek() will return but the
button push will remain pending to be read again at the top of this for
loop. It is safe to uses a queue function on a semaphore handle as
semaphores are implemented as macros that uses queues, so the two are
basically the same thing. */
xQueuePeek( xSemaphores[ ucIndex ], NULL, diceDELAY_WHILE_DISPLAYING_RESULT );
/* Clear the display then resume the tasks or co-routines that were using
the segments of the display. */
}
}
/*-----------------------------------------------------------*/
/* Handler for the SW2 button push interrupt. */
__interrupt void vExternalInt8Handler( void )
{
short sHigherPriorityTaskWoken = pdFALSE;
@ -153,8 +192,18 @@ short sHigherPriorityTaskWoken = pdFALSE;
/* Reset the interrupt. */
EIRR1_ER8 = 0;
xSemaphoreGiveFromISR( xSemaphores[ 0 ], &sHigherPriorityTaskWoken );
/* Check the semaphore has been created before attempting to use it. */
if( xSemaphores[ configLEFT_DISPLAY ] != NULL )
{
/* Send a message via the semaphore to the dice task that controls the
left side display. This will unblock the task if it is blocked waiting
for a button push. */
xSemaphoreGiveFromISR( xSemaphores[ configLEFT_DISPLAY ], &sHigherPriorityTaskWoken );
}
/* If sending the semaphore unblocked a task, and the unblocked task has a
priority that is higher than the currently running task, then force a context
switch. */
if( sHigherPriorityTaskWoken != pdFALSE )
{
portYIELD_FROM_ISR();
@ -162,6 +211,7 @@ short sHigherPriorityTaskWoken = pdFALSE;
}
/*-----------------------------------------------------------*/
/* As per vExternalInt8Handler(), but for SW3 and the right side display. */
__interrupt void vExternalInt9Handler( void )
{
short sHigherPriorityTaskWoken = pdFALSE;
@ -169,7 +219,10 @@ short sHigherPriorityTaskWoken = pdFALSE;
/* Reset the interrupt. */
EIRR1_ER9 = 0;
xSemaphoreGiveFromISR( xSemaphores[ 1 ], &sHigherPriorityTaskWoken );
if( xSemaphores[ configRIGHT_DISPLAY ] != NULL )
{
xSemaphoreGiveFromISR( xSemaphores[ configRIGHT_DISPLAY ], &sHigherPriorityTaskWoken );
}
if( sHigherPriorityTaskWoken != pdFALSE )
{

@ -79,39 +79,45 @@ the ComTest tasks will be included in place of the trace task. */
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 180 ) /* This can be greatly reduced when using the small or medium memory model. */
#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 56000000 ) /* Clock setup from start.asm in the demo application. */
#define configCLKP1_CLOCK_HZ ( ( unsigned portLONG ) 56000000 ) /* Clock setup from start.asm in the demo application. */
#define configTICK_RATE_HZ ( (portTickType) 1000 )
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 6 )
#define configTOTAL_HEAP_SIZE ( (size_t) (5000) )
#define configMAX_TASK_NAME_LEN ( 20 )
#define configUSE_16_BIT_TICKS 1
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configUSE_TRACE_FACILITY 1
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 180 ) /* This can be greatly reduced when using the small or medium memory model. */
#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 56000000 ) /* Clock setup from start.asm in the demo application. */
#define configCLKP1_CLOCK_HZ ( ( unsigned portLONG ) 56000000 ) /* Clock setup from start.asm in the demo application. */
#define configTICK_RATE_HZ ( (portTickType) 1000 )
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 6 )
#define configTOTAL_HEAP_SIZE ( (size_t) (5000) )
#define configMAX_TASK_NAME_LEN ( 20 )
#define configUSE_16_BIT_TICKS 1
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configUSE_TRACE_FACILITY 0
#define configCHECK_FOR_STACK_OVERFLOW 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 1
#define configMAX_CO_ROUTINE_PRIORITIES ( 4 )
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskPrioritySet 0
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vResumeFromISR 1
#define INCLUDE_vResumeFromISR 0
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_xTaskGetSchedulerState 0
#define INCLUDE_xTaskGetCurrentTaskHandle 0
#define configKERNEL_INTERRUPT_PRIORITY 6
/* Passed into the Dice tasks to let then know if they are controlling the
display on the left side or the right side. */
#define configLEFT_DISPLAY 0
#define configRIGHT_DISPLAY 1
#endif /* FREERTOS_CONFIG_H */

@ -18,5 +18,5 @@
-a "C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\croutine.obj"
-a "C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\DiceTask.obj"
-a "C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\ParTest.obj"
-a "C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\flash.obj"
-a "C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\SegmentToggleTasks.obj"

@ -36,5 +36,5 @@
"C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\croutine.obj"
"C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\DiceTask.obj"
"C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\ParTest.obj"
"C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\flash.obj"
"C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\SegmentToggleTasks.obj"

@ -29,10 +29,10 @@ F8=0 c ..\..\Source\queue.c
F9=0 c ..\..\Source\tasks.c
F10=0 f Demo Source
F11=0 c DiceTask.c
F12=0 c flash.c
F13=0 c main.c
F14=0 a mb96356rs.asm
F15=0 c ParTest\ParTest.c
F12=0 c main.c
F13=0 a mb96356rs.asm
F14=0 c ParTest\ParTest.c
F15=0 c SegmentToggleTasks.c
F16=0 a START.ASM
F17=0 c vectors.c
@ -146,7 +146,7 @@ F12-7=- ..\..\Source\portable\Softune\MB96340\portmacro.h
F12-8=- ..\..\Source\Include\task.h
F12-9=- ..\..\Source\Include\list.h
F12-10=- ..\..\Source\Include\croutine.h
F13=9 c 1 DiceTask.c
F13=11 c 1 DiceTask.c
F13-1=- ..\..\Source\Include\FreeRTOS.h
F13-2=- ..\..\..\..\..\..\devtools\Softune\LIB\907\INCLUDE\stddef.h
F13-3=- ..\..\Source\Include\projdefs.h
@ -156,6 +156,8 @@ F13-6=- ..\..\Source\Include\portable.h
F13-7=- ..\..\Source\portable\Softune\MB96340\portmacro.h
F13-8=- ..\..\Source\Include\task.h
F13-9=- ..\..\Source\Include\list.h
F13-10=- ..\..\Source\Include\semphr.h
F13-11=- ..\..\Source\Include\queue.h
F14=10 c 1 ParTest\ParTest.c
F14-1=- ..\..\Source\Include\FreeRTOS.h
F14-2=- ..\..\..\..\..\..\devtools\Softune\LIB\907\INCLUDE\stddef.h
@ -167,19 +169,7 @@ F14-7=- ..\..\Source\portable\Softune\MB96340\portmacro.h
F14-8=- ..\..\Source\Include\task.h
F14-9=- ..\..\Source\Include\list.h
F14-10=- ..\Common\Include\ParTest.h
F15=12 c 1 flash.c
F15-1=- ..\..\..\..\..\..\devtools\Softune\LIB\907\INCLUDE\stdlib.h
F15-2=- ..\..\..\..\..\..\devtools\Softune\LIB\907\INCLUDE\stddef.h
F15-3=- ..\..\Source\Include\FreeRTOS.h
F15-4=- ..\..\Source\Include\projdefs.h
F15-5=- FreeRTOSConfig.h
F15-6=- mb96356rs.h
F15-7=- ..\..\Source\Include\portable.h
F15-8=- ..\..\Source\portable\Softune\MB96340\portmacro.h
F15-9=- ..\..\Source\Include\task.h
F15-10=- ..\..\Source\Include\list.h
F15-11=- ..\Common\Include\ParTest.h
F15-12=- ..\Common\Include\Flash.h
F15=0 c 1 SegmentToggleTasks.c
[BUILDMODE-Debug]
kernel=0

@ -18,6 +18,5 @@ AutoLoad=1
WSP=C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\
[EditState]
STATE-1=vectors.c:40
Count=1
Count=0

@ -47,6 +47,57 @@
licensing and training services.
*/
/*****
*
* See http://www.freertos.org/Documentation/FreeRTOS-documentation-and-book.html
* for an introductory guide to using real time kernels, and FreeRTOS in
* particular.
*
*****
*
* The DICE-KIT-16FX has two 7 segment displays and two buttons that can
* generate interrupts. This example uses this IO as follows:
*
*
* - Left 7 segment display -
*
* 7 'flash' tasks are created, each of which toggles a single segment of the
* left display. Each task executes at a fixed frequency, with a different
* frequency being used by each task.
*
* When button SW2 is pressed an interrupt is generated that wakes up a 'dice'
* task. The dice task suspends the 7 tasks that are accessing the left display
* before simulating a dice being thrown by generating a random number between
* 1 and 6. After the number has been generated the task sleeps for 5 seconds,
* if SW2 is pressed again within the 5 seconds another random number is
* generated, if SW2 is not pressed within the 5 seconds then the 7 tasks are
* un-suspended and will once again toggle the segments of the left hand display.
*
*
* - Right 7 segment display -
*
* Control of the right side 7 segment display is very similar to that of the
* left, except co-routines are used to toggle the segments instead of tasks,
* and button SW3 is used instead of SW2.
*
*
* - Notes -
*
* Only one dice task is actually defined. Two instances of this single
* definition are created, the first to simulate a dice being thrown on the left
* display, and the other to simulate a dice being thrown on the right display.
* The task parameter is used to let the dice tasks know which display to
* control.
*
* Both dice tasks and the flash tasks operate completely independently under
* the control of FreeRTOS. 11 tasks and 7 co-routines are created in total,
* including the idle task.
*
* The co-routines all execute within a single low priority task.
*
*****/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "Task.h"
@ -56,34 +107,45 @@
#include "ParTest.h"
#include "Flash.h"
/* The priority at which the dice task execute. */
#define mainDICE_PRIORITY ( tskIDLE_PRIORITY + 2 )
/*
* Sets up the MCU IO for the 7 segment displays and the button inputs.
*/
static void prvSetupHardware( void );
#define mainDISPLAY_1 0
#define mainDISPLAY_2 1
/*
* The function that creates the flash tasks and co-routines (the tasks and
* co-routines that toggle the 7 segment display segments.
*/
extern vCreateFlashTasksAndCoRoutines( void );
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/*-----------------------------------------------------------*/
void main( void )
{
/* Setup the MCU IO. */
prvSetupHardware();
vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
/* Create the tasks and co-routines that toggle the display segments. */
vCreateFlashTasksAndCoRoutines();
/* Create a 'dice' task to control the left hand display. */
xTaskCreate( vDiceTask, ( signed char * ) "Dice1", configMINIMAL_STACK_SIZE, ( void * ) configLEFT_DISPLAY, mainDICE_PRIORITY, NULL );
xTaskCreate( vDiceTask, ( signed char * ) "Dice1", configMINIMAL_STACK_SIZE, ( void * ) mainDISPLAY_1, tskIDLE_PRIORITY, NULL );
xTaskCreate( vDiceTask, ( signed char * ) "Dice2", configMINIMAL_STACK_SIZE, ( void * ) mainDISPLAY_2, tskIDLE_PRIORITY, NULL );
/* Create a 'dice' task to control the right hand display. */
xTaskCreate( vDiceTask, ( signed char * ) "Dice2", configMINIMAL_STACK_SIZE, ( void * ) configRIGHT_DISPLAY, mainDICE_PRIORITY, NULL );
/* Start the scheduler running. */
vTaskStartScheduler();
/* If this loop is executed then there was insufficient heap memory for the
idle task to be created - causing vTaskStartScheduler() to return. */
while( 1 );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
/* Setup interrupt hardware - interrupts are kept disabled for now to
@ -136,7 +198,7 @@ static void prvSetupHardware( void )
ELVRL1_LB9 = 1;
ELVRL1_LA9 = 1;
/* Reset and enable the interrput request. */
/* Reset and enable the interrupt request. */
EIRR1_ER9 = 0;
ENIR1_EN9 = 1;
}

@ -60,7 +60,7 @@ $2
$other
-Xset_rora
$time
1233330876
1233411019
$end
$3
-dt s,d,r,a
@ -70,7 +70,7 @@ $3
-Xdof
$other
$time
1233330876
1233411019
$end
$4
-Xdof

Loading…
Cancel
Save