/* =============================================================================== Name : main.c Author : Version : Copyright : Copyright (C) Description : main definition =============================================================================== */ /* Kernel includes. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" /* SSP includes */ #include "ssp.h" /* Priorities at which the tasks are created. */ #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SSP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define configSND_TASK_STACK_SIZE ( ( unsigned short ) 32 ) #define configRCV_TASK_STACK_SIZE ( ( unsigned short ) 32 ) #define configSPI_LOOP_TASK_STACK_SIZE ( ( unsigned short ) 32 ) /* The bit of port 0 that the LPCXpresso LPC13xx LED is connected. */ #define mainLED_BIT ( 7 ) /* The rate at which data is sent to the queue, specified in milliseconds. */ #define mainQUEUE_SEND_FREQUENCY_MS ( 500 / portTICK_RATE_MS ) /* The number of items the queue can hold. This is 1 as the receive task will remove items as they are added, meaning the send task should always find the queue empty. */ #define mainQUEUE_LENGTH ( 1 ) /* * The tasks. */ static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueSendTask( void *pvParameters ); static void prvLoopBackTestTask( void *pvParameters ); /* * Simple function to toggle the LED on the LPCXpresso LPC13xx board. */ static void prvToggleLED( void ); /* The queue used by both tasks. */ static xQueueHandle xQueue = NULL; /* SSP buffer */ uint8_t src_addr[SSP_BUFSIZE]; uint8_t dest_addr[SSP_BUFSIZE]; /*-----------------------------------------------------------*/ int main(void) { /* Set the LPCXpresso LPC13xx LED port to output. */ LPC_GPIO0->DIR |= ( 0x1 << mainLED_BIT ); /* Create the queue. */ xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); if( xQueue != NULL ) { /* Start the two tasks as described in the accompanying application note. */ xTaskCreate( prvQueueReceiveTask, ( signed char * ) "Rx", configRCV_TASK_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configSND_TASK_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvLoopBackTestTask, ( signed char * ) "LoopBckTst", configSPI_LOOP_TASK_STACK_SIZE, NULL, mainQUEUE_SSP_TASK_PRIORITY, NULL ); /* Start the tasks running. */ vTaskStartScheduler(); } /* If all is well we will never reach here as the scheduler will now be running. If we do reach here then it is likely that there was insufficient heap available for the idle task to be created. */ for( ;; ); /* // Enter an infinite loop, just incrementing a counter volatile static int i = 0 ; while(1) { i++ ; } */ return 0 ; } /* * ------------------------------------------------------------- */ static void prvQueueSendTask( void *pvParameters ) { portTickType xNextWakeTime; unsigned long ulValueToSend = 100UL; /* Initialise xNextWakeTime - this only needs to be done once. */ xNextWakeTime = xTaskGetTickCount(); for( ;; ) { /* Place this task in the blocked state until it is time to run again. The block state is specified in ticks, the constant used converts ticks to ms. While in the blocked state this task will not consume any CPU time. */ vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); /* Send to the queue - causing the queue receive task to flash its LED. 0 is used as the block time so the sending operation will not block - it shouldn't need to block as the queue should always be empty at this point in the code. */ if(ulValueToSend == 200UL) ulValueToSend = 100UL; else ulValueToSend = 200UL; xQueueSend( xQueue, &ulValueToSend, 0 ); } } /*-----------------------------------------------------------*/ static void prvQueueReceiveTask( void *pvParameters ) { unsigned long ulReceivedValue; for( ;; ) { /* Wait until something arrives in the queue - this task will block indefinitely provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. */ xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); /* To get here something must have been received from the queue, but is it the expected value? If it is, toggle the LED. */ if( ulReceivedValue == 100UL ) { prvToggleLED(); } } } /*-----------------------------------------------------------*/ static void prvLoopBackTestTask( void *pvParameters ) { uint8_t u; unsigned long ulReceivedValue; portTickType xNextWakeTime; xNextWakeTime = xTaskGetTickCount(); u = 3; SSPInit(); for(;;) { xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); if(ulReceivedValue == 200UL) { prvToggleLED(); vTaskDelayUntil( &xNextWakeTime, (500 / portTICK_RATE_MS) ); prvToggleLED(); vTaskDelayUntil( &xNextWakeTime, (500 / portTICK_RATE_MS) ); prvToggleLED(); } vTaskDelayUntil( &xNextWakeTime, (100 / portTICK_RATE_MS) ); u++; LoopbackTest(); } } /*-----------------------------------------------------------*/ static void prvToggleLED( void ) { /* This function is only called from one task so does not have to be reentrant, so the static qualifier is acceptable. */ static unsigned long ulLEDState = 1; /* Turn the LED off if it was on, and on if it was off. */ ulLEDState = !ulLEDState; LPC_GPIO0->MASKED_ACCESS[ ( 1 << mainLED_BIT) ] = ( ulLEDState << mainLED_BIT ); } /*-----------------------------------------------------------*/