From 9d906b5965b91084ed226fb78faf4bb80a152224 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 14 Feb 2017 09:15:07 -0800 Subject: use FreeRTOS --- .../low_power_demo/armgcc/CMakeLists.txt | 32 +++- .../imx7_colibri_m4/low_power_demo/hardware_init.c | 14 +- examples/imx7_colibri_m4/low_power_demo/main.c | 191 ++++++++++++++++++++- 3 files changed, 227 insertions(+), 10 deletions(-) diff --git a/examples/imx7_colibri_m4/low_power_demo/armgcc/CMakeLists.txt b/examples/imx7_colibri_m4/low_power_demo/armgcc/CMakeLists.txt index 098ce0d..95aa16b 100644 --- a/examples/imx7_colibri_m4/low_power_demo/armgcc/CMakeLists.txt +++ b/examples/imx7_colibri_m4/low_power_demo/armgcc/CMakeLists.txt @@ -60,27 +60,36 @@ SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DCPU_MCIMX7D_M4") # INCLUDE_DIRECTORIES IF(CMAKE_BUILD_TYPE MATCHES Debug) INCLUDE_DIRECTORIES(${ProjDirPath}/../..) + INCLUDE_DIRECTORIES(${BspRootDirPath}/rtos/FreeRTOS/Source/portable/GCC/ARM_CM4F) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/CMSIS/Include) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/devices) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/devices/MCIMX7D/include) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/devices/MCIMX7D/startup) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/drivers/inc) + INCLUDE_DIRECTORIES(${BspRootDirPath}/rtos/FreeRTOS/Source/include) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/utilities/inc) - INCLUDE_DIRECTORIES(${BspRootDirPath}/../..) + INCLUDE_DIRECTORIES(${ProjDirPath}/../..) + INCLUDE_DIRECTORIES(${ProjDirPath}/..) ELSEIF(CMAKE_BUILD_TYPE MATCHES Release) INCLUDE_DIRECTORIES(${ProjDirPath}/../..) + INCLUDE_DIRECTORIES(${BspRootDirPath}/rtos/FreeRTOS/Source/portable/GCC/ARM_CM4F) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/CMSIS/Include) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/devices) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/devices/MCIMX7D/include) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/devices/MCIMX7D/startup) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/drivers/inc) + INCLUDE_DIRECTORIES(${BspRootDirPath}/rtos/FreeRTOS/Source/include) INCLUDE_DIRECTORIES(${BspRootDirPath}/platform/utilities/inc) INCLUDE_DIRECTORIES(${ProjDirPath}/../..) + INCLUDE_DIRECTORIES(${ProjDirPath}/..) ENDIF() # ADD_EXECUTABLE ADD_EXECUTABLE(low_power_demo + "${BspRootDirPath}/rtos/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c" + "${BspRootDirPath}/rtos/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h" "${BspRootDirPath}/platform/devices/MCIMX7D/startup/gcc/startup_MCIMX7D_M4.S" + "${BspRootDirPath}/rtos/FreeRTOS/Source/portable/MemMang/heap_2.c" "${BspRootDirPath}/platform/utilities/src/debug_console_imx.c" "${BspRootDirPath}/platform/utilities/inc/debug_console_imx.h" "${BspRootDirPath}/platform/utilities/src/print_scan.c" @@ -96,6 +105,26 @@ ADD_EXECUTABLE(low_power_demo "${BspRootDirPath}/platform/drivers/src/lmem.c" "${BspRootDirPath}/platform/drivers/src/rdc.c" "${BspRootDirPath}/platform/drivers/src/wdog_imx.c" + "${BspRootDirPath}/platform/drivers/src/ecspi.c" + "${BspRootDirPath}/platform/drivers/inc/ecspi.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/croutine.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/event_groups.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/FreeRTOS.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/list.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/mpu_wrappers.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/portable.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/projdefs.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/queue.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/semphr.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/StackMacros.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/task.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/include/timers.h" + "${BspRootDirPath}/rtos/FreeRTOS/Source/croutine.c" + "${BspRootDirPath}/rtos/FreeRTOS/Source/event_groups.c" + "${BspRootDirPath}/rtos/FreeRTOS/Source/list.c" + "${BspRootDirPath}/rtos/FreeRTOS/Source/queue.c" + "${BspRootDirPath}/rtos/FreeRTOS/Source/tasks.c" + "${BspRootDirPath}/rtos/FreeRTOS/Source/timers.c" "${BspRootDirPath}/platform/devices/MCIMX7D/startup/system_MCIMX7D_M4.c" "${BspRootDirPath}/platform/devices/MCIMX7D/startup/system_MCIMX7D_M4.h" "${ProjDirPath}/../../pin_mux.c" @@ -104,6 +133,7 @@ ADD_EXECUTABLE(low_power_demo "${ProjDirPath}/../../board.h" "${ProjDirPath}/../../clock_freq.c" "${ProjDirPath}/../../clock_freq.h" + "${ProjDirPath}/../FreeRTOSConfig.h" "${ProjDirPath}/../hardware_init.c" "${ProjDirPath}/../gpio_pins.c" "${ProjDirPath}/../gpio_pins.h" diff --git a/examples/imx7_colibri_m4/low_power_demo/hardware_init.c b/examples/imx7_colibri_m4/low_power_demo/hardware_init.c index 0b11809..3658b64 100644 --- a/examples/imx7_colibri_m4/low_power_demo/hardware_init.c +++ b/examples/imx7_colibri_m4/low_power_demo/hardware_init.c @@ -45,7 +45,19 @@ void hardware_init(void) RDC_SetPdapAccess(RDC, rdcPdapGpio4, 0xFF, false, false); /* Enable gpio clock gate */ - CCM_ControlGate(CCM, BOARD_GPIO_KEY_CCM_CCGR, ccmClockNeededRunWait); + CCM_ControlGate(CCM, ccmCcgrGateGpio1, ccmClockNeededRunWait); + CCM_ControlGate(CCM, ccmCcgrGateGpio4, ccmClockNeededRunWait); + + /* RDC ECSPI */ + RDC_SetPdapAccess(RDC, rdcPdapEcspi3, 0xff, false, false); + //RDC_SetPdapAccess(RDC, rdcPdapEcspi3, 3 << (BOARD_DOMAIN_ID * 2), false, false); + /* Select board ecspi clock derived from OSC clock(24M) */ + CCM_UpdateRoot(CCM, BOARD_ECSPI_CCM_ROOT, ccmRootmuxEcspiOsc24m, 0, 0); + /* Enable ecspi clock gate */ + CCM_EnableRoot(CCM, BOARD_ECSPI_CCM_ROOT); + CCM_ControlGate(CCM, BOARD_ECSPI_CCM_CCGR, ccmClockNeededAll); + /* Configure ecspi pin IOMUX */ + configure_ecspi_pins(BOARD_ECSPI_BASEADDR); } /******************************************************************************* diff --git a/examples/imx7_colibri_m4/low_power_demo/main.c b/examples/imx7_colibri_m4/low_power_demo/main.c index 71d0052..fc56bc3 100644 --- a/examples/imx7_colibri_m4/low_power_demo/main.c +++ b/examples/imx7_colibri_m4/low_power_demo/main.c @@ -29,40 +29,201 @@ */ #include +#include "FreeRTOS.h" +#include "task.h" #include "board.h" +#include "debug_console_imx.h" +#include "ecspi.h" #include "gpio_pins.h" #include "gpio_imx.h" -#include "debug_console_imx.h" #define GPIO_INTERRUPT (1) #define GPIO_POLLING (0) #define GPIO_DEBOUNCE_DELAY (100000) +#define BURST_LENGTH_IN_BYTES(x) ((8 * x) - 1) + +enum lcd_cmd_type { + LCD_COMMAND = 0, + LCD_DATA = 1, +}; + gpio_config_t gpioLcdA0 = { .name = "LCD A0 [SSPRXD]", .muxReg = &IOMUXC_SW_MUX_CTL_PAD_I2C1_SCL, /* GPIO4 IO08 */ - .muxConfig = 0, + .muxConfig = 5, .padReg = &IOMUXC_SW_PAD_CTL_PAD_I2C1_SCL, - .padConfig = 0, + .padConfig = 0x4, /* SRE=Slow */ .base = GPIO4, .pin = 8, }; +gpio_config_t gpioLcdReset = { + .name = "GPIO1 IO9 [PWM B]", + .muxReg = &IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO09, + .muxConfig = 0, + .padReg = &IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO09, + .padConfig = 0, + .base = GPIO1, + .pin = 9, +}; + /*! * @brief Initialize LCD display */ static void LCD_Init(void) { - configure_gpio_pin(&gpioLcdA0); - gpio_init_config_t lcdA0InitConfig = { .pin = gpioLcdA0.pin, .direction = gpioDigitalOutput, .interruptMode = gpioNoIntmode }; + + gpio_init_config_t lcdResetConfig = { + .pin = gpioLcdReset.pin, + .direction = gpioDigitalOutput, + .interruptMode = gpioNoIntmode + }; + + ecspi_init_config_t ecspiMasterInitConfig = { + .baudRate = 1000000, + .mode = ecspiMasterMode, + .burstLength = 7, + .channelSelect = ecspiSelectChannel0, + .clockPhase = ecspiClockPhaseSecondEdge, + .clockPolarity = ecspiClockPolarityActiveLow, + .ecspiAutoStart = false, + }; + + configure_gpio_pin(&gpioLcdReset); + GPIO_Init(gpioLcdReset.base, &lcdResetConfig); + + GPIO_WritePinOutput(gpioLcdReset.base, gpioLcdReset.pin, gpioPinClear); + vTaskDelay(2); + GPIO_WritePinOutput(gpioLcdReset.base, gpioLcdReset.pin, gpioPinSet); + + configure_gpio_pin(&gpioLcdA0); GPIO_Init(gpioLcdA0.base, &lcdA0InitConfig); + ecspiMasterInitConfig.clockRate = + get_ecspi_clock_freq(BOARD_ECSPI_BASEADDR); + ECSPI_Init(BOARD_ECSPI_BASEADDR, &ecspiMasterInitConfig); + ECSPI_SetSCLKInactiveState(BOARD_ECSPI_BASEADDR, 0, ecspiSclkStayHigh); + NVIC_EnableIRQ(BOARD_ECSPI_IRQ_NUM); +} + +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; + + if (cmd == LCD_COMMAND) + a0 = gpioPinClear; + else + a0 = gpioPinSet; + GPIO_WritePinOutput(gpioLcdA0.base, gpioLcdA0.pin, a0); + + ECSPI_SetBurstLength(BOARD_ECSPI_BASEADDR, BURST_LENGTH_IN_BYTES(count)); + + while (count > 0 && !ECSPI_GetStatusFlag(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoFull)) { + int i; + bytes = count & 0x3; + bytes = bytes ? bytes : 4; + + data = 0; + for(i = 0; i < bytes; i++) + data = (data << 8) | *(buf)++; + + ECSPI_SendData(BOARD_ECSPI_BASEADDR, data); + count -= bytes; + } + +// PRINTF("LCD_SendBytes, end count %d\n\r", count); + + //ECSPI_SetIntCmd(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoEmpty, 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); +} + +#define CLAMP(x, low, high) { if ( (x) < (low) ) x = (low); if ( (x) > (high) ) x = (high); } +#define LCDWIDTH 128 +#define LCDHEIGHT 64 +#define LCDPAGES (LCDHEIGHT+7)/8 + +static void LCD_SetXY(int x, int y) +{ + unsigned char cmd[3]; + + PRINTF("LCD_SetXY(%d,%d)\n\r", x, y); + CLAMP(x, 0, LCDWIDTH-1); + CLAMP(y, 0, LCDPAGES-1); + + cmd[0] = 0xB0 | (y&0xF); + cmd[1] = 0x10 | (x&0xF); + cmd[2] = (x>>4)&0xF; + LCD_SendBytes(cmd, 3, LCD_COMMAND); +} + +void UITask(void *pvParameters) +{ + const uint8_t LCD_init_seq[] = { + 0x40, // Display start line 0 + 0xa1, // ADC reverse + 0xc0, // Normal COM0~COM63 + 0xa6, // Display normal + 0xa2, // Set bias 1/9 (Duty 1/65) + 0x2f, // Booster, Regulator and Follower on + 0xf8, // Set internal Booster to 4x + 0x00, + 0x27, // Contrast set + 0x81, + 0x16, + 0xac, // No indicator + 0x00, + 0xaf, // Display on + }; + + + /* GPIO module initialize, configure "LED" as output and button as interrupt mode. */ + LCD_Init(); + + LCD_SendBytes(LCD_init_seq, sizeof(LCD_init_seq), LCD_COMMAND); + PRINTF("After init\n\r"); +/* + uint8_t cmd = 0xA4 | 1; + LCD_SendBytes(&cmd, 1, LCD_COMMAND); +*/ + uint8_t data = 0xff; + while (true) { + data = ~data; + for (int y = 0; y < 8; y++) { + LCD_SetXY(0,y); + for (int x = 0; x < 128; x++) { + LCD_SendBytes(&data, 1, LCD_DATA); + vTaskDelay(5); + } + } + } +/* + while (true) { + LCD_SetXY(x,y); + LCD_SendBytes(&data, 1, LCD_DATA); + x++; + if (x == 128) { + x = 0; + y++; + } + if (y == 64) { + x = 0; + y = 0; + } + }*/ } /*! @@ -74,11 +235,25 @@ int main(void) hardware_init(); PRINTF("\n\r=> Low Power Demo\n\r"); - /* GPIO module initialize, configure "LED" as output and button as interrupt mode. */ - LCD_Init(); + xTaskCreate(UITask, "UI Task", configMINIMAL_STACK_SIZE, + NULL, tskIDLE_PRIORITY+1, NULL); - while(true); + /* Start FreeRTOS scheduler. */ + vTaskStartScheduler(); return 0; } +void eCSPI3_Handler(void) +{ + uint32_t flags; + + flags = ECSPI_GetStatusFlag(BOARD_ECSPI_BASEADDR, ~0); + + //PRINTF("IRQ, flags %08x\n\r", flags); + + if (flags & ecspiFlagTxfifoTc) { + PRINTF("Transfer Complete\n\r"); + //ECSPI_ClearStatusFlag(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoTc); + } +} -- cgit v1.2.3