view target-utils/pirexplore/lcd.c @ 77:fcbe1332b197

pirexplore: LCD init and BL control work now
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 01 Aug 2013 00:57:49 +0000
parents 07b686248ab7
children 2c266d4339ff
line wrap: on
line source

#include <sys/types.h>
#include "types.h"

#define	GPIO_OUT_REG	(*(volatile u16 *)0xFFFE4802)
#define	nCS4_ADDR0	(*(volatile u16 *)0x02800000)
#define	nCS4_ADDR2	(*(volatile u16 *)0x02800002)

fb_spca_write(addr, data)
{
	GPIO_OUT_REG &= 0xFF7F;
	nCS4_ADDR0 = addr;
	nCS4_ADDR2 = data;
}

void
cmd_spca(argbulk)
	char *argbulk;
{
	char *argv[3];
	u_long addr, data;

	if (parse_args(argbulk, 2, 2, argv, 0) < 0)
		return;
	if (parse_hexarg(argv[0], 4, &addr) < 0) {
		printf("ERROR: arg1 must be a valid 16-bit hex value\n");
		return;
	}
	if (parse_hexarg(argv[1], 4, &data) < 0) {
		printf("ERROR: arg2 must be a valid 16-bit hex value\n");
		return;
	}
	fb_spca_write(addr, data);
}

void
cmd_spcainit()
{
	/*
	 * Apparently we have to give it a reset pulse, then immediately
	 * do the black magic register write sequence.
	 */
	GPIO_OUT_REG = 0x0000;
	GPIO_OUT_REG = 0x0012;
	/* non-understandable voodoo copied from OsmocomBB */
	fb_spca_write(0x7e, 0x00);	/* internal register access */
	osmo_delay_ms(10);
	fb_spca_write(0x7a, 0x00);	/* keep CPU in reset state */
	osmo_delay_ms(10);
	fb_spca_write(0x7f, 0x00);	/* select main page */
	osmo_delay_ms(5);
	fb_spca_write(0x72, 0x07);	/* don't reshape timing, 16 bit mode */
	fb_spca_write(0x14, 0x03);
	fb_spca_write(0x7f, 0x00);	/* select main page */
	osmo_delay_ms(5);
	fb_spca_write(0x06, 0xff);
	fb_spca_write(0x7f, 0x09);
	fb_spca_write(0x19, 0x08);	/* backlight: 0x08 is on, 0x0c is off */
	fb_spca_write(0x23, 0x18);
}

enum s6b33b1x_cmdflag { CMD, DATA, END };

struct s6b33b1x_cmdlist {
	enum s6b33b1x_cmdflag is_cmd:8;	/* 1: is a command, 0: is data, 2: end marker! */
	u_char data;			/* 8 bit to send to LC display */
};

static const struct s6b33b1x_cmdlist
s6b33b1x_initdata[] = {
	{ CMD,  0x26 }, /* CMD   DCDC and AMP ON/OFF set */
	{ DATA, 0x00 }, /* DATA: everything off */
	{ CMD,  0x02 }, /* CMD   Oscillation Mode Set */
	{ DATA, 0x00 }, /* DATA: oscillator off */
	{ CMD,  0x2c }, /* CMD   Standby Mode off */
	{ CMD,  0x50 }, /* CMD   Display off */
	{ CMD,  0x02 }, /* CMD   Oscillation Mode Set */
	{ DATA, 0x01 }, /* DATA: oscillator on */
	{ CMD,  0x26 }, /* CMD   DCDC and AMP ON/OFF set */
	{ DATA, 0x01 }, /* DATA: Booster 1 on */
	{ CMD,  0x26 }, /* CMD   DCDC and AMP ON/OFF set */
	{ DATA, 0x09 }, /* DATA: Booster 1 on, OP-AMP on */
	{ CMD,  0x26 }, /* CMD   DCDC and AMP ON/OFF set */
	{ DATA, 0x0b }, /* DATA: Booster 1 + 2 on, OP-AMP on */
	{ CMD,  0x26 }, /* CMD   DCDC and AMP ON/OFF set */
	{ DATA, 0x0f }, /* DATA: Booster 1 + 2 + 3 on, OP-AMP on */
	{ CMD,  0x20 }, /* CMD   DC-DC Select */
	{ DATA, 0x01 }, /* DATA: step up x1.5 */
	{ CMD,  0x24 }, /* CMD   DCDC Clock Division Set */
	{ DATA, 0x0a }, /* DATA: fPCK = fOSC/6 */
	{ CMD,  0x2a }, /* CMD   Contrast Control */
	{ DATA, 0x2d }, /* DATA: default contrast */
	{ CMD,  0x30 }, /* CMD   Adressing mode set */
	{ DATA, 0x0b }, /* DATA: 65536 color mode */
	{ CMD,  0x10 }, /* CMD   Driver output mode set */
	{ DATA, 0x03 }, /* DATA: Display duty: 1/132 */
	{ CMD,  0x34 }, /* CMD   N-line inversion set */
	{ DATA, 0x88 }, /* DATA: inversion on, one frame, every 8 blocks */
	{ CMD,  0x40 }, /* CMD   Entry mode set */
	{ DATA, 0x00 }, /* DATA: Y address counter mode */
	{ CMD,  0x28 }, /* CMD   Temperature Compensation set */
	{ DATA, 0x01 }, /* DATA: slope -0.05%/degC */
	{ CMD,  0x32 }, /* CMD   ROW vector mode set */
	{ DATA, 0x01 }, /* DATA: every 2 subgroup */
	{ CMD,  0x51 }, /* CMD   Display on */
	{ END,  0x00 }, /* MARKER: end of list */
};

static void
fb_s6b33b1x_send_cmdlist(p)
	struct s6b33b1x_cmdlist *p;
{
	while(p->is_cmd != END) {
		nCS4_ADDR0 = p->data;
		p++;
	}
}

void
cmd_lcdinit()
{
	GPIO_OUT_REG |= 0x0080;
	fb_s6b33b1x_send_cmdlist(s6b33b1x_initdata);
}