drv_lcd.c 7.0 KB
Newer Older
1
/*
2
 * File      : drv_lcd.c
3
 * This file is part of RT-Thread RTOS
4
 * COPYRIGHT (C) 2006-2013, RT-Thread Development Team
5 6 7 8 9 10 11 12
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rt-thread.org/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2017-10-30     Tanek        the first version
13
 * 2018-04-05     Liu2guang    export LCD config parameters.
14
 */
15 16
 
#include "drv_lcd.h" 
17 18

#include "fsl_common.h"
19
#include "fsl_iomuxc.h" 
20 21
#include "fsl_elcdif.h"

22 23
#if !defined(LCD_WIDTH) || !defined(LCD_HEIGHT) 
#error "Please config lcd pixel parameters." 
24 25
#endif

26 27 28 29
#if !defined(LCD_HFP) || !defined(LCD_HBP) || !defined(LCD_HSW) || \
    !defined(LCD_VFP) || !defined(LCD_VBP) || !defined(LCD_VSW)
#error "Please config lcd timing parameters." 
#endif
30

31 32 33
#if !defined(LCD_BL_PIN) || !defined(LCD_RST_PIN) 
#error "Please config lcd backlight or reset pin." 
#endif
34

35
struct rt1050_lcd
36
{
37 38 39
    struct rt_device device; 
    struct rt_device_graphic_info info; 
}; 
40

41 42
static struct rt1050_lcd lcd; 
ALIGN(64) static uint16_t frame_buffer[LCD_HEIGHT][LCD_WIDTH] SECTION("NonCacheable"); 
43

44
static rt_err_t rt1050_lcd_init(rt_device_t device)
45
{
46 47 48
    RT_ASSERT(device != RT_NULL); 
    
    rt_memset(frame_buffer, 0x00, sizeof(frame_buffer)); 
49

50 51 52 53 54 55 56 57 58
    /* CLK */
    clock_video_pll_config_t pll_config;
    
    pll_config.loopDivider = 43;
    pll_config.postDivider = 4;
    pll_config.numerator   = 0;
    pll_config.denominator = 0;
    
    CLOCK_InitVideoPll(&pll_config); 
59

60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
    CLOCK_SetMux(kCLOCK_Lcdif1PreMux, 2); 
    CLOCK_SetDiv(kCLOCK_Lcdif1PreDiv, 4); 
    CLOCK_SetMux(kCLOCK_Lcdif1Mux, 0); 
    CLOCK_SetDiv(kCLOCK_Lcdif1Div, 1); 
    
    /* GPIO */ 
    CLOCK_EnableClock(kCLOCK_Iomuxc); 
    
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_04_LCD_DATA00, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_04_LCD_DATA00, 0x01B0B0U); /* LCD_B3 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_05_LCD_DATA01, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_05_LCD_DATA01, 0x01B0B0U); /* LCD_B4 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_06_LCD_DATA02, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_06_LCD_DATA02, 0x01B0B0U); /* LCD_B5 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_07_LCD_DATA03, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_07_LCD_DATA03, 0x01B0B0U); /* LCD_B6 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_08_LCD_DATA04, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_08_LCD_DATA04, 0x01B0B0U); /* LCD_B7 */ 
    
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_09_LCD_DATA05, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_09_LCD_DATA05, 0x01B0B0U); /* LCD_G2 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_10_LCD_DATA06, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_10_LCD_DATA06, 0x01B0B0U); /* LCD_G3 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_11_LCD_DATA07, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_11_LCD_DATA07, 0x01B0B0U); /* LCD_G4 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_12_LCD_DATA08, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_12_LCD_DATA08, 0x01B0B0U); /* LCD_G5 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_13_LCD_DATA09, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_13_LCD_DATA09, 0x01B0B0U); /* LCD_G6 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_14_LCD_DATA10, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_14_LCD_DATA10, 0x01B0B0U); /* LCD_G7 */ 
    
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_15_LCD_DATA11, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_15_LCD_DATA11, 0x01B0B0U); /* LCD_R3 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B1_00_LCD_DATA12, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_00_LCD_DATA12, 0x01B0B0U); /* LCD_R4 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B1_01_LCD_DATA13, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_01_LCD_DATA13, 0x01B0B0U); /* LCD_R5 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B1_02_LCD_DATA14, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_02_LCD_DATA14, 0x01B0B0U); /* LCD_R6 */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B1_03_LCD_DATA15, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_03_LCD_DATA15, 0x01B0B0U); /* LCD_R7 */ 
    
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_00_LCD_CLK,    0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_00_LCD_CLK,    0x01B0B0u); /* LCD_CLK */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_02_LCD_HSYNC,  0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_02_LCD_HSYNC,  0x01B0B0u); /* LCD_HSYNC */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_03_LCD_VSYNC,  0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_03_LCD_VSYNC,  0x01B0B0u); /* LCD_VSYNC */ 
    IOMUXC_SetPinMux   (IOMUXC_GPIO_B0_01_LCD_ENABLE, 0U); 
    IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0x01B0B0u); /* LCD_ENABLE */ 
    
    rt_pin_mode(LCD_RST_PIN, PIN_MODE_OUTPUT); /* LCD_RESET */ 
    rt_pin_write(LCD_RST_PIN, PIN_LOW); 
    rt_thread_delay(RT_TICK_PER_SECOND/100); 
    rt_pin_write(LCD_RST_PIN, PIN_HIGH); 
    
    rt_pin_mode (LCD_BL_PIN, PIN_MODE_OUTPUT);  /* LCD_BL */ 
    rt_pin_write(LCD_BL_PIN, PIN_HIGH); 
    
    /* LCD */ 
    elcdif_rgb_mode_config_t lcd_config; 
    
    lcd_config.hfp           = LCD_HFP; 
    lcd_config.vfp           = LCD_VFP; 
    lcd_config.hbp           = LCD_HBP; 
    lcd_config.vbp           = LCD_VBP; 
    lcd_config.hsw           = LCD_HSW; 
    lcd_config.vsw           = LCD_VSW; 
    
    lcd_config.polarityFlags = kELCDIF_DataEnableActiveHigh | 
                               kELCDIF_VsyncActiveHigh      | 
                               kELCDIF_HsyncActiveLow       | 
                               kELCDIF_DriveDataOnRisingClkEdge;
    
    lcd_config.panelWidth    = LCD_WIDTH; 
    lcd_config.panelHeight   = LCD_HEIGHT; 
    lcd_config.pixelFormat   = kELCDIF_PixelFormatRGB565; 
    lcd_config.dataBus       = kELCDIF_DataBus16Bit; 
    lcd_config.bufferAddr    = (uint32_t)frame_buffer; 
    
    ELCDIF_RgbModeInit (LCDIF, &lcd_config);
    ELCDIF_RgbModeStart(LCDIF); 
    
    /* LCD DEVICE */
    lcd.info.width          = LCD_WIDTH;
    lcd.info.height         = LCD_HEIGHT;
    lcd.info.pixel_format   = RTGRAPHIC_PIXEL_FORMAT_RGB565;
    lcd.info.bits_per_pixel = 16; 
    lcd.info.framebuffer    = (void *)frame_buffer;

    return RT_EOK; 
