summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2017-02-14 11:19:11 -0800
committerStefan Agner <stefan.agner@toradex.com>2017-03-02 14:04:11 -0800
commit2f0bf47cb890e1db4f51b19687536eade94881c2 (patch)
tree268a194cd6a1d2405c7676109e5d0048d05d220a
parent9d906b5965b91084ed226fb78faf4bb80a152224 (diff)
add FreeRTOSConfig.h, use Task notifiers
-rw-r--r--examples/imx7_colibri_m4/low_power_demo/FreeRTOSConfig.h164
-rw-r--r--examples/imx7_colibri_m4/low_power_demo/main.c69
2 files changed, 216 insertions, 17 deletions
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 <stdint.h>
+#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 <limits.h>
#include <stdio.h>
#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);
}
}