From 36f2ebbf95125c247ab6e7f26d33aff279223abd Mon Sep 17 00:00:00 2001 From: Wang_Weigen Date: Mon, 20 Dec 2021 15:42:24 +0800 Subject: [PATCH 1/7] add fpu status set --- Ubiquitous/XiUOS/arch/risc-v/shared/riscv64_switch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ubiquitous/XiUOS/arch/risc-v/shared/riscv64_switch.c b/Ubiquitous/XiUOS/arch/risc-v/shared/riscv64_switch.c index d9f9234af..cabc6612b 100644 --- a/Ubiquitous/XiUOS/arch/risc-v/shared/riscv64_switch.c +++ b/Ubiquitous/XiUOS/arch/risc-v/shared/riscv64_switch.c @@ -24,7 +24,7 @@ void __attribute__((naked)) SwitchKTaskContextExit() asm volatile ("mv a0, sp"); asm volatile ("jal RestoreMstatus"); #else - asm volatile ("li t0, 0x00001800"); + asm volatile ("li t0, 0x00007800"); asm volatile ("csrw mstatus, t0"); asm volatile (LoadDS " a0, 2 * " RegLengthS "(sp)"); asm volatile ("csrs mstatus, a0"); From 37c247f4d710a13b71d56dedaaed1d8d96aebdb4 Mon Sep 17 00:00:00 2001 From: Wang_Weigen Date: Wed, 5 Jan 2022 15:23:12 +0800 Subject: [PATCH 2/7] add lvgl --- APP_Framework/Applications/Makefile | 6 + APP_Framework/Applications/framework_init.c | 6 + APP_Framework/Applications/lv_app/Makefile | 3 + APP_Framework/Applications/lv_app/lv_demo.c | 40 ++++ .../Applications/lv_app/lv_demo_calendar.c | 50 ++++ .../Applications/lv_app/lv_demo_calendar.h | 6 + APP_Framework/Applications/lv_init.c | 38 +++ .../transform_layer/xiuos/transform.c | 10 + .../transform_layer/xiuos/transform.h | 27 +++ APP_Framework/lib/Kconfig | 2 +- APP_Framework/lib/Makefile | 12 +- APP_Framework/lib/lvgl | 1 + Ubiquitous/Nuttx/apps/graphics/lvgl/lv_conf.h | 2 +- .../third_party_driver/include/graphic.h | 10 +- .../third_party_driver/lcd/Kconfig | 18 +- .../third_party_driver/lcd/connect_lcd.c | 225 ++++++++++-------- .../third_party_driver/gpio/connect_gpio.c | 8 +- .../XiUOS/kernel/kernel_test/test_lcd.c | 2 +- Ubiquitous/XiUOS/path_kernel.mk | 6 + Ubiquitous/XiUOS/resources/include/dev_lcd.h | 14 ++ 20 files changed, 360 insertions(+), 126 deletions(-) create mode 100644 APP_Framework/Applications/lv_app/Makefile create mode 100644 APP_Framework/Applications/lv_app/lv_demo.c create mode 100644 APP_Framework/Applications/lv_app/lv_demo_calendar.c create mode 100644 APP_Framework/Applications/lv_app/lv_demo_calendar.h create mode 100644 APP_Framework/Applications/lv_init.c create mode 160000 APP_Framework/lib/lvgl diff --git a/APP_Framework/Applications/Makefile b/APP_Framework/Applications/Makefile index af2f86d2c..97257c9dc 100644 --- a/APP_Framework/Applications/Makefile +++ b/APP_Framework/Applications/Makefile @@ -2,6 +2,12 @@ SRC_DIR := general_functions app_test SRC_FILES := main.c framework_init.c +ifeq ($(CONFIG_LIB_LV),y) +SRC_FILES += lv_init.c + +SRC_DIR += lv_app +endif + ifeq ($(CONFIG_APPLICATION_OTA),y) SRC_DIR += ota endif diff --git a/APP_Framework/Applications/framework_init.c b/APP_Framework/Applications/framework_init.c index 603af2fac..f618df6af 100644 --- a/APP_Framework/Applications/framework_init.c +++ b/APP_Framework/Applications/framework_init.c @@ -34,6 +34,8 @@ extern int Tb600bIaq10IaqInit(void); extern int Tb600bTvoc10TvocInit(void); extern int Tb600bWqHcho1osInit(void); +extern int lv_port_init(void); + typedef int (*InitFunc)(void); struct InitDesc { @@ -200,5 +202,9 @@ int FrameworkInit() ConnectionDeviceFrameworkInit(framework); #endif +#ifdef LIB_LV + lv_port_init(); +#endif + return 0; } \ No newline at end of file diff --git a/APP_Framework/Applications/lv_app/Makefile b/APP_Framework/Applications/lv_app/Makefile new file mode 100644 index 000000000..0efc4bd16 --- /dev/null +++ b/APP_Framework/Applications/lv_app/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := lv_demo.c lv_demo_calendar.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/Applications/lv_app/lv_demo.c b/APP_Framework/Applications/lv_app/lv_demo.c new file mode 100644 index 000000000..538a61ca4 --- /dev/null +++ b/APP_Framework/Applications/lv_app/lv_demo.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-10-17 Meco Man First version + */ +#include +#include +#include "lv_demo_calendar.h" +#include + +void* lvgl_thread(void *parameter) +{ + /* display demo; you may replace with your LVGL application at here */ + lv_demo_calendar(); + + /* handle the tasks of LVGL */ + while(1) + { + lv_task_handler(); + PrivTaskDelay(10); + } +} + +pthread_t lvgl_task; +static int lvgl_demo_init(void) +{ + pthread_attr_t attr; + attr.schedparam.sched_priority = 20; + attr.stacksize = 4096; + + PrivTaskCreate(&lvgl_task, &attr, lvgl_thread, NULL); + + return 0; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),lvgl_demo_init, lvgl_demo_init, lvgl_demo_init ); + diff --git a/APP_Framework/Applications/lv_app/lv_demo_calendar.c b/APP_Framework/Applications/lv_app/lv_demo_calendar.c new file mode 100644 index 000000000..de1a68e9f --- /dev/null +++ b/APP_Framework/Applications/lv_app/lv_demo_calendar.c @@ -0,0 +1,50 @@ +#include +#include "lv_demo_calendar.h" +// #include + +static void event_handler(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * obj = lv_event_get_current_target(e); + + if(code == LV_EVENT_VALUE_CHANGED) { + lv_calendar_date_t date; + if(lv_calendar_get_pressed_date(obj, &date)) { + LV_LOG_USER("Clicked date: %02d.%02d.%d", date.day, date.month, date.year); + } + } +} + +void lv_demo_calendar(void) +{ + lv_obj_t * calendar = lv_calendar_create(lv_scr_act()); + lv_obj_set_size(calendar, 240, 240); + lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 0); + lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL); + + lv_calendar_set_today_date(calendar, 2021, 02, 23); + lv_calendar_set_showed_date(calendar, 2021, 02); + + /*Highlight a few days*/ + static lv_calendar_date_t highlighted_days[3]; /*Only its pointer will be saved so should be static*/ + highlighted_days[0].year = 2021; + highlighted_days[0].month = 02; + highlighted_days[0].day = 6; + + highlighted_days[1].year = 2021; + highlighted_days[1].month = 02; + highlighted_days[1].day = 11; + + highlighted_days[2].year = 2022; + highlighted_days[2].month = 02; + highlighted_days[2].day = 22; + + lv_calendar_set_highlighted_dates(calendar, highlighted_days, 3); + +#if LV_USE_CALENDAR_HEADER_DROPDOWN + lv_calendar_header_dropdown_create(calendar); +#elif LV_USE_CALENDAR_HEADER_ARROW + lv_calendar_header_arrow_create(calendar); +#endif + lv_calendar_set_showed_date(calendar, 2021, 10); +} diff --git a/APP_Framework/Applications/lv_app/lv_demo_calendar.h b/APP_Framework/Applications/lv_app/lv_demo_calendar.h new file mode 100644 index 000000000..b8a7772f2 --- /dev/null +++ b/APP_Framework/Applications/lv_app/lv_demo_calendar.h @@ -0,0 +1,6 @@ +#ifndef __LV_DEMO_CALENDAR_H__ +#define __LV_DEMO_CALENDAR_H__ + +void lv_demo_calendar(void); + +#endif diff --git a/APP_Framework/Applications/lv_init.c b/APP_Framework/Applications/lv_init.c new file mode 100644 index 000000000..3ff01dddc --- /dev/null +++ b/APP_Framework/Applications/lv_init.c @@ -0,0 +1,38 @@ +#include +#define DBG_TAG "LVGL" +#define DBG_LVL DBG_INFO + +#ifndef PKG_USING_LVGL_DISP_DEVICE +#include +#endif + +#ifndef PKG_USING_LVGL_INDEV_DEVICE +#include +#endif +extern void lv_port_disp_init(void); +extern void lv_port_indev_init(void); +#if LV_USE_LOG && LV_LOG_PRINTF +static void lv_rt_log(const char *buf) +{ + LOG_I(buf); +} +#endif + +int lv_port_init(void) +{ +#if LV_USE_LOG && LV_LOG_PRINTF + lv_log_register_print_cb(lv_rt_log); +#endif + + lv_init(); + +#ifndef PKG_USING_LVGL_DISP_DEVICE + lv_port_disp_init(); +#endif +#ifndef PKG_USING_LVGL_INDEV_DEVICE + lv_port_indev_init(); +#endif + + return 0; +} + diff --git a/APP_Framework/Framework/transform_layer/xiuos/transform.c b/APP_Framework/Framework/transform_layer/xiuos/transform.c index e80102a65..36d7c3181 100644 --- a/APP_Framework/Framework/transform_layer/xiuos/transform.c +++ b/APP_Framework/Framework/transform_layer/xiuos/transform.c @@ -138,6 +138,13 @@ static int PrivPinIoctl(int fd, int cmd, void *args) return ioctl(fd, cmd, pin_cfg); } +static int PrivLcdIoctl(int fd, int cmd, void *args) +{ + struct DeviceLcdInfo *lcd_cfg = (struct DeviceLcdInfo *)args; + + return ioctl(fd, cmd, lcd_cfg); +} + int PrivIoctl(int fd, int cmd, void *args) { int ret; @@ -154,6 +161,9 @@ int PrivIoctl(int fd, int cmd, void *args) case I2C_TYPE: ret = ioctl(fd, cmd, ioctl_cfg->args); break; + case LCD_TYPE: + ret = PrivLcdIoctl(fd, cmd, ioctl_cfg->args); + break; default: break; } diff --git a/APP_Framework/Framework/transform_layer/xiuos/transform.h b/APP_Framework/Framework/transform_layer/xiuos/transform.h index b2996fd44..1e50350d5 100644 --- a/APP_Framework/Framework/transform_layer/xiuos/transform.h +++ b/APP_Framework/Framework/transform_layer/xiuos/transform.h @@ -138,6 +138,7 @@ enum IoctlDriverType SPI_TYPE, I2C_TYPE, PIN_TYPE, + LCD_TYPE, DEFAULT_TYPE, }; @@ -147,6 +148,32 @@ struct PrivIoctlCfg void *args; }; +typedef struct +{ + uint16 x_pos; + uint16 y_pos; + uint16 width; + uint16 height; + uint8 font_size; + uint8 *addr; + uint16 font_color; + uint16 back_color; +}LcdStringParam; + +typedef struct +{ + uint16 x_pos; + uint16 y_pos; + uint16 pixel_color; +}LcdPixelParam; + +typedef struct +{ + char type; // 0:write string;1:write dot + LcdStringParam string_info; + LcdPixelParam pixel_info; +}LcdWriteParam; + /**********************mutex**************************/ int PrivMutexCreate(pthread_mutex_t *p_mutex, const pthread_mutexattr_t *attr); diff --git a/APP_Framework/lib/Kconfig b/APP_Framework/lib/Kconfig index f92cf7cfd..cc9317522 100755 --- a/APP_Framework/lib/Kconfig +++ b/APP_Framework/lib/Kconfig @@ -1,5 +1,4 @@ menu "lib" - choice prompt "chose a kind of lib for app" default APP_SELECT_NEWLIB @@ -12,4 +11,5 @@ menu "lib" endchoice source "$APP_DIR/lib/cJSON/Kconfig" source "$APP_DIR/lib/queue/Kconfig" + source "$APP_DIR/lib/lvgl/Kconfig" endmenu diff --git a/APP_Framework/lib/Makefile b/APP_Framework/lib/Makefile index ec6061b73..3e8e31a84 100644 --- a/APP_Framework/lib/Makefile +++ b/APP_Framework/lib/Makefile @@ -1,9 +1,13 @@ -SRC_DIR := +# SRC_DIR := lvgl ifeq ($(CONFIG_APP_SELECT_NEWLIB),y) - ifeq ($(CONFIG_SEPARATE_COMPILE),y) - SRC_DIR += app_newlib - endif + ifeq ($(CONFIG_SEPARATE_COMPILE),y) + SRC_DIR += app_newlib + endif +endif + +ifeq ($(CONFIG_LIB_LV),y) + SRC_DIR += lvgl endif diff --git a/APP_Framework/lib/lvgl b/APP_Framework/lib/lvgl new file mode 160000 index 000000000..d38eb1e68 --- /dev/null +++ b/APP_Framework/lib/lvgl @@ -0,0 +1 @@ +Subproject commit d38eb1e689fa5a64c25e677275172d9c8a4ab2f0 diff --git a/Ubiquitous/Nuttx/apps/graphics/lvgl/lv_conf.h b/Ubiquitous/Nuttx/apps/graphics/lvgl/lv_conf.h index 3ea42c8aa..2f584c0cc 100644 --- a/Ubiquitous/Nuttx/apps/graphics/lvgl/lv_conf.h +++ b/Ubiquitous/Nuttx/apps/graphics/lvgl/lv_conf.h @@ -851,7 +851,7 @@ typedef void * lv_obj_user_data_t; #ifdef CONFIG_USE_LV_CALENDAR #define LV_USE_CALENDAR CONFIG_USE_LV_CALENDAR #else -#define LV_USE_CALENDAR 0 +#define LV_USE_CALENDAR 1 #endif /* Canvas (dependencies: lv_img) */ diff --git a/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/include/graphic.h b/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/include/graphic.h index cbc4e2bcd..aa02acac9 100644 --- a/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/include/graphic.h +++ b/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/include/graphic.h @@ -32,11 +32,11 @@ Modification: add aiit-riscv64-board lcd configure and operation function #include #define GRAPHIC_CTRL_RECT_UPDATE 0 -#define GRAPHIC_CTRL_POWERON 1 -#define GRAPHIC_CTRL_POWEROFF 2 -#define GRAPHIC_CTRL_GET_INFO 3 -#define GRAPHIC_CTRL_SET_MODE 4 -#define GRAPHIC_CTRL_GET_EXT 5 +#define GRAPHIC_CTRL_POWERON 1 +#define GRAPHIC_CTRL_POWEROFF 2 +#define GRAPHIC_CTRL_GET_INFO 3 +#define GRAPHIC_CTRL_SET_MODE 4 +#define GRAPHIC_CTRL_GET_EXT 5 enum { diff --git a/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/Kconfig b/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/Kconfig index f29f599eb..f058a8bb1 100644 --- a/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/Kconfig +++ b/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/Kconfig @@ -1,14 +1,14 @@ if BSP_USING_LCD - config LCD_BUS_NAME_1 - string "lcd bus 1 name" - default "lcd1" - config LCD_DRV_NAME_1 - string "lcd bus 1 driver name" - default "lcd1drv" - config LCD_1_DEVICE_NAME_0 - string "lcd bus 1 device 0 name" - default "lcd10" + config LCD_BUS_NAME + string "lcd bus name" + default "lcd" + config LCD_DRV_NAME + string "lcd bus driver name" + default "lcd_drv" + config LCD_DEVICE_NAME + string "lcd bus device name" + default "lcd_dev" config BSP_LCD_CS_PIN int "CS pin number of 8080 interface" default 40 diff --git a/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/connect_lcd.c b/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/connect_lcd.c index f96b11cd5..25e109d11 100644 --- a/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/connect_lcd.c +++ b/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/connect_lcd.c @@ -137,7 +137,7 @@ typedef enum _lcd_dir typedef struct Lcd8080Device { - struct LcdBus lcd_bus; + struct LcdBus lcd_bus; struct DeviceLcdInfo lcd_info; int spi_channel; int cs; @@ -145,46 +145,46 @@ typedef struct Lcd8080Device int dma_channel; } * Lcd8080DeviceType; -Lcd8080DeviceType lcd ; +Lcd8080DeviceType aiit_lcd ; static void DrvLcdCmd(uint8 cmd) { - gpiohs_set_pin(lcd->dc_pin, GPIO_PV_LOW); - spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); - spi_init_non_standard(lcd->spi_channel/*spi num*/, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/, + gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_LOW); + spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); + spi_init_non_standard(aiit_lcd->spi_channel/*spi num*/, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/, SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); - spi_send_data_normal_dma(lcd->dma_channel, lcd->spi_channel, lcd->cs, &cmd, 1, SPI_TRANS_CHAR); + spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, &cmd, 1, SPI_TRANS_CHAR); } static void DrvLcdDataByte(uint8 *data_buf, uint32 length) { - gpiohs_set_pin(lcd->dc_pin, GPIO_PV_HIGH); - spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); - spi_init_non_standard(lcd->spi_channel, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/, + gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH); + spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); + spi_init_non_standard(aiit_lcd->spi_channel, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/, SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); - spi_send_data_normal_dma(lcd->dma_channel, lcd->spi_channel, lcd->cs, data_buf, length, SPI_TRANS_CHAR); + spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, data_buf, length, SPI_TRANS_CHAR); } static void DrvLcdDataHalfWord(uint16 *data_buf, uint32 length) { - gpiohs_set_pin(lcd->dc_pin, GPIO_PV_HIGH); - spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 16, 0); - spi_init_non_standard(lcd->spi_channel, 16 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/, + gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH); + spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 16, 0); + spi_init_non_standard(aiit_lcd->spi_channel, 16 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/, SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); - spi_send_data_normal_dma(lcd->dma_channel, lcd->spi_channel, lcd->cs, data_buf, length, SPI_TRANS_SHORT); + spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, data_buf, length, SPI_TRANS_SHORT); } static void DrvLcdDataWord(uint32 *data_buf, uint32 length) { - gpiohs_set_pin(lcd->dc_pin, GPIO_PV_HIGH); + gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH); /*spi num Polarity and phase mode Multi-line mode Data bit width little endian */ - spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); + spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); /* spi num instrction length address length wait cycles spi address trans mode*/ - spi_init_non_standard(lcd->spi_channel, 0 , 32, 0 ,SPI_AITM_AS_FRAME_FORMAT ); + spi_init_non_standard(aiit_lcd->spi_channel, 0 , 32, 0 ,SPI_AITM_AS_FRAME_FORMAT ); /*dma channel spi num chip_selete tx_buff tx_len spi_trans_data_width */ - spi_send_data_normal_dma(lcd->dma_channel, lcd->spi_channel, lcd->cs, data_buf, length, SPI_TRANS_INT); + spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, data_buf, length, SPI_TRANS_INT); } static void DrvLcdHwInit(Lcd8080DeviceType lcd) @@ -201,11 +201,11 @@ static void DrvLcdSetDirection(lcd_dir_t dir) dir |= 0x08; #endif if (dir & DIR_XY_MASK) { - lcd->lcd_info.width = 320; - lcd->lcd_info.height = 240; + aiit_lcd->lcd_info.width = 320; + aiit_lcd->lcd_info.height = 240; } else { - lcd->lcd_info.width = 240; - lcd->lcd_info.height = 320; + aiit_lcd->lcd_info.width = 240; + aiit_lcd->lcd_info.height = 320; } DrvLcdCmd(MEMORY_ACCESS_CTL); @@ -265,12 +265,12 @@ void LcdShowChar(uint16 x,uint16 y,uint8 num,uint8 size,uint16 color,uint16 back temp<<=1; y++; - if(y>=lcd->lcd_info.height) + if(y>=aiit_lcd->lcd_info.height) return; if ((y-y0) == size) { y=y0; x++; - if(x>=lcd->lcd_info.width) + if(x>=aiit_lcd->lcd_info.width) return; break; } @@ -305,29 +305,29 @@ void DrvLcdClear(uint16 color) { uint32 data = ((uint32)color << 16) | (uint32)color; - DrvLcdSetArea(0, 0, lcd->lcd_info.width - 1, lcd->lcd_info.height - 1); - gpiohs_set_pin(lcd->dc_pin, GPIO_PV_HIGH); - spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); - spi_init_non_standard(lcd->spi_channel, + DrvLcdSetArea(0, 0, aiit_lcd->lcd_info.width - 1, aiit_lcd->lcd_info.height - 1); + gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH); + spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); + spi_init_non_standard(aiit_lcd->spi_channel, 0 /*instrction length*/, 32 /*address length */, 0 /*wait cycles */, SPI_AITM_AS_FRAME_FORMAT ); - spi_fill_data_dma(lcd->dma_channel, lcd->spi_channel, lcd->cs, (const uint32_t *)&data, lcd->lcd_info.width * lcd->lcd_info.height / 2); + spi_fill_data_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, (const uint32_t *)&data, aiit_lcd->lcd_info.width * aiit_lcd->lcd_info.height / 2); } static void DrvLcdRectUpdate(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height) { static uint16 * rect_buffer = NONE; if (!rect_buffer) { - rect_buffer = x_malloc(lcd->lcd_info.height * lcd->lcd_info.width * (lcd->lcd_info.bits_per_pixel / 8)); + rect_buffer = x_malloc(aiit_lcd->lcd_info.height * aiit_lcd->lcd_info.width * (aiit_lcd->lcd_info.bits_per_pixel / 8)); if (!rect_buffer) { return; } } - if (x1 == 0 && y1 == 0 && width == lcd->lcd_info.width && height == lcd->lcd_info.height) { + if (x1 == 0 && y1 == 0 && width == aiit_lcd->lcd_info.width && height == aiit_lcd->lcd_info.height) { DrvLcdSetArea(x1, y1, x1 + width - 1, y1 + height - 1); - DrvLcdDataWord((uint32 *)lcd->lcd_info.framebuffer, width * height / (lcd->lcd_info.bits_per_pixel / 8)); + DrvLcdDataWord((uint32 *)aiit_lcd->lcd_info.framebuffer, width * height / (aiit_lcd->lcd_info.bits_per_pixel / 8)); } else { DrvLcdSetArea(x1, y1, x1 + width - 1, y1 + height - 1); DrvLcdDataWord((uint32 *)rect_buffer, width * height / 2); @@ -337,13 +337,14 @@ static void DrvLcdRectUpdate(uint16_t x1, uint16_t y1, uint16_t width, uint16_t x_err_t DrvLcdInit(Lcd8080DeviceType dev) { x_err_t ret = EOK; - lcd = (Lcd8080DeviceType)dev; + aiit_lcd = (Lcd8080DeviceType)dev; uint8 data = 0; - if (!lcd) { - return ERROR; + if (!aiit_lcd) + { + return -ERROR; } - DrvLcdHwInit(lcd); + DrvLcdHwInit(aiit_lcd); /* reset LCD */ DrvLcdCmd(SOFTWARE_RESET); MdelayKTask(100); @@ -360,8 +361,8 @@ x_err_t DrvLcdInit(Lcd8080DeviceType dev) /* set direction */ DrvLcdSetDirection(DIR_YX_RLUD); - lcd->lcd_info.framebuffer = x_malloc(lcd->lcd_info.height * lcd->lcd_info.width * (lcd->lcd_info.bits_per_pixel / 8)); - CHECK(lcd->lcd_info.framebuffer); + aiit_lcd->lcd_info.framebuffer = x_malloc(aiit_lcd->lcd_info.height * aiit_lcd->lcd_info.width * (aiit_lcd->lcd_info.bits_per_pixel / 8)); + CHECK(aiit_lcd->lcd_info.framebuffer); /*display on*/ DrvLcdCmd(DISPALY_ON); @@ -369,18 +370,18 @@ x_err_t DrvLcdInit(Lcd8080DeviceType dev) return ret; } -static x_err_t drv_lcd_control(Lcd8080DeviceType dev, int cmd, void *args) +static uint32 drv_lcd_control(void* drv, struct BusConfigureInfo *configure_info) { x_err_t ret = EOK; - Lcd8080DeviceType lcd = (Lcd8080DeviceType)dev; - x_base level; - struct DeviceRectInfo* rect_info = (struct DeviceRectInfo*)args; + struct LcdDriver *lcddrv = (struct LcdDriver *)drv; - NULL_PARAM_CHECK(dev); + struct DeviceRectInfo* rect_info; + NULL_PARAM_CHECK(drv); - switch (cmd) + switch (configure_info->configure_cmd) { case GRAPHIC_CTRL_RECT_UPDATE: + rect_info = (struct DeviceRectInfo*)configure_info->private_data; if(!rect_info) { SYS_ERR("GRAPHIC_CTRL_RECT_UPDATE error args"); @@ -400,7 +401,7 @@ static x_err_t drv_lcd_control(Lcd8080DeviceType dev, int cmd, void *args) break; case GRAPHIC_CTRL_GET_INFO: - *(struct DeviceLcdInfo *)args = lcd->lcd_info; + *(struct DeviceLcdInfo *)configure_info->private_data = aiit_lcd->lcd_info; break; case GRAPHIC_CTRL_SET_MODE: @@ -410,7 +411,7 @@ static x_err_t drv_lcd_control(Lcd8080DeviceType dev, int cmd, void *args) ret = -ENONESYS; break; default: - SYS_ERR("drv_lcd_control cmd: %d", cmd); + SYS_ERR("drv_lcd_control cmd: %d", configure_info->configure_cmd); break; } @@ -456,20 +457,33 @@ void HandTest(unsigned short *x_pos, unsigned short *y_pos) static uint32 LcdWrite(void *dev, struct BusBlockWriteParam *write_param) { if (write_param == NONE) { - return ERROR; + return -ERROR; } - - LcdStringParam * show = (LcdStringParam *)write_param->buffer; - - if (0==write_param->pos) { //output string - LcdShowString(show->x_pos,show->y_pos,show->width,show->height,show->font_size,show->addr,show->font_color,show->back_color); - return EOK; - } else if (1==write_param->pos) { //output dot - DrvLcdSetPixel(show->x_pos, show->y_pos, show->font_color); - return EOK; - } else { - return ERROR; + LcdWriteParam * show = (LcdWriteParam *)write_param->buffer; + KPrintf("DEBUG TYPE %d X:%d Y:%d color %d\n",show->pixel_info.x_pos, show->pixel_info.y_pos, show->pixel_info.pixel_color); + if(0 == show->type) //output string + { + LcdShowString(show->string_info.x_pos,show->string_info.y_pos,show->string_info.width,show->string_info.height,show->string_info.font_size,show->string_info.addr,show->string_info.font_color,show->string_info.back_color); + return EOK; + } + else if(1 == show->type) //output dot + { + DrvLcdSetPixel(show->pixel_info.x_pos, show->pixel_info.y_pos, show->pixel_info.pixel_color); + return EOK; + } + else + { + return -ERROR; } + // if (0==write_param->pos) { //output string + // LcdShowString(show->x_pos,show->y_pos,show->width,show->height,show->font_size,show->addr,show->font_color,show->back_color); + // return EOK; + // } else if (1==write_param->pos) { //output dot + // DrvLcdSetPixel(show->x_pos, show->y_pos, show->font_color); + // return EOK; + // } else { + // return -ERROR; + // } } uint32 DrvLcdClearDone(void * dev, struct BusConfigureInfo *configure_info) @@ -488,55 +502,49 @@ const struct LcdDevDone lcd_dev_done = .read = NONE }; -static int BoardLcdBusInit(struct LcdBus * lcd_bus, struct LcdDriver * lcd_driver) +static int BoardLcdBusInit(struct LcdBus * lcd_bus, struct LcdDriver * lcd_driver,const char *bus_name, const char *drv_name) { x_err_t ret = EOK; /*Init the lcd bus */ - ret = LcdBusInit( lcd_bus, LCD_BUS_NAME_1); + ret = LcdBusInit( lcd_bus, bus_name); if (EOK != ret) { KPrintf("Board_lcd_init LcdBusInit error %d\n", ret); - return ERROR; + return -ERROR; } - lcd_driver->configure = DrvLcdClearDone; /*Init the lcd driver*/ - ret = LcdDriverInit( lcd_driver, LCD_DRV_NAME_1); + ret = LcdDriverInit( lcd_driver, drv_name); if (EOK != ret) { KPrintf("Board_LCD_init LcdDriverInit error %d\n", ret); - return ERROR; + return -ERROR; } /*Attach the lcd driver to the lcd bus*/ - ret = LcdDriverAttachToBus(LCD_DRV_NAME_1, LCD_BUS_NAME_1); + ret = LcdDriverAttachToBus(drv_name, bus_name); if (EOK != ret) { KPrintf("Board_LCD_init LcdDriverAttachToBus error %d\n", ret); - return ERROR; + return -ERROR; } return ret; } /*Attach the lcd device to the lcd bus*/ -static int BoardLcdDevBend(void) +static int BoardLcdDevBend(struct LcdHardwareDevice *lcd_device, void *param, const char *bus_name, const char *dev_name) { x_err_t ret = EOK; - static struct LcdHardwareDevice lcd_device; - memset(&lcd_device, 0, sizeof(struct LcdHardwareDevice)); - - lcd_device.dev_done = &(lcd_dev_done); - - ret = LcdDeviceRegister(&lcd_device, NONE, LCD_1_DEVICE_NAME_0); + ret = LcdDeviceRegister(lcd_device, NONE, dev_name); if (EOK != ret) { - KPrintf("Board_LCD_init LcdDeviceInit device %s error %d\n", LCD_1_DEVICE_NAME_0, ret); - return ERROR; + KPrintf("Board_LCD_init LcdDeviceInit device %s error %d\n", dev_name, ret); + return -ERROR; } - ret = LcdDeviceAttachToBus(LCD_1_DEVICE_NAME_0, LCD_BUS_NAME_1); + ret = LcdDeviceAttachToBus(dev_name, bus_name); if (EOK != ret) { - KPrintf("Board_LCD_init LcdDeviceAttachToBus device %s error %d\n", LCD_1_DEVICE_NAME_0, ret); - return ERROR; + KPrintf("Board_LCD_init LcdDeviceAttachToBus device %s error %d\n", dev_name, ret); + return -ERROR; } return ret; @@ -549,44 +557,59 @@ int HwLcdInit(void) static struct LcdDriver lcd_driver; memset(&lcd_driver, 0, sizeof(struct LcdDriver)); - Lcd8080DeviceType lcd_dev = (Lcd8080DeviceType )malloc(sizeof( struct Lcd8080Device)); - memset(lcd_dev, 0, sizeof(struct Lcd8080Device)); - - if (!lcd_dev) { - return -1; + Lcd8080DeviceType lcd_dev = (Lcd8080DeviceType )x_malloc(sizeof( struct Lcd8080Device)); + if (!lcd_dev) + { + return -ERROR; } - FpioaSetFunction(41,FUNC_GPIOHS9); //DC order / data - FpioaSetFunction(47,FUNC_GPIOHS10); //BL - FpioaSetFunction(40,FUNC_SPI0_SS0); //chip select - FpioaSetFunction(38,FUNC_SPI0_SCLK); //clk + memset(lcd_dev, 0, sizeof(struct Lcd8080Device)); - lcd_dev->cs = SPI_CHIP_SELECT_0; - lcd_dev->dc_pin = 9; - lcd_dev->dma_channel = DMAC_CHANNEL0; - lcd_dev->spi_channel = SPI_DEVICE_0; - lcd_dev->lcd_info.bits_per_pixel = 16; - lcd_dev->lcd_info.pixel_format = PIXEL_FORMAT_BGR565; + FpioaSetFunction(BSP_LCD_DC_PIN, FUNC_GPIOHS9); //DC order/data + FpioaSetFunction(BSP_LCD_BL_PIN, FUNC_GPIOHS10); //BL + FpioaSetFunction(BSP_LCD_CS_PIN, FUNC_SPI0_SS0); //chip select + FpioaSetFunction(BSP_LCD_WR_PIN, FUNC_SPI0_SCLK); //clk + + lcd_dev->cs = SPI_CHIP_SELECT_0; + lcd_dev->dc_pin = 9; + lcd_dev->dma_channel = DMAC_CHANNEL0; + lcd_dev->spi_channel = SPI_DEVICE_0; + lcd_dev->lcd_info.bits_per_pixel = 16; + lcd_dev->lcd_info.pixel_format = PIXEL_FORMAT_BGR565; sysctl_set_power_mode(SYSCTL_POWER_BANK6, SYSCTL_POWER_V18); sysctl_set_power_mode(SYSCTL_POWER_BANK7, SYSCTL_POWER_V18); - sysctl_set_spi0_dvp_data(1); //open the lcd interface with spi0 - ret = BoardLcdBusInit(&lcd_dev->lcd_bus, &lcd_driver); //init lcd bus - if (EOK != ret) { + sysctl_set_spi0_dvp_data(1); //open the lcd interface with spi0 + + lcd_driver.configure = &drv_lcd_control; + + ret = BoardLcdBusInit(&lcd_dev->lcd_bus, &lcd_driver, LCD_BUS_NAME, LCD_DRV_NAME); //init lcd bus + if (EOK != ret) + { KPrintf("Board_lcd_Init error ret %u\n", ret); - return ERROR; + x_free(lcd_dev); + return -ERROR; } - ret = BoardLcdDevBend(); //init lcd device - if (EOK != ret) { + static struct LcdHardwareDevice lcd_device; + memset(&lcd_device, 0, sizeof(struct LcdHardwareDevice)); + + lcd_device.dev_done = &(lcd_dev_done); + + ret = BoardLcdDevBend(&lcd_device, NONE, LCD_BUS_NAME, LCD_DEVICE_NAME); //init lcd device + if (EOK != ret) + { KPrintf("BoardLcdDevBend error ret %u\n", ret); - return ERROR; + x_free(lcd_dev); + return -ERROR; } gpiohs_set_drive_mode(10, GPIO_DM_OUTPUT); - gpiohs_set_pin(10, GPIO_PV_HIGH); + gpiohs_set_pin(10, GPIO_PV_HIGH); + KPrintf("LCD driver inited ...\r\n"); + DrvLcdInit(lcd_dev); return ret; diff --git a/Ubiquitous/XiUOS/board/kd233/third_party_driver/gpio/connect_gpio.c b/Ubiquitous/XiUOS/board/kd233/third_party_driver/gpio/connect_gpio.c index 23fd3222e..475e13a88 100644 --- a/Ubiquitous/XiUOS/board/kd233/third_party_driver/gpio/connect_gpio.c +++ b/Ubiquitous/XiUOS/board/kd233/third_party_driver/gpio/connect_gpio.c @@ -303,13 +303,13 @@ int HwGpioInit(void) ret = PinDriverInit(&drv, PIN_DRIVER_NAME, NONE); if (ret != EOK) { KPrintf("pin driver init error %d\n", ret); - return ERROR; + return -ERROR; } ret = PinDriverAttachToBus(PIN_DRIVER_NAME, PIN_BUS_NAME); if (ret != EOK) { KPrintf("pin driver attach error %d\n", ret); - return ERROR; + return -ERROR; } static struct PinHardwareDevice dev; @@ -318,13 +318,13 @@ int HwGpioInit(void) ret = PinDeviceRegister(&dev, NONE, PIN_DEVICE_NAME); if (ret != EOK) { KPrintf("pin device register error %d\n", ret); - return ERROR; + return -ERROR; } ret = PinDeviceAttachToBus(PIN_DEVICE_NAME, PIN_BUS_NAME); if (ret != EOK) { KPrintf("pin device register error %d\n", ret); - return ERROR; + return -ERROR; } return ret; diff --git a/Ubiquitous/XiUOS/kernel/kernel_test/test_lcd.c b/Ubiquitous/XiUOS/kernel/kernel_test/test_lcd.c index cc4088c0d..4932c703a 100644 --- a/Ubiquitous/XiUOS/kernel/kernel_test/test_lcd.c +++ b/Ubiquitous/XiUOS/kernel/kernel_test/test_lcd.c @@ -93,7 +93,7 @@ int EnableLcd(const char *bus_name, const char *driver_name, const char *device_ */ void TestLcd(void) { - EnableLcd(LCD_BUS_NAME_1,LCD_DRV_NAME_1,LCD_1_DEVICE_NAME_0); + EnableLcd(LCD_BUS_NAME,LCD_DRV_NAME,LCD_DEVICE_NAME); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),TestLcd, TestLcd, Test LCD ); diff --git a/Ubiquitous/XiUOS/path_kernel.mk b/Ubiquitous/XiUOS/path_kernel.mk index b8ab6d15c..1c6ddad5a 100755 --- a/Ubiquitous/XiUOS/path_kernel.mk +++ b/Ubiquitous/XiUOS/path_kernel.mk @@ -239,6 +239,12 @@ KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/knowing/tensorflow KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/knowing/tensorflow-lite/tensorflow-lite-for-mcu/source/third_party/ruy # endif +ifeq ($(CONFIG_LIB_LV),y) +KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/lib/lvgl_new # +KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/lib/lvgl_new/examples/porting # + +endif + ifeq ($(CONFIG_CRYPTO), y) KERNELPATHS += -I$(KERNEL_ROOT)/framework/security/crypto/include # endif diff --git a/Ubiquitous/XiUOS/resources/include/dev_lcd.h b/Ubiquitous/XiUOS/resources/include/dev_lcd.h index fe967a633..7cf9380d2 100644 --- a/Ubiquitous/XiUOS/resources/include/dev_lcd.h +++ b/Ubiquitous/XiUOS/resources/include/dev_lcd.h @@ -63,6 +63,20 @@ typedef struct uint16 back_color; }LcdStringParam; +typedef struct +{ + uint16 x_pos; + uint16 y_pos; + uint16 pixel_color; +}LcdPixelParam; + +typedef struct +{ + char type; + LcdStringParam string_info; + LcdPixelParam pixel_info; +}LcdWriteParam; + struct LcdDevDone { uint32 (*open) (void *dev); From c6458f1f1dfb2b6d479f8c91b86c3a25f4273742 Mon Sep 17 00:00:00 2001 From: Wang_Weigen Date: Tue, 11 Jan 2022 17:11:17 +0800 Subject: [PATCH 3/7] add lvgl for xiuos --- APP_Framework/Applications/lv_app/lv_demo.c | 16 +++++++++--- .../Applications/lv_app/lv_demo_calendar.c | 6 ++--- APP_Framework/Applications/lv_init.c | 5 ++-- .../transform_layer/xiuos/transform.h | 16 ++++++++---- .../third_party_driver/lcd/connect_lcd.c | 13 ++++++++-- Ubiquitous/XiUOS/kernel/memory/byte_manage.c | 26 ++++++++++--------- Ubiquitous/XiUOS/path_kernel.mk | 4 +-- Ubiquitous/XiUOS/resources/include/dev_lcd.h | 14 +++++----- 8 files changed, 65 insertions(+), 35 deletions(-) diff --git a/APP_Framework/Applications/lv_app/lv_demo.c b/APP_Framework/Applications/lv_app/lv_demo.c index 538a61ca4..13536434d 100644 --- a/APP_Framework/Applications/lv_app/lv_demo.c +++ b/APP_Framework/Applications/lv_app/lv_demo.c @@ -12,11 +12,21 @@ #include "lv_demo_calendar.h" #include +extern void lv_example_chart_2(void); +extern void lv_example_img_1(void); +extern void lv_example_img_2(void); +extern void lv_example_img_3(void); +extern void lv_example_img_4(void); +extern void lv_example_line_1(void); +extern void lv_example_aoteman(void); void* lvgl_thread(void *parameter) { /* display demo; you may replace with your LVGL application at here */ - lv_demo_calendar(); - + // lv_demo_calendar(); + // lv_example_img_1(); + // lv_example_chart_2(); + // lv_example_line_1(); + lv_example_aoteman(); /* handle the tasks of LVGL */ while(1) { @@ -29,7 +39,7 @@ pthread_t lvgl_task; static int lvgl_demo_init(void) { pthread_attr_t attr; - attr.schedparam.sched_priority = 20; + attr.schedparam.sched_priority = 25; attr.stacksize = 4096; PrivTaskCreate(&lvgl_task, &attr, lvgl_thread, NULL); diff --git a/APP_Framework/Applications/lv_app/lv_demo_calendar.c b/APP_Framework/Applications/lv_app/lv_demo_calendar.c index de1a68e9f..3b4cabb68 100644 --- a/APP_Framework/Applications/lv_app/lv_demo_calendar.c +++ b/APP_Framework/Applications/lv_app/lv_demo_calendar.c @@ -18,7 +18,7 @@ static void event_handler(lv_event_t * e) void lv_demo_calendar(void) { lv_obj_t * calendar = lv_calendar_create(lv_scr_act()); - lv_obj_set_size(calendar, 240, 240); + lv_obj_set_size(calendar, 320, 240); lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 0); lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL); @@ -35,7 +35,7 @@ void lv_demo_calendar(void) highlighted_days[1].month = 02; highlighted_days[1].day = 11; - highlighted_days[2].year = 2022; + highlighted_days[2].year = 2021; highlighted_days[2].month = 02; highlighted_days[2].day = 22; @@ -46,5 +46,5 @@ void lv_demo_calendar(void) #elif LV_USE_CALENDAR_HEADER_ARROW lv_calendar_header_arrow_create(calendar); #endif - lv_calendar_set_showed_date(calendar, 2021, 10); + // lv_calendar_set_showed_date(calendar, 2021, 10); } diff --git a/APP_Framework/Applications/lv_init.c b/APP_Framework/Applications/lv_init.c index 3ff01dddc..c5989a514 100644 --- a/APP_Framework/Applications/lv_init.c +++ b/APP_Framework/Applications/lv_init.c @@ -14,7 +14,8 @@ extern void lv_port_indev_init(void); #if LV_USE_LOG && LV_LOG_PRINTF static void lv_rt_log(const char *buf) { - LOG_I(buf); + printf(buf); + printf("\n"); } #endif @@ -23,12 +24,12 @@ int lv_port_init(void) #if LV_USE_LOG && LV_LOG_PRINTF lv_log_register_print_cb(lv_rt_log); #endif - lv_init(); #ifndef PKG_USING_LVGL_DISP_DEVICE lv_port_disp_init(); #endif + #ifndef PKG_USING_LVGL_INDEV_DEVICE lv_port_indev_init(); #endif diff --git a/APP_Framework/Framework/transform_layer/xiuos/transform.h b/APP_Framework/Framework/transform_layer/xiuos/transform.h index 1e50350d5..a43c13770 100644 --- a/APP_Framework/Framework/transform_layer/xiuos/transform.h +++ b/APP_Framework/Framework/transform_layer/xiuos/transform.h @@ -154,7 +154,7 @@ typedef struct uint16 y_pos; uint16 width; uint16 height; - uint8 font_size; + uint8 font_size; uint8 *addr; uint16 font_color; uint16 back_color; @@ -162,18 +162,24 @@ typedef struct typedef struct { - uint16 x_pos; - uint16 y_pos; - uint16 pixel_color; + uint16 x_startpos; + uint16 x_endpos; + uint16 y_startpos; + uint16 y_endpos; + void* pixel_color; }LcdPixelParam; typedef struct { char type; // 0:write string;1:write dot + LcdPixelParam pixel_info; LcdStringParam string_info; - LcdPixelParam pixel_info; }LcdWriteParam; +#define PRIV_SYSTICK_GET (CurrentTicksGain()) +#define PRIV_LCD_DEV "/dev/lcd_dev" +#define MY_DISP_HOR_RES BSP_LCD_Y_MAX +#define MY_DISP_VER_RES BSP_LCD_X_MAX /**********************mutex**************************/ int PrivMutexCreate(pthread_mutex_t *p_mutex, const pthread_mutexattr_t *attr); diff --git a/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/connect_lcd.c b/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/connect_lcd.c index 25e109d11..d7370d1f8 100644 --- a/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/connect_lcd.c +++ b/Ubiquitous/XiUOS/board/aiit-riscv64-board/third_party_driver/lcd/connect_lcd.c @@ -239,6 +239,14 @@ static void DrvLcdSetPixel(uint16_t x, uint16_t y, uint16_t color) DrvLcdDataHalfWord(&color, 1); } +static void DrvLcdSetPixelDot(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,void* color) +{ + uint32 size = 0; + size = (x2- x1 + 1)*(y2 - y1 + 1); + DrvLcdSetArea(x1, y1, x2, y2); + DrvLcdDataHalfWord(color, size); +} + void LcdShowChar(uint16 x,uint16 y,uint8 num,uint8 size,uint16 color,uint16 back_color) { uint8 temp,t1,t; @@ -460,7 +468,7 @@ static uint32 LcdWrite(void *dev, struct BusBlockWriteParam *write_param) return -ERROR; } LcdWriteParam * show = (LcdWriteParam *)write_param->buffer; - KPrintf("DEBUG TYPE %d X:%d Y:%d color %d\n",show->pixel_info.x_pos, show->pixel_info.y_pos, show->pixel_info.pixel_color); + // KPrintf("DEBUG TYPE %d X1:%d X2:%d Y1:%d Y2:%d\n",show->type,show->pixel_info.x_startpos, show->pixel_info.x_endpos,show->pixel_info.y_startpos, show->pixel_info.y_endpos); if(0 == show->type) //output string { LcdShowString(show->string_info.x_pos,show->string_info.y_pos,show->string_info.width,show->string_info.height,show->string_info.font_size,show->string_info.addr,show->string_info.font_color,show->string_info.back_color); @@ -468,7 +476,8 @@ static uint32 LcdWrite(void *dev, struct BusBlockWriteParam *write_param) } else if(1 == show->type) //output dot { - DrvLcdSetPixel(show->pixel_info.x_pos, show->pixel_info.y_pos, show->pixel_info.pixel_color); + // DrvLcdSetPixel(show->pixel_info.x_pos, show->pixel_info.y_pos, show->pixel_info.pixel_color); + DrvLcdSetPixelDot(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos,show->pixel_info.pixel_color); return EOK; } else diff --git a/Ubiquitous/XiUOS/kernel/memory/byte_manage.c b/Ubiquitous/XiUOS/kernel/memory/byte_manage.c index 1f447528d..9fda3a1dc 100644 --- a/Ubiquitous/XiUOS/kernel/memory/byte_manage.c +++ b/Ubiquitous/XiUOS/kernel/memory/byte_manage.c @@ -349,11 +349,11 @@ static void* BigMemMalloc(struct DynamicBuddyMemory *dynamic_buddy, x_size_t siz } /* best-fit method */ - for (node = dynamic_buddy->mm_freenode_list[ndx].next; - (ndx < MEM_LINKNRS ) && (node->size < allocsize); - node = node->next) { - ndx++; - }; + for (node = dynamic_buddy->mm_freenode_list[ndx].next; + (ndx < MEM_LINKNRS ) && (node->size < allocsize); + node = node->next) { + ndx++; + }; /* get the best-fit freeNode */ if (node && (node->size >= allocsize)) { struct DynamicFreeNode *remainder; @@ -1167,7 +1167,7 @@ void MemoryInfo(uint32 *total_memory, uint32 *used_memory, uint32 *max_used_memo #ifdef TOOL_SHELL #include -void ShowBuddy(void); +void ShowBuddy(); void ShowMemory(void); /** * This function will list the statistic information about memory. @@ -1206,16 +1206,18 @@ void ShowBuddy(void) lock = CriticalAreaLock(); KPrintf("\n\033[41;1mlist memory information\033[0m\n", __func__); for(int level = 0; level < MEM_LINKNRS; level++) { - KPrintf("\n %s level [%d],memory size[2^%d] \n",__func__, level,level +6); + KPrintf("%s level [%d],memory size[2^%d] \n",__func__, level,level +6); for (debug = &ByteManager.dynamic_buddy_manager.mm_freenode_list[level]; ; ) { - if(debug->size > 0) - KPrintf(" [current node %x,next node %x, size %u, flag %x]\n",debug, debug->next,debug->size,debug->flag); - else - KPrintf(" [listhead node %x,next node %x]\n",debug, debug->next); if(debug->next) + { debug = debug->next; - if(debug->size == 0) + if(debug->size > 0) + KPrintf(" [current node %x,next node %x, size %u, flag %x]\n",debug, debug->next,debug->size,debug->flag); + else + KPrintf(" \n"); + } + if(debug->size == 0 || NONE == debug->next) break; }; } diff --git a/Ubiquitous/XiUOS/path_kernel.mk b/Ubiquitous/XiUOS/path_kernel.mk index 1c6ddad5a..e2a76c2cd 100755 --- a/Ubiquitous/XiUOS/path_kernel.mk +++ b/Ubiquitous/XiUOS/path_kernel.mk @@ -240,8 +240,8 @@ KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/knowing/tensorflow endif ifeq ($(CONFIG_LIB_LV),y) -KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/lib/lvgl_new # -KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/lib/lvgl_new/examples/porting # +KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/lib/lvgl # +KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/lib/lvgl/examples/porting # endif diff --git a/Ubiquitous/XiUOS/resources/include/dev_lcd.h b/Ubiquitous/XiUOS/resources/include/dev_lcd.h index 7cf9380d2..1e2056dee 100644 --- a/Ubiquitous/XiUOS/resources/include/dev_lcd.h +++ b/Ubiquitous/XiUOS/resources/include/dev_lcd.h @@ -57,24 +57,26 @@ typedef struct uint16 y_pos; uint16 width; uint16 height; - uint8 font_size; - uint8 *addr; + uint8 font_size; + uint8 *addr; uint16 font_color; uint16 back_color; }LcdStringParam; typedef struct { - uint16 x_pos; - uint16 y_pos; - uint16 pixel_color; + uint16 x_startpos; + uint16 x_endpos; + uint16 y_startpos; + uint16 y_endpos; + void* pixel_color; }LcdPixelParam; typedef struct { char type; + LcdPixelParam pixel_info; LcdStringParam string_info; - LcdPixelParam pixel_info; }LcdWriteParam; struct LcdDevDone From 3ca98f520d3bb046df4543005952adcc10df94b6 Mon Sep 17 00:00:00 2001 From: Wang_Weigen Date: Tue, 11 Jan 2022 17:51:44 +0800 Subject: [PATCH 4/7] repair the compiler error of lvgl --- APP_Framework/Applications/Makefile | 11 +++-------- APP_Framework/Applications/lv_app/Makefile | 2 +- APP_Framework/Applications/{ => lv_app}/lv_init.c | 0 3 files changed, 4 insertions(+), 9 deletions(-) rename APP_Framework/Applications/{ => lv_app}/lv_init.c (100%) diff --git a/APP_Framework/Applications/Makefile b/APP_Framework/Applications/Makefile index 251e972f6..c3815e1bf 100644 --- a/APP_Framework/Applications/Makefile +++ b/APP_Framework/Applications/Makefile @@ -4,21 +4,16 @@ ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) include $(APPDIR)/Make.defs CSRCS += framework_init.c include $(APPDIR)/Application.mk - -ifeq ($(CONFIG_LIB_LV),y) -SRC_FILES += lv_init.c - -SRC_DIR += lv_app endif -ifeq ($(CONFIG_APPLICATION_OTA),y) - SRC_DIR += ota -endif ifeq ($(CONFIG_ADD_XIUOS_FETURES),y) SRC_DIR := general_functions app_test SRC_FILES := main.c framework_init.c + ifeq ($(CONFIG_LIB_LV),y) + SRC_DIR += lv_app + endif ifeq ($(CONFIG_APPLICATION_OTA),y) SRC_DIR += ota diff --git a/APP_Framework/Applications/lv_app/Makefile b/APP_Framework/Applications/lv_app/Makefile index 0efc4bd16..43c648340 100644 --- a/APP_Framework/Applications/lv_app/Makefile +++ b/APP_Framework/Applications/lv_app/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := lv_demo.c lv_demo_calendar.c +SRC_FILES := lv_init.c lv_demo.c lv_demo_calendar.c include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/Applications/lv_init.c b/APP_Framework/Applications/lv_app/lv_init.c similarity index 100% rename from APP_Framework/Applications/lv_init.c rename to APP_Framework/Applications/lv_app/lv_init.c From 27a40042f440d4c7141eb0f9ab55e57c172995f9 Mon Sep 17 00:00:00 2001 From: Wang_Weigen Date: Tue, 11 Jan 2022 18:17:26 +0800 Subject: [PATCH 5/7] add fpu test --- Ubiquitous/XiUOS/kernel/kernel_test/Makefile | 2 +- .../XiUOS/kernel/kernel_test/test_fpu.c | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 Ubiquitous/XiUOS/kernel/kernel_test/test_fpu.c diff --git a/Ubiquitous/XiUOS/kernel/kernel_test/Makefile b/Ubiquitous/XiUOS/kernel/kernel_test/Makefile index e1daf45c1..d8d58996c 100644 --- a/Ubiquitous/XiUOS/kernel/kernel_test/Makefile +++ b/Ubiquitous/XiUOS/kernel/kernel_test/Makefile @@ -1,4 +1,4 @@ -SRC_FILES := test_main.c +SRC_FILES := test_main.c test_fpu.c ifeq ($(CONFIG_KERNEL_TEST_SEM),y) SRC_FILES += test_sem.c diff --git a/Ubiquitous/XiUOS/kernel/kernel_test/test_fpu.c b/Ubiquitous/XiUOS/kernel/kernel_test/test_fpu.c new file mode 100644 index 000000000..fddb3de19 --- /dev/null +++ b/Ubiquitous/XiUOS/kernel/kernel_test/test_fpu.c @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file test_fpu.c +* @brief support to test touch function +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-01-11 +*/ +#include +void FpuTest(void) +{ + float i = 8.25; + KPrintf("float i = 8.25 ['i %s 8' && 'i %s 9']\n",i > 8 ? ">" : "<",i < 9 ? "<" : ">"); + float add = i + 5.1; + KPrintf("float add(13.35) = i + 5.1 ['add %s 13' && 'add %s 14']\n",add > 13 ? ">" : "<",add < 14 ? "<" : ">"); + float sub = i - 5.1; + KPrintf("float sub(3.15) = i - 5.1 ['sub %s 3' && 'sub %s 4']\n",sub > 3 ? ">" : "<",sub < 4 ? "<" : ">"); + float mul = i * 5.1; + KPrintf("float mul(42.075) = i * 5.1 ['mul %s 42' && 'mul %s 43']\n",mul > 42 ? ">" : "<",mul < 43 ? "<" : ">"); + float div = i / 5.1; + KPrintf("float div(1.617) = i / 5.1 ['div %s 1' && 'div %s 2']\n",div > 1 ? ">" : "<",div < 2 ? "<" : ">"); +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),FpuTest, FpuTest, Close AC task ); \ No newline at end of file From c88dc282fcbfd7f3acee50632dde29cf6c3ade27 Mon Sep 17 00:00:00 2001 From: Wang_Weigen Date: Mon, 17 Jan 2022 15:05:42 +0800 Subject: [PATCH 6/7] add semc and extern sram test for ok-1052 --- Ubiquitous/XiUOS/board/ok1052-c/board.c | 27 + .../board/ok1052-c/third_party_driver/Kconfig | 26 +- .../ok1052-c/third_party_driver/Makefile | 4 + .../third_party_driver/common/pin_mux.c | 553 ++++++++- .../ok1052-c/third_party_driver/semc/Kconfig | 9 + .../ok1052-c/third_party_driver/semc/Makefile | 3 + .../third_party_driver/semc/connect_semc.c | 57 + .../third_party_driver/semc/fsl_semc.c | 1066 +++++++++++++++++ .../third_party_driver/semc/fsl_semc.h | 830 +++++++++++++ .../semc/semc_externsdram_test.c | 180 +++ .../XiUOS/kernel/kernel_test/extsram_test.c | 12 +- Ubiquitous/XiUOS/kernel/memory/byte_manage.c | 14 +- 12 files changed, 2762 insertions(+), 19 deletions(-) create mode 100644 Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/Kconfig create mode 100644 Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/Makefile create mode 100644 Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/connect_semc.c create mode 100644 Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/fsl_semc.c create mode 100644 Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/fsl_semc.h create mode 100644 Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/semc_externsdram_test.c diff --git a/Ubiquitous/XiUOS/board/ok1052-c/board.c b/Ubiquitous/XiUOS/board/ok1052-c/board.c index fe07ae869..02fd1cd76 100644 --- a/Ubiquitous/XiUOS/board/ok1052-c/board.c +++ b/Ubiquitous/XiUOS/board/ok1052-c/board.c @@ -29,6 +29,14 @@ #include "board.h" #include "pin_mux.h" + +#ifdef BSP_USING_SEMC +extern status_t BOARD_InitSEMC(void); +#ifdef BSP_USING_EXTSRAM +extern int ExtSramInit(void); +#endif +#endif + #if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED #include "fsl_lpi2c.h" #endif /* SDK_I2C_BASED_COMPONENT_USED */ @@ -607,6 +615,23 @@ void InitBoardHardware() #endif InitBoardMemory((void *)HEAP_BEGIN, (void *)HEAP_END); +#ifdef BSP_USING_SEMC + CLOCK_InitSysPfd(kCLOCK_Pfd2, 29); + /* Set semc clock to 163.86 MHz */ + CLOCK_SetMux(kCLOCK_SemcMux, 1); + CLOCK_SetDiv(kCLOCK_SemcDiv, 1); + + if (BOARD_InitSEMC() != kStatus_Success) + { + KPrintf("\r\n SEMC Init Failed\r\n"); + } +#ifdef MEM_EXTERN_SRAM + else + { + ExtSramInit(); + } +#endif +#endif #ifdef BSP_USING_LWIP ETH_BSP_Config(); @@ -616,5 +641,7 @@ void InitBoardHardware() Imrt1052HwUartInit(); #endif InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); + + } diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/Kconfig b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/Kconfig index 8674a2ef6..a0480d689 100644 --- a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/Kconfig +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/Kconfig @@ -1,12 +1,20 @@ menuconfig BSP_USING_LPUART -bool "Using UART device" -default y -select RESOURCES_SERIAL -if BSP_USING_LPUART -source "$BSP_DIR/third_party_driver/uart/Kconfig" -endif + bool "Using UART device" + default y + select RESOURCES_SERIAL + if BSP_USING_LPUART + source "$BSP_DIR/third_party_driver/uart/Kconfig" + endif menuconfig BSP_USING_LWIP -bool "Using LwIP device" -default n -select RESOURCES_LWIP + bool "Using LwIP device" + default n + select RESOURCES_LWIP + +menuconfig BSP_USING_SEMC + bool "Using SEMC device" + default y + + if BSP_USING_SEMC + source "$BSP_DIR/third_party_driver/semc/Kconfig" + endif diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/Makefile b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/Makefile index 71b25e5e8..b55123bc5 100644 --- a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/Makefile +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/Makefile @@ -8,4 +8,8 @@ ifeq ($(CONFIG_BSP_USING_LWIP),y) SRC_DIR += ethernet endif +ifeq ($(CONFIG_BSP_USING_SEMC),y) + SRC_DIR += semc +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/common/pin_mux.c b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/common/pin_mux.c index 8d0a4cf50..8504b75df 100755 --- a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/common/pin_mux.c +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/common/pin_mux.c @@ -46,6 +46,557 @@ void BOARD_InitBootPins(void) { BOARD_InitPins(); } +void SemcPinmuxConfig(void) +{ + + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_00_SEMC_DATA00, /* GPIO_EMC_00 is configured as SEMC_DATA00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_01_SEMC_DATA01, /* GPIO_EMC_01 is configured as SEMC_DATA01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_02_SEMC_DATA02, /* GPIO_EMC_02 is configured as SEMC_DATA02 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_03_SEMC_DATA03, /* GPIO_EMC_03 is configured as SEMC_DATA03 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_04_SEMC_DATA04, /* GPIO_EMC_04 is configured as SEMC_DATA04 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_05_SEMC_DATA05, /* GPIO_EMC_05 is configured as SEMC_DATA05 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_06_SEMC_DATA06, /* GPIO_EMC_06 is configured as SEMC_DATA06 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_07_SEMC_DATA07, /* GPIO_EMC_07 is configured as SEMC_DATA07 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_08_SEMC_DM00, /* GPIO_EMC_08 is configured as SEMC_DM00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_09_SEMC_ADDR00, /* GPIO_EMC_09 is configured as SEMC_ADDR00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_10_SEMC_ADDR01, /* GPIO_EMC_10 is configured as SEMC_ADDR01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_11_SEMC_ADDR02, /* GPIO_EMC_11 is configured as SEMC_ADDR02 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_12_SEMC_ADDR03, /* GPIO_EMC_12 is configured as SEMC_ADDR03 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_13_SEMC_ADDR04, /* GPIO_EMC_13 is configured as SEMC_ADDR04 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_14_SEMC_ADDR05, /* GPIO_EMC_14 is configured as SEMC_ADDR05 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_15_SEMC_ADDR06, /* GPIO_EMC_15 is configured as SEMC_ADDR06 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_16_SEMC_ADDR07, /* GPIO_EMC_16 is configured as SEMC_ADDR07 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_17_SEMC_ADDR08, /* GPIO_EMC_17 is configured as SEMC_ADDR08 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_18_SEMC_ADDR09, /* GPIO_EMC_18 is configured as SEMC_ADDR09 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_19_SEMC_ADDR11, /* GPIO_EMC_19 is configured as SEMC_ADDR11 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_20_SEMC_ADDR12, /* GPIO_EMC_20 is configured as SEMC_ADDR12 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_21_SEMC_BA0, /* GPIO_EMC_21 is configured as SEMC_BA0 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_22_SEMC_BA1, /* GPIO_EMC_22 is configured as SEMC_BA1 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_23_SEMC_ADDR10, /* GPIO_EMC_23 is configured as SEMC_ADDR10 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_24_SEMC_CAS, /* GPIO_EMC_24 is configured as SEMC_CAS */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_25_SEMC_RAS, /* GPIO_EMC_25 is configured as SEMC_RAS */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_26_SEMC_CLK, /* GPIO_EMC_26 is configured as SEMC_CLK */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_27_SEMC_CKE, /* GPIO_EMC_27 is configured as SEMC_CKE */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_28_SEMC_WE, /* GPIO_EMC_28 is configured as SEMC_WE */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_29_SEMC_CS0, /* GPIO_EMC_29 is configured as SEMC_CS0 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_30_SEMC_DATA08, /* GPIO_EMC_30 is configured as SEMC_DATA08 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_31_SEMC_DATA09, /* GPIO_EMC_31 is configured as SEMC_DATA09 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_32_SEMC_DATA10, /* GPIO_EMC_32 is configured as SEMC_DATA10 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_33_SEMC_DATA11, /* GPIO_EMC_33 is configured as SEMC_DATA11 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_34_SEMC_DATA12, /* GPIO_EMC_34 is configured as SEMC_DATA12 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_35_SEMC_DATA13, /* GPIO_EMC_35 is configured as SEMC_DATA13 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_36_SEMC_DATA14, /* GPIO_EMC_36 is configured as SEMC_DATA14 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_37_SEMC_DATA15, /* GPIO_EMC_37 is configured as SEMC_DATA15 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_38_SEMC_DM01, /* GPIO_EMC_38 is configured as SEMC_DM01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_39_SEMC_DQS, /* GPIO_EMC_39 is configured as SEMC_DQS */ + 1U); /* Software Input On Field: Force input path of pad GPIO_EMC_39 */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_40_SEMC_RDY, /* GPIO_EMC_40 is configured as SEMC_RDY */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_41_SEMC_CSX00, /* GPIO_EMC_41 is configured as SEMC_CSX00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_00_SEMC_DATA00, /* GPIO_EMC_00 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_01_SEMC_DATA01, /* GPIO_EMC_01 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_02_SEMC_DATA02, /* GPIO_EMC_02 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_03_SEMC_DATA03, /* GPIO_EMC_03 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_04_SEMC_DATA04, /* GPIO_EMC_04 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_05_SEMC_DATA05, /* GPIO_EMC_05 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_06_SEMC_DATA06, /* GPIO_EMC_06 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_07_SEMC_DATA07, /* GPIO_EMC_07 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_08_SEMC_DM00, /* GPIO_EMC_08 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_09_SEMC_ADDR00, /* GPIO_EMC_09 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_10_SEMC_ADDR01, /* GPIO_EMC_10 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_11_SEMC_ADDR02, /* GPIO_EMC_11 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_12_SEMC_ADDR03, /* GPIO_EMC_12 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_13_SEMC_ADDR04, /* GPIO_EMC_13 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_14_SEMC_ADDR05, /* GPIO_EMC_14 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_15_SEMC_ADDR06, /* GPIO_EMC_15 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_16_SEMC_ADDR07, /* GPIO_EMC_16 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_17_SEMC_ADDR08, /* GPIO_EMC_17 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_18_SEMC_ADDR09, /* GPIO_EMC_18 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_19_SEMC_ADDR11, /* GPIO_EMC_19 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_20_SEMC_ADDR12, /* GPIO_EMC_20 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_21_SEMC_BA0, /* GPIO_EMC_21 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_22_SEMC_BA1, /* GPIO_EMC_22 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_23_SEMC_ADDR10, /* GPIO_EMC_23 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_24_SEMC_CAS, /* GPIO_EMC_24 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_25_SEMC_RAS, /* GPIO_EMC_25 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_26_SEMC_CLK, /* GPIO_EMC_26 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_27_SEMC_CKE, /* GPIO_EMC_27 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_28_SEMC_WE, /* GPIO_EMC_28 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_29_SEMC_CS0, /* GPIO_EMC_29 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_30_SEMC_DATA08, /* GPIO_EMC_30 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_31_SEMC_DATA09, /* GPIO_EMC_31 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_32_SEMC_DATA10, /* GPIO_EMC_32 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_33_SEMC_DATA11, /* GPIO_EMC_33 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_34_SEMC_DATA12, /* GPIO_EMC_34 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_35_SEMC_DATA13, /* GPIO_EMC_35 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_36_SEMC_DATA14, /* GPIO_EMC_36 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_37_SEMC_DATA15, /* GPIO_EMC_37 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_38_SEMC_DM01, /* GPIO_EMC_38 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_39_SEMC_DQS, /* GPIO_EMC_39 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_40_SEMC_RDY, /* GPIO_EMC_40 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_41_SEMC_CSX00, /* GPIO_EMC_41 PAD functional properties : */ + 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/7 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Enabled */ +} /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: @@ -94,7 +645,7 @@ void BOARD_InitPins(void) { // IOMUXC_SetPinMux( // IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, /* GPIO_AD_B0_09 is configured as GPIO1_IO09 */ // 0U); /* Software Input On Field: Input Path is determined by functionality */ - + SemcPinmuxConfig(); IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_03_GPIO1_IO03, /* GPIO_AD_B0_09 is configured as GPIO1_IO09 */ diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/Kconfig b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/Kconfig new file mode 100644 index 000000000..f081299fb --- /dev/null +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/Kconfig @@ -0,0 +1,9 @@ +config BSP_USING_EXTSRAM + bool "config semc extern sram" + default n + select MEM_EXTERN_SRAM + if BSP_USING_EXTSRAM + config EXTSRAM_MAX_NUM + int "config extsram chip num" + default 4 + endif diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/Makefile b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/Makefile new file mode 100644 index 000000000..6438aa6ea --- /dev/null +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_semc.c fsl_semc.c semc_externsdram_test.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/connect_semc.c b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/connect_semc.c new file mode 100644 index 000000000..1f05cd4ed --- /dev/null +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/connect_semc.c @@ -0,0 +1,57 @@ +#include "fsl_semc.h" +#include "clock_config.h" +#include + +#define EXAMPLE_SEMC SEMC +#define EXAMPLE_SEMC_START_ADDRESS (0x80000000U) +#define EXAMPLE_SEMC_CLK_FREQ CLOCK_GetFreq(kCLOCK_SemcClk) +#define SEMC_SRAM_SIZE (32 * 1024) + +status_t BOARD_InitSEMC(void) +{ + semc_config_t config; + semc_sdram_config_t sdramconfig; + uint32_t clockFrq = EXAMPLE_SEMC_CLK_FREQ; + + /* Initializes the MAC configure structure to zero. */ + memset(&config, 0, sizeof(semc_config_t)); + memset(&sdramconfig, 0, sizeof(semc_sdram_config_t)); + + /* Initialize SEMC. */ + SEMC_GetDefaultConfig(&config); + config.dqsMode = kSEMC_Loopbackdqspad; /* For more accurate timing. */ + SEMC_Init(SEMC, &config); + + /* Configure SDRAM. */ + sdramconfig.csxPinMux = kSEMC_MUXCSX0; + sdramconfig.address = 0x80000000; + sdramconfig.memsize_kbytes = 32 * 1024; /* 32MB = 32*1024*1KBytes*/ + sdramconfig.portSize = kSEMC_PortSize16Bit; + sdramconfig.burstLen = kSEMC_Sdram_BurstLen8; + sdramconfig.columnAddrBitNum = kSEMC_SdramColunm_9bit; + sdramconfig.casLatency = kSEMC_LatencyThree; + sdramconfig.tPrecharge2Act_Ns = 18; /* Trp 18ns */ + sdramconfig.tAct2ReadWrite_Ns = 18; /* Trcd 18ns */ + sdramconfig.tRefreshRecovery_Ns = 67; /* Use the maximum of the (Trfc , Txsr). */ + sdramconfig.tWriteRecovery_Ns = 12; /* 12ns */ + sdramconfig.tCkeOff_Ns = + 42; /* The minimum cycle of SDRAM CLK off state. CKE is off in self refresh at a minimum period tRAS.*/ + sdramconfig.tAct2Prechage_Ns = 42; /* Tras 42ns */ + sdramconfig.tSelfRefRecovery_Ns = 67; + sdramconfig.tRefresh2Refresh_Ns = 60; + sdramconfig.tAct2Act_Ns = 60; + sdramconfig.tPrescalePeriod_Ns = 160 * (1000000000 / clockFrq); + sdramconfig.refreshPeriod_nsPerRow = 64 * 1000000 / 8192; /* 64ms/8192 */ + sdramconfig.refreshUrgThreshold = sdramconfig.refreshPeriod_nsPerRow; + sdramconfig.refreshBurstLen = 1; + return SEMC_ConfigureSDRAM(SEMC, kSEMC_SDRAM_CS0, &sdramconfig, clockFrq); +} + +#ifdef BSP_USING_EXTSRAM +int ExtSramInit(void) +{ + extern void ExtSramInitBoardMemory(void *start_phy_address, void *end_phy_address, uint8 extsram_idx); + ExtSramInitBoardMemory((void*)(EXAMPLE_SEMC_START_ADDRESS), (void*)((EXAMPLE_SEMC_START_ADDRESS + SEMC_SRAM_SIZE)), kSEMC_SDRAM_CS0); + return 0; +} +#endif \ No newline at end of file diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/fsl_semc.c b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/fsl_semc.c new file mode 100644 index 000000000..be3f225e7 --- /dev/null +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/fsl_semc.c @@ -0,0 +1,1066 @@ +/* + * Copyright 2017-2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_semc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.semc" +#endif + +/*! @brief Define macros for SEMC driver. */ +#define SEMC_IPCOMMANDDATASIZEBYTEMAX (4U) +#define SEMC_IPCOMMANDMAGICKEY (0xA55A) +#define SEMC_IOCR_PINMUXBITWIDTH (0x3U) +#define SEMC_IOCR_NAND_CE (4U) +#define SEMC_IOCR_NOR_CE (5U) +#define SEMC_IOCR_NOR_CE_A8 (2U) +#define SEMC_IOCR_PSRAM_CE (6U) +#define SEMC_IOCR_PSRAM_CE_A8 (3U) +#define SEMC_IOCR_DBI_CSX (7U) +#define SEMC_IOCR_DBI_CSX_A8 (4U) +#define SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE (24U) +#define SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHMAX (28U) +#define SEMC_BMCR0_TYPICAL_WQOS (5U) +#define SEMC_BMCR0_TYPICAL_WAGE (8U) +#define SEMC_BMCR0_TYPICAL_WSH (0x40U) +#define SEMC_BMCR0_TYPICAL_WRWS (0x10U) +#define SEMC_BMCR1_TYPICAL_WQOS (5U) +#define SEMC_BMCR1_TYPICAL_WAGE (8U) +#define SEMC_BMCR1_TYPICAL_WPH (0x60U) +#define SEMC_BMCR1_TYPICAL_WBR (0x40U) +#define SEMC_BMCR1_TYPICAL_WRWS (0x24U) +#define SEMC_STARTADDRESS (0x80000000U) +#define SEMC_ENDADDRESS (0xDFFFFFFFU) +#define SEMC_BR_MEMSIZE_MIN (4) +#define SEMC_BR_MEMSIZE_OFFSET (2) +#define SEMC_BR_MEMSIZE_MAX (4 * 1024 * 1024) +#define SEMC_SDRAM_MODESETCAL_OFFSET (4) +#define SEMC_BR_REG_NUM (9) +#define SEMC_BYTE_NUMBIT (8) +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get instance number for SEMC module. + * + * @param base SEMC peripheral base address + */ +static uint32_t SEMC_GetInstance(SEMC_Type *base); + +/*! + * @brief Covert the input memory size to internal register set value. + * + * @param base SEMC peripheral base address + * @param size_kbytes SEMC memory size in unit of kbytes. + * @param sizeConverted SEMC converted memory size to 0 ~ 0x1F. + * @return Execution status. + */ +static status_t SEMC_CovertMemorySize(SEMC_Type *base, uint32_t size_kbytes, uint8_t *sizeConverted); + +/*! + * @brief Covert the external timing nanosecond to internal clock cycle. + * + * @param time_ns SEMC external time interval in unit of nanosecond. + * @param clkSrc_Hz SEMC clock source frequency. + * @return The changed internal clock cycle. + */ +static uint8_t SEMC_ConvertTiming(uint32_t time_ns, uint32_t clkSrc_Hz); + +/*! + * @brief Configure IP command. + * + * @param base SEMC peripheral base address. + * @param size_bytes SEMC IP command data size. + * @return Execution status. + */ +static status_t SEMC_ConfigureIPCommand(SEMC_Type *base, uint8_t size_bytes); + +/*! + * @brief Check if the IP command has finished. + * + * @param base SEMC peripheral base address. + * @return Execution status. + */ +static status_t SEMC_IsIPCommandDone(SEMC_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to SEMC clocks for each instance. */ +static const clock_ip_name_t s_semcClock[FSL_FEATURE_SOC_SEMC_COUNT] = SEMC_CLOCKS; +static const clock_ip_name_t s_semcExtClock[FSL_FEATURE_SOC_SEMC_COUNT] = SEMC_EXSC_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Pointers to SEMC bases for each instance. */ +static SEMC_Type *const s_semcBases[] = SEMC_BASE_PTRS; +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t SEMC_GetInstance(SEMC_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_semcBases); instance++) + { + if (s_semcBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_semcBases)); + + return instance; +} + +static status_t SEMC_CovertMemorySize(SEMC_Type *base, uint32_t size_kbytes, uint8_t *sizeConverted) +{ + assert(sizeConverted); + uint32_t memsize; + + if ((size_kbytes < SEMC_BR_MEMSIZE_MIN) || (size_kbytes > SEMC_BR_MEMSIZE_MAX)) + { + return kStatus_SEMC_InvalidMemorySize; + } + + *sizeConverted = 0; + memsize = size_kbytes / 8; + while (memsize) + { + memsize >>= 1; + (*sizeConverted)++; + } + return kStatus_Success; +} + +static uint8_t SEMC_ConvertTiming(uint32_t time_ns, uint32_t clkSrc_Hz) +{ + assert(clkSrc_Hz); + + uint8_t clockCycles = 0; + uint32_t tClk_us; + + clkSrc_Hz /= 1000000; + tClk_us = 1000000 / clkSrc_Hz; + + while (tClk_us * clockCycles < (time_ns * 1000)) + { + clockCycles++; + } + + return clockCycles; +} + +static status_t SEMC_ConfigureIPCommand(SEMC_Type *base, uint8_t size_bytes) +{ + if ((size_bytes > SEMC_IPCOMMANDDATASIZEBYTEMAX) || (!size_bytes)) + { + return kStatus_SEMC_InvalidIpcmdDataSize; + } + + /* Set data size. */ + /* Note: It is better to set data size as the device data port width when transfering + * device command data. but for device memory data transfer, it can be set freely. + * Note: If the data size is greater than data port width, for example, datsz = 4, data port = 16bit, + * then the 4-byte data transfer will be split into two 2-byte transfer, the slave address + * will be switched automatically according to connected device type*/ + base->IPCR1 = SEMC_IPCR1_DATSZ(size_bytes); + /* Clear data size. */ + base->IPCR2 = 0; + /* Set data size. */ + if (size_bytes < 4) + { + base->IPCR2 |= SEMC_IPCR2_BM3_MASK; + } + if (size_bytes < 3) + { + base->IPCR2 |= SEMC_IPCR2_BM2_MASK; + } + if (size_bytes < 2) + { + base->IPCR2 |= SEMC_IPCR2_BM1_MASK; + } + return kStatus_Success; +} + +static status_t SEMC_IsIPCommandDone(SEMC_Type *base) +{ + /* Poll status bit till command is done*/ + while (!(base->INTR & SEMC_INTR_IPCMDDONE_MASK)) + { + }; + + /* Clear status bit */ + base->INTR |= SEMC_INTR_IPCMDDONE_MASK; + + /* Check error status */ + if (base->INTR & SEMC_INTR_IPCMDERR_MASK) + { + base->INTR |= SEMC_INTR_IPCMDERR_MASK; + return kStatus_SEMC_IpCommandExecutionError; + } + + return kStatus_Success; +} + +/*! + * brief Gets the SEMC default basic configuration structure. + * + * The purpose of this API is to get the default SEMC + * configure structure for SEMC_Init(). User may use the initialized + * structure unchanged in SEMC_Init(), or modify some fields of the + * structure before calling SEMC_Init(). + * Example: + code + semc_config_t config; + SEMC_GetDefaultConfig(&config); + endcode + * param config The SEMC configuration structure pointer. + */ +void SEMC_GetDefaultConfig(semc_config_t *config) +{ + assert(config); + + /* Initializes the configure structure to zero. */ + memset(config, 0, sizeof(*config)); + + semc_queuea_weight_struct_t *queueaWeight = &(config->queueWeight.queueaWeight.queueaConfig); + semc_queueb_weight_struct_t *queuebWeight = &(config->queueWeight.queuebWeight.queuebConfig); + + /* Get default settings. */ + config->dqsMode = kSEMC_Loopbackinternal; + config->cmdTimeoutCycles = 0; + config->busTimeoutCycles = 0x1F; + + queueaWeight->qos = SEMC_BMCR0_TYPICAL_WQOS; + queueaWeight->aging = SEMC_BMCR0_TYPICAL_WAGE; + queueaWeight->slaveHitSwith = SEMC_BMCR0_TYPICAL_WSH; + queueaWeight->slaveHitNoswitch = SEMC_BMCR0_TYPICAL_WRWS; + queuebWeight->qos = SEMC_BMCR1_TYPICAL_WQOS; + queuebWeight->aging = SEMC_BMCR1_TYPICAL_WAGE; + queuebWeight->slaveHitSwith = SEMC_BMCR1_TYPICAL_WRWS; + queuebWeight->weightPagehit = SEMC_BMCR1_TYPICAL_WPH; + queuebWeight->bankRotation = SEMC_BMCR1_TYPICAL_WBR; +} + +/*! + * brief Initializes SEMC. + * This function ungates the SEMC clock and initializes SEMC. + * This function must be called before calling any other SEMC driver functions. + * + * param base SEMC peripheral base address. + * param configure The SEMC configuration structure pointer. + */ +void SEMC_Init(SEMC_Type *base, semc_config_t *configure) +{ + assert(configure); + + uint8_t index = 0; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Un-gate sdram controller clock. */ + CLOCK_EnableClock(s_semcClock[SEMC_GetInstance(base)]); + CLOCK_EnableClock(s_semcExtClock[SEMC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Initialize all BR to zero due to the default base address set. */ + for (index = 0; index < SEMC_BR_REG_NUM; index++) + { + base->BR[index] = 0; + } + + /* Software reset for SEMC internal logical . */ + base->MCR = SEMC_MCR_SWRST_MASK; + while (base->MCR & SEMC_MCR_SWRST_MASK) + { + } + + /* Configure, disable module first. */ + base->MCR |= SEMC_MCR_MDIS_MASK | SEMC_MCR_BTO(configure->busTimeoutCycles) | + SEMC_MCR_CTO(configure->cmdTimeoutCycles) | SEMC_MCR_DQSMD(configure->dqsMode); + + /* Configure Queue 0/1 for AXI bus. */ + base->BMCR0 = (uint32_t)(configure->queueWeight.queueaWeight.queueaValue); + base->BMCR1 = (uint32_t)(configure->queueWeight.queuebWeight.queuebValue); + + /* Enable SEMC. */ + base->MCR &= ~SEMC_MCR_MDIS_MASK; +} + +/*! + * brief Deinitializes the SEMC module and gates the clock. + * This function gates the SEMC clock. As a result, the SEMC + * module doesn't work after calling this function. + * + * param base SEMC peripheral base address. + */ +void SEMC_Deinit(SEMC_Type *base) +{ + /* Disable module. Check there is no pending command before disable module. */ + while (!(base->STS0 & SEMC_STS0_IDLE_MASK)) + { + ; + } + + base->MCR |= SEMC_MCR_MDIS_MASK | SEMC_MCR_SWRST_MASK; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable SDRAM clock. */ + CLOCK_DisableClock(s_semcClock[SEMC_GetInstance(base)]); + CLOCK_DisableClock(s_semcExtClock[SEMC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Configures SDRAM controller in SEMC. + * + * param base SEMC peripheral base address. + * param cs The chip selection. + * param config The sdram configuration. + * param clkSrc_Hz The SEMC clock frequency. + */ +status_t SEMC_ConfigureSDRAM(SEMC_Type *base, semc_sdram_cs_t cs, semc_sdram_config_t *config, uint32_t clkSrc_Hz) +{ + assert(config); + assert(clkSrc_Hz); + assert(config->refreshBurstLen); + + uint8_t memsize; + status_t result = kStatus_Success; + uint16_t prescale = config->tPrescalePeriod_Ns / 16 / (1000000000 / clkSrc_Hz); + uint16_t refresh; + uint16_t urgentRef; + uint16_t idle; + uint16_t mode; + + if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS)) + { + return kStatus_SEMC_InvalidBaseAddress; + } + + if (config->csxPinMux == kSEMC_MUXA8) + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + + if (prescale > 256) + { + return kStatus_SEMC_InvalidTimerSetting; + } + + refresh = config->refreshPeriod_nsPerRow / config->tPrescalePeriod_Ns; + urgentRef = config->refreshUrgThreshold / config->tPrescalePeriod_Ns; + idle = config->tIdleTimeout_Ns / config->tPrescalePeriod_Ns; + + uint32_t iocReg = base->IOCR & ~(SEMC_IOCR_PINMUXBITWIDTH << config->csxPinMux); + + /* Base control. */ + result = SEMC_CovertMemorySize(base, config->memsize_kbytes, &memsize); + if (result != kStatus_Success) + { + return result; + } + + base->BR[cs] = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; + base->SDRAMCR0 = SEMC_SDRAMCR0_PS(config->portSize) | SEMC_SDRAMCR0_BL(config->burstLen) | + SEMC_SDRAMCR0_COL(config->columnAddrBitNum) | SEMC_SDRAMCR0_CL(config->casLatency); + /* IOMUX setting. */ + if (cs) + { + base->IOCR = iocReg | (cs << config->csxPinMux); + } + + base->IOCR &= ~SEMC_IOCR_MUX_A8_MASK; + + /* Timing setting. */ + base->SDRAMCR1 = SEMC_SDRAMCR1_PRE2ACT(SEMC_ConvertTiming(config->tPrecharge2Act_Ns, clkSrc_Hz) - 1) | + SEMC_SDRAMCR1_ACT2RW(SEMC_ConvertTiming(config->tAct2ReadWrite_Ns, clkSrc_Hz) - 1) | + SEMC_SDRAMCR1_RFRC(SEMC_ConvertTiming(config->tRefreshRecovery_Ns, clkSrc_Hz) - 1) | + SEMC_SDRAMCR1_WRC(SEMC_ConvertTiming(config->tWriteRecovery_Ns, clkSrc_Hz) - 1) | + SEMC_SDRAMCR1_CKEOFF(SEMC_ConvertTiming(config->tCkeOff_Ns, clkSrc_Hz) - 1) | + SEMC_SDRAMCR1_ACT2PRE(SEMC_ConvertTiming(config->tAct2Prechage_Ns, clkSrc_Hz) - 1); + base->SDRAMCR2 = + SEMC_SDRAMCR2_SRRC(SEMC_ConvertTiming(config->tSelfRefRecovery_Ns, clkSrc_Hz) - 1) | + SEMC_SDRAMCR2_REF2REF( + SEMC_ConvertTiming(config->tRefresh2Refresh_Ns, clkSrc_Hz)) | /* No Minus one to keep with RM */ + SEMC_SDRAMCR2_ACT2ACT(SEMC_ConvertTiming(config->tAct2Act_Ns, clkSrc_Hz)) | /* No Minus one to keep with RM */ + SEMC_SDRAMCR2_ITO(idle); + base->SDRAMCR3 = SEMC_SDRAMCR3_REBL(config->refreshBurstLen - 1) | + /* N * 16 * 1s / clkSrc_Hz = config->tPrescalePeriod_Ns */ + SEMC_SDRAMCR3_PRESCALE(prescale) | SEMC_SDRAMCR3_RT(refresh) | SEMC_SDRAMCR3_UT(urgentRef); + + SEMC->IPCR1 = 0x2; + SEMC->IPCR2 = 0; + + result = SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, kSEMC_SDRAMCM_Prechargeall, 0, NULL); + if (result != kStatus_Success) + { + return result; + } + result = SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, kSEMC_SDRAMCM_AutoRefresh, 0, NULL); + if (result != kStatus_Success) + { + return result; + } + result = SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, kSEMC_SDRAMCM_AutoRefresh, 0, NULL); + if (result != kStatus_Success) + { + return result; + } + /* Mode setting value. */ + mode = (uint16_t)config->burstLen | (uint16_t)(config->casLatency << SEMC_SDRAM_MODESETCAL_OFFSET); + result = SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, kSEMC_SDRAMCM_Modeset, mode, NULL); + if (result != kStatus_Success) + { + return result; + } + /* Enables refresh */ + base->SDRAMCR3 |= SEMC_SDRAMCR3_REN_MASK; + + return kStatus_Success; +} + +/*! + * brief Configures NAND controller in SEMC. + * + * param base SEMC peripheral base address. + * param config The nand configuration. + * param clkSrc_Hz The SEMC clock frequency. + */ +status_t SEMC_ConfigureNAND(SEMC_Type *base, semc_nand_config_t *config, uint32_t clkSrc_Hz) +{ + assert(config); + assert(config->timingConfig); + + uint8_t memsize; + status_t result; + + if ((config->axiAddress < SEMC_STARTADDRESS) || (config->axiAddress > SEMC_ENDADDRESS)) + { + return kStatus_SEMC_InvalidBaseAddress; + } + + if (config->cePinMux == kSEMC_MUXRDY) + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + + uint32_t iocReg = base->IOCR & ~((SEMC_IOCR_PINMUXBITWIDTH << config->cePinMux) | SEMC_IOCR_MUX_RDY_MASK); + + /* Base control. */ + if (config->rdyactivePolarity == kSEMC_RdyActivehigh) + { + base->MCR |= SEMC_MCR_WPOL1_MASK; + } + else + { + base->MCR &= ~SEMC_MCR_WPOL1_MASK; + } + result = SEMC_CovertMemorySize(base, config->axiMemsize_kbytes, &memsize); + if (result != kStatus_Success) + { + return result; + } + base->BR[4] = (config->axiAddress & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; + + result = SEMC_CovertMemorySize(base, config->ipgMemsize_kbytes, &memsize); + if (result != kStatus_Success) + { + return result; + } + base->BR[8] = (config->ipgAddress & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; + + /* IOMUX setting. */ + if (config->cePinMux) + { + base->IOCR = iocReg | (SEMC_IOCR_NAND_CE << config->cePinMux); + } + else + { + base->IOCR = iocReg | (1U << config->cePinMux); + } + + base->NANDCR0 = SEMC_NANDCR0_PS(config->portSize) | SEMC_NANDCR0_BL(config->burstLen) | + SEMC_NANDCR0_EDO(config->edoModeEnabled) | SEMC_NANDCR0_COL(config->columnAddrBitNum); + + /* Timing setting. */ + base->NANDCR1 = SEMC_NANDCR1_CES(SEMC_ConvertTiming(config->timingConfig->tCeSetup_Ns, clkSrc_Hz) - 1) | + SEMC_NANDCR1_CEH(SEMC_ConvertTiming(config->timingConfig->tCeHold_Ns, clkSrc_Hz) - 1) | + SEMC_NANDCR1_WEL(SEMC_ConvertTiming(config->timingConfig->tWeLow_Ns, clkSrc_Hz) - 1) | + SEMC_NANDCR1_WEH(SEMC_ConvertTiming(config->timingConfig->tWeHigh_Ns, clkSrc_Hz) - 1) | + SEMC_NANDCR1_REL(SEMC_ConvertTiming(config->timingConfig->tReLow_Ns, clkSrc_Hz) - 1) | + SEMC_NANDCR1_REH(SEMC_ConvertTiming(config->timingConfig->tReHigh_Ns, clkSrc_Hz) - 1) | + SEMC_NANDCR1_TA(SEMC_ConvertTiming(config->timingConfig->tTurnAround_Ns, clkSrc_Hz) - 1) | + SEMC_NANDCR1_CEITV(SEMC_ConvertTiming(config->timingConfig->tCeInterval_Ns, clkSrc_Hz) - 1); + base->NANDCR2 = SEMC_NANDCR2_TWHR(SEMC_ConvertTiming(config->timingConfig->tWehigh2Relow_Ns, clkSrc_Hz) - 1) | + SEMC_NANDCR2_TRHW(SEMC_ConvertTiming(config->timingConfig->tRehigh2Welow_Ns, clkSrc_Hz) - 1) | + SEMC_NANDCR2_TADL(SEMC_ConvertTiming(config->timingConfig->tAle2WriteStart_Ns, clkSrc_Hz) - 1) | + SEMC_NANDCR2_TRR(SEMC_ConvertTiming(config->timingConfig->tReady2Relow_Ns, clkSrc_Hz) - 1) | + SEMC_NANDCR2_TWB(SEMC_ConvertTiming(config->timingConfig->tWehigh2Busy_Ns, clkSrc_Hz) - 1); + base->NANDCR3 = config->arrayAddrOption; + return kStatus_Success; +} + +/*! + * brief Configures NOR controller in SEMC. + * + * param base SEMC peripheral base address. + * param config The nor configuration. + * param clkSrc_Hz The SEMC clock frequency. + */ +status_t SEMC_ConfigureNOR(SEMC_Type *base, semc_nor_config_t *config, uint32_t clkSrc_Hz) +{ + assert(config); + + uint8_t memsize; + status_t result; + + if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS)) + { + return kStatus_SEMC_InvalidBaseAddress; + } + + uint32_t iocReg = base->IOCR & ~(SEMC_IOCR_PINMUXBITWIDTH << config->cePinMux); + uint32_t muxCe = (config->cePinMux == kSEMC_MUXRDY) ? + SEMC_IOCR_NOR_CE - 1 : + ((config->cePinMux == kSEMC_MUXA8) ? SEMC_IOCR_NOR_CE_A8 : SEMC_IOCR_NOR_CE); + + /* IOMUX setting. */ + base->IOCR = iocReg | (muxCe << config->cePinMux); + /* Address bit setting. */ + if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE) + { + if (config->addrPortWidth >= SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 1) + { + /* Address bit 24 (A24) */ + base->IOCR &= (uint32_t)~SEMC_IOCR_MUX_CSX0_MASK; + if (config->cePinMux == kSEMC_MUXCSX0) + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + } + if (config->addrPortWidth >= SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 2) + { + /* Address bit 25 (A25) */ + base->IOCR &= (uint32_t)~SEMC_IOCR_MUX_CSX1_MASK; + if (config->cePinMux == kSEMC_MUXCSX1) + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + } + if (config->addrPortWidth >= SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 3) + { + /* Address bit 26 (A26) */ + base->IOCR &= (uint32_t)~SEMC_IOCR_MUX_CSX2_MASK; + if (config->cePinMux == kSEMC_MUXCSX2) + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + } + if (config->addrPortWidth >= SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 4) + { + if (config->addr27 == kSEMC_NORA27_MUXCSX3) + { + /* Address bit 27 (A27) */ + base->IOCR &= (uint32_t)~SEMC_IOCR_MUX_CSX3_MASK; + } + else if (config->addr27 == kSEMC_NORA27_MUXRDY) + { + base->IOCR |= SEMC_IOCR_MUX_RDY_MASK; + } + else + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + if (config->cePinMux == kSEMC_MUXCSX3) + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + } + if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHMAX) + { + return kStatus_SEMC_InvalidAddressPortWidth; + } + } + + /* Base control. */ + if (config->rdyactivePolarity == kSEMC_RdyActivehigh) + { + base->MCR |= SEMC_MCR_WPOL0_MASK; + } + else + { + base->MCR &= ~SEMC_MCR_WPOL0_MASK; + } + result = SEMC_CovertMemorySize(base, config->memsize_kbytes, &memsize); + if (result != kStatus_Success) + { + return result; + } + base->BR[5] = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; + base->NORCR0 = SEMC_NORCR0_PS(config->portSize) | SEMC_NORCR0_BL(config->burstLen) | + SEMC_NORCR0_AM(config->addrMode) | SEMC_NORCR0_ADVP(config->advActivePolarity) | + SEMC_NORCR0_COL(config->columnAddrBitNum); + + /* Timing setting. */ + base->NORCR1 = SEMC_NORCR1_CES(SEMC_ConvertTiming(config->tCeSetup_Ns, clkSrc_Hz)) | + SEMC_NORCR1_CEH(SEMC_ConvertTiming(config->tCeHold_Ns, clkSrc_Hz)) | + SEMC_NORCR1_AS(SEMC_ConvertTiming(config->tAddrSetup_Ns, clkSrc_Hz)) | + SEMC_NORCR1_AH(SEMC_ConvertTiming(config->tAddrHold_Ns, clkSrc_Hz)) | + SEMC_NORCR1_WEL(SEMC_ConvertTiming(config->tWeLow_Ns, clkSrc_Hz)) | + SEMC_NORCR1_WEH(SEMC_ConvertTiming(config->tWeHigh_Ns, clkSrc_Hz)) | + SEMC_NORCR1_REL(SEMC_ConvertTiming(config->tReLow_Ns, clkSrc_Hz)) | + SEMC_NORCR1_REH(SEMC_ConvertTiming(config->tReHigh_Ns, clkSrc_Hz)); + base->NORCR2 = +#if defined(FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME) + SEMC_NORCR2_WDS(SEMC_ConvertTiming(config->tWriteSetup_Ns, clkSrc_Hz)) | +#endif /* FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME */ +#if defined(FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME) + SEMC_NORCR2_WDH(SEMC_ConvertTiming(config->tWriteHold_Ns, clkSrc_Hz)) | +#endif /* FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME */ + SEMC_NORCR2_TA(SEMC_ConvertTiming(config->tTurnAround_Ns, clkSrc_Hz)) | + SEMC_NORCR2_AWDH(SEMC_ConvertTiming(config->tAddr2WriteHold_Ns, clkSrc_Hz) + 1) | + SEMC_NORCR2_LC(config->latencyCount) | SEMC_NORCR2_RD(config->readCycle) | + SEMC_NORCR2_CEITV(SEMC_ConvertTiming(config->tCeInterval_Ns, clkSrc_Hz)); + + return SEMC_ConfigureIPCommand(base, (config->portSize + 1)); +} + +/*! + * brief Configures SRAM controller in SEMC. + * + * param base SEMC peripheral base address. + * param config The sram configuration. + * param clkSrc_Hz The SEMC clock frequency. + */ +status_t SEMC_ConfigureSRAM(SEMC_Type *base, semc_sram_config_t *config, uint32_t clkSrc_Hz) +{ + assert(config); + + uint8_t memsize; + status_t result = kStatus_Success; + + if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS)) + { + return kStatus_SEMC_InvalidBaseAddress; + } + + uint32_t iocReg = base->IOCR & ~(SEMC_IOCR_PINMUXBITWIDTH << config->cePinMux); + uint32_t muxCe = (config->cePinMux == kSEMC_MUXRDY) ? + SEMC_IOCR_PSRAM_CE - 1 : + ((config->cePinMux == kSEMC_MUXA8) ? SEMC_IOCR_PSRAM_CE_A8 : SEMC_IOCR_PSRAM_CE); + + /* IOMUX setting. */ + base->IOCR = iocReg | (muxCe << config->cePinMux); + /* Address bit setting. */ + if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE) + { + if (config->addrPortWidth >= SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 1) + { + /* Address bit 24 (A24) */ + base->IOCR &= (uint32_t)~SEMC_IOCR_MUX_CSX0_MASK; + if (config->cePinMux == kSEMC_MUXCSX0) + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + } + if (config->addrPortWidth >= SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 2) + { + /* Address bit 25 (A25) */ + base->IOCR &= (uint32_t)~SEMC_IOCR_MUX_CSX1_MASK; + if (config->cePinMux == kSEMC_MUXCSX1) + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + } + if (config->addrPortWidth >= SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 3) + { + /* Address bit 26 (A26) */ + base->IOCR &= (uint32_t)~SEMC_IOCR_MUX_CSX2_MASK; + if (config->cePinMux == kSEMC_MUXCSX2) + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + } + if (config->addrPortWidth >= SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 4) + { + if (config->addr27 == kSEMC_NORA27_MUXCSX3) + { + /* Address bit 27 (A27) */ + base->IOCR &= (uint32_t)~SEMC_IOCR_MUX_CSX3_MASK; + } + else if (config->addr27 == kSEMC_NORA27_MUXRDY) + { + base->IOCR |= SEMC_IOCR_MUX_RDY_MASK; + } + else + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + + if (config->cePinMux == kSEMC_MUXCSX3) + { + return kStatus_SEMC_InvalidSwPinmuxSelection; + } + } + if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHMAX) + { + return kStatus_SEMC_InvalidAddressPortWidth; + } + } + /* Base control. */ + result = SEMC_CovertMemorySize(base, config->memsize_kbytes, &memsize); + if (result != kStatus_Success) + { + return result; + } + base->BR[6] = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; + base->SRAMCR0 = SEMC_SRAMCR0_PS(config->portSize) | SEMC_SRAMCR0_BL(config->burstLen) | + SEMC_SRAMCR0_AM(config->addrMode) | SEMC_SRAMCR0_ADVP(config->advActivePolarity) | + SEMC_SRAMCR0_COL_MASK; + + /* Timing setting. */ + base->SRAMCR1 = SEMC_SRAMCR1_CES(SEMC_ConvertTiming(config->tCeSetup_Ns, clkSrc_Hz)) | + SEMC_SRAMCR1_CEH(SEMC_ConvertTiming(config->tCeHold_Ns, clkSrc_Hz)) | + SEMC_SRAMCR1_AS(SEMC_ConvertTiming(config->tAddrSetup_Ns, clkSrc_Hz)) | + SEMC_SRAMCR1_AH(SEMC_ConvertTiming(config->tAddrHold_Ns, clkSrc_Hz)) | + SEMC_SRAMCR1_WEL(SEMC_ConvertTiming(config->tWeLow_Ns, clkSrc_Hz)) | + SEMC_SRAMCR1_WEH(SEMC_ConvertTiming(config->tWeHigh_Ns, clkSrc_Hz)) | + SEMC_SRAMCR1_REL(SEMC_ConvertTiming(config->tReLow_Ns, clkSrc_Hz)) | + SEMC_SRAMCR1_REH(SEMC_ConvertTiming(config->tReHigh_Ns, clkSrc_Hz)); + + base->SRAMCR2 = SEMC_SRAMCR2_WDS(SEMC_ConvertTiming(config->tWriteSetup_Ns, clkSrc_Hz)) | + SEMC_SRAMCR2_WDH(SEMC_ConvertTiming(config->tWriteHold_Ns, clkSrc_Hz)) | + SEMC_SRAMCR2_TA(SEMC_ConvertTiming(config->tTurnAround_Ns, clkSrc_Hz)) | + SEMC_SRAMCR2_AWDH(SEMC_ConvertTiming(config->tAddr2WriteHold_Ns, clkSrc_Hz) + 1) | + SEMC_SRAMCR2_LC(config->latencyCount) | SEMC_SRAMCR2_RD(config->readCycle) | + SEMC_SRAMCR2_CEITV(SEMC_ConvertTiming(config->tCeInterval_Ns, clkSrc_Hz)); + + return result; +} + +/*! + * brief Configures DBI controller in SEMC. + * + * param base SEMC peripheral base address. + * param config The dbi configuration. + * param clkSrc_Hz The SEMC clock frequency. + */ +status_t SEMC_ConfigureDBI(SEMC_Type *base, semc_dbi_config_t *config, uint32_t clkSrc_Hz) +{ + assert(config); + + uint8_t memsize; + status_t result; + + if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS)) + { + return kStatus_SEMC_InvalidBaseAddress; + } + + uint32_t iocReg = base->IOCR & ~(SEMC_IOCR_PINMUXBITWIDTH << config->csxPinMux); + uint32_t muxCsx = (config->csxPinMux == kSEMC_MUXRDY) ? + SEMC_IOCR_DBI_CSX - 1 : + ((config->csxPinMux == kSEMC_MUXA8) ? SEMC_IOCR_DBI_CSX_A8 : SEMC_IOCR_DBI_CSX); + + /* IOMUX setting. */ + base->IOCR = iocReg | (muxCsx << config->csxPinMux); + /* Base control. */ + result = SEMC_CovertMemorySize(base, config->memsize_kbytes, &memsize); + if (result != kStatus_Success) + { + return result; + } + base->BR[7] = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; + base->DBICR0 = + SEMC_DBICR0_PS(config->portSize) | SEMC_DBICR0_BL(config->burstLen) | SEMC_DBICR0_COL(config->columnAddrBitNum); + + /* Timing setting. */ + base->DBICR1 = SEMC_DBICR1_CES(SEMC_ConvertTiming(config->tCsxSetup_Ns, clkSrc_Hz) - 1) | + SEMC_DBICR1_CEH(SEMC_ConvertTiming(config->tCsxHold_Ns, clkSrc_Hz) - 1) | + SEMC_DBICR1_WEL(SEMC_ConvertTiming(config->tWexLow_Ns, clkSrc_Hz) - 1) | + SEMC_DBICR1_WEH(SEMC_ConvertTiming(config->tWexHigh_Ns, clkSrc_Hz) - 1) | + SEMC_DBICR1_REL(SEMC_ConvertTiming(config->tRdxLow_Ns, clkSrc_Hz) - 1) | + SEMC_DBICR1_REH(SEMC_ConvertTiming(config->tRdxHigh_Ns, clkSrc_Hz) - 1) | + SEMC_DBICR1_CEITV(SEMC_ConvertTiming(config->tCsxInterval_Ns, clkSrc_Hz) - 1); + return SEMC_ConfigureIPCommand(base, (config->portSize + 1)); +} + +/*! + * brief SEMC IP command access. + * + * param base SEMC peripheral base address. + * param type SEMC memory type. refer to "semc_mem_type_t" + * param address SEMC device address. + * param command SEMC IP command. + * For NAND device, we should use the SEMC_BuildNandIPCommand to get the right nand command. + * For NOR/DBI device, take refer to "semc_ipcmd_nor_dbi_t". + * For SRAM device, take refer to "semc_ipcmd_sram_t". + * For SDRAM device, take refer to "semc_ipcmd_sdram_t". + * param write Data for write access. + * param read Data pointer for read data out. + */ +status_t SEMC_SendIPCommand( + SEMC_Type *base, semc_mem_type_t type, uint32_t address, uint16_t command, uint32_t write, uint32_t *read) +{ + uint32_t cmdMode; + bool readCmd = 0; + bool writeCmd = 0; + status_t result; + + /* Clear status bit */ + base->INTR |= SEMC_INTR_IPCMDDONE_MASK; + /* Set address. */ + base->IPCR0 = address; + + /* Check command mode. */ + cmdMode = command & 0xFU; + switch (type) + { + case kSEMC_MemType_NAND: + readCmd = (cmdMode == kSEMC_NANDCM_CommandAddressRead) || (cmdMode == kSEMC_NANDCM_CommandRead) || + (cmdMode == kSEMC_NANDCM_Read); + writeCmd = (cmdMode == kSEMC_NANDCM_CommandAddressWrite) || (cmdMode == kSEMC_NANDCM_CommandWrite) || + (cmdMode == kSEMC_NANDCM_Write); + break; + case kSEMC_MemType_NOR: + case kSEMC_MemType_8080: + readCmd = (cmdMode == kSEMC_NORDBICM_Read); + writeCmd = (cmdMode == kSEMC_NORDBICM_Write); + break; + case kSEMC_MemType_SRAM: + readCmd = (cmdMode == kSEMC_SRAMCM_ArrayRead) || (cmdMode == kSEMC_SRAMCM_RegRead); + writeCmd = (cmdMode == kSEMC_SRAMCM_ArrayWrite) || (cmdMode == kSEMC_SRAMCM_RegWrite); + break; + case kSEMC_MemType_SDRAM: + readCmd = (cmdMode == kSEMC_SDRAMCM_Read); + writeCmd = (cmdMode == kSEMC_SDRAMCM_Write) || (cmdMode == kSEMC_SDRAMCM_Modeset); + break; + default: + break; + } + + if (writeCmd) + { + /* Set data. */ + base->IPTXDAT = write; + } + + /* Set command code. */ + base->IPCMD = command | SEMC_IPCMD_KEY(SEMC_IPCOMMANDMAGICKEY); + /* Wait for command done. */ + result = SEMC_IsIPCommandDone(base); + if (result != kStatus_Success) + { + return result; + } + + if (readCmd) + { + /* Get the read data */ + *read = base->IPRXDAT; + } + + return kStatus_Success; +} + +/*! + * brief SEMC NAND device memory write through IP command. + * + * param base SEMC peripheral base address. + * param address SEMC NAND device address. + * param data Data for write access. + * param size_bytes Data length. + */ +status_t SEMC_IPCommandNandWrite(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes) +{ + assert(data); + + status_t result = kStatus_Success; + uint16_t ipCmd; + uint32_t tempData = 0; + + /* Write command built */ + ipCmd = SEMC_BuildNandIPCommand(0, kSEMC_NANDAM_ColumnRow, kSEMC_NANDCM_Write); + while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX) + { + /* Configure IP command data size. */ + SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX); + result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, *(uint32_t *)data, NULL); + if (result != kStatus_Success) + { + break; + } + + data += SEMC_IPCOMMANDDATASIZEBYTEMAX; + size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX; + } + + if ((result == kStatus_Success) && size_bytes) + { + SEMC_ConfigureIPCommand(base, size_bytes); + + while (size_bytes) + { + tempData |= ((uint32_t) * (data + size_bytes - 1) << ((size_bytes - 1) * SEMC_BYTE_NUMBIT)); + size_bytes--; + } + + result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, tempData, NULL); + } + + return result; +} + +/*! + * brief SEMC NAND device memory read through IP command. + * + * param base SEMC peripheral base address. + * param address SEMC NAND device address. + * param data Data pointer for data read out. + * param size_bytes Data length. + */ +status_t SEMC_IPCommandNandRead(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes) +{ + assert(data); + + status_t result = kStatus_Success; + uint16_t ipCmd; + uint32_t tempData = 0; + + /* Configure IP command data size. */ + SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX); + /* Read command built */ + ipCmd = SEMC_BuildNandIPCommand(0, kSEMC_NANDAM_ColumnRow, kSEMC_NANDCM_Read); + + while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX) + { + result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, 0, (uint32_t *)data); + if (result != kStatus_Success) + { + break; + } + + data += SEMC_IPCOMMANDDATASIZEBYTEMAX; + size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX; + } + + if ((result == kStatus_Success) && size_bytes) + { + SEMC_ConfigureIPCommand(base, size_bytes); + result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, 0, &tempData); + + while (size_bytes) + { + size_bytes--; + *(data + size_bytes) = (tempData >> (SEMC_BYTE_NUMBIT * size_bytes)) & 0xFFU; + } + } + + return result; +} + +/*! + * brief SEMC NOR device memory read through IP command. + * + * param base SEMC peripheral base address. + * param address SEMC NOR device address. + * param data Data pointer for data read out. + * param size_bytes Data length. + */ +status_t SEMC_IPCommandNorRead(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes) +{ + assert(data); + + uint32_t tempData = 0; + status_t result = kStatus_Success; + uint8_t dataSize = base->NORCR0 & SEMC_NORCR0_PS_MASK; + + /* Configure IP command data size. */ + SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX); + + while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX) + { + result = SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, kSEMC_NORDBICM_Read, 0, (uint32_t *)data); + if (result != kStatus_Success) + { + break; + } + + data += SEMC_IPCOMMANDDATASIZEBYTEMAX; + size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX; + } + + if ((result == kStatus_Success) && size_bytes) + { + SEMC_ConfigureIPCommand(base, size_bytes); + result = SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, kSEMC_NORDBICM_Read, 0, &tempData); + while (size_bytes) + { + size_bytes--; + *(data + size_bytes) = (tempData >> (SEMC_BYTE_NUMBIT * size_bytes)) & 0xFFU; + } + } + + SEMC_ConfigureIPCommand(base, dataSize); + return result; +} + +/*! + * brief SEMC NOR device memory write through IP command. + * + * param base SEMC peripheral base address. + * param address SEMC NOR device address. + * param data Data for write access. + * param size_bytes Data length. + */ +status_t SEMC_IPCommandNorWrite(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes) +{ + assert(data); + + uint32_t tempData = 0; + status_t result = kStatus_Success; + uint8_t dataSize = base->NORCR0 & SEMC_NORCR0_PS_MASK; + + /* Write command built */ + while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX) + { + /* Configure IP command data size. */ + SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX); + result = SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, kSEMC_NORDBICM_Write, *(uint32_t *)data, NULL); + if (result != kStatus_Success) + { + break; + } + size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX; + data += SEMC_IPCOMMANDDATASIZEBYTEMAX; + } + + if ((result == kStatus_Success) && size_bytes) + { + SEMC_ConfigureIPCommand(base, size_bytes); + + while (size_bytes) + { + tempData |= ((uint32_t) * (data + size_bytes - 1) << ((size_bytes - 1) * SEMC_BYTE_NUMBIT)); + size_bytes--; + } + + result = SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, kSEMC_NORDBICM_Write, tempData, NULL); + } + SEMC_ConfigureIPCommand(base, dataSize); + + return result; +} diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/fsl_semc.h b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/fsl_semc.h new file mode 100644 index 000000000..75704eadf --- /dev/null +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/fsl_semc.h @@ -0,0 +1,830 @@ +/* + * Copyright 2017-2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_SEMC_H_ +#define _FSL_SEMC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup semc + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief SEMC driver version 2.0.4. */ +#define FSL_SEMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 4)) +/*@}*/ + +/*! @brief SEMC status. */ +enum _semc_status +{ + kStatus_SEMC_InvalidDeviceType = MAKE_STATUS(kStatusGroup_SEMC, 0), + kStatus_SEMC_IpCommandExecutionError = MAKE_STATUS(kStatusGroup_SEMC, 1), + kStatus_SEMC_AxiCommandExecutionError = MAKE_STATUS(kStatusGroup_SEMC, 2), + kStatus_SEMC_InvalidMemorySize = MAKE_STATUS(kStatusGroup_SEMC, 3), + kStatus_SEMC_InvalidIpcmdDataSize = MAKE_STATUS(kStatusGroup_SEMC, 4), + kStatus_SEMC_InvalidAddressPortWidth = MAKE_STATUS(kStatusGroup_SEMC, 5), + kStatus_SEMC_InvalidDataPortWidth = MAKE_STATUS(kStatusGroup_SEMC, 6), + kStatus_SEMC_InvalidSwPinmuxSelection = MAKE_STATUS(kStatusGroup_SEMC, 7), + kStatus_SEMC_InvalidBurstLength = MAKE_STATUS(kStatusGroup_SEMC, 8), + kStatus_SEMC_InvalidColumnAddressBitWidth = MAKE_STATUS(kStatusGroup_SEMC, 9), + kStatus_SEMC_InvalidBaseAddress = MAKE_STATUS(kStatusGroup_SEMC, 10), + kStatus_SEMC_InvalidTimerSetting = MAKE_STATUS(kStatusGroup_SEMC, 11), +}; + +/*! @brief SEMC memory device type. */ +typedef enum _semc_mem_type +{ + kSEMC_MemType_SDRAM = 0, /*!< SDRAM */ + kSEMC_MemType_SRAM, /*!< SRAM */ + kSEMC_MemType_NOR, /*!< NOR */ + kSEMC_MemType_NAND, /*!< NAND */ + kSEMC_MemType_8080 /*!< 8080. */ +} semc_mem_type_t; + +/*! @brief SEMC WAIT/RDY polarity. */ +typedef enum _semc_waitready_polarity +{ + kSEMC_LowActive = 0, /*!< Low active. */ + kSEMC_HighActive, /*!< High active. */ +} semc_waitready_polarity_t; + +/*! @brief SEMC SDRAM Chip selection . */ +typedef enum _semc_sdram_cs +{ + kSEMC_SDRAM_CS0 = 0, /*!< SEMC SDRAM CS0. */ + kSEMC_SDRAM_CS1, /*!< SEMC SDRAM CS1. */ + kSEMC_SDRAM_CS2, /*!< SEMC SDRAM CS2. */ + kSEMC_SDRAM_CS3 /*!< SEMC SDRAM CS3. */ +} semc_sdram_cs_t; + +/*! @brief SEMC NAND device type. */ +typedef enum _semc_nand_access_type +{ + kSEMC_NAND_ACCESS_BY_AXI = 0, + kSEMC_NAND_ACCESS_BY_IPCMD, +} semc_nand_access_type_t; + +/*! @brief SEMC interrupts . */ +typedef enum _semc_interrupt_enable +{ + kSEMC_IPCmdDoneInterrupt = SEMC_INTEN_IPCMDDONEEN_MASK, /*!< Ip command done interrupt. */ + kSEMC_IPCmdErrInterrupt = SEMC_INTEN_IPCMDERREN_MASK, /*!< Ip command error interrupt. */ + kSEMC_AXICmdErrInterrupt = SEMC_INTEN_AXICMDERREN_MASK, /*!< AXI command error interrupt. */ + kSEMC_AXIBusErrInterrupt = SEMC_INTEN_AXIBUSERREN_MASK /*!< AXI bus error interrupt. */ +} semc_interrupt_enable_t; + +/*! @brief SEMC IP command data size in bytes. */ +typedef enum _semc_ipcmd_datasize +{ + kSEMC_IPcmdDataSize_1bytes = 1, /*!< The IP command data size 1 byte. */ + kSEMC_IPcmdDataSize_2bytes, /*!< The IP command data size 2 byte. */ + kSEMC_IPcmdDataSize_3bytes, /*!< The IP command data size 3 byte. */ + kSEMC_IPcmdDataSize_4bytes /*!< The IP command data size 4 byte. */ +} semc_ipcmd_datasize_t; + +/*! @brief SEMC auto-refresh timing. */ +typedef enum _semc_refresh_time +{ + kSEMC_RefreshThreeClocks = 0x0U, /*!< The refresh timing with three bus clocks. */ + kSEMC_RefreshSixClocks, /*!< The refresh timing with six bus clocks. */ + kSEMC_RefreshNineClocks /*!< The refresh timing with nine bus clocks. */ +} semc_refresh_time_t; + +/*! @brief CAS latency */ +typedef enum _semc_caslatency +{ + kSEMC_LatencyOne = 1, /*!< Latency 1. */ + kSEMC_LatencyTwo, /*!< Latency 2. */ + kSEMC_LatencyThree, /*!< Latency 3. */ +} semc_caslatency_t; + +/*! @brief SEMC sdram column address bit number. */ +typedef enum _semc_sdram_column_bit_num +{ + kSEMC_SdramColunm_12bit = 0x0U, /*!< 12 bit. */ + kSEMC_SdramColunm_11bit, /*!< 11 bit. */ + kSEMC_SdramColunm_10bit, /*!< 10 bit. */ + kSEMC_SdramColunm_9bit, /*!< 9 bit. */ +} semc_sdram_column_bit_num_t; + +/*! @brief SEMC sdram burst length. */ +typedef enum _semc_sdram_burst_len +{ + kSEMC_Sdram_BurstLen1 = 0, /*!< Burst length 1*/ + kSEMC_Sdram_BurstLen2, /*!< Burst length 2*/ + kSEMC_Sdram_BurstLen4, /*!< Burst length 4*/ + kSEMC_Sdram_BurstLen8 /*!< Burst length 8*/ +} sem_sdram_burst_len_t; + +/*! @brief SEMC nand column address bit number. */ +typedef enum _semc_nand_column_bit_num +{ + kSEMC_NandColum_16bit = 0x0U, /*!< 16 bit. */ + kSEMC_NandColum_15bit, /*!< 15 bit. */ + kSEMC_NandColum_14bit, /*!< 14 bit. */ + kSEMC_NandColum_13bit, /*!< 13 bit. */ + kSEMC_NandColum_12bit, /*!< 12 bit. */ + kSEMC_NandColum_11bit, /*!< 11 bit. */ + kSEMC_NandColum_10bit, /*!< 10 bit. */ + kSEMC_NandColum_9bit, /*!< 9 bit. */ +} semc_nand_column_bit_num_t; + +/*! @brief SEMC nand burst length. */ +typedef enum _semc_nand_burst_len +{ + kSEMC_Nand_BurstLen1 = 0, /*!< Burst length 1*/ + kSEMC_Nand_BurstLen2, /*!< Burst length 2*/ + kSEMC_Nand_BurstLen4, /*!< Burst length 4*/ + kSEMC_Nand_BurstLen8, /*!< Burst length 8*/ + kSEMC_Nand_BurstLen16, /*!< Burst length 16*/ + kSEMC_Nand_BurstLen32, /*!< Burst length 32*/ + kSEMC_Nand_BurstLen64 /*!< Burst length 64*/ +} sem_nand_burst_len_t; + +/*! @brief SEMC nor/sram column address bit number. */ +typedef enum _semc_norsram_column_bit_num +{ + kSEMC_NorColum_12bit = 0x0U, /*!< 12 bit. */ + kSEMC_NorColum_11bit, /*!< 11 bit. */ + kSEMC_NorColum_10bit, /*!< 10 bit. */ + kSEMC_NorColum_9bit, /*!< 9 bit. */ + kSEMC_NorColum_8bit, /*!< 8 bit. */ + kSEMC_NorColum_7bit, /*!< 7 bit. */ + kSEMC_NorColum_6bit, /*!< 6 bit. */ + kSEMC_NorColum_5bit, /*!< 5 bit. */ + kSEMC_NorColum_4bit, /*!< 4 bit. */ + kSEMC_NorColum_3bit, /*!< 3 bit. */ + kSEMC_NorColum_2bit /*!< 2 bit. */ +} semc_norsram_column_bit_num_t; + +/*! @brief SEMC nor/sram burst length. */ +typedef enum _semc_norsram_burst_len +{ + kSEMC_Nor_BurstLen1 = 0, /*!< Burst length 1*/ + kSEMC_Nor_BurstLen2, /*!< Burst length 2*/ + kSEMC_Nor_BurstLen4, /*!< Burst length 4*/ + kSEMC_Nor_BurstLen8, /*!< Burst length 8*/ + kSEMC_Nor_BurstLen16, /*!< Burst length 16*/ + kSEMC_Nor_BurstLen32, /*!< Burst length 32*/ + kSEMC_Nor_BurstLen64 /*!< Burst length 64*/ +} sem_norsram_burst_len_t; + +/*! @brief SEMC dbi column address bit number. */ +typedef enum _semc_dbi_column_bit_num +{ + kSEMC_Dbi_Colum_12bit = 0x0U, /*!< 12 bit. */ + kSEMC_Dbi_Colum_11bit, /*!< 11 bit. */ + kSEMC_Dbi_Colum_10bit, /*!< 10 bit. */ + kSEMC_Dbi_Colum_9bit, /*!< 9 bit. */ + kSEMC_Dbi_Colum_8bit, /*!< 8 bit. */ + kSEMC_Dbi_Colum_7bit, /*!< 7 bit. */ + kSEMC_Dbi_Colum_6bit, /*!< 6 bit. */ + kSEMC_Dbi_Colum_5bit, /*!< 5 bit. */ + kSEMC_Dbi_Colum_4bit, /*!< 4 bit. */ + kSEMC_Dbi_Colum_3bit, /*!< 3 bit. */ + kSEMC_Dbi_Colum_2bit /*!< 2 bit. */ +} semc_dbi_column_bit_num_t; + +/*! @brief SEMC dbi burst length. */ +typedef enum _semc_dbi_burst_len +{ + kSEMC_Dbi_BurstLen1 = 0, /*!< Burst length 1*/ + kSEMC_Dbi_BurstLen2, /*!< Burst length 2*/ + kSEMC_Dbi_Dbi_BurstLen4, /*!< Burst length 4*/ + kSEMC_Dbi_BurstLen8, /*!< Burst length 8*/ + kSEMC_Dbi_BurstLen16, /*!< Burst length 16*/ + kSEMC_Dbi_BurstLen32, /*!< Burst length 32*/ + kSEMC_Dbi_BurstLen64 /*!< Burst length 64*/ +} sem_dbi_burst_len_t; + +/*! @brief SEMC IOMUXC. */ +typedef enum _semc_iomux_pin +{ + kSEMC_MUXA8 = SEMC_IOCR_MUX_A8_SHIFT, /*!< MUX A8 pin. */ + kSEMC_MUXCSX0 = SEMC_IOCR_MUX_CSX0_SHIFT, /*!< MUX CSX0 pin */ + kSEMC_MUXCSX1 = SEMC_IOCR_MUX_CSX1_SHIFT, /*!< MUX CSX1 Pin.*/ + kSEMC_MUXCSX2 = SEMC_IOCR_MUX_CSX2_SHIFT, /*!< MUX CSX2 Pin. */ + kSEMC_MUXCSX3 = SEMC_IOCR_MUX_CSX3_SHIFT, /*!< MUX CSX3 Pin. */ + kSEMC_MUXRDY = SEMC_IOCR_MUX_RDY_SHIFT /*!< MUX RDY pin. */ +} semc_iomux_pin; + +/*! @brief SEMC NOR/PSRAM Address bit 27 A27. */ +typedef enum _semc_iomux_nora27_pin +{ + kSEMC_MORA27_NONE = 0, /*!< No NOR/SRAM A27 pin. */ + kSEMC_NORA27_MUXCSX3 = SEMC_IOCR_MUX_CSX3_SHIFT, /*!< MUX CSX3 Pin. */ + kSEMC_NORA27_MUXRDY = SEMC_IOCR_MUX_RDY_SHIFT /*!< MUX RDY pin. */ +} semc_iomux_nora27_pin; + +/*! @brief SEMC port size. */ +typedef enum _semc_port_size +{ + kSEMC_PortSize8Bit = 0, /*!< 8-Bit port size. */ + kSEMC_PortSize16Bit /*!< 16-Bit port size. */ +} smec_port_size_t; + +/*! @brief SEMC address mode. */ +typedef enum _semc_addr_mode +{ + kSEMC_AddrDataMux = 0, /*!< SEMC address/data mux mode. */ + kSEMC_AdvAddrdataMux, /*!< Advanced address/data mux mode. */ + kSEMC_AddrDataNonMux /*!< Address/data non-mux mode. */ +} semc_addr_mode_t; + +/*! @brief SEMC DQS read strobe mode. */ +typedef enum _semc_dqs_mode +{ + kSEMC_Loopbackinternal = 0, /*!< Dummy read strobe loopbacked internally. */ + kSEMC_Loopbackdqspad, /*!< Dummy read strobe loopbacked from DQS pad. */ +} semc_dqs_mode_t; + +/*! @brief SEMC ADV signal active polarity. */ +typedef enum _semc_adv_polarity +{ + kSEMC_AdvActiveLow = 0, /*!< Adv active low. */ + kSEMC_AdvActivehigh, /*!< Adv active low. */ +} semc_adv_polarity_t; + +/*! @brief SEMC RDY signal active polarity. */ +typedef enum _semc_rdy_polarity +{ + kSEMC_RdyActiveLow = 0, /*!< Adv active low. */ + kSEMC_RdyActivehigh, /*!< Adv active low. */ +} semc_rdy_polarity_t; + +/*! @brief SEMC IP command for NAND: address mode. */ +typedef enum _semc_ipcmd_nand_addrmode +{ + kSEMC_NANDAM_ColumnRow = 0x0U, /*!< Address mode: column and row address(5Byte-CA0/CA1/RA0/RA1/RA2). */ + kSEMC_NANDAM_ColumnCA0, /*!< Address mode: column address only(1 Byte-CA0). */ + kSEMC_NANDAM_ColumnCA0CA1, /*!< Address mode: column address only(2 Byte-CA0/CA1). */ + kSEMC_NANDAM_RawRA0, /*!< Address mode: row address only(1 Byte-RA0). */ + kSEMC_NANDAM_RawRA0RA1, /*!< Address mode: row address only(2 Byte-RA0/RA1). */ + kSEMC_NANDAM_RawRA0RA1RA2 /*!< Address mode: row address only(3 Byte-RA0). */ +} semc_ipcmd_nand_addrmode_t; + +/*! @brief SEMC IP command for NAND: command mode. */ +typedef enum _semc_ipcmd_nand_cmdmode +{ + kSEMC_NANDCM_Command = 0x2U, /*!< command. */ + kSEMC_NANDCM_CommandHold, /*!< Command hold. */ + kSEMC_NANDCM_CommandAddress, /*!< Command address. */ + kSEMC_NANDCM_CommandAddressHold, /*!< Command address hold. */ + kSEMC_NANDCM_CommandAddressRead, /*!< Command address read. */ + kSEMC_NANDCM_CommandAddressWrite, /*!< Command address write. */ + kSEMC_NANDCM_CommandRead, /*!< Command read. */ + kSEMC_NANDCM_CommandWrite, /*!< Command write. */ + kSEMC_NANDCM_Read, /*!< Read. */ + kSEMC_NANDCM_Write /*!< Write. */ +} semc_ipcmd_nand_cmdmode_t; + +/*! @brief SEMC NAND address option. */ +typedef enum _semc_nand_address_option +{ + kSEMC_NandAddrOption_5byte_CA2RA3 = 0U, /*!< CA0+CA1+RA0+RA1+RA2 */ + kSEMC_NandAddrOption_4byte_CA2RA2 = 2U, /*!< CA0+CA1+RA0+RA1 */ + kSEMC_NandAddrOption_3byte_CA2RA1 = 4U, /*!< CA0+CA1+RA0 */ + kSEMC_NandAddrOption_4byte_CA1RA3 = 1U, /*!< CA0+RA0+RA1+RA2 */ + kSEMC_NandAddrOption_3byte_CA1RA2 = 3U, /*!< CA0+RA0+RA1 */ + kSEMC_NandAddrOption_2byte_CA1RA1 = 7U, /*!< CA0+RA0 */ +} semc_nand_address_option_t; + +/*! @brief SEMC IP command for NOR. */ +typedef enum _semc_ipcmd_nor_dbi +{ + kSEMC_NORDBICM_Read = 0x2U, /*!< NOR read. */ + kSEMC_NORDBICM_Write /*!< NOR write. */ +} semc_ipcmd_nor_dbi_t; + +/*! @brief SEMC IP command for SRAM. */ +typedef enum _semc_ipcmd_sram +{ + kSEMC_SRAMCM_ArrayRead = 0x2U, /*!< SRAM memory array read. */ + kSEMC_SRAMCM_ArrayWrite, /*!< SRAM memory array write. */ + kSEMC_SRAMCM_RegRead, /*!< SRAM memory register read. */ + kSEMC_SRAMCM_RegWrite /*!< SRAM memory register write. */ +} semc_ipcmd_sram_t; + +/*! @brief SEMC IP command for SDARM. */ +typedef enum _semc_ipcmd_sdram +{ + kSEMC_SDRAMCM_Read = 0x8U, /*!< SDRAM memory read. */ + kSEMC_SDRAMCM_Write, /*!< SDRAM memory write. */ + kSEMC_SDRAMCM_Modeset, /*!< SDRAM MODE SET. */ + kSEMC_SDRAMCM_Active, /*!< SDRAM active. */ + kSEMC_SDRAMCM_AutoRefresh, /*!< SDRAM auto-refresh. */ + kSEMC_SDRAMCM_SelfRefresh, /*!< SDRAM self-refresh. */ + kSEMC_SDRAMCM_Precharge, /*!< SDRAM precharge. */ + kSEMC_SDRAMCM_Prechargeall /*!< SDRAM precharge all. */ +} semc_ipcmd_sdram_t; + +/*! @brief SEMC SDRAM configuration structure. + * + * 1. The memory size in the configuration is in the unit of KB. So memsize_kbytes + * should be set as 2^2, 2^3, 2^4 .etc which is base 2KB exponential function. + * Take refer to BR0~BR3 register in RM for details. + * 2. The prescalePeriod_N16Cycle is in unit of 16 clock cycle. It is a exception for prescaleTimer_n16cycle = 0, + * it means the prescaler timer period is 256 * 16 clock cycles. For precalerIf precalerTimer_n16cycle not equal to 0, + * The prescaler timer period is prescalePeriod_N16Cycle * 16 clock cycles. + * idleTimeout_NprescalePeriod, refreshUrgThreshold_NprescalePeriod, refreshPeriod_NprescalePeriod are + * similar to prescalePeriod_N16Cycle. + * + */ +typedef struct _semc_sdram_config +{ + semc_iomux_pin csxPinMux; /*!< CS pin mux. The kSEMC_MUXA8 is not valid in sdram pin mux setting. */ + uint32_t address; /*!< The base address. */ + uint32_t memsize_kbytes; /*!< The memory size in unit of kbytes. */ + smec_port_size_t portSize; /*!< Port size. */ + sem_sdram_burst_len_t burstLen; /*!< Burst length. */ + semc_sdram_column_bit_num_t columnAddrBitNum; /*!< Column address bit number. */ + semc_caslatency_t casLatency; /*!< CAS latency. */ + uint8_t tPrecharge2Act_Ns; /*!< Precharge to active wait time in unit of nanosecond. */ + uint8_t tAct2ReadWrite_Ns; /*!< Act to read/write wait time in unit of nanosecond. */ + uint8_t tRefreshRecovery_Ns; /*!< Refresh recovery time in unit of nanosecond. */ + uint8_t tWriteRecovery_Ns; /*!< write recovery time in unit of nanosecond. */ + uint8_t tCkeOff_Ns; /*!< CKE off minimum time in unit of nanosecond. */ + uint8_t tAct2Prechage_Ns; /*!< Active to precharge in unit of nanosecond. */ + uint8_t tSelfRefRecovery_Ns; /*!< Self refresh recovery time in unit of nanosecond. */ + uint8_t tRefresh2Refresh_Ns; /*!< Refresh to refresh wait time in unit of nanosecond. */ + uint8_t tAct2Act_Ns; /*!< Active to active wait time in unit of nanosecond. */ + uint32_t tPrescalePeriod_Ns; /*!< Prescaler timer period should not be larger than 256 * 16 * clock cycle. */ + uint32_t tIdleTimeout_Ns; /*!< Idle timeout in unit of prescale time period. */ + uint32_t refreshPeriod_nsPerRow; /*!< Refresh timer period like 64ms * 1000000/8192 . */ + uint32_t refreshUrgThreshold; /*!< Refresh urgent threshold. */ + uint8_t refreshBurstLen; /*!< Refresh burst length. */ +} semc_sdram_config_t; + +/*! @brief SEMC NAND device timing configuration structure. */ +typedef struct _semc_nand_timing_config +{ + uint8_t tCeSetup_Ns; /*!< CE setup time: tCS. */ + uint8_t tCeHold_Ns; /*!< CE hold time: tCH. */ + uint8_t tCeInterval_Ns; /*!< CE interval time:tCEITV. */ + uint8_t tWeLow_Ns; /*!< WE low time: tWP. */ + uint8_t tWeHigh_Ns; /*!< WE high time: tWH. */ + uint8_t tReLow_Ns; /*!< RE low time: tRP. */ + uint8_t tReHigh_Ns; /*!< RE high time: tREH. */ + uint8_t tTurnAround_Ns; /*!< Turnaround time for async mode: tTA. */ + uint8_t tWehigh2Relow_Ns; /*!< WE# high to RE# wait time: tWHR. */ + uint8_t tRehigh2Welow_Ns; /*!< RE# high to WE# low wait time: tRHW. */ + uint8_t tAle2WriteStart_Ns; /*!< ALE to write start wait time: tADL. */ + uint8_t tReady2Relow_Ns; /*!< Ready to RE# low min wait time: tRR. */ + uint8_t tWehigh2Busy_Ns; /*!< WE# high to busy wait time: tWB. */ +} semc_nand_timing_config_t; + +/*! @brief SEMC NAND configuration structure. */ +typedef struct _semc_nand_config +{ + semc_iomux_pin cePinMux; /*!< The CE pin mux setting. The kSEMC_MUXRDY is not valid for CE pin setting. */ + uint32_t axiAddress; /*!< The base address for AXI nand. */ + uint32_t axiMemsize_kbytes; /*!< The memory size in unit of kbytes for AXI nand. */ + uint32_t ipgAddress; /*!< The base address for IPG nand . */ + uint32_t ipgMemsize_kbytes; /*!< The memory size in unit of kbytes for IPG nand. */ + semc_rdy_polarity_t rdyactivePolarity; /*!< Wait ready polarity. */ + bool edoModeEnabled; /*!< EDO mode enabled. */ + semc_nand_column_bit_num_t columnAddrBitNum; /*!< Column address bit number. */ + semc_nand_address_option_t arrayAddrOption; /*!< Address option. */ + sem_nand_burst_len_t burstLen; /*!< Burst length. */ + smec_port_size_t portSize; /*!< Port size. */ + semc_nand_timing_config_t *timingConfig; /*!< SEMC nand timing configuration. */ +} semc_nand_config_t; + +/*! @brief SEMC NOR configuration structure. */ +typedef struct _semc_nor_config +{ + semc_iomux_pin cePinMux; /*!< The CE# pin mux setting. */ + semc_iomux_nora27_pin addr27; /*!< The Addr bit 27 pin mux setting. */ + uint32_t address; /*!< The base address. */ + uint32_t memsize_kbytes; /*!< The memory size in unit of kbytes. */ + uint8_t addrPortWidth; /*!< The address port width. */ + semc_rdy_polarity_t rdyactivePolarity; /*!< Wait ready polarity. */ + semc_adv_polarity_t advActivePolarity; /*!< ADV# polarity. */ + semc_norsram_column_bit_num_t columnAddrBitNum; /*!< Column address bit number. */ + semc_addr_mode_t addrMode; /*!< Address mode. */ + sem_norsram_burst_len_t burstLen; /*!< Burst length. */ + smec_port_size_t portSize; /*!< Port size. */ + uint8_t tCeSetup_Ns; /*!< The CE setup time. */ + uint8_t tCeHold_Ns; /*!< The CE hold time. */ + uint8_t tCeInterval_Ns; /*!< CE interval minimum time. */ + uint8_t tAddrSetup_Ns; /*!< The address setup time. */ + uint8_t tAddrHold_Ns; /*!< The address hold time. */ + uint8_t tWeLow_Ns; /*!< WE low time for async mode. */ + uint8_t tWeHigh_Ns; /*!< WE high time for async mode. */ + uint8_t tReLow_Ns; /*!< RE low time for async mode. */ + uint8_t tReHigh_Ns; /*!< RE high time for async mode. */ + uint8_t tTurnAround_Ns; /*!< Turnaround time for async mode. */ + uint8_t tAddr2WriteHold_Ns; /*!< Address to write data hold time for async mode. */ +#if defined(FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME) + uint8_t tWriteSetup_Ns; /*!< Write data setup time for sync mode.*/ +#endif +#if defined(FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME) + uint8_t tWriteHold_Ns; /*!< Write hold time for sync mode. */ +#endif + uint8_t latencyCount; /*!< Latency count for sync mode. */ + uint8_t readCycle; /*!< Read cycle time for sync mode. */ +} semc_nor_config_t; + +/*! @brief SEMC SRAM configuration structure. */ +typedef struct _semc_sram_config +{ + semc_iomux_pin cePinMux; /*!< The CE# pin mux setting. */ + semc_iomux_nora27_pin addr27; /*!< The Addr bit 27 pin mux setting. */ + uint32_t address; /*!< The base address. */ + uint32_t memsize_kbytes; /*!< The memory size in unit of kbytes. */ + uint8_t addrPortWidth; /*!< The address port width. */ + semc_adv_polarity_t advActivePolarity; /*!< ADV# polarity 1: active high, 0: active low. */ + semc_addr_mode_t addrMode; /*!< Address mode. */ + sem_norsram_burst_len_t burstLen; /*!< Burst length. */ + smec_port_size_t portSize; /*!< Port size. */ + uint8_t tCeSetup_Ns; /*!< The CE setup time. */ + uint8_t tCeHold_Ns; /*!< The CE hold time. */ + uint8_t tCeInterval_Ns; /*!< CE interval minimum time. */ + uint8_t tAddrSetup_Ns; /*!< The address setup time. */ + uint8_t tAddrHold_Ns; /*!< The address hold time. */ + uint8_t tWeLow_Ns; /*!< WE low time for async mode. */ + uint8_t tWeHigh_Ns; /*!< WE high time for async mode. */ + uint8_t tReLow_Ns; /*!< RE low time for async mode. */ + uint8_t tReHigh_Ns; /*!< RE high time for async mode. */ + uint8_t tTurnAround_Ns; /*!< Turnaround time for async mode. */ + uint8_t tAddr2WriteHold_Ns; /*!< Address to write data hold time for async mode. */ + uint8_t tWriteSetup_Ns; /*!< Write data setup time for sync mode.*/ + uint8_t tWriteHold_Ns; /*!< Write hold time for sync mode. */ + uint8_t latencyCount; /*!< Latency count for sync mode. */ + uint8_t readCycle; /*!< Read cycle time for sync mode. */ +} semc_sram_config_t; + +/*! @brief SEMC DBI configuration structure. */ +typedef struct _semc_dbi_config +{ + semc_iomux_pin csxPinMux; /*!< The CE# pin mux. */ + uint32_t address; /*!< The base address. */ + uint32_t memsize_kbytes; /*!< The memory size in unit of 4kbytes. */ + semc_dbi_column_bit_num_t columnAddrBitNum; /*!< Column address bit number. */ + sem_dbi_burst_len_t burstLen; /*!< Burst length. */ + smec_port_size_t portSize; /*!< Port size. */ + uint8_t tCsxSetup_Ns; /*!< The CSX setup time. */ + uint8_t tCsxHold_Ns; /*!< The CSX hold time. */ + uint8_t tWexLow_Ns; /*!< WEX low time. */ + uint8_t tWexHigh_Ns; /*!< WEX high time. */ + uint8_t tRdxLow_Ns; /*!< RDX low time. */ + uint8_t tRdxHigh_Ns; /*!< RDX high time. */ + uint8_t tCsxInterval_Ns; /*!< Write data setup time.*/ +} semc_dbi_config_t; + +/*! @brief SEMC AXI queue a weight setting structure. */ +typedef struct _semc_queuea_weight_struct +{ + uint32_t qos : 4; /*!< weight of qos for queue 0 . */ + uint32_t aging : 4; /*!< weight of aging for queue 0.*/ + uint32_t slaveHitSwith : 8; /*!< weight of read/write switch for queue 0.*/ + uint32_t slaveHitNoswitch : 8; /*!< weight of read/write no switch for queue 0 .*/ +} semc_queuea_weight_struct_t; + +/*! @brief SEMC AXI queue a weight setting union. */ +typedef union _semc_queuea_weight +{ + semc_queuea_weight_struct_t queueaConfig; /*!< Structure configuration for queueA. */ + uint32_t queueaValue; /*!< Configuration value for queueA which could directly write to the reg. */ +} semc_queuea_weight_t; + +/*! @brief SEMC AXI queue b weight setting structure. */ +typedef struct _semc_queueb_weight_struct +{ + uint32_t qos : 4; /*!< weight of qos for queue 1. */ + uint32_t aging : 4; /*!< weight of aging for queue 1.*/ + uint32_t slaveHitSwith : 8; /*!< weight of read/write switch for queue 1.*/ + uint32_t weightPagehit : 8; /*!< weight of page hit for queue 1 only .*/ + uint32_t bankRotation : 8; /*!< weight of bank rotation for queue 1 only .*/ +} semc_queueb_weight_struct_t; + +/*! @brief SEMC AXI queue b weight setting union. */ +typedef union _semc_queueb_weight +{ + semc_queueb_weight_struct_t queuebConfig; /*!< Structure configuration for queueB. */ + uint32_t queuebValue; /*!< Configuration value for queueB which could directly write to the reg. */ +} semc_queueb_weight_t; + +/*! @brief SEMC AXI queue weight setting. */ +typedef struct _semc_axi_queueweight +{ + semc_queuea_weight_t queueaWeight; /*!< Weight settings for queue a. */ + semc_queueb_weight_t queuebWeight; /*!< Weight settings for queue b. */ +} semc_axi_queueweight_t; + +/*! + * @brief SEMC configuration structure. + * + * busTimeoutCycles: when busTimeoutCycles is zero, the bus timeout cycle is + * 255*1024. otherwise the bus timeout cycles is busTimeoutCycles*1024. + * cmdTimeoutCycles: is used for command execution timeout cycles. it's + * similar to the busTimeoutCycles. + */ +typedef struct _semc_config_t +{ + semc_dqs_mode_t dqsMode; /*!< Dummy read strobe mode: use enum in "semc_dqs_mode_t". */ + uint8_t cmdTimeoutCycles; /*!< Command execution timeout cycles. */ + uint8_t busTimeoutCycles; /*!< Bus timeout cycles. */ + semc_axi_queueweight_t queueWeight; /*!< AXI queue weight. */ +} semc_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name SEMC Initialization and De-initialization + * @{ + */ + +/*! + * @brief Gets the SEMC default basic configuration structure. + * + * The purpose of this API is to get the default SEMC + * configure structure for SEMC_Init(). User may use the initialized + * structure unchanged in SEMC_Init(), or modify some fields of the + * structure before calling SEMC_Init(). + * Example: + @code + semc_config_t config; + SEMC_GetDefaultConfig(&config); + @endcode + * @param config The SEMC configuration structure pointer. + */ +void SEMC_GetDefaultConfig(semc_config_t *config); + +/*! + * @brief Initializes SEMC. + * This function ungates the SEMC clock and initializes SEMC. + * This function must be called before calling any other SEMC driver functions. + * + * @param base SEMC peripheral base address. + * @param configure The SEMC configuration structure pointer. + */ +void SEMC_Init(SEMC_Type *base, semc_config_t *configure); + +/*! + * @brief Deinitializes the SEMC module and gates the clock. + * + * This function gates the SEMC clock. As a result, the SEMC module doesn't work after + * calling this function, for some IDE, calling this API may cause the next downloading + * operation failed. so, please call this API cautiously. Additional, users can + * using "#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL (1)" to disable the clock control + * operation in drivers. + * + * @param base SEMC peripheral base address. + */ +void SEMC_Deinit(SEMC_Type *base); + +/* @} */ + +/*! + * @name SEMC Configuration Operation For Each Memory Type + * @{ + */ + +/*! + * @brief Configures SDRAM controller in SEMC. + * + * @param base SEMC peripheral base address. + * @param cs The chip selection. + * @param config The sdram configuration. + * @param clkSrc_Hz The SEMC clock frequency. + */ +status_t SEMC_ConfigureSDRAM(SEMC_Type *base, semc_sdram_cs_t cs, semc_sdram_config_t *config, uint32_t clkSrc_Hz); + +/*! + * @brief Configures NAND controller in SEMC. + * + * @param base SEMC peripheral base address. + * @param config The nand configuration. + * @param clkSrc_Hz The SEMC clock frequency. + */ +status_t SEMC_ConfigureNAND(SEMC_Type *base, semc_nand_config_t *config, uint32_t clkSrc_Hz); + +/*! + * @brief Configures NOR controller in SEMC. + * + * @param base SEMC peripheral base address. + * @param config The nor configuration. + * @param clkSrc_Hz The SEMC clock frequency. + */ +status_t SEMC_ConfigureNOR(SEMC_Type *base, semc_nor_config_t *config, uint32_t clkSrc_Hz); + +/*! + * @brief Configures SRAM controller in SEMC. + * + * @param base SEMC peripheral base address. + * @param config The sram configuration. + * @param clkSrc_Hz The SEMC clock frequency. + */ +status_t SEMC_ConfigureSRAM(SEMC_Type *base, semc_sram_config_t *config, uint32_t clkSrc_Hz); + +/*! + * @brief Configures DBI controller in SEMC. + * + * @param base SEMC peripheral base address. + * @param config The dbi configuration. + * @param clkSrc_Hz The SEMC clock frequency. + */ +status_t SEMC_ConfigureDBI(SEMC_Type *base, semc_dbi_config_t *config, uint32_t clkSrc_Hz); + +/* @} */ + +/*! + * @name SEMC Interrupt Operation + * @{ + */ + +/*! + * @brief Enables the SEMC interrupt. + * + * This function enables the SEMC interrupts according to the provided mask. The mask + * is a logical OR of enumeration members. See @ref semc_interrupt_enable_t. + * For example, to enable the IP command done and error interrupt, do the following. + * @code + * SEMC_EnableInterrupts(ENET, kSEMC_IPCmdDoneInterrupt | kSEMC_IPCmdErrInterrupt); + * @endcode + * + * @param base SEMC peripheral base address. + * @param mask SEMC interrupts to enable. This is a logical OR of the + * enumeration :: semc_interrupt_enable_t. + */ +static inline void SEMC_EnableInterrupts(SEMC_Type *base, uint32_t mask) +{ + base->INTEN |= mask; +} + +/*! + * @brief Disables the SEMC interrupt. + * + * This function disables the SEMC interrupts according to the provided mask. The mask + * is a logical OR of enumeration members. See @ref semc_interrupt_enable_t. + * For example, to disable the IP command done and error interrupt, do the following. + * @code + * SEMC_DisableInterrupts(ENET, kSEMC_IPCmdDoneInterrupt | kSEMC_IPCmdErrInterrupt); + * @endcode + * + * @param base SEMC peripheral base address. + * @param mask SEMC interrupts to disable. This is a logical OR of the + * enumeration :: semc_interrupt_enable_t. + */ +static inline void SEMC_DisableInterrupts(SEMC_Type *base, uint32_t mask) +{ + base->INTEN &= ~mask; +} + +/*! + * @brief Gets the SEMC status. + * + * This function gets the SEMC interrupts event status. + * User can use the a logical OR of enumeration member as a mask. + * See @ref semc_interrupt_enable_t. + * + * @param base SEMC peripheral base address. + * @return status flag, use status flag in semc_interrupt_enable_t to get the related status. + */ +static inline bool SEMC_GetStatusFlag(SEMC_Type *base) +{ + return base->INTR; +} + +/*! + * @brief Clears the SEMC status flag state. + * + * The following status register flags can be cleared SEMC interrupt status. + * + * @param base SEMC base pointer + * @param mask The status flag mask, a logical OR of enumeration member @ref semc_interrupt_enable_t. + */ +static inline void SEMC_ClearStatusFlags(SEMC_Type *base, uint32_t mask) +{ + base->INTR |= mask; +} + +/* @} */ + +/*! + * @name SEMC Memory Access Operation + * @{ + */ + +/*! + * @brief Check if SEMC is in idle. + * + * @param base SEMC peripheral base address. + * @return True SEMC is in idle, false is not in idle. + */ +static inline bool SEMC_IsInIdle(SEMC_Type *base) +{ + return (base->STS0 & SEMC_STS0_IDLE_MASK) ? true : false; +} + +/*! + * @brief SEMC IP command access. + * + * @param base SEMC peripheral base address. + * @param type SEMC memory type. refer to "semc_mem_type_t" + * @param address SEMC device address. + * @param command SEMC IP command. + * For NAND device, we should use the SEMC_BuildNandIPCommand to get the right nand command. + * For NOR/DBI device, take refer to "semc_ipcmd_nor_dbi_t". + * For SRAM device, take refer to "semc_ipcmd_sram_t". + * For SDRAM device, take refer to "semc_ipcmd_sdram_t". + * @param write Data for write access. + * @param read Data pointer for read data out. + */ +status_t SEMC_SendIPCommand( + SEMC_Type *base, semc_mem_type_t type, uint32_t address, uint16_t command, uint32_t write, uint32_t *read); + +/*! + * @brief Build SEMC IP command for NAND. + * + * This function build SEMC NAND IP command. The command is build of user command code, + * SEMC address mode and SEMC command mode. + * + * @param userCommand NAND device normal command. + * @param addrMode NAND address mode. Refer to "semc_ipcmd_nand_addrmode_t". + * @param cmdMode NAND command mode. Refer to "semc_ipcmd_nand_cmdmode_t". + */ +static inline uint16_t SEMC_BuildNandIPCommand(uint8_t userCommand, + semc_ipcmd_nand_addrmode_t addrMode, + semc_ipcmd_nand_cmdmode_t cmdMode) +{ + return (uint16_t)((uint16_t)userCommand << 8) | (uint16_t)(addrMode << 4) | ((uint8_t)cmdMode & 0x0Fu); +} + +/*! + * @brief Check if the NAND device is ready. + * + * @param base SEMC peripheral base address. + * @return True NAND is ready, false NAND is not ready. + */ +static inline bool SEMC_IsNandReady(SEMC_Type *base) +{ + return (base->STS0 & SEMC_STS0_NARDY_MASK) ? true : false; +} + +/*! + * @brief SEMC NAND device memory write through IP command. + * + * @param base SEMC peripheral base address. + * @param address SEMC NAND device address. + * @param data Data for write access. + * @param size_bytes Data length. + */ +status_t SEMC_IPCommandNandWrite(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes); + +/*! + * @brief SEMC NAND device memory read through IP command. + * + * @param base SEMC peripheral base address. + * @param address SEMC NAND device address. + * @param data Data pointer for data read out. + * @param size_bytes Data length. + */ +status_t SEMC_IPCommandNandRead(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes); + +/*! + * @brief SEMC NOR device memory write through IP command. + * + * @param base SEMC peripheral base address. + * @param address SEMC NOR device address. + * @param data Data for write access. + * @param size_bytes Data length. + */ +status_t SEMC_IPCommandNorWrite(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes); + +/*! + * @brief SEMC NOR device memory read through IP command. + * + * @param base SEMC peripheral base address. + * @param address SEMC NOR device address. + * @param data Data pointer for data read out. + * @param size_bytes Data length. + */ +status_t SEMC_IPCommandNorRead(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_SEMC_H_*/ diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/semc_externsdram_test.c b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/semc_externsdram_test.c new file mode 100644 index 000000000..c09b6dc27 --- /dev/null +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/semc_externsdram_test.c @@ -0,0 +1,180 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "board.h" + +#define EXAMPLE_SEMC_START_ADDRESS (0x80000000U) + +#define SEMC_EXAMPLE_DATALEN (0x1000U) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SEMC_SDRAMReadWrite32Bit(void); +static void SEMC_SDRAMReadWrite16Bit(void); +static void SEMC_SDRAMReadWrite8Bit(void); +/******************************************************************************* + * Variables + ******************************************************************************/ + +uint32_t sdram_writeBuffer[SEMC_EXAMPLE_DATALEN]; +uint32_t sdram_readBuffer[SEMC_EXAMPLE_DATALEN]; + +/*! + * @brief Main function + */ +int semc_externsram_test(void) +{ + KPrintf("\r\n SEMC SDRAM Example Start!\r\n"); + + /* 32Bit data read and write. */ + SEMC_SDRAMReadWrite32Bit(); + /* 16Bit data read and write. */ + SEMC_SDRAMReadWrite16Bit(); + /* 8Bit data read and write. */ + SEMC_SDRAMReadWrite8Bit(); + + KPrintf("\r\n SEMC SDRAM Example End.\r\n"); + +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),semc_externsram_test, semc_externsram_test, semc_externsram_test ); + +void SEMC_SDRAMReadWrite32Bit(void) +{ + uint32_t index; + uint32_t datalen = SEMC_EXAMPLE_DATALEN; + uint32_t *sdram = (uint32_t *)EXAMPLE_SEMC_START_ADDRESS; /* SDRAM start address. */ + int result = 0; + + KPrintf("\r\n SEMC SDRAM Memory 32 bit Write Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + /* Prepare data and write to SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_writeBuffer[index] = index; + sdram[index] = sdram_writeBuffer[index]; + } + + KPrintf("\r\n SEMC SDRAM Read 32 bit Data Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + /* Read data from the SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_readBuffer[index] = sdram[index]; + } + + KPrintf("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Start!\r\n"); + /* Compare the two buffers. */ + while (datalen--) + { + if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen]) + { + result = -1; + break; + } + } + + if (result < 0) + { + KPrintf("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Failed!\r\n"); + } + else + { + KPrintf("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Succeed!\r\n"); + } +} + +static void SEMC_SDRAMReadWrite16Bit(void) +{ + uint32_t index; + uint32_t datalen = SEMC_EXAMPLE_DATALEN; + uint16_t *sdram = (uint16_t *)EXAMPLE_SEMC_START_ADDRESS; /* SDRAM start address. */ + int result = 0; + + KPrintf("\r\n SEMC SDRAM Memory 16 bit Write Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + + memset(sdram_writeBuffer, 0, sizeof(sdram_writeBuffer)); + memset(sdram_readBuffer, 0, sizeof(sdram_readBuffer)); + + /* Prepare data and write to SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_writeBuffer[index] = index % 0xFFFF; + sdram[index] = sdram_writeBuffer[index]; + } + + KPrintf("\r\n SEMC SDRAM Read 16 bit Data Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + /* Read data from the SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_readBuffer[index] = sdram[index]; + } + + KPrintf("\r\n SEMC SDRAM 16 bit Data Write and Read Compare Start!\r\n"); + /* Compare the two buffers. */ + while (datalen--) + { + if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen]) + { + result = -1; + break; + } + } + + if (result < 0) + { + KPrintf("\r\n SEMC SDRAM 16 bit Data Write and Read Compare Failed!\r\n"); + } + else + { + KPrintf("\r\n SEMC SDRAM 16 bit Data Write and Read Compare Succeed!\r\n"); + } +} + +static void SEMC_SDRAMReadWrite8Bit(void) +{ + uint32_t index; + uint32_t datalen = SEMC_EXAMPLE_DATALEN; + uint8_t *sdram = (uint8_t *)EXAMPLE_SEMC_START_ADDRESS; /* SDRAM start address. */ + int result = 0; + + KPrintf("\r\n SEMC SDRAM Memory 8 bit Write Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + + memset(sdram_writeBuffer, 0, sizeof(sdram_writeBuffer)); + memset(sdram_readBuffer, 0, sizeof(sdram_readBuffer)); + + /* Prepare data and write to SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_writeBuffer[index] = index % 0x100; + sdram[index] = sdram_writeBuffer[index]; + } + + KPrintf("\r\n SEMC SDRAM Read 8 bit Data Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + /* Read data from the SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_readBuffer[index] = sdram[index]; + } + + KPrintf("\r\n SEMC SDRAM 8 bit Data Write and Read Compare Start!\r\n"); + /* Compare the two buffers. */ + while (datalen--) + { + if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen]) + { + result = -1; + break; + } + } + + if (result < 0) + { + KPrintf("\r\n SEMC SDRAM 8 bit Data Write and Read Compare Failed!\r\n"); + } + else + { + KPrintf("\r\n SEMC SDRAM 8 bit Data Write and Read Compare Succeed!\r\n"); + } +} diff --git a/Ubiquitous/XiUOS/kernel/kernel_test/extsram_test.c b/Ubiquitous/XiUOS/kernel/kernel_test/extsram_test.c index 1e0741430..62402162a 100644 --- a/Ubiquitous/XiUOS/kernel/kernel_test/extsram_test.c +++ b/Ubiquitous/XiUOS/kernel/kernel_test/extsram_test.c @@ -2,12 +2,18 @@ #include /* parameters for sram peripheral */ -/* stm32f4 Bank3:0X68000000 */ -#define SRAM_BANK_ADDR ((uint32_t)0X68000000) +// /* stm32f4 Bank3:0X68000000 */ +// #define SRAM_BANK_ADDR ((uint32_t)0X68000000) + +/* OK-1052 semc:0X80000000 */ +#define SRAM_BANK_ADDR ((uint32_t)0X80000000) /* data width: 8, 16, 32 */ #define SRAM_DATA_WIDTH 16 + +// /* sram size */ +// #define SRAM_SIZE ((uint32_t)0x00100000) /* sram size */ -#define SRAM_SIZE ((uint32_t)0x00100000) +#define SRAM_SIZE ((uint32_t)0x008000) int sram_test(void) { diff --git a/Ubiquitous/XiUOS/kernel/memory/byte_manage.c b/Ubiquitous/XiUOS/kernel/memory/byte_manage.c index 9fda3a1dc..0df9136da 100644 --- a/Ubiquitous/XiUOS/kernel/memory/byte_manage.c +++ b/Ubiquitous/XiUOS/kernel/memory/byte_manage.c @@ -1222,7 +1222,7 @@ void ShowBuddy(void) }; } - KPrintf("\nlist memory information\n\n"); + KPrintf("\n\033[41;1mlist extern memory information\033[0m\n"); #ifdef MEM_EXTERN_SRAM for(i = 0; i < EXTSRAM_MAX_NUM; i++) { if(NONE != ExtByteManager[i].done){ @@ -1230,14 +1230,16 @@ void ShowBuddy(void) for(int lev = 0; lev < MEM_LINKNRS; lev++) { KPrintf("\n %s level [%d],memory size[2^%d] \n",__func__, lev,lev +6); for (debug = & ExtByteManager[i].dynamic_buddy_manager.mm_freenode_list[lev]; ; ) { - if(debug->size > 0) - KPrintf(" [current node %x,next node %x, size %u, flag %x]\n",debug, debug->next,debug->size,debug->flag); - else - KPrintf(" [listhead node %x,next node %x]\n",debug, debug->next); if(debug->next) + { debug = debug->next; - if(debug->size == 0) + if(debug->size > 0) + KPrintf(" [current node %x,next node %x, size %u, flag %x]\n",debug, debug->next,debug->size,debug->flag); + else + KPrintf(" \n"); + } + if(debug->size == 0 || NONE == debug->next) break; } } From d56a5315ddb904bb3dd11f5178286bd7f0227758 Mon Sep 17 00:00:00 2001 From: Wang_Weigen Date: Mon, 17 Jan 2022 15:43:06 +0800 Subject: [PATCH 7/7] modify the extern sram size as 32MBytes --- .../XiUOS/board/ok1052-c/third_party_driver/semc/connect_semc.c | 2 +- Ubiquitous/XiUOS/kernel/kernel_test/extsram_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/connect_semc.c b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/connect_semc.c index 1f05cd4ed..2477fb2f6 100644 --- a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/connect_semc.c +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/semc/connect_semc.c @@ -5,7 +5,7 @@ #define EXAMPLE_SEMC SEMC #define EXAMPLE_SEMC_START_ADDRESS (0x80000000U) #define EXAMPLE_SEMC_CLK_FREQ CLOCK_GetFreq(kCLOCK_SemcClk) -#define SEMC_SRAM_SIZE (32 * 1024) +#define SEMC_SRAM_SIZE (32 * 1024 * 1024) status_t BOARD_InitSEMC(void) { diff --git a/Ubiquitous/XiUOS/kernel/kernel_test/extsram_test.c b/Ubiquitous/XiUOS/kernel/kernel_test/extsram_test.c index 62402162a..d17b63a29 100644 --- a/Ubiquitous/XiUOS/kernel/kernel_test/extsram_test.c +++ b/Ubiquitous/XiUOS/kernel/kernel_test/extsram_test.c @@ -13,7 +13,7 @@ // /* sram size */ // #define SRAM_SIZE ((uint32_t)0x00100000) /* sram size */ -#define SRAM_SIZE ((uint32_t)0x008000) +#define SRAM_SIZE ((uint32_t)0x2000000) int sram_test(void) {