summaryrefslogtreecommitdiff
path: root/Demo/CORTEX_LM3S811_GCC/main.c
diff options
context:
space:
mode:
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2007-02-08 06:34:35 +0000
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2007-02-08 06:34:35 +0000
commit310b02c8307c5a8434b0bd4f2b8cc11277ee56ea (patch)
treeb9d04fbb0e731b985237b7b5a57f7ae5aa08515c /Demo/CORTEX_LM3S811_GCC/main.c
parent6176f5b3e93ef292085fc144414222dd74db7e5d (diff)
downloadfreertos-310b02c8307c5a8434b0bd4f2b8cc11277ee56ea.tar.gz
freertos-310b02c8307c5a8434b0bd4f2b8cc11277ee56ea.tar.bz2
freertos-310b02c8307c5a8434b0bd4f2b8cc11277ee56ea.tar.xz
GCC demo for the LM3S811 eval board from Luminary Micro.
git-svn-id: https://freertos.svn.sourceforge.net/svnroot/freertos/trunk@63 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
Diffstat (limited to 'Demo/CORTEX_LM3S811_GCC/main.c')
-rw-r--r--Demo/CORTEX_LM3S811_GCC/main.c362
1 files changed, 362 insertions, 0 deletions
diff --git a/Demo/CORTEX_LM3S811_GCC/main.c b/Demo/CORTEX_LM3S811_GCC/main.c
new file mode 100644
index 00000000..44b65eaa
--- /dev/null
+++ b/Demo/CORTEX_LM3S811_GCC/main.c
@@ -0,0 +1,362 @@
+/*
+ FreeRTOS.org V4.1.3 - Copyright (C) 2003-2006 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+ ***************************************************************************
+*/
+
+
+/*
+ * This project contains an application demonstrating the use of the
+ * FreeRTOS.org mini real time scheduler on the Luminary Micro LM3S811 Eval
+ * board. See http://www.FreeRTOS.org for more information.
+ *
+ * main() simply sets up the hardware, creates all the demo application tasks,
+ * then starts the scheduler. http://www.freertos.org/a00102.html provides
+ * more information on the standard demo tasks.
+ *
+ * In addition to a subset of the standard demo application tasks, main.c also
+ * defines the following tasks:
+ *
+ * + A 'Print' task. The print task is the only task permitted to access the
+ * LCD - thus ensuring mutual exclusion and consistent access to the resource.
+ * Other tasks do not access the LCD directly, but instead send the text they
+ * wish to display to the print task. The print task spends most of its time
+ * blocked - only waking when a message is queued for display.
+ *
+ * + A 'Button handler' task. The eval board contains a user push button that
+ * is configured to generate interrupts. The interrupt handler uses a
+ * semaphore to wake the button handler task - demonstrating how the priority
+ * mechanism can be used to defer interrupt processing to the task level. The
+ * button handler task sends a message both to the LCD (via the print task) and
+ * the UART where it can be viewed using a dumb terminal (via the UART to USB
+ * converter on the eval board). NOTES: The dumb terminal must be closed in
+ * order to reflash the microcontroller. A very basic interrupt driven UART
+ * driver is used that does not use the FIFO. 19200 baud is used.
+ *
+ * + A 'check' task. The check task only executes every five seconds but has a
+ * high priority so is guaranteed to get processor time. Its function is to
+ * check that all the other tasks are still operational and that no errors have
+ * been detected at any time. If no errors have every been detected 'PASS' is
+ * written to the display (via the print task) - if an error has ever been
+ * detected the message is changed to 'FAIL'. The position of the message is
+ * changed for each write.
+ */
+
+
+
+/* Environment includes. */
+#include "DriverLib.h"
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* Demo app includes. */
+#include "integer.h"
+#include "PollQ.h"
+#include "semtest.h"
+#include "BlockQ.h"
+
+/* Delay between cycles of the 'check' task. */
+#define mainCHECK_DELAY ( ( portTickType ) 5000 / portTICK_RATE_MS )
+
+/* UART configuration - note this does not use the FIFO so is not very
+efficient. */
+#define mainBAUD_RATE ( 19200 )
+#define mainFIFO_SET ( 0x10 )
+
+/* Demo task priorities. */
+#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
+#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
+#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
+#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
+
+/* Demo board specifics. */
+#define mainPUSH_BUTTON GPIO_PIN_4
+
+/* Misc. */
+#define mainQUEUE_SIZE ( 3 )
+#define mainDEBOUNCE_DELAY ( ( portTickType ) 150 / portTICK_RATE_MS )
+#define mainNO_DELAY ( ( portTickType ) 0 )
+/*
+ * Configure the processor and peripherals for this demo.
+ */
+static void prvSetupHardware( void );
+
+/*
+ * The 'check' task, as described at the top of this file.
+ */
+static void vCheckTask( void *pvParameters );
+
+/*
+ * The task that is woken by the ISR that processes GPIO interrupts originating
+ * from the push button.
+ */
+static void vButtonHandlerTask( void *pvParameters );
+
+/*
+ * The task that controls access to the LCD.
+ */
+static void vPrintTask( void *pvParameter );
+
+/* String that is transmitted on the UART. */
+static portCHAR *cMessage = "Task woken by button interrupt! --- ";
+static volatile portCHAR *pcNextChar;
+
+/* The semaphore used to wake the button handler task from within the GPIO
+interrupt handler. */
+xSemaphoreHandle xButtonSemaphore;
+
+/* The queue used to send strings to the print task for display on the LCD. */
+xQueueHandle xPrintQueue;
+
+/*-----------------------------------------------------------*/
+
+int main( void )
+{
+ /* Configure the clocks, UART and GPIO. */
+ prvSetupHardware();
+
+ /* Create the semaphore used to wake the button handler task from the GPIO
+ ISR. */
+ vSemaphoreCreateBinary( xButtonSemaphore );
+ xSemaphoreTake( xButtonSemaphore, 0 );
+
+ /* Create the queue used to pass message to vPrintTask. */
+ xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( portCHAR * ) );
+
+ /* Start the standard demo tasks. */
+ vStartIntegerMathTasks( tskIDLE_PRIORITY );
+ vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
+ vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
+ vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
+
+ /* Start the tasks defined within the file. */
+ xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
+ xTaskCreate( vButtonHandlerTask, "Status", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY + 1, NULL );
+ xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL );
+
+ /* Start the scheduler. */
+ vTaskStartScheduler();
+
+ /* Will only get here if there was insufficient heap to start the
+ scheduler. */
+
+ return 0;
+}
+/*-----------------------------------------------------------*/
+
+static void vCheckTask( void *pvParameters )
+{
+portBASE_TYPE xErrorOccurred = pdFALSE;
+portTickType xLastExecutionTime;
+const portCHAR *pcPassMessage = "PASS";
+const portCHAR *pcFailMessage = "FAIL";
+
+ /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
+ works correctly. */
+ xLastExecutionTime = xTaskGetTickCount();
+
+ for( ;; )
+ {
+ /* Perform this check every mainCHECK_DELAY milliseconds. */
+ vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
+
+ /* Has an error been found in any task? */
+
+ if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
+ {
+ xErrorOccurred = pdTRUE;
+ }
+
+ if( xArePollingQueuesStillRunning() != pdTRUE )
+ {
+ xErrorOccurred = pdTRUE;
+ }
+
+ if( xAreSemaphoreTasksStillRunning() != pdTRUE )
+ {
+ xErrorOccurred = pdTRUE;
+ }
+
+ if( xAreBlockingQueuesStillRunning() != pdTRUE )
+ {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* Send either a pass or fail message. If an error is found it is
+ never cleared again. We do not write directly to the LCD, but instead
+ queue a message for display by the print task. */
+ if( xErrorOccurred == pdTRUE )
+ {
+ xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY );
+ }
+ else
+ {
+ xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvSetupHardware( void )
+{
+ /* Setup the PLL. */
+ SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
+
+ /* Setup the push button. */
+ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
+ GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN);
+ GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE );
+ GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
+ IntEnable( INT_GPIOC );
+
+
+
+ /* Enable the UART. */
+ SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
+ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
+
+ /* Set GPIO A0 and A1 as peripheral function. They are used to output the
+ UART signals. */
+ GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
+
+ /* Configure the UART for 8-N-1 operation. */
+ UARTConfigSet( UART0_BASE, mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );
+
+ /* We don't want to use the fifo. This is for test purposes to generate
+ as many interrupts as possible. */
+ HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;
+
+ /* Enable Tx interrupts. */
+ HWREG( UART0_BASE + UART_O_IM ) |= UART_INT_TX;
+ IntEnable( INT_UART0 );
+
+
+ /* Initialise the LCD> */
+ OSRAMInit( false );
+ OSRAMStringDraw("www.FreeRTOS.org", 0, 0);
+ OSRAMStringDraw("LM3S811 demo", 16, 1);
+}
+/*-----------------------------------------------------------*/
+
+static void vButtonHandlerTask( void *pvParameters )
+{
+const portCHAR *pcInterruptMessage = "Int";
+
+ for( ;; )
+ {
+ /* Wait for a GPIO interrupt to wake this task. */
+ while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS );
+
+ /* Start the Tx of the message on the UART. */
+ UARTIntDisable( UART0_BASE, UART_INT_TX );
+ {
+ pcNextChar = cMessage;
+
+ /* Send the first character. */
+ if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
+ {
+ HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
+ }
+
+ pcNextChar++;
+ }
+ UARTIntEnable(UART0_BASE, UART_INT_TX);
+
+ /* Queue a message for the print task to display on the LCD. */
+ xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY );
+
+ /* Make sure we don't process bounces. */
+ vTaskDelay( mainDEBOUNCE_DELAY );
+ xSemaphoreTake( xButtonSemaphore, mainNO_DELAY );
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+void vUART_ISR(void)
+{
+unsigned portLONG ulStatus;
+
+ /* What caused the interrupt. */
+ ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
+
+ /* Clear the interrupt. */
+ UARTIntClear( UART0_BASE, ulStatus );
+
+ /* Was a Tx interrupt pending? */
+ if( ulStatus & UART_INT_TX )
+ {
+ /* Send the next character in the string. We are not using the FIFO. */
+ if( *pcNextChar != 0 )
+ {
+ if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
+ {
+ HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
+ }
+ pcNextChar++;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+void vGPIO_ISR( void )
+{
+ /* Clear the interrupt. */
+ GPIOPinIntClear(GPIO_PORTC_BASE, mainPUSH_BUTTON);
+
+ /* Wake the button handler task. */
+ if( xSemaphoreGiveFromISR( xButtonSemaphore, pdFALSE ) )
+ {
+ portEND_SWITCHING_ISR( pdTRUE );
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void vPrintTask( void *pvParameters )
+{
+portCHAR *pcMessage;
+unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
+
+ for( ;; )
+ {
+ /* Wait for a message to arrive. */
+ xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
+
+ /* Write the message to the LCD. */
+ uxRow++;
+ uxLine++;
+ OSRAMClear();
+ OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01);
+ }
+}
+