From 1ecb6d2c4c42f41887494db19ad3b8522225b6db Mon Sep 17 00:00:00 2001 From: "jianzhen.guo" Date: Wed, 28 Sep 2022 14:38:17 +0800 Subject: [PATCH] [Add] Add lcd driver support (including TFT and SLCD). --- cpu/soc-x16xx/include/dpu.h | 2 + drivers/drivers-x16xx/include/x16xx_hal_lcd.h | 612 ++++++++++++++++ drivers/drivers-x16xx/src/x16xx_hal_lcd.c | 677 ++++++++++++++++++ drivers/drivers-x16xx/src/x16xx_hal_uart.c | 4 + 4 files changed, 1295 insertions(+) create mode 100644 drivers/drivers-x16xx/include/x16xx_hal_lcd.h create mode 100644 drivers/drivers-x16xx/src/x16xx_hal_lcd.c diff --git a/cpu/soc-x16xx/include/dpu.h b/cpu/soc-x16xx/include/dpu.h index 11656cb6..59248335 100755 --- a/cpu/soc-x16xx/include/dpu.h +++ b/cpu/soc-x16xx/include/dpu.h @@ -677,6 +677,8 @@ typedef struct { #define SLCD_FRM_SIZE_H_SIZE_15 (0x8000UL << SLCD_FRM_SIZE_H_SIZE_Pos) /*!< 0x00008000 */ /********* Register BitField Details: SLCD_REG_IF BASE+0xA014 *********/ +#define SLCD_REG_IF_Pos (0U) +#define SLCD_REG_IF_Msk (0xffffffffUL << SLCD_REG_IF_Pos) #define SLCD_REG_IF_FLAG_Pos (30U) #define SLCD_REG_IF_FLAG_Msk (0x3UL << SLCD_REG_IF_FLAG_Pos) /*!< 0xc0000000 */ #define SLCD_REG_IF_FLAG SLCD_REG_IF_FLAG_Msk diff --git a/drivers/drivers-x16xx/include/x16xx_hal_lcd.h b/drivers/drivers-x16xx/include/x16xx_hal_lcd.h new file mode 100644 index 00000000..fcd3b54f --- /dev/null +++ b/drivers/drivers-x16xx/include/x16xx_hal_lcd.h @@ -0,0 +1,612 @@ +/** + * @file x16xx_hal_lcd.h + * @author MPU系统软件部团队 + * @brief [!!!!删除此内容,添加文件简介!!!!] + * + * @copyright 版权所有 (北京君正集成电路股份有限公司) {2022} + * @copyright Copyright© 2022 Ingenic Semiconductor Co.,Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __X16XX_HAL_LCD_H__ +#define __X16XX_HAL_LCD_H__ + + +/** + * @addtogroup group_LCD + * @{ + */ + +/** + * @addtogroup g_X16XX_LCD_HAL_Driver LCD HAL 驱动 + * @{ + */ + +/* 1.头文件 (Includes)------------------------------------------------- */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* 2.导出的类型 (Exported Types)--------------------------------------- */ +/** + * @defgroup LCD_exported_types LCD 导出的类型 (Exported Types) + * @{ + */ + +enum lcdc_out_format { + OUT_FORMAT_RGB565, + OUT_FORMAT_RGB666, + OUT_FORMAT_RGB888, + OUT_FORMAT_RGB444, + OUT_FORMAT_RGB555, +}; + +enum lcdc_mcu_data_width { + MCU_WIDTH_8BITS, + MCU_WIDTH_9BITS, + MCU_WIDTH_16BITS, + MCU_WIDTH_18BITS, + MCU_WIDTH_24BITS, +}; + +enum lcdc_out_order { + ORDER_RGB, + ORDER_RBG, + ORDER_GRB, + ORDER_BRG, + ORDER_GBR, + ORDER_BGR, +}; + +enum lcdc_lcd_mode { + TFT_24BITS, + TFT_8BITS_SERIAL = 2, + TFT_8BITS_DUMMY_SERIAL, + + SLCD_6800, + SLCD_8080, + SLCD_SPI_3LINE, + SLCD_SPI_4LINE, +}; + +enum lcdc_signal_polarity { + AT_FALLING_EDGE, + AT_RISING_EDGE, +}; + +enum lcdc_signal_level { + AT_LOW_LEVEL, + AT_HIGH_LEVEL, +}; + +enum lcdc_dc_pin { + CMD_LOW_DATA_HIGH, + CMD_HIGH_DATA_LOW, +}; + +enum lcdc_data_trans_mode { + LCD_PARALLEL_MODE, + LCD_SERIAL_MODE, +}; + +enum lcdc_te_type { + TE_NOT_EANBLE, + TE_GPIO_IRQ_TRIGGER, + TE_LCDC_TRIGGER, +}; + +enum smart_config_type { + SMART_CONFIG_DATA, + SMART_CONFIG_PRM, + SMART_CONFIG_CMD, + SMART_CONFIG_UDELAY, +}; + +struct smart_lcd_data_table { + enum smart_config_type type; + unsigned int value; +}; + +enum fb_fmt { + fb_fmt_RGB555, + fb_fmt_RGB565, + fb_fmt_RGB888, + fb_fmt_ARGB8888, + fb_fmt_NV12, + fb_fmt_NV21, + fb_fmt_yuv422, +}; + + +enum frame_state { + state_clear, + state_display_start, + state_display_end, + state_stop, +}; + +struct srdmadesc { + unsigned long RdmaNextCfgAddr; + unsigned long FrameBufferAddr; + unsigned long stride; + unsigned long FrameCtrl; + unsigned long InterruptControl; +}; + +struct lcdc_srdma_cfg { + enum fb_fmt fb_fmt; + void *fb_mem; + int is_video; + int stride; +}; + +#define EVEN_RGBTORGB 0x00000000U +#define EVEN_RGBTORBG ((uint32_t)TFT_TRAN_CFG_COLOR_EVEN_0) +#define EVEN_RGBTOBGR ((uint32_t)TFT_TRAN_CFG_COLOR_EVEN_1) +#define EVEN_RGBTOBRG ((uint32_t)TFT_TRAN_CFG_COLOR_EVEN_0 | TFT_TRAN_CFG_COLOR_EVEN_1) +#define EVEN_RGBTOGBR ((uint32_t)TFT_TRAN_CFG_COLOR_EVEN_2) +#define ENEN_RGBTOGRB ((uint32_t)TFT_TRAN_CFG_COLOR_EVEN_0 | TFT_TRAN_CFG_COLOR_EVEN_2) + +#define ODD_RGBTORGB 0x00000000U +#define ODD_RGBTORBG ((uint32_t)TFT_TRAN_CFG_COLOR_ODD_0) +#define ODD_RGBTOBGR ((uint32_t)TFT_TRAN_CFG_COLOR_ODD_1) +#define ODD_RGBTOBRG ((uint32_t)TFT_TRAN_CFG_COLOR_ODD_0 | TFT_TRAN_CFG_COLOR_ODD_1) +#define ODD_RGBTOGBR ((uint32_t)TFT_TRAN_CFG_COLOR_ODD_2) +#define ODD_RGBTOGRB ((uint32_t)TFT_TRAN_CFG_COLOR_ODD_0 | TFT_TRAN_CFG_COLOR_ODD_2) + +struct lcd_data{ + const char *name; + unsigned int refresh; + unsigned int xres; + unsigned int yres; + unsigned int pixclock; + unsigned int left_margin; + unsigned int right_margin; + unsigned int upper_margin; + unsigned int lower_margin; + unsigned int hsync_len; + unsigned int vsync_len; + + enum fb_fmt fb_fmt; + enum lcdc_lcd_mode lcd_mode; + enum lcdc_out_format out_format; + struct { + int even_line_order; + int odd_line_order; + enum lcdc_signal_polarity pix_clk_polarity; + enum lcdc_signal_level de_active_level; + enum lcdc_signal_level hsync_active_level; + enum lcdc_signal_level vsync_active_level; + } tft; + struct { + unsigned int pixclock_when_init; + int te_gpio; + int cmd_of_start_frame; + int mcu_data_width; + int mcu_cmd_width; + enum lcdc_signal_polarity wr_data_sample_edge; + enum lcdc_dc_pin dc_pin; + enum lcdc_signal_polarity te_data_transfered_edge; + enum lcdc_te_type te_pin_mode; + enum lcdc_signal_level rdy_cmd_send_level; + int enable_rdy_pin:1; + } slcd; + + int height; // 屏的物理高度,单位毫米 + int width; // 屏的物理宽度,单位毫米 + struct smart_lcd_data_table *slcd_data_table; + unsigned int slcd_data_table_length; + int (*power_on)(void); + int (*power_off)(void); +}; + +typedef struct __LCD_HandleTypeDef { + DPU_TypeDef *Instance; + struct lcd_data *pdata; + struct srdmadesc *desc; + +} LCD_HandleTypeDef; + +/** + * @} + */ +/* 3.导出常量定义 (Exported Constants) -------------------------------- */ +/** + * @defgroup LCD_exported_constants LCD 导出的常量 (Exported Constants) + * @{ + */ + +#define TFT_d0 0 +#define TFT_d1 1 +#define TFT_d2 2 +#define TFT_d3 3 +#define TFT_d4 4 +#define TFT_d5 5 +#define TFT_d6 6 +#define TFT_d7 7 +#define TFT_d8 8 +#define TFT_d9 9 +#define TFT_d10 10 +#define TFT_d11 11 +#define TFT_d12 12 +#define TFT_d13 13 +#define TFT_d14 14 +#define TFT_d15 15 +#define TFT_d16 16 +#define TFT_d17 17 +#define TFT_d18 18 +#define TFT_d19 19 +#define TFT_d20 20 +#define TFT_d21 21 +#define TFT_d22 22 +#define TFT_d23 23 + +#define TFT_pclk 24 +#define TFT_vsync 25 +#define TFT_hsync 26 +#define TFT_de 27 + +#define SLCD_CE 23 +#define SLCD_DC 25 +#define SLCD_WR 26 +#define SLCD_TE 27 + + +#define BURST_LEN_RDMA_4 0x00000000U /*读取DMA的最大长度4*/ +#define BURST_LEN_RDMA_8 0x00000001U/*读取DMA的最大长度8*/ +#define BURST_LEN_RDMA_16 0x00000002U/*读取DMA的最大长度16*/ +#define BURST_LEN_RDMA_32 0x00000003U/*读取DMA的最大长度32*/ + + +#define QoS_value_0 0x00000000U /*重置值为0*/ +#define QoS_value_1 0x00000001U /*重置值为1*/ +#define QoS_value_2 0x00000002U /*重置值为2*/ +#define QoS_value_3 0x00000003U /*重置值为3*/ + + +#define DISPLAY_SELECT_NO 0x00000000U +#define DISPLAY_SELECT_TFT 0x00000001U +#define DISPLAY_SELECT_SLCD 0x00000002U + + + +#define FLAG_DATA 0x00000000U +#define FLAG_PARAMETER 0x00000001U +#define FLAG_CMD_1 0x00000002U +#define FLAG_CMD_2 0x00000003U + +#define VIR_TO_PHY(add) (((uint32_t)add) & (~0x80000000)) +/** + * @} + */ +/* 4.导出宏定义 (Exported Macros) ------------------------------------- */ +/** + * @defgroup LCD_exported_macros LCD 导出宏 (Exported Macros) + * @{ + */ + +/** + * @defgroup LCD_exported_macros_group0 RDMA描述符地址 + * @{ + */ +#define __HAL_SRD_CHAIN_ADDR(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->DC_SRD_CHAIN_ADDR, __VALUE__) + +/** + * @defgroup LCD_exported_macros_group1 RDMA描述符控制 + * @{ + */ +#define __HAL_SRD_CHAIN_START(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_SRD_CHAIN_CTRL, DC_SRD_CHAIN_CTRL_SRD_CHAIN_START_0) +/** + * @defgroup LCD_exported_macros_group2 控件配置 + * @{ + */ +/*正常停止LCD显示*/ +#define __GEN_STP_SRD(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_CTRL,DC_CTRL_GEN_STP_SRD_0) +/*重置DMA计数器*/ +#define __DES_CNT_RST(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_CTRL,DC_CTRL_DES_CNT_RST_0) +/*快速停止LCD显示*/ +#define __QCK_STP_SRD(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_CTRL,DC_CTRL_QCK_STP_SRD_0) +/** + * @defgroup LCD_exported_macros_group3 状态判断 + * @{ + */ +#define __HAL_DISP_END(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_ST_DISP_END_0) +#define __HAL_TFT_UNDR(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_ST_TFT_UNDR_0) +#define __HAL_STOP_SRD_ACK(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_ST_STOP_SRD_ACK_0) +#define __HAL_SRD_WORKING(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_ST_SRD_WORKING_0) +#define __HAL_SRD_START(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_ST_SRD_START_0) +#define __HAL_SRD_END(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_ST_SRD_END_0) +#define __HAL_WORKING(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_ST_WORKING_0) +/** + * @defgroup LCD_exported_macros_group4 清除状态 + * @{ + */ +#define __GEN_CLR_DISP_END(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_CLR_ST, DC_CLR_ST_CLR_DISP_END_0) +#define __GEN_CLR_TFT_UNDR(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_CLR_ST, DC_CLR_ST_CLR_TFT_UNDR_0) +#define __GEN_CLR_STOP_SRD_ACK(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_CLR_ST, DC_CLR_ST_CLR_STP_SRD_ACK_0) +#define __GEN_CLR_SRD_START(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_CLR_ST, DC_CLR_ST_CLR_SRD_START_0) +#define __GEN_CLR_SRD_END(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_CLR_ST, DC_CLR_ST_CLR_SRD_END_0) +/** + * @defgroup LCD_exported_macros_group5 中断 + * @{ + */ +#define __HAL_EOD_MSK(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_INTC, DC_INTC_EOD_MSK_0) +#define __HAL_UOT_MSK(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_INTC, DC_INTC_UOT_MSK_0) +#define __HAL_SSA_MSK(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_INTC, DC_INTC_SSA_MSK_0) +#define __HAL_SOS_MSK(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_INTC, DC_INTC_SOS_MSK_0) +#define __HAL_EOS_MSK(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_INTC, DC_INTC_EOS_MSK_0) +/** + * @defgroup LCD_exported_macros_group6 中断标志 + * @{ + */ +#define __HAL_INT_EOD(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_INT_FLAG_INT_EOD_0) +#define __HAL_INT_UOT(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_INT_FLAG_INT_UOT_0) +#define __HAL_INT_SSA(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_INT_FLAG_INT_SSA_0) +#define __HAL_INT_SOS(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_INT_FLAG_INT_SOS_0) +#define __HAL_INT_EOS(__HANDLE__) READ_BIT((__HANDLE__)->Instance->DC_ST, DC_INT_FLAG_INT_EOS_0) +/** + * @defgroup LCD_exported_macros_group7 读取DMA的最大长度 + * @{ + */ +#define __HAL_BURST_LEN_RDMA(__HANDLE__, __VALUE__) WRITE_REG((__HANDLE__)->Instance->DC_COM_CONFIG, (__VALUE__) << DC_COM_CONFIG_BURST_LEN_RDMA_Pos) +/** + * @defgroup LCD_exported_macros_group8 优先级配置 + * @{ + */ +#define __HAL_ARQOS_VAL(__HANDLE__, __VALUE__) WRITE_REG((__HANDLE__)->Instance->DC_PCFG_RD_CTRL, (__VALUE__) << DC_PCFG_RD_CTRL_ARQOS_VAL_Pos) +#define __HAL_ARQOS_CTRL(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DC_PCFG_RD_CTRL, DC_PCFG_RD_CTRL_ARQOS_CTRL_0) +/** + * @defgroup LCD_exported_macros_group9 显示页面配置 + * @{ + */ +#define __HAL_DP_DITHER_DW(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->DISP_COM, ((~DISP_COM_DP_DITHER_DW_Msk) & (READ_REG((__HANDLE__)->Instance->DISP_COM))) | (__VALUE__) << DISP_COM_DP_DITHER_DW_Pos) + +#define __HAL_DITHER_CLKGATE_EN(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DISP_COM, DISP_COM_DITHER_CLKGATE_EN_0) + +#define __HAL_SLCD_CLKGATE_EN(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DISP_COM, DISP_COM_SLCD_CLKGATE_EN_0) + +#define __HAL_TFT_CLKGATE_EN(__HANDLE__) SET_BIT((__HANDLE__)->Instance->DISP_COM, DISP_COM_TFT_CLKGATE_EN_0) + +#define __HAL_DP_DITHER_EN(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->DISP_COM, ((~DISP_COM_DP_DITHER_EN_Msk) & (READ_REG((__HANDLE__)->Instance->DISP_COM))) | (__VALUE__) << DISP_COM_DP_DITHER_EN_Pos) + + +#define __HAL_DP_IF_SEL(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->DISP_COM, ((~DISP_COM_DP_DITHER_DW_Msk) & (READ_REG((__HANDLE__)->Instance->DISP_COM))) | (__VALUE__)) +/** + * @defgroup LCD_exported_macros_group10 定时HSYNC + * @{ + */ +#define __HAL_HPS(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->TFT_TIMING_HSYNC, ((~TFT_TIMING_HSYNC_HPS_Msk) & (READ_REG((__HANDLE__)->Instance->TFT_TIMING_HSYNC))) | (__VALUE__) << TFT_TIMING_HSYNC_HPS_Pos) + +#define __HAL_HPE(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->TFT_TIMING_HSYNC, ((~TFT_TIMING_HSYNC_HPE_Msk) & (READ_REG((__HANDLE__)->Instance->TFT_TIMING_HSYNC))) | (__VALUE__)) +/** + * @defgroup LCD_exported_macros_group11 定时VSYNC + * @{ + */ +#define __HAL_VPS(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->TFT_TIMIING_VSYNC, ((~TFT_TIMING_VSYNC_VPS_Msk) & (READ_REG((__HANDLE__)->Instance->TFT_TIMIING_VSYNC))) | (__VALUE__) << TFT_TIMING_VSYNC_VPS_Pos) + +#define __HAL_VPE(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->TFT_TIMIING_VSYNC, ((~TFT_TIMING_VSYNC_VPE_Msk) & (READ_REG((__HANDLE__)->Instance->TFT_TIMIING_VSYNC))) | (__VALUE__)) +/** + * @defgroup LCD_exported_macros_group12 定时HDE + * @{ + */ +#define __HAL_HDS(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->TFT_TIMIING_HDE, ((~TFT_TIMING_HDE_HDS_Msk) & (READ_REG((__HANDLE__)->Instance->TFT_TIMIING_HDE))) | (__VALUE__) << TFT_TIMING_HDE_HDS_Pos) + +#define __HAL_HDE(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->TFT_TIMIING_HDE, ((~TFT_TIMING_HDE_HDE_Msk) & (READ_REG((__HANDLE__)->Instance->TFT_TIMIING_HDE))) | (__VALUE__)) +/** + * @defgroup LCD_exported_macros_group12 定时VDE + * @{ + */ +#define __HAL_VDS(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->TFT_TIMIING_VDE, ((~TFT_TIMING_VDE_VDS_Msk) & (READ_REG((__HANDLE__)->Instance->TFT_TIMIING_VDE))) | (__VALUE__) << TFT_TIMING_VDE_VDS_Pos) + +#define __HAL_VDE(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->TFT_TIMIING_VDE, ((~TFT_TIMING_VDE_VDE_Msk) & (READ_REG((__HANDLE__)->Instance->TFT_TIMIING_VDE))) | (__VALUE__)) +/** + * @defgroup LCD_exported_macros_group13 传输配置 + * @{ + */ +#define __HAL_COLOR_EVEN(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->TFT_TRAN_CFG, ((~TFT_TRAN_CFG_COLOR_EVEN_Msk) & (READ_REG((__HANDLE__)->Instance->TFT_TRAN_CFG))) | (__VALUE__) << TFT_TRAN_CFG_COLOR_EVEN_Pos) + +#define __HAL_COLOR_ODD(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->TFT_TRAN_CFG, ((~TFT_TRAN_CFG_COLOR_ODD_Msk) & (READ_REG((__HANDLE__)->Instance->TFT_TRAN_CFG))) | (__VALUE__) << TFT_TRAN_CFG_COLOR_ODD_Pos) + +#define __HAL_SET_CLK_INV(__HANDLE__) SET_BIT((__HANDLE__)->Instance->TFT_TRAN_CFG, TFT_TRAN_CFG_PIX_CLK_INV_0) +#define __HAL_CLEAR_CLK_INV(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->TFT_TRAN_CFG, TFT_TRAN_CFG_PIX_CLK_INV_0) + +#define __HAL_SET_DE_DL(__HANDLE__) SET_BIT((__HANDLE__)->Instance->TFT_TRAN_CFG, TFT_TRAN_CFG_DE_DL_0) +#define __HAL_CLEAR_DE_DL(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->TFT_TRAN_CFG, TFT_TRAN_CFG_DE_DL_0) + +#define __HAL_SET_HSYNC_DL(__HANDLE__) SET_BIT((__HANDLE__)->Instance->TFT_TRAN_CFG, TFT_TRAN_CFG_HSYNC_DL_0) +#define __HAL_CLEAR_HSYNC_DL(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->TFT_TRAN_CFG, TFT_TRAN_CFG_HSYNC_DL_0) + +#define __HAL_SET_VSYNC_DL(__HANDLE__) SET_BIT((__HANDLE__)->Instance->TFT_TRAN_CFG, TFT_TRAN_CFG_VSYNC_DL_0) +#define __HAL_CLEAR_VSYNC_DL(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->TFT_TRAN_CFG, TFT_TRAN_CFG_VSYNC_DL_0) +/* jzguo add */ +//#define __HAL_SET_SYNC_DL(__HANDLE__) SET_BIT((__HANDLE__)->Instance->TFT_TRAN_CFG, TFT_TRAN_CFG_SYNC_DL_0) +//#define __HAL_CLEAR_SYNC_DL(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->TFT_TRAN_CFG, TFT_TRAN_CFG_SYNC_DL_0) +/* jzguo end */ +#define __HAL_TFAN(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->TFT_TRAN_CFG, ((~TFT_TRAN_CFG_MODE_Msk) & (READ_REG((__HANDLE__)->Instance->TFT_TRAN_CFG))) | (__VALUE__)) +/** + * @defgroup LCD_exported_macros_group14 SLCD配置 + * @{ + */ +#define __HAL_RDY_PIXCLK_1(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_RDY_ANTI_JIT_0) +#define __RDY_PIXCLK_3(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_RDY_ANTI_JIT_0) + +#define __HAL_FMT_DIS(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_FMT_EN_0) +#define __RDY_FMT_EN(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_FMT_EN_0) + +#define __HAL_DBI_TYPE(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->SLCD_PANEL_CFG, ((~SLCD_PANEL_CFG_DBI_TYPE_Msk) & (READ_REG((__HANDLE__)->Instance->SLCD_PANEL_CFG))) | (__VALUE__) << SLCD_PANEL_CFG_DBI_TYPE_Pos) + +#define __HAL_PIX_FMT(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->SLCD_PANEL_CFG, ((~SLCD_PANEL_CFG_PIX_FMT_Msk) & (READ_REG((__HANDLE__)->Instance->SLCD_PANEL_CFG))) | (__VALUE__) << SLCD_PANEL_CFG_PIX_FMT_Pos) + +#define __HAL_TE_ANTI_JIT_1(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_TE_ANTI_JIT_0) +#define __HAL_TE_ANTI_JIT_3(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_TE_ANTI_JIT_0) + +#define __HAL_TE_MD_FRONT(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_TE_MD_0) +#define __HAL_TE_MD_BACK(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_TE_MD_0) + +#define __HAL_TE_SWITCH_NOWAIT(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_TE_SWITCH_0) +#define __HAL_TE_SWITCH_WAIT(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_TE_SWITCH_0) + +#define __HAL_RDY_SWITCH(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->SLCD_PANEL_CFG, ((~SLCD_PANEL_CFG_RDY_SWITCH_Msk) & (READ_REG((__HANDLE__)->Instance->SLCD_PANEL_CFG))) | (__VALUE__)<Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_CS_EN_0) +#define __HAL_CS_EN_SLCD(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_CS_EN_0) + +#define __HAL_CS_DP_LOW(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_CS_DP_0) +#define __HAL_CS_DP_HIGH(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_CS_DP_0) + +#define __HAL_RDY_DP_LOW(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_RDY_DP_0) +#define __HAL_RDY_DP_HIGH(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_RDY_DP_0) + +#define __HAL_DC_MD_LOW(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_DC_MD_0) +#define __HAL_DC_MD_HIGH(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_DC_MD_0) + +#define __HAL_WR_MD_HIGH(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_WR_MD_0) +#define __HAL_WR_MD_LOW(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_WR_MD_0) + +#define __HAL_TE_DP_LOW(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_TE_DP_0) +#define __HAL_TE_DP_HIGH(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_PANEL_CFG, SLCD_PANEL_CFG_TE_DP_0) + +#define __HAL_DWIDTH(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->SLCD_PANEL_CFG, ((~SLCD_PANEL_CFG_DWIDTH_Msk) & (READ_REG((__HANDLE__)->Instance->SLCD_PANEL_CFG))) | (__VALUE__) << SLCD_PANEL_CFG_DWIDTH_Pos) + +#define __HAL_CWIDTH(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->SLCD_PANEL_CFG, ((~SLCD_PANEL_CFG_CWIDTH_Msk) & (READ_REG((__HANDLE__)->Instance->SLCD_PANEL_CFG))) | (__VALUE__)) +/** + * @defgroup LCD_exported_macros_group15 SLCD长度和宽度 + * @{ + */ + +#define __HAL_V_SIZE(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->SLCD_FRM_SIZE, ((~SLCD_FRM_SIZE_V_SIZE_Msk) & (READ_REG((__HANDLE__)->Instance->SLCD_FRM_SIZE))) | (__VALUE__) << SLCD_FRM_SIZE_V_SIZE_Pos) + +#define __HAL_H_SIZE(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->SLCD_FRM_SIZE, ((~SLCD_FRM_SIZE_H_SIZE_Msk) & (READ_REG((__HANDLE__)->Instance->SLCD_FRM_SIZE))) | (__VALUE__)) +/** + * @defgroup LCD_exported_macros_group16 SLCD数据传输 + * @{ + */ +#define __HAL_SEND_CMD(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->SLCD_REG_IF, READ_REG((__HANDLE__)->Instance->SLCD_REG_IF) & (~SLCD_REG_IF_Msk) | (FLAG_CMD_1 << SLCD_REG_IF_FLAG_Pos | __VALUE__)) + +#define __HAL_SEND_DATA(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->SLCD_REG_IF, READ_REG((__HANDLE__)->Instance->SLCD_REG_IF) & (~SLCD_REG_IF_Msk) | (FLAG_DATA << SLCD_REG_IF_FLAG_Pos | __VALUE__)) + +#define __HAL_SEND_PRM(__HANDLE__,__VALUE__) WRITE_REG((__HANDLE__)->Instance->SLCD_REG_IF, READ_REG((__HANDLE__)->Instance->SLCD_REG_IF) & (~SLCD_REG_IF_Msk) | (FLAG_PARAMETER << SLCD_REG_IF_FLAG_Pos | __VALUE__)) + +#define __HAL_IF_CMD_END(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_REG_IF, SLCD_REG_IF_CMD_END_0) + +/** + * @defgroup LCD_exported_macros_group17 SLCD状态 + * @{ + */ +#define __HAL_ST_BUSY(__HANDLE__) READ_BIT((__HANDLE__)->Instance->SLCD_ST, SLCD_ST_BUSY_0) +/** + * @defgroup LCD_exported_macros_group17 SLCD长度和宽度 + * @{ + */ +#define __HAL_SLCD_REG_CTRL(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SLCD_REG_CTRL, SLCD_REG_CTRL_RESET_3LINE_0) + +/** + * @} + */ +/* 5.导出函数申明 (Exported Funcs) ------------------------------------ */ +/** + * @defgroup LCD_exported_funcs LCD 导出函数申明 (Exported Funcs) + * @{ + */ + +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +/* 6.导出变量申明 (Exported Variables) -------------------------------- */ +/** + * @defgroup LCD_exported_var LCD 导出变量申明 (Exported Variables) + * @{ + */ + +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +/* 7.私有类型定义 (Private Types) ------------------------------------- */ +/** + * @defgroup LCD_private_types LCD 私有类型定义 (Private Types) + * @{ + */ + +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +/* 8.私有常量定义 (Private Constants) -------------------------------- */ +/** + * @defgroup LCD_private_constants LCD 私有常量定义 (Private Constants) + * @{ + */ + +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +/* 9.私有宏定义 (Private Macros) ------------------------------------- */ +/** + * @defgroup LCD_private_macros LCD 私有宏定义 (Private Macros) + * @{ + */ + +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +/* 10.私有函数申明 (Private Funcs) ------------------------------------ */ +/** + * @defgroup LCD_private_funcs LCD 私有函数申明 (Private Funcs) + * @{ + */ +void HAL_LCDC_INIT(LCD_HandleTypeDef *hlcd); +void HAL_LCDC_ENABLE(LCD_HandleTypeDef *hlcd); +void HAL_SRDMA_INIT(LCD_HandleTypeDef *hlcd, uint32_t *buffer); +void process_slcd_data_table(LCD_HandleTypeDef * hlcd, struct smart_lcd_data_table *table, unsigned int length); +void lcdc_irq_handler(int irq, void *data); +void HAL_SRDMA_START(LCD_HandleTypeDef *hlcd); +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +/* 11.私有变量申明 Private Variables ---------------------------------- */ +/** + * @defgroup LCD_private_var LCD 私有变量申明 (Private Variables) + * @{ + */ + +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif +#endif /* __X16XX_HAL_LCD_H__ */ diff --git a/drivers/drivers-x16xx/src/x16xx_hal_lcd.c b/drivers/drivers-x16xx/src/x16xx_hal_lcd.c new file mode 100644 index 00000000..1a390f7d --- /dev/null +++ b/drivers/drivers-x16xx/src/x16xx_hal_lcd.c @@ -0,0 +1,677 @@ +/** + * @file x16xx_hal_template.c + * @author MPU系统软件部团队 + * @brief [!!!!删除此内容,添加文件简介!!!!] + * + * @copyright 版权所有 (北京君正集成电路股份有限公司) {2022} + * @copyright Copyright© 2022 Ingenic Semiconductor Co.,Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + @verbatim + ============================================================================== + ##### 使用说明 ##### + ============================================================================== + [!!!!删除此内容,添加针对模块的使用方法说明,例如: 配置,启动/停止,状态,重点提醒等等.!!!!] + @endverbatim + */ + +/* 1.头文件 (Includes)--------------------------------------------------- */ +#include "x16xx_hal.h" +/** @addtogroup g_X16XX_TEMPLATE_HAL_Driver + * @{ + */ + +/* 2.私有常量定义 (Private Constants) ----------------------------------- */ +/** + * @addtogroup TEMPLATE_private_constants TEMPLATE 私有常量定义 (Private Constants) + * @{ + */ + +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +/* 3.私有类型定义 (Private Types) --------------------------------------- */ +/** + * @addtogroup TEMPLATE_private_types TEMPLATE 私有类型定义 (Private Types) + * @{ + */ +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +/* 4.私有宏定义 (Private Macros) ---------------------------------------- */ +/** + * @addtogroup TEMPLATE_private_macros TEMPLATE 私有宏定义 (Private Macros) + * @{ + */ + +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +/* 5.私有变量申明 (Private Variables) ----------------------------------- */ +/** + * @addtogroup TEMPLATE_private_var TEMPLATE 私有变量申明 (Private Variables) + * @{ + */ + +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +/* 6.私有函数申明 (Private Funcs) --------------------------------------- */ +/** + * @addtogroup TEMPLATE_private_funcs TEMPLATE 私有函数申明 (Private Funcs) + * @{ + */ + +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +/* 7.私有函数实现 (Private Funcs) -------------------------------------- */ +/** + * @defgroup TEMPLATE_private_funcs_impl TEMPLATE 私有函数实现 (Private Funcs) + * @{ + */ +static void lcdc_dump_regs(LCD_HandleTypeDef *hlcd) +{ + prom_printk("==================================================================================\n"); + prom_printk("SRD_CHAIN_ADDR = %08x\n", hlcd->Instance->DC_SRD_CHAIN_ADDR); //0x1000 + prom_printk("SRD_CHAIN_CTRL = %08x\n", hlcd->Instance->DC_SRD_CHAIN_CTRL); //0x1004 + prom_printk("CTRL = %08x\n", hlcd->Instance->DC_CTRL); //0x2000 + prom_printk("ST = %08x\n", hlcd->Instance->DC_ST); //0x2004 + prom_printk("CLR_ST = %08x\n", hlcd->Instance->DC_CLR_ST); //0x2008 + prom_printk("INTC = %08x\n", hlcd->Instance->DC_INTC); //0x200C + prom_printk("INT_FLAG = %08x\n", hlcd->Instance->DC_INT_FLAG); //0x2010 + prom_printk("COM_CFG = %08x\n", hlcd->Instance->DC_COM_CONFIG); //0x2014 + prom_printk("PCFG_RD_CTRL = %08x\n", hlcd->Instance->DC_PCFG_RD_CTRL); //0x2018 + prom_printk("PCFG_OFIFO = %08x\n", hlcd->Instance->DC_PCFG_OFIFO); //0x2020 + prom_printk("RDMA_DES = %08x\n", hlcd->Instance->DC_RDMA_DES); //0x2114 + prom_printk("RDMA_CHAIN_SITE = %08x\n", hlcd->Instance->DC_RDMA_CHAIN_SITE);//0x2204 + prom_printk("RDMA_SITE = %08x\n", hlcd->Instance->DC_RDMA_SITE); //0x3110 + prom_printk("DISP_COM = %08x\n", hlcd->Instance->DISP_COM); //0x8000 + + prom_printk("SLCD_CFG = %08x\n", hlcd->Instance->SLCD_PANEL_CFG); //0xA000 + prom_printk("SLCD_WR_DUTY = %08x\n", hlcd->Instance->SLCD_WR_DUTY); //0xA004 + prom_printk("SLCD_TIMING = %08x\n", hlcd->Instance->SLCD_TIMING); //0xA008 + prom_printk("SLCD_FRM_SIZE = %08x\n", hlcd->Instance->SLCD_FRM_SIZE); //0xA00C + prom_printk("SLCD_SLOW_TIME = %08x\n", hlcd->Instance->SLCD_SLOW_TIME); //0xA010 + prom_printk("SLCD_REG_IF = %08x\n", hlcd->Instance->SLCD_REG_IF); //0xA014 + prom_printk("SLCD_ST = %08x\n", hlcd->Instance->SLCD_ST); //0xA018 + prom_printk("SLCD_REG_CTRL = %08x\n", hlcd->Instance->SLCD_REG_CTRL); //0xA01C + + prom_printk("TFT_HSYNC = %08x\n", hlcd->Instance->TFT_TIMING_HSYNC); //0x9000 + prom_printk("TFT_VSYNC = %08x\n", hlcd->Instance->TFT_TIMIING_VSYNC); //0x9004 + prom_printk("TFT_HDE = %08x\n", hlcd->Instance->TFT_TIMIING_HDE); //0x9008 + prom_printk("TFT_VDE = %08x\n", hlcd->Instance->TFT_TIMIING_VDE); //0x900C + prom_printk("TFT_CFG = %08x\n", hlcd->Instance->TFT_TRAN_CFG); //0x9010 + prom_printk("TFT_ST = %08x\n", hlcd->Instance->TFT_ST); //0x9014 + prom_printk("==================================================================================\n"); +} + +static void init_tft(LCD_HandleTypeDef *hlcd) +{ + struct lcd_data *pdata = hlcd -> pdata; + int hps = pdata->hsync_len; + int hpe = hps + pdata->left_margin + pdata->xres + pdata->right_margin; + int vps = pdata->vsync_len; + int vpe = vps + pdata->upper_margin + pdata->yres + pdata->lower_margin; + int hds = pdata->hsync_len + pdata->left_margin; + int hde = hds + pdata->xres; + int vds = pdata->vsync_len + pdata->upper_margin; + int vde = vds + pdata->yres; + + __HAL_HPS(hlcd,hps); + __HAL_HPE(hlcd,hpe); + __HAL_VPS(hlcd,vps); + __HAL_VPE(hlcd,vpe); + __HAL_HDS(hlcd,hds); + __HAL_HDE(hlcd,hde); + __HAL_VDS(hlcd,vds); + __HAL_VDE(hlcd,vde); + + if(pdata->tft.pix_clk_polarity == AT_FALLING_EDGE){ + __HAL_SET_CLK_INV(hlcd); + }else{ + __HAL_CLEAR_CLK_INV(hlcd); + } + if(pdata->tft.de_active_level == AT_LOW_LEVEL){ + __HAL_SET_DE_DL(hlcd); + }else{ + __HAL_CLEAR_DE_DL(hlcd); + } + if(pdata->tft.hsync_active_level == AT_LOW_LEVEL){ + __HAL_SET_HSYNC_DL(hlcd); + }else{ + __HAL_CLEAR_HSYNC_DL(hlcd); + } + if(pdata->tft.vsync_active_level == AT_LOW_LEVEL){ + __HAL_SET_VSYNC_DL(hlcd); + }else{ + __HAL_CLEAR_VSYNC_DL(hlcd); + } + __HAL_COLOR_EVEN(hlcd,pdata->tft.even_line_order); + __HAL_COLOR_ODD(hlcd,pdata->tft.odd_line_order); + __HAL_TFAN(hlcd,pdata->lcd_mode); +} + +static void init_slcd(LCD_HandleTypeDef *hlcd) +{ + struct lcd_data *pdata = hlcd -> pdata; + int dbi_type = 2; + /* 判断传输格式 */ + if (pdata->lcd_mode == SLCD_6800) + dbi_type = 1; + if (pdata->lcd_mode == SLCD_8080) + dbi_type = 2; + if (pdata->lcd_mode == SLCD_SPI_3LINE) + dbi_type = 4; + if (pdata->lcd_mode == SLCD_SPI_4LINE) + dbi_type = 5; + + int pix_fmt = pdata->out_format; + if (pdata->out_format == OUT_FORMAT_RGB444) + pix_fmt = 1; + if (pdata->out_format == OUT_FORMAT_RGB555) + prom_printk("slcd outformat can't be 555\n"); + + __HAL_RDY_PIXCLK_1(hlcd); /* 设置RDY的抗抖动 */ + __HAL_FMT_DIS(hlcd); /* 通过REG_IF转换像素 */ + __HAL_DBI_TYPE(hlcd,dbi_type); /* 设置传输格式 */ + __HAL_PIX_FMT(hlcd,pix_fmt); /* 设置颜色(RGB)格式 */ + __HAL_TE_ANTI_JIT_3(hlcd); /* 使用3个pixclk周期对TE进行采样,以防抖动 */ + __HAL_TE_MD_FRONT(hlcd); /* 设置TE的活动边沿 */ + /* 选择是否等待TE,再发送数据 */ + if(pdata->slcd.te_pin_mode == TE_LCDC_TRIGGER){ + __HAL_TE_SWITCH_WAIT(hlcd); + }else{ + __HAL_TE_SWITCH_NOWAIT(hlcd); + } + /* 选择是否等待RDY,再发送命令或数据*/ + __HAL_RDY_SWITCH(hlcd,pdata->slcd.enable_rdy_pin); + __HAL_CS_EN_GPIO(hlcd); /* 设置CS引脚由GPIO控制还是SLCD控制 */ + __HAL_CS_DP_HIGH(hlcd); /* 设置CS的默认极性 */ + /* 设置RDY的默认极性*/ + if(pdata->slcd.rdy_cmd_send_level == AT_HIGH_LEVEL){ + __HAL_RDY_DP_HIGH(hlcd); + }else{ + __HAL_RDY_DP_LOW(hlcd); + } + /* 设置命令和数据的默认电平值 */ + if(pdata->slcd.dc_pin == CMD_HIGH_DATA_LOW){ + __HAL_DC_MD_HIGH(hlcd); + }else{ + __HAL_DC_MD_LOW(hlcd); + } + /* */ + if(pdata->slcd.wr_data_sample_edge == AT_RISING_EDGE){ + __HAL_WR_MD_LOW(hlcd); + }else{ + __HAL_WR_MD_HIGH(hlcd); + } + /* 设置读写电平 */ + if(pdata->slcd.te_data_transfered_edge == AT_RISING_EDGE){ + __HAL_TE_DP_HIGH(hlcd); + }else{ + __HAL_TE_DP_LOW(hlcd); + } + __HAL_DWIDTH(hlcd,pdata->slcd.mcu_data_width); /* 设置屏幕数据总线宽度 */ + __HAL_CWIDTH(hlcd,pdata->slcd.mcu_cmd_width); /* 面板命令及其参数的宽度。单位bit */ + WRITE_REG(hlcd->Instance->SLCD_WR_DUTY, 0); /* */ + WRITE_REG(hlcd->Instance->SLCD_TIMING, 0); + __HAL_V_SIZE(hlcd,pdata->yres); /* 设置屏幕宽高 */ + __HAL_H_SIZE(hlcd,pdata->xres); + WRITE_REG(hlcd->Instance->SLCD_SLOW_TIME, 0); /* 设置延时 */ +} + +static inline unsigned long bit_field_mask(int start, int end) +{ + unsigned long e = (1ul << end); + unsigned long s = (1ul << start); + return (e - s) + e; +} + +static int tft_init_gpio(int r, int g, int b) +{ + int i; + unsigned int pins = + bit_field_mask(TFT_d7 - b + 1, TFT_d7) | + bit_field_mask(TFT_d15 - g + 1, TFT_d15) | + bit_field_mask(TFT_d23 - r + 1, TFT_d23) | + (1 << TFT_pclk) | (1 << TFT_de) | (1 << TFT_vsync) | (1 << TFT_hsync); + for (i = 0; i < 32; i++) { + if(pins & (1 << i)){ + LL_GPIO_setPinMode(GPIOA_Instance, i, GPIO_MODE_FUNCTION0); + } + } + return 0; +} +static int tft_serial_init_gpio(void) +{ + unsigned int pins = + bit_field_mask(TFT_d0, TFT_d7) | + (1 << TFT_pclk) | (1 << TFT_de) | (1 << TFT_vsync) | (1 << TFT_hsync); + for (int i = 0; i < 32; i++) { + if(pins & (1 << i)){ + LL_GPIO_setPinMode(GPIOA_Instance, i, GPIO_MODE_FUNCTION0); + } + } + return 0; +} +static int slcd_init_gpio_data8(void) +{ + unsigned int pins = bit_field_mask(TFT_d0, TFT_d7) | (1 << SLCD_DC) | (1 << SLCD_WR) | (1 << SLCD_TE); + for (int i = 0; i < 32; i++) { + if(pins & (1 << i)){ + LL_GPIO_setPinMode(GPIOA_Instance, i, GPIO_MODE_FUNCTION1); + } + } + return 0; +} +static int slcd_init_gpio_data9(void) +{ + unsigned int pins = bit_field_mask(TFT_d0, TFT_d8) | (1 << SLCD_DC) | (1 << SLCD_WR) | (1 << SLCD_TE); + for (int i = 0; i < 32; i++) { + if(pins & (1 << i)){ + LL_GPIO_setPinMode(GPIOA_Instance, i, GPIO_MODE_FUNCTION1); + } + } + return 0; +} +static int slcd_init_gpio_data16(void) +{ + unsigned int pins = bit_field_mask(TFT_d0, TFT_d15) | (1 << SLCD_DC) | (1 << SLCD_WR) | (1 << SLCD_TE); + for (int i = 0; i < 32; i++) { + if(pins & (1 << i)){ + LL_GPIO_setPinMode(GPIOA_Instance, i, GPIO_MODE_FUNCTION1); + } + } + return 0; +} + +static int init_lcd_gpio(struct lcd_data *pdata) +{ + int ret = -HAL_ERROR; + + switch (pdata->lcd_mode) { + case TFT_24BITS: + if (pdata->out_format == OUT_FORMAT_RGB444) + ret = tft_init_gpio(4, 4, 4); + if (pdata->out_format == OUT_FORMAT_RGB555) + ret = tft_init_gpio(5, 5, 5); + if (pdata->out_format == OUT_FORMAT_RGB565) + ret = tft_init_gpio(5, 6, 5); + if (pdata->out_format == OUT_FORMAT_RGB666) + ret = tft_init_gpio(6, 6, 6); + if (pdata->out_format == OUT_FORMAT_RGB888) + ret = tft_init_gpio(8, 8, 8); + break; + + case TFT_8BITS_SERIAL: + case TFT_8BITS_DUMMY_SERIAL: + ret = tft_serial_init_gpio(); + break; + + case SLCD_6800: + case SLCD_8080:{ + int width; + if(pdata->slcd.mcu_cmd_width > pdata->slcd.mcu_data_width){ + width = pdata->slcd.mcu_cmd_width; + }else{ + width = pdata->slcd.mcu_data_width; + } + if (width == MCU_WIDTH_8BITS) + ret = slcd_init_gpio_data8(); + if (width == MCU_WIDTH_9BITS) + ret = slcd_init_gpio_data9(); + if (width == MCU_WIDTH_16BITS) + ret = slcd_init_gpio_data16(); + break; + } + default: + prom_printk("This mode is not currently implemented: %d\n", pdata->lcd_mode); + break; + } + return ret; +} + +static int slcd_wait_busy(LCD_HandleTypeDef * hlcd, unsigned int count) +{ + int busy; + busy = __HAL_ST_BUSY(hlcd); + + while (count-- && busy) { + busy = __HAL_ST_BUSY(hlcd); + } + return busy; +} + +static void slcd_send_cmd(LCD_HandleTypeDef * hlcd, unsigned int cmd) +{ + if (slcd_wait_busy(hlcd,10 * 1000)) + prom_printk("lcdc busy\n"); + + __HAL_SEND_CMD(hlcd, cmd); +} + +static void slcd_send_data(LCD_HandleTypeDef *hlcd, unsigned int data) +{ + if (slcd_wait_busy(hlcd,10 * 1000)) + prom_printk("lcdc busy\n"); + + __HAL_SEND_DATA(hlcd, data); +} + +static void slcd_send_prm(LCD_HandleTypeDef *hlcd, unsigned int prm) +{ + if (slcd_wait_busy(hlcd,10 * 1000)) + prom_printk("lcdc busy\n"); + + __HAL_SEND_PRM(hlcd, prm); +} + +void process_slcd_data_table(LCD_HandleTypeDef * hlcd, struct smart_lcd_data_table *table, unsigned int length) +{ + int i = 0; + for (; i < length; i++) { + switch (table[i].type) { + case SMART_CONFIG_CMD: + slcd_send_cmd(hlcd,table[i].value); + break; + case SMART_CONFIG_DATA: + slcd_send_data(hlcd,table[i].value); + break; + case SMART_CONFIG_PRM: + slcd_send_prm(hlcd,table[i].value); + break; + case SMART_CONFIG_UDELAY: + HAL_uDelay(table[i].value); + break; + default: + prom_printk("why this type: %d\n", table[i].type); + break; + } + } + if (slcd_wait_busy(hlcd, 10 * 1000)) + prom_printk("lcdc busy\n"); +} + +static int check_scld_fmt(LCD_HandleTypeDef * hlcd) +{ + struct lcd_data *pdata = hlcd->pdata; + int pix_fmt = pdata->out_format; + + if (pdata->lcd_mode >= SLCD_SPI_3LINE) + return -1; + + int width = pdata->slcd.mcu_data_width; + if (width == MCU_WIDTH_8BITS) { + if (pix_fmt != OUT_FORMAT_RGB565 && pix_fmt != OUT_FORMAT_RGB888) + return -1; + } + if (width == MCU_WIDTH_9BITS) { + if (pix_fmt != OUT_FORMAT_RGB666) + return -1; + } + if (width == MCU_WIDTH_16BITS) { + if (pix_fmt != OUT_FORMAT_RGB565) + return -1; + } + + return 0; +} + +static inline int is_tft(struct lcd_data *pdata) +{ + return pdata->lcd_mode <= TFT_8BITS_DUMMY_SERIAL; +} + +static inline int is_slcd(struct lcd_data *pdata) +{ + return pdata->lcd_mode >= SLCD_6800; +} + +static void init_lcdc(LCD_HandleTypeDef *hlcd) +{ + struct lcd_data *pdata = hlcd -> pdata; + + __HAL_EOD_MSK(hlcd); + __HAL_UOT_MSK(hlcd); + __HAL_SSA_MSK(hlcd); + __HAL_SOS_MSK(hlcd); +// __HAL_EOS_MSK(hlcd); + + WRITE_REG(hlcd->Instance->DC_CLR_ST, READ_REG(hlcd->Instance->DC_INT_FLAG)); + __HAL_BURST_LEN_RDMA(hlcd, BURST_LEN_RDMA_32); + + int dither_en = 0; + int dither_dw = 0; + if (pdata->fb_fmt == fb_fmt_RGB888 || pdata->fb_fmt == fb_fmt_ARGB8888) { + if (pdata->out_format != OUT_FORMAT_RGB888) + dither_en = 1; + if (pdata->out_format == OUT_FORMAT_RGB444) + dither_dw = 0b111111; + if (pdata->out_format == OUT_FORMAT_RGB555) + dither_dw = 0b101010; + if (pdata->out_format == OUT_FORMAT_RGB565) + dither_dw = 0b100110; + if (pdata->out_format == OUT_FORMAT_RGB666) + dither_dw = 0b010101; + } + + __HAL_DP_DITHER_EN(hlcd, dither_en); + __HAL_DP_DITHER_DW(hlcd, dither_dw); + + __HAL_DITHER_CLKGATE_EN(hlcd); + __HAL_SLCD_CLKGATE_EN(hlcd); + __HAL_TFT_CLKGATE_EN(hlcd); + + if(is_slcd(pdata)) { + __HAL_DP_IF_SEL(hlcd, DISPLAY_SELECT_SLCD); + prom_printk("is_slcd \n"); + } else { + __HAL_DP_IF_SEL(hlcd, DISPLAY_SELECT_TFT); + prom_printk("is_tft \n"); + } + + if (is_tft(pdata)){ + init_tft(hlcd); + prom_printk("tft mode \n"); + } + if (is_slcd(pdata)){ + init_slcd(hlcd); + prom_printk("slcd mode \n"); + } + +} + +static int slcd_pixclock_cycle(struct lcd_data *pdata) +{ + + int cycle = 0; + int width = pdata->slcd.mcu_data_width; + int pix_fmt = pdata->out_format; + if (width == MCU_WIDTH_8BITS) { + if (pix_fmt == OUT_FORMAT_RGB565) + cycle = 2; + if (pix_fmt == OUT_FORMAT_RGB888) + cycle = 3; + } + if (width == MCU_WIDTH_9BITS) { + if (pix_fmt == OUT_FORMAT_RGB666) + cycle = 2; + } + if (width == MCU_WIDTH_16BITS) { + if (pix_fmt == OUT_FORMAT_RGB666) + cycle = 1; + } + + + return cycle * 2 + 1; +} + +void auto_calculate_pixel_clock(struct lcd_data *pdata) +{ + int hps = pdata->hsync_len; + int hpe = hps + pdata->left_margin + pdata->xres + pdata->right_margin; + int vps = pdata->vsync_len; + int vpe = vps + pdata->upper_margin + pdata->yres + pdata->lower_margin; + + if (!pdata->refresh) + pdata->refresh = 40; + + if (is_tft(pdata)) { + if (!pdata->pixclock) + pdata->pixclock = hpe * vpe * pdata->refresh; + } + + if (is_slcd(pdata)) { + if (!pdata->pixclock) { + pdata->pixclock = pdata->xres * pdata->yres * pdata->refresh; + pdata->pixclock *= slcd_pixclock_cycle(pdata); + } + + if (!pdata->slcd.pixclock_when_init) + pdata->slcd.pixclock_when_init = pdata->xres * pdata->yres * 3; + } +} + +void HAL_LCDC_INIT(LCD_HandleTypeDef *hlcd) +{ + struct lcd_data *pdata = hlcd->pdata; + int ret; + + if (is_slcd(pdata)){ + ret = check_scld_fmt(hlcd); + if(ret < 0) + prom_printk("slcd fmt error\n"); + } + + ret = init_lcd_gpio(pdata); + if(ret < 0) + prom_printk("init lcd gpio failed\n"); + + auto_calculate_pixel_clock(pdata); + +} + +void HAL_LCDC_ENABLE(LCD_HandleTypeDef *hlcd) +{ + struct lcd_data *pdata = hlcd -> pdata; + + init_lcdc(hlcd); + + if (pdata->power_on) + pdata->power_on(); + + if (is_slcd(pdata)) + process_slcd_data_table(hlcd, pdata->slcd_data_table, pdata->slcd_data_table_length); + +} + +void HAL_SRDMA_INIT(LCD_HandleTypeDef *hlcd, uint32_t *buffer) +{ + int format; + switch (hlcd->pdata->fb_fmt) { + case fb_fmt_RGB555: + format = 0; break; + case fb_fmt_RGB565: + format = 2; break; + case fb_fmt_ARGB8888: + case fb_fmt_RGB888: + format = 4; break; + default: + prom_printk("format err:%d\n", hlcd->pdata->fb_fmt); break; + } + + hlcd->desc->RdmaNextCfgAddr = CPHYSADDR(hlcd->desc); + + hlcd->desc->FrameCtrl = 0; + hlcd->desc->FrameCtrl |= (format << 19); + hlcd->desc->FrameCtrl |= (0 << 16); + hlcd->desc->FrameCtrl &= ~(1); + + hlcd->desc->InterruptControl = 0; + + hlcd->desc->stride = hlcd->pdata->xres; + hlcd->desc->FrameBufferAddr = CPHYSADDR(buffer); + + CleanDCache_by_Addr((unsigned long*)hlcd->desc, sizeof(struct srdmadesc)); + + if (is_slcd(hlcd->pdata)){ + if (slcd_wait_busy(hlcd, 10 * 1000)) + prom_printk("slcd busy\n"); + } + + WRITE_REG(hlcd->Instance->DC_SRD_CHAIN_ADDR, CPHYSADDR(hlcd->desc)); +} + +void HAL_SRDMA_START(LCD_HandleTypeDef *hlcd) +{ + __HAL_SRD_CHAIN_START(hlcd); +// lcdc_dump_regs(hlcd); +} + +/** + * @} + */ +/* 8.导出函数实现 (Exported Funcs)-------------------------------------- */ +/** + * @defgroup TEMPLATE_exported_funcs_impl TEMPLATE 导出函数实现 (Exported Funcs) + * @{ + */ + +// 删除此行, 添加内容 +// 删除此行, 添加内容 + +/** + * @} + */ +void lcdc_irq_handler(int irq, void *data) +{ + LCD_HandleTypeDef *hlcd = (LCD_HandleTypeDef*)data; + if (__HAL_INT_EOD(hlcd)) { + prom_printk("__HAL_INT_EOD\n"); + __GEN_CLR_DISP_END(hlcd); + return; + } + if (__HAL_INT_SSA(hlcd)) { + prom_printk("__HAL_INT_SSA\n"); + __GEN_CLR_STOP_SRD_ACK(hlcd); + return; + } + + if (__HAL_INT_UOT(hlcd)) { + prom_printk("err: lcd underrun\n"); + __GEN_CLR_TFT_UNDR(hlcd); + return; + } + if (__HAL_INT_EOS(hlcd)) { + prom_printk("RDMA END\n"); + __GEN_CLR_SRD_END(hlcd); + return; + } + if (__HAL_INT_SOS(hlcd)) { + __GEN_CLR_SRD_START(hlcd); + prom_printk("RDAM START\n"); + return; + } +} +/** + * @} + */ diff --git a/drivers/drivers-x16xx/src/x16xx_hal_uart.c b/drivers/drivers-x16xx/src/x16xx_hal_uart.c index 5fc2a74d..9f2585d2 100644 --- a/drivers/drivers-x16xx/src/x16xx_hal_uart.c +++ b/drivers/drivers-x16xx/src/x16xx_hal_uart.c @@ -253,6 +253,10 @@ static void UART_ReadData(UART_HandleTypeDef *huart) uint32_t n, i; n = READ_REG(huart->Instance->URCR); + if(n > huart->RxXferCount){ + n = huart->RxXferCount; + } + for (i = 0; i < n; i++) { *huart->pRxBuffPtr = (uint8_t)(huart->Instance->URBR & (uint8_t)0x00FF); huart->pRxBuffPtr++; -- Gitee