From 2f0bf47cb890e1db4f51b19687536eade94881c2 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 14 Feb 2017 11:19:11 -0800 Subject: add FreeRTOSConfig.h, use Task notifiers --- .../low_power_demo/FreeRTOSConfig.h | 164 +++++++++++++++++++++ examples/imx7_colibri_m4/low_power_demo/main.c | 69 ++++++--- 2 files changed, 216 insertions(+), 17 deletions(-) create mode 100644 examples/imx7_colibri_m4/low_power_demo/FreeRTOSConfig.h diff --git a/examples/imx7_colibri_m4/low_power_demo/FreeRTOSConfig.h b/examples/imx7_colibri_m4/low_power_demo/FreeRTOSConfig.h new file mode 100644 index 0000000..0ec37ab --- /dev/null +++ b/examples/imx7_colibri_m4/low_power_demo/FreeRTOSConfig.h @@ -0,0 +1,164 @@ +/* + FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +/* Ensure stdint is only used by the compiler, and not the assembler. */ +#ifdef __ICCARM__ + #include +#endif + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ (240000000ul) +#define configTICK_RATE_HZ ((TickType_t)1000) +#define configMAX_PRIORITIES (5) +#define configMINIMAL_STACK_SIZE ((unsigned short)130) +#define configTOTAL_HEAP_SIZE ((size_t)(20 * 1024)) +#define configMAX_TASK_NAME_LEN (10) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_MUTEXES 0 +#define configQUEUE_REGISTRY_SIZE 8 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_RECURSIVE_MUTEXES 0 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 0 +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TASK_NOTIFICATIONS 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES (2) + +/* Software timer definitions. */ +#define configUSE_TIMERS 0 +#define configTIMER_TASK_PRIORITY (2) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 0 +#define INCLUDE_vTaskDelay 1 + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS + /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 4 /* 15 priority levels */ +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) + +/* Normal assert() semantics without relying on the provision of an assert.h +header file. */ +#define configASSERT(x) if((x) == 0) {taskDISABLE_INTERRUPTS(); for(;;);} + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS +standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler + +#endif /* FREERTOS_CONFIG_H */ diff --git a/examples/imx7_colibri_m4/low_power_demo/main.c b/examples/imx7_colibri_m4/low_power_demo/main.c index fc56bc3..44949f6 100644 --- a/examples/imx7_colibri_m4/low_power_demo/main.c +++ b/examples/imx7_colibri_m4/low_power_demo/main.c @@ -28,6 +28,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include "FreeRTOS.h" #include "task.h" @@ -37,9 +38,7 @@ #include "gpio_pins.h" #include "gpio_imx.h" -#define GPIO_INTERRUPT (1) -#define GPIO_POLLING (0) -#define GPIO_DEBOUNCE_DELAY (100000) +TaskHandle_t xLcdTaskHandle; #define BURST_LENGTH_IN_BYTES(x) ((8 * x) - 1) @@ -110,6 +109,13 @@ static void LCD_Init(void) ECSPI_Init(BOARD_ECSPI_BASEADDR, &ecspiMasterInitConfig); ECSPI_SetSCLKInactiveState(BOARD_ECSPI_BASEADDR, 0, ecspiSclkStayHigh); + ECSPI_ClearStatusFlag(BOARD_ECSPI_BASEADDR, ~0); + + /* + * IRQ priority must be lower than configMAX_SYSCALL_INTERRUPT_PRIORITY + * (8) to allow FreeRTOS syscalls. + */ + NVIC_SetPriority(BOARD_ECSPI_IRQ_NUM, 3); NVIC_EnableIRQ(BOARD_ECSPI_IRQ_NUM); } @@ -118,6 +124,18 @@ static void LCD_SendBytes(const uint8_t *buf, int count, enum lcd_cmd_type cmd) int bytes; uint32_t data; gpio_pin_action_t a0; + uint32_t ulNotifiedValue = 0; + + // For simplicity, we only allow up to 256 bytes in one transfer. This + // fits into the FIFO and is below the maximum burst size of 512 bytes. + // It simplifies the code here and is good enouth for the ST7565R + // controller, where we have to send a "Page Address Set Command" to + // select the next page after 128 * 8 bit => 128 bytes of data + // anyway. + if (count > 64 * 4) { + PRINTF("%s: Maximum 256 bytes!\n\r", __func__); + return; + } if (cmd == LCD_COMMAND) a0 = gpioPinClear; @@ -127,7 +145,7 @@ static void LCD_SendBytes(const uint8_t *buf, int count, enum lcd_cmd_type cmd) ECSPI_SetBurstLength(BOARD_ECSPI_BASEADDR, BURST_LENGTH_IN_BYTES(count)); - while (count > 0 && !ECSPI_GetStatusFlag(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoFull)) { + while (count > 0) { int i; bytes = count & 0x3; bytes = bytes ? bytes : 4; @@ -138,17 +156,21 @@ static void LCD_SendBytes(const uint8_t *buf, int count, enum lcd_cmd_type cmd) ECSPI_SendData(BOARD_ECSPI_BASEADDR, data); count -= bytes; + if (ECSPI_GetStatusFlag(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoFull)) { + PRINTF("%s: FIFO Full!?\n\r", __func__); + break; + } } -// PRINTF("LCD_SendBytes, end count %d\n\r", count); - - //ECSPI_SetIntCmd(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoEmpty, true); - //ECSPI_SetIntCmd(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoTc, true); + ECSPI_SetIntCmd(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoTc, true); ECSPI_StartBurst(BOARD_ECSPI_BASEADDR); -//PRINTF("Status %x\n\r", ECSPI_GetStatusFlag(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoTc)); - while (!ECSPI_GetStatusFlag(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoTc)); - ECSPI_ClearStatusFlag(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoTc); + + ulNotifiedValue = ulTaskNotifyTake(pdFALSE, 10); + + if (ulNotifiedValue < 1) { + PRINTF("%s: Transfer timeout\n\r", __func__); + } } #define CLAMP(x, low, high) { if ( (x) < (low) ) x = (low); if ( (x) > (high) ) x = (high); } @@ -170,7 +192,7 @@ static void LCD_SetXY(int x, int y) LCD_SendBytes(cmd, 3, LCD_COMMAND); } -void UITask(void *pvParameters) +void LCD_Task(void *pvParameters) { const uint8_t LCD_init_seq[] = { 0x40, // Display start line 0 @@ -189,7 +211,6 @@ void UITask(void *pvParameters) 0xaf, // Display on }; - /* GPIO module initialize, configure "LED" as output and button as interrupt mode. */ LCD_Init(); @@ -211,6 +232,18 @@ void UITask(void *pvParameters) } } /* + uint8_t page[128]; + while (true) { + data = ~data; + for (int x = 0; x < 128; x++) + page[x] = data; + for (int y = 0; y < 8; y++) { + LCD_SetXY(0,y); + LCD_SendBytes(page, 128, LCD_DATA); + vTaskDelay(100); + } + } + while (true) { LCD_SetXY(x,y); LCD_SendBytes(&data, 1, LCD_DATA); @@ -235,8 +268,8 @@ int main(void) hardware_init(); PRINTF("\n\r=> Low Power Demo\n\r"); - xTaskCreate(UITask, "UI Task", configMINIMAL_STACK_SIZE, - NULL, tskIDLE_PRIORITY+1, NULL); + xTaskCreate(LCD_Task, "LCD Task", configMINIMAL_STACK_SIZE, + NULL, tskIDLE_PRIORITY+1, &xLcdTaskHandle); /* Start FreeRTOS scheduler. */ vTaskStartScheduler(); @@ -246,6 +279,7 @@ int main(void) void eCSPI3_Handler(void) { + BaseType_t xHigherPriorityTaskWoken; uint32_t flags; flags = ECSPI_GetStatusFlag(BOARD_ECSPI_BASEADDR, ~0); @@ -253,7 +287,8 @@ void eCSPI3_Handler(void) //PRINTF("IRQ, flags %08x\n\r", flags); if (flags & ecspiFlagTxfifoTc) { - PRINTF("Transfer Complete\n\r"); - //ECSPI_ClearStatusFlag(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoTc); + ECSPI_ClearStatusFlag(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoTc); + vTaskNotifyGiveFromISR(xLcdTaskHandle, &xHigherPriorityTaskWoken); + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } } -- cgit v1.2.3