📄 mode.c
字号:
/* * $QNXLicenseC: * Copyright 2007, QNX Software Systems. * * Licensed under the Apache License, Version 2.0 (the "License"). You * may not reproduce, modify or distribute this software except in * compliance with the License. You may obtain a copy of the License * at: http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OF ANY KIND, either express or implied. * * This file may contain contributions from others, either as * contributors under the License or as licensors under other terms. * Please review this entire file for other proprietary rights or license * notices, as well as the QNX Development Suite License Guide at * http://licensing.qnx.com/license-guide/ for other information. * $ */#include <stdlib.h>#include <string.h>#include <errno.h>#include <sys/mman.h>#include <fcntl.h>#include <hw/i2c.h>#include "imx21.h"static char *i2c_dev = "/dev/i2c0";#define PM_SM3_SET 0x16inti2c_write (disp_adapter_t *adapter, uint8_t reg, uint8_t val){ int i2c_fd = open (i2c_dev, O_RDWR); int status; unsigned char buf[sizeof(i2c_send_t) + 1 + 1]; i2c_send_t *pshdr = (i2c_send_t *)buf; if (i2c_fd == -1) { disp_printf(adapter,"I2C open failed\n"); return -1; } pshdr->slave.addr = 0x90 >> 1; pshdr->slave.fmt = I2C_ADDRFMT_7BIT; pshdr->len = 2; pshdr->stop = 1; buf[sizeof(i2c_send_t)] = reg; buf[sizeof(i2c_send_t) + 1] = val; status = devctl (i2c_fd, DCMD_I2C_SEND, buf, sizeof(i2c_send_t) + 2, NULL); close (i2c_fd); return status;}voidspi_write(imx21_context_t *i_ctx, uint8_t addr, uint8_t data){ unsigned short value; int i; *PTB_DR |= 1 << 31; *PTB_DR |= 1 << 30; *PTB_DR &= ~(1 << 26); *PTB_DR &= ~(1<<31); delay(5); value = (addr<<8) | (data & 0xFF); for (i = 0; i < 16; i++) { *PTB_DR &= ~(1<<30); if ((value & 0x8000) == 0x8000) *PTB_DR |= 1<<26; else *PTB_DR &= ~(1<<26); delay(5); *PTB_DR |= 1<<30; value = (value << 1); delay(5); } *PTB_DR |= 1 << 31; delay(10);}voidpa1_lcd_control(disp_adapter_t *adapter, int enable){ imx21_context_t *i_ctx = adapter->ms_ctx; if (enable) { delay(5); *PTB_DDIR |= 0xd4000000; *PTB_OCR2 |= 0xf3300000; *PTB_DR |= 0xd0000000; *PTA_DDIR |= 0xf7000020; *PTA_OCR2 |= 0xf03f0000; *PTA_GIUS |= 0x87000000; *PTA_DR |= 0xc7000000; } else { *PTB_DDIR &= ~0xd4000000; *PTB_OCR2 &= ~0xf3300000; *PTB_DR &= ~0xd0000000; *PTA_DDIR &= ~0xf7000020; *PTA_OCR2 &= ~0xf03f0000; *PTA_GIUS &= ~0x87000000; }}intimx21_mode_init(disp_adapter_t *adapter, char *optstring){ imx21_context_t *i_ctx; if (disp_register_adapter(adapter) == -1) return -1; i_ctx = adapter->gd_ctx = adapter->ms_ctx = calloc(1, sizeof(imx21_context_t)); if (i_ctx == NULL) { disp_unregister_adapter(adapter); return -1; } i_ctx->adapter = adapter; get_config_data(i_ctx, optstring); /* map LCDC registers */ i_ctx->regptr = disp_mmap_device_memory(i_ctx->regbase, LCDC_REG_SIZE, PROT_READ | PROT_WRITE | PROT_NOCACHE, 0); if (i_ctx->regptr == NULL) { goto fail; } /* map clock registers */ i_ctx->cregptr = disp_mmap_device_memory(i_ctx->cregbase, PLL_REG_SIZE, PROT_READ | PROT_WRITE | PROT_NOCACHE, 0); if (i_ctx->cregptr == NULL) { goto fail; } /* map GPIO registers */ i_ctx->gregptr = disp_mmap_device_memory(i_ctx->gregbase, GPIO_REG_SIZE, PROT_READ | PROT_WRITE | PROT_NOCACHE, 0); if (i_ctx->gregptr == NULL) { goto fail; } /* map M9328MX21ADS MMIO latch */ i_ctx->mmioptr = disp_mmap_device_memory(i_ctx->mmiobase, MMIO_SIZE, PROT_READ | PROT_WRITE | PROT_NOCACHE, 0); if (i_ctx->mmioptr == NULL) { goto fail; } /* lcd off */ *MMIO &= ~0x200; /* set driving strength control */ *DSCR1 = 0; /* disable clock */ *PCCR0 &= 0xFBFBFFFF; /* Clear GPIO port A for LCD signals */ *PTA_GIUS = 0x40000000; *PTA_GPR = 0; /* enable LCDC clock */ *PCCR0 |= 1 << 18 | 1 << 26; /* LCDC setup */ *LCPR = 0; /* cursor off */ *LSCR = i_ctx->sharp; /* Sharp control */ *LPOR = 0; /* panning offset */ *LPCCR = i_ctx->contrast; /* LCD contrast control with backlight */ *LRMCR = 0; /* self-refresh off */ *LDCR = i_ctx->dma; /* DMA defaults - make them driver options? */ *LICR = 0; *LIER = 0; /* no interrupts */ *LGWCR = 0; /* disable graphic plane (could use bit 22) */ return 1;fail: if (i_ctx->cregptr) disp_munmap_device_memory(i_ctx->regptr, PLL_REG_SIZE); if (i_ctx->regptr) disp_munmap_device_memory(i_ctx->regptr, LCDC_REG_SIZE); if (i_ctx->gregptr) disp_munmap_device_memory(i_ctx->gregptr, GPIO_REG_SIZE); if (i_ctx->mmioptr) disp_munmap_device_memory(i_ctx->regptr, MMIO_SIZE); free(i_ctx); disp_unregister_adapter(adapter); return -1;}voidimx21_mode_fini(disp_adapter_t *adapter){ imx21_context_t *i_ctx = adapter->ms_ctx; if (i_ctx != NULL) { *PCCR0 &= 0xFBFBFFFF; if (i_ctx->pa1) { i2c_write(adapter, PM_SM3_SET, 0x0); pa1_lcd_control(adapter, 0); } else *MMIO &= ~0x200; if (i_ctx->cregptr) disp_munmap_device_memory(i_ctx->regptr, LCDC_REG_SIZE); if (i_ctx->regptr) disp_munmap_device_memory(i_ctx->regptr, LCDC_REG_SIZE); if (i_ctx->gregptr) disp_munmap_device_memory(i_ctx->gregptr, GPIO_REG_SIZE); if (i_ctx->mmioptr) disp_munmap_device_memory(i_ctx->regptr, MMIO_SIZE); disp_unregister_adapter(adapter); free(i_ctx); }}intimx21_get_modeinfo(disp_adapter_t *adp, int dispno, disp_mode_t mode, disp_mode_info_t *info){ imx21_context_t *i_ctx = adp->ms_ctx; memset(info, 0, sizeof(*info)); info->size = sizeof(*info); info->mode = mode; switch (mode) { case 8: info->pixel_format = DISP_SURFACE_FORMAT_PAL8; info->num_colors = 256; break; case 16: info->pixel_format = DISP_SURFACE_FORMAT_RGB565; break; default: return -1; } info->xres = i_ctx->width; info->yres = i_ctx->height; info->u.fixed.refresh[0] = 60; info->u.fixed.refresh[1] = 0; return 0;}intimx21_set_mode(disp_adapter_t *adp, int dispno, disp_mode_t mode, disp_crtc_settings_t *settings, disp_surface_t *surf, unsigned flags){ imx21_context_t *i_ctx = adp->ms_ctx; int xmax = ((i_ctx->width + 15) & ~15)/16; int stride = i_ctx->width * (mode / 8); int bpp = 5; int sharp = 0; if (mode == 8) bpp = 3; if (i_ctx->sharp != 0) sharp = 1; *LSR = (xmax & 0x3F) << 20 | (i_ctx->height & 0x3ff); *LVPWR = (stride + 3) / 4; *LPCR = i_ctx->tft << 31 | i_ctx->color << 30 | i_ctx->pbsiz << 28 | bpp << 25 | i_ctx->pixpol << 24 | i_ctx->flmpol << 23 | i_ctx->lppol << 22 | i_ctx->clkpol << 21 | i_ctx->oepol << 20 | i_ctx->sclkidle << 19 | i_ctx->end_sel << 18 | i_ctx->swap_sel << 17 | i_ctx->rev_vs << 16 | i_ctx->acdsel << 15 | i_ctx->acd << 8 | i_ctx->sclksel << 7 | sharp << 6 | (i_ctx->pcd-1); *LHCR = (i_ctx->hsw - 1) << 26 | (i_ctx->hw1 - 1) << 8 | (i_ctx->hw2 - 2); /* hw1= time between hactive & hss, hw2 = time between hs_end and h_total */ *LVCR = (i_ctx->vsw << 26) | i_ctx->vw1 << 8 | i_ctx->vw2; /*vw1 = vss, vw2 = vtotal -vsend */ i_ctx->mode = mode; return 0;}intimx21_get_modelist(disp_adapter_t *adp, int dispno, unsigned short *list, int index, int size){ list[0] = 8; list[1] = 16; list[2] = DISP_MODE_LISTEND; return 0;}intimx21_set_palette(disp_adapter_t *adp, int dispno, int index, int count, disp_color_t *pal){ imx21_context_t *i_ctx = adp->ms_ctx; if (index + count > 256) { errno = EINVAL; return - 1; } while (count--) { *(BPLUT + index) = ((DISP_TRUE_RED(*pal) >> 3) << 11) | ((DISP_TRUE_GREEN(*pal) >> 2) << 5) | (DISP_TRUE_BLUE(*pal) >> 3); index++; } return 0;}intimx21_set_display_offset(disp_adapter_t *adapter, int dispno, unsigned offset, int wait_vsync){ imx21_context_t *i_ctx = adapter->ms_ctx; int retry = 10; if (!i_ctx->rev_vs) { *LSSAR = offset; } else { *LSSAR = offset + ((i_ctx->width * (i_ctx->height -1 ) * 32)/i_ctx->mode); } if (!i_ctx->lcd_on) { if (i_ctx->pa1) { pa1_lcd_control(adapter, 1); spi_write(i_ctx, 0x0a, 0x10); /* to orient display correctly */ while (retry--) { if (i2c_write(adapter, PM_SM3_SET, 0x80) == 0) break; } if (retry == 0) { disp_printf(adapter, "I2C error - unable to enable backlight\n"); return -1; } } else *MMIO |= 0x200; i_ctx->lcd_on++; } return 0;}intdevg_get_modefuncs(disp_adapter_t *adp, disp_modefuncs_t *funcs, int tabsize){ DISP_ADD_FUNC(disp_modefuncs_t, funcs, init, imx21_mode_init, tabsize); DISP_ADD_FUNC(disp_modefuncs_t, funcs, fini, imx21_mode_fini, tabsize); DISP_ADD_FUNC(disp_modefuncs_t, funcs, module_info, imx21_module_info, tabsize); DISP_ADD_FUNC(disp_modefuncs_t, funcs, get_modeinfo, imx21_get_modeinfo, tabsize); DISP_ADD_FUNC(disp_modefuncs_t, funcs, get_modelist, imx21_get_modelist, tabsize); DISP_ADD_FUNC(disp_modefuncs_t, funcs, set_mode, imx21_set_mode, tabsize); DISP_ADD_FUNC(disp_modefuncs_t, funcs, set_palette, imx21_set_palette, tabsize); DISP_ADD_FUNC(disp_modefuncs_t, funcs, set_display_offset, imx21_set_display_offset, tabsize); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -