drv_clcd.c 2.8 KB
Newer Older
B
bernard 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 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
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

#include <rtthread.h>
#include "drv_clcd.h"

#define CLCD_WIDTH  480
#define CLCD_HEIGHT 320

#define CLCD_DEVICE(dev)    (struct drv_clcd_device*)(dev)

#define PL111_CR_EN         0x001
#define PL111_CR_PWR        0x800
#define PL111_IOBASE        0x10020000
#define PL111_PALBASE       (PL111_IOBASE + 0x200)

typedef struct _PL111MMIO
{
    uint32_t      volatile tim0;      //0
    uint32_t      volatile tim1;      //4
    uint32_t      volatile tim2;      //8
    uint32_t      volatile tim3;      //c
    uint32_t      volatile upbase;    //10
    uint32_t      volatile f;         //14
    uint32_t      volatile control;   //18
    uint32_t      volatile g;         //1c
} PL111MMIO;

struct drv_clcd_device
{
    struct rt_device parent;

    int width;
    int height;

    uint8_t *fb;
};
struct drv_clcd_device _lcd;

static rt_err_t drv_clcd_init(struct rt_device *device)
{
    struct drv_clcd_device *lcd = CLCD_DEVICE(device);

    lcd = lcd; /* nothing, right now */
    return RT_EOK;
}

static rt_err_t drv_clcd_control(struct rt_device *device, int cmd, void *args)
{
    struct drv_clcd_device *lcd = CLCD_DEVICE(device);

    switch (cmd)
    {
    case RTGRAPHIC_CTRL_RECT_UPDATE:
        {
            struct rt_device_rect_info *info = (struct rt_device_rect_info*)args;

            info = info; /* nothing, right now */
        }
        break;

    case RTGRAPHIC_CTRL_GET_INFO:
        {
            struct rt_device_graphic_info* info = (struct rt_device_graphic_info*)args;

            RT_ASSERT(info != RT_NULL);
            info->pixel_format  = RTGRAPHIC_PIXEL_FORMAT_RGB565;
            // info->pixel_format  = RTGRAPHIC_PIXEL_FORMAT_ARGB888;
            info->bits_per_pixel= 16;
            info->width         = lcd->width;
            info->height        = lcd->height;
            info->framebuffer   = lcd->fb;
        }
        break;
    }

    return RT_EOK;
}

int drv_clcd_hw_init(void)
{
    PL111MMIO   *plio;
    struct rt_device *device = &_lcd.parent;

    /* memset _lcd to zero */
    memset(&_lcd, 0x0, sizeof(_lcd));

    _lcd.width  = CLCD_WIDTH;
    _lcd.height = CLCD_HEIGHT;
    _lcd.fb     = rt_malloc (_lcd.width * _lcd.height * 2);
    if (_lcd.fb == NULL)
    {
        rt_kprintf("initialize frame buffer failed!\n");
        return -1;
    }

    memset(_lcd.fb, 0xff, _lcd.width * _lcd.height * 2);

    plio = (PL111MMIO*)PL111_IOBASE;

    plio->tim0 = 0x3F1F3C00 | ((CLCD_WIDTH/16 - 1) << 2);
    plio->tim1 = 0x080B6000 | (CLCD_HEIGHT - 1);

    plio->upbase = _lcd.fb;
    /* 16-bit 565 color */
    plio->control = 0x1921 | (0x6 << 1);

    device->type    = RT_Device_Class_Graphic;
    device->init    = drv_clcd_init;
    device->control = drv_clcd_control;
    rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR);

    return 0;
}
INIT_DEVICE_EXPORT(drv_clcd_hw_init);