152 153
}

154
static rt_err_t rt1050_lcd_control(rt_device_t device, int cmd, void *args)
155
{
156
    switch(cmd)
157
    {
158 159
    case RTGRAPHIC_CTRL_RECT_UPDATE: 
        break;
160
    
161 162
    case RTGRAPHIC_CTRL_POWERON: 
        rt_pin_write(LCD_BL_PIN, PIN_HIGH); 
163 164
        break;
    
165 166
    case RTGRAPHIC_CTRL_POWEROFF: 
        rt_pin_write(LCD_BL_PIN, PIN_LOW); 
167 168 169
        break;
    
    case RTGRAPHIC_CTRL_GET_INFO:
170
        rt_memcpy(args, &lcd.info, sizeof(lcd.info)); 
171 172 173 174 175 176 177 178 179
        break;
    
    case RTGRAPHIC_CTRL_SET_MODE:
        break;
    }

    return RT_EOK;
}

180
int rt_hw_lcd_init(void)
181
{
182 183 184 185 186 187 188 189 190
    rt_err_t ret; 

    lcd.device.type    = RT_Device_Class_Graphic; 
    lcd.device.init    = rt1050_lcd_init; 
    lcd.device.open    = RT_NULL;
    lcd.device.close   = RT_NULL;
    lcd.device.read    = RT_NULL;
    lcd.device.write   = RT_NULL;
    lcd.device.control = rt1050_lcd_control; 
191
    
192
    lcd.device.user_data = (void *)&lcd.info; 
193
    
194
    ret = rt_device_register(&lcd.device, "lcd", RT_DEVICE_FLAG_RDWR); 
195
    
196
    return ret; 
197
}
198
INIT_DEVICE_EXPORT(rt_hw_lcd_init);