⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sed135x_16bit.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================
//
//      sed135x_16bit.c
//
// Author(s):   Michael Kelly - Cogent Computer Systems, Inc.
// Date:        05-24-2002
// Description:	Init Code for SED135x Display Controller
//
//==========================================================================

#include "config.h"
#include "cpuio.h"
#include "genlib.h"
#include "stddefs.h"
#include "sed1356_16bit.h"
#include "font8x16.h"
#include "sed_lut.h"

//--------------------------------------------------------------------------
// function prototypes
//
ulong sed135x_init(void);
void sed135x_on(void);
void sed135x_off(void);
void sed_lcd_bkl(uchar bright);
void sed_putchar(char c);
void sed_writechar(uchar c);
void sed_clr_row(int char_row);
int sed_tst(int argc,char *argv[]);
int sed(int argc,char *argv[]);

extern int udelay(int delay);
extern void lcd_bkl(uchar bright);
extern void fs6377_init(int);
extern ulong i2c_rd_device(uchar dev, uchar reg, uchar *data);

// global flags to determine what, if anything, was found
int sed135x_ok;
int sed135x_tst = 0;	// flag to indicate we are testing to disable sed_puchar
int sed_disp_mode_crt;

// globals to keep track of foreground, background colors and x,y position
int sed_color_depth;		// 4, 8 or 16
int sed_fg_color;			// 0 to 15, used as lookup into VGA color table
int sed_bg_color;			// 0 to 15, used as lookup into VGA color table
int sed_col;				// current column, 0 to COLS_PER_SCREEN - 1
int sed_row;				// current row, 0 to (ROWS_PER_SCREEN * 2) - 1
ulong sed_fb_offset;	   	// current offset into frame buffer for sed_putchar

// GPIO1 is used to control the LCD backlight on many CSB's
#define SED1356_BKL_ON		SED1356_REG_GPIO_CTL |= H2SED(SED1356_GPIO_GPIO1)		// GPIO1 = 1 
#define SED1356_BKL_OFF		SED1356_REG_GPIO_CTL &= H2SED(~SED1356_GPIO_GPIO1)	// GPIO1 = 0

// GPIO2 is used to sense the presence of a monitor.  0 = monitor connected, 1 = no monitor
// we invert the sense to make it easier to test and more logical.
//#define SED1356_CRT			SED1356_REG_GPIO_CTL & H2SED(SED1356_GPIO_GPIO2)

#define SED_FB_SIZE(_depth_)				(((PIXELS_PER_COL * PIXELS_PER_ROW) * _depth_) / 8)

#define SED_ROW_SIZE(_depth_)				((PIXELS_PER_ROW * _depth_) / 8)

#define SED_GET_ADD(_row_, _col_, _depth_)	(((((_row_ * PIXELS_PER_ROW) * FONT_HEIGHT) \
											  + (_col_ * FONT_WIDTH)) \
											  * _depth_) / 8)

//--------------------------------------------------------------------------
// sed135x_on
//
// This function turns on the SED1355 or SED1356 LCD and/or CRT
//
void sed135x_on()
{
	sed135x_off();

	// Turn on the LCD and/or CRT
	// The SED1356 supports seperate LCD and CRT timing registers
	// that have already been setup.  We just blank the side we 
	// aren't using and enable the other.
	if (sed_disp_mode_crt) {	// 1 = CRT Mode
		// Blank the LCD and CRT
		SED1356_REG_LCD_DISP_MODE_and_MISC |= H2SED(SED1356_LCD_DISP_BLANK);
		SED1356_REG_CRT_DISP_MODE |= H2SED(SED1356_CRT_DISP_BLANK);

		// turn the LCD backlight off
		lcd_bkl(0);

		// Set the SED1356 to CRT Mode
		SED1356_REG_DISP_MODE = H2SED(SED1356_DISP_SWIV_NORM | SED1356_DISP_MODE_CRT);

		// Turn on the CRT
		SED1356_REG_CRT_DISP_MODE &= ~H2SED(SED1356_CRT_DISP_BLANK);
	} // if CRT mode
	else {	// 0 = LCD Mode
		// Blank the LCD and CRT
		SED1356_REG_LCD_DISP_MODE_and_MISC |= H2SED(SED1356_LCD_DISP_BLANK);
		SED1356_REG_CRT_DISP_MODE |= H2SED(SED1356_CRT_DISP_BLANK);

		// Set the SED1356 to LCD Mode
		SED1356_REG_DISP_MODE = H2SED(SED1356_DISP_SWIV_NORM | SED1356_DISP_MODE_LCD);

		// Turn on the LCD
		SED1356_REG_LCD_DISP_MODE_and_MISC &= ~H2SED(SED1356_LCD_DISP_BLANK);

		lcd_bkl(0xff);		// turn the LCD backlight on/full brightness
	} // else LCD Mode

	monDelay(10); 		// wait for Power-up sequence to complete
}

//--------------------------------------------------------------------------
// sed_lcd_bkl()
//
// This function turns on the LCD backlight connected to GPIO1.  This is
// not used if the board has a different method of controlling the
// backlight.  Since the Sed has only a single GPIO bit and no way
// to modulate it, we use any non-zero value of bright to turn it on.
//
void sed_lcd_bkl(uchar bright)
{
	// Any non-zero value for bright means on
	if (bright) SED1356_BKL_ON;
	else SED1356_BKL_OFF;

}

//--------------------------------------------------------------------------
// sed135x_off
//
// This function turns off the SED1356 LCD and/or CRT and the display
// fifo.  It can also turn off the clocks if mode is true, thus allowing
// the programmable clock generator to be changed.
//
void sed135x_off()
{
	SED1356_REG_DISP_MODE = H2SED(SED1356_DISP_SWIV_NORM | SED1356_DISP_MODE_OFF);
	lcd_bkl(0);	// turn the LCD backlight off
}

//--------------------------------------------------------------------------
// sed135x_init
//
// This function sets up the sed1355 or sed1356 whichever is found
//
vulong sed135x_init()
{

	vushort temp16;
	int i;
	
	sed135x_ok = 0;
	sed_disp_mode_crt = 0;	// assume LCD

	// enable host access
	SED1356_REG_REV_and_MISC = 0x0000;

	// Check the ID to make sure we even have a SED1356 installed
	temp16 = SED1356_REG_REV_and_MISC & H2SED(SED1356_REV_ID_MASK);

	if (temp16 != H2SED(SED1356_REV_ID_1356)){
#ifdef LCD_DEBUG
		printf("SED1356 Not Found! SED_REG_REV = %04x.\n", temp16);
#endif
		return -1;
	}

	// Disable the display
	SED1356_REG_DISP_MODE = H2SED(SED1356_DISP_SWIV_NORM | SED1356_DISP_MODE_OFF);

	// Test for the presence of a CRT
	SED1356_REG_GPIO_CTL = 0x0000;						// Disable Backlight 
	SED1356_REG_GPIO_CFG = H2SED(SED1356_GPIO_GPIO1);	// GPIO1 Out, GPIO2 In
	if (SED1356_CRT)
	{
		 sed_disp_mode_crt = 0;
#ifdef LCD_DEBUG
		printf("SED1356 is in LCD Mode.\n");
#endif
	} 
	else 
	{
		sed_disp_mode_crt = 1;
#ifdef LCD_DEBUG
		printf("SED1356 is in CRT Mode.\n");
#endif
	}

	// Enable Power Save Mode before we mess with the clocks
	SED1356_REG_MEM_CFG_and_REF_RATE = H2SED(SED1356_REF_TYPE_SELF);	// set dram to self refresh first
	// shut off MCLK
	SED1356_REG_PWR_CFG_and_STAT = H2SED(SED1356_PWR_MCLK);

	// Wait until power is down - when MCLK bit goes true
	while ((SED1356_REG_PWR_CFG_and_STAT & H2SED(SED1356_PWR_MCLK)) == 0){}

	// Change the programmable clock generator to the desired timing
	if (sed_disp_mode_crt) fs6377_init(SED_DISP_MODE_CRT);
	else fs6377_init(SED_DISP_MODE_LCD);

	// Re-enable Power
	SED1356_REG_PWR_CFG_and_STAT = 0x0000;

	// Common Control Registers
	SED1356_REG_MCLK_CFG = H2SED(SED1356_MCLK_SRC_BCLK);
	SED1356_REG_LCD_PCLK_CFG = H2SED(SED1356_PCLK_SRC_CLKI);
	SED1356_REG_CRT_PCLK_CFG = H2SED(SED1356_PCLK_SRC_CLKI);
	SED1356_REG_MEDIA_PCLK_CFG = 0x0000;
	SED1356_REG_WAIT_STATE = H2SED(0x0001);
	SED1356_REG_MEM_CFG_and_REF_RATE = H2SED(SED1356_MEM_CFG_2CAS_EDO | SED1356_REF_RATE_2048);
	SED1356_REG_MEM_TMG0_and_1 = H2SED(SED1356_MEM_TMG0_EDO50_MCLK33 | SED1356_MEM_TMG1_EDO50_MCLK33);
	SED1356_REG_PANEL_TYPE_and_MOD_RATE = H2SED(SED1356_PANEL_TYPE_16 | SED1356_PANEL_TYPE_CLR | SED1356_PANEL_TYPE_TFT);

	// LCD Specific Registers
	SED1356_REG_LCD_HOR_DISP = H2SED((PIXELS_PER_ROW/8) - 1);
	SED1356_REG_LCD_HOR_NONDISP_and_START = H2SED(SED_HOR_NONDISP_LCD | (SED_HOR_PULSE_START_LCD << 8));
	SED1356_REG_LCD_HOR_PULSE = H2SED(SED1356_PULSE_WID(SED_HOR_PULSE_WIDTH_LCD) | SED1356_PULSE_POL_LOW);
	SED1356_REG_LCD_VER_DISP_HT_LO_and_HI = H2SED((PIXELS_PER_COL - 1) & 0x3ff);
	SED1356_REG_LCD_VER_NONDISP_and_START = H2SED(SED_VER_NONDISP_LCD | (SED_VER_PULSE_START_LCD << 8));
	SED1356_REG_LCD_VER_PULSE = H2SED(SED1356_PULSE_WID(SED_VER_PULSE_WIDTH_LCD) | SED1356_PULSE_POL_LOW);
	switch (sed_color_depth) {
		case 4:  SED1356_REG_LCD_DISP_MODE_and_MISC = H2SED(SED1356_LCD_DISP_BLANK | SED1356_LCD_DISP_SWIV_NORM | SED1356_LCD_DISP_4BPP);  break;
		case 8:  SED1356_REG_LCD_DISP_MODE_and_MISC = H2SED(SED1356_LCD_DISP_BLANK | SED1356_LCD_DISP_SWIV_NORM | SED1356_LCD_DISP_8BPP);  break;
		default: SED1356_REG_LCD_DISP_MODE_and_MISC = H2SED(SED1356_LCD_DISP_BLANK | SED1356_LCD_DISP_SWIV_NORM | SED1356_LCD_DISP_16BPP); break;
	}

	SED1356_REG_LCD_DISP_START_LO_and_MID = 0x0000;
	SED1356_REG_LCD_DISP_START_HI = 0x0000;
	SED1356_REG_LCD_ADD_OFFSET_LO_and_HI = H2SED((SED_ROW_SIZE(sed_color_depth) / 2) & 0x7ff);
	SED1356_REG_LCD_PIXEL_PAN = 0x0000;
	SED1356_REG_LCD_FIFO_THRESH_LO_and_HI = 0x0000;	// auto mode

	// CRT Specific Registers
	SED1356_REG_CRT_HOR_DISP = H2SED((PIXELS_PER_ROW/8) - 1);
	SED1356_REG_CRT_HOR_NONDISP_and_START = H2SED(SED_HOR_NONDISP_CRT | (SED_HOR_PULSE_START_CRT << 8));
	SED1356_REG_CRT_HOR_PULSE = H2SED(SED1356_PULSE_WID(SED_HOR_PULSE_WIDTH_CRT) | SED1356_PULSE_POL_LOW);
	SED1356_REG_CRT_VER_DISP_HT_LO_and_HI = H2SED((PIXELS_PER_COL - 1) & 0x3ff);
	SED1356_REG_CRT_VER_NONDISP_and_START = H2SED(SED_VER_NONDISP_CRT | (SED_VER_PULSE_START_CRT << 8));
	SED1356_REG_CRT_VER_PULSE_and_OUT_CTL = H2SED(SED1356_PULSE_WID(SED_VER_PULSE_WIDTH_CRT) | SED1356_PULSE_POL_LOW | SED1356_CRT_OUT_DAC_LVL);
	switch (sed_color_depth) {
		case 4:  SED1356_REG_CRT_DISP_MODE = H2SED(SED1356_CRT_DISP_BLANK | SED1356_CRT_DISP_4BPP);  break;
		case 8:  SED1356_REG_CRT_DISP_MODE = H2SED(SED1356_CRT_DISP_BLANK | SED1356_CRT_DISP_8BPP);  break;
		default: SED1356_REG_CRT_DISP_MODE = H2SED(SED1356_CRT_DISP_BLANK | SED1356_CRT_DISP_16BPP); break;
	}


	SED1356_REG_CRT_DISP_START_LO_and_MID = 0x0000;
	SED1356_REG_CRT_DISP_START_HI = 0x0000;
	SED1356_REG_CRT_ADD_OFFSET_LO_and_HI = H2SED((SED_ROW_SIZE(sed_color_depth) / 2) & 0x7ff);
	SED1356_REG_CRT_PIXEL_PAN = 0x0000;
	SED1356_REG_CRT_FIFO_THRESH_LO_and_HI = 0x0000;	// auto mode

	// Disable Cursor
	SED1356_REG_LCD_CURSOR_CTL_and_START_ADD = 0x0000;
	SED1356_REG_CRT_CURSOR_CTL_and_START_ADD = 0x0000;

	// Disable BitBlt
	SED1356_REG_BLT_CTL_0_and_1 = 0x0000;
	SED1356_REG_BLT_ROP_CODE_and_BLT_OP = 0x0000;
	SED1356_REG_BLT_SRC_START_LO_and_MID = 0x0000;
	SED1356_REG_BLT_SRC_START_HI = 0x0000;
	SED1356_REG_BLT_DEST_START_LO_and_MID = 0x0000;
	SED1356_REG_BLT_DEST_START_HI = 0x0000;
	SED1356_REG_BLT_ADD_OFFSET_LO_and_HI = 0x0000;
	SED1356_REG_BLT_WID_LO_and_HI = 0x0000;
	SED1356_REG_BLT_HGT_LO_and_HI = 0x0000;
	SED1356_REG_BLT_BG_CLR_LO_and_HI = 0x0000;
	SED1356_REG_BLT_FG_CLR_LO_and_HI = 0x0000;

	// Fill the LUT, write to both LCD and CRT luts simultaneously
	SED1356_REG_LUT_MODE = 0x0000;
	for (i = 0; i < 256; i++){

		SED1356_REG_LUT_ADD = H2SED(i);
		SED1356_REG_LUT_DATA = H2SED(sed_lut_16bit[i][0]);	// red
		SED1356_REG_LUT_DATA = H2SED(sed_lut_16bit[i][1]);	// green
		SED1356_REG_LUT_DATA = H2SED(sed_lut_16bit[i][2]);	// blue
	}

	// Disable Power Save Mode
	SED1356_REG_PWR_CFG_and_STAT = 0x0000;

	// Set Watchdog						   
	SED1356_REG_WATCHDOG_CTL = 0x0000;

	// initialize the globals	
	sed135x_ok = 1;
	sed_fg_color = SED_FG_DEF;
	sed_bg_color = SED_BG_DEF;
	sed_row = 0;
	sed_col = 0;
	sed_fb_offset = 0x00;

	// fill the screen with the background color, remember for the console driver
	// we do double buffering, so fill twice as mush as the active screen size
	switch (sed_color_depth){
		case 4:  temp16 = sed_bg_color | sed_bg_color << 4 | sed_bg_color << 8 | sed_bg_color << 12; break;
		case 8:  temp16 = sed_bg_color | sed_bg_color << 8; break;
		default: temp16 = vga_lookup[sed_bg_color]; break;
	}
	for (i = 0; i < (PIXELS_PER_COL * PIXELS_PER_ROW) * 4; i += 2){	
		WR_FB16(i, temp16);
	}

	// turn on the display
	sed135x_on();
	
#ifdef LCD_DEBUG
	printf("SED1356 init complete.\n");
#endif
	
	return 0;
}

//--------------------------------------------------------------------------
// sed_pwr_dn()
void sed_pwr_dn(){

		// Enable Host Access
		SED1356_REG_REV_and_MISC = 0x0000;

		// Disable the display
		SED1356_REG_DISP_MODE = H2SED(SED1356_DISP_MODE_OFF);

		// Enable Power Save Mode
		// set dram to self refresh first
		SED1356_REG_MEM_CFG_and_REF_RATE = H2SED(SED1356_REF_TYPE_SELF);

		// shut off MCLK
		SED1356_REG_PWR_CFG_and_STAT = H2SED(SED1356_PWR_MCLK);

		// Wait until power is down - when MCLK bit goes true
		while ((SED1356_REG_PWR_CFG_and_STAT & H2SED(SED1356_PWR_MCLK)) == 0){}
}

//--------------------------------------------------------------------------
// sed_tst()
//
// This test will initialize the SED135x, do a frame buffer
// test and then display 16 VGA colors full screen until stopped.
//
#define SED_I_OPTION 
#define SED_S_OPTION 
#define USAGE_STRING "-[cd:ilns]"
#include "sed_tstHelp.c"

int sed_tst(int argc,char *argv[])
{
	volatile ushort wr16, rd16, temp16;
	int i, x, opt;
	int no_wait = 0;
	int init_only = 0;
	char c;

	sed135x_tst = 1;
	sed135x_off();

    while ((opt=getopt(argc,argv,"clnsid:")) != -1) {
        switch(opt) {
	        case 'l':   // Override sed_disp_mode_crt, Run Test in LCD Mode
				sed_disp_mode_crt = 0;
				printf("Forcing LCD Mode!\n");
			break;
	        case 'c':   // Override sed_disp_mode_crt, Run Test in CRT Mode
				sed_disp_mode_crt = 1;
				printf("Forcing CRT Mode!\n");
			break;
			case 'd':	// set the color depth
                switch(*optarg) {
            	    case '4':
	        	        sed_color_depth = 4;
						printf("Forcing 4bpp Mode!\n");
        	            break;
    	            case '8':
            	        sed_color_depth = 8;
						printf("Forcing 8bpp Mode!\n");
                    	break;
    	            case '1':
	                    sed_color_depth = 16;
						printf("Forcing 16bpp Mode!\n");
        	            break;
	                default:	// test with current depth
						break;
                }
	            break;
	        case 'n':   // no waiting for keypress - fastest operation
				no_wait = 1;
				printf("No Keypress Mode, Must Reset System to Stop!\n");
				break;
	        case 'i':   // init only 
				no_wait = 1;
				printf("Initializing SED, Skipping tests!\n");
				init_only = 1;
				break;
	        case 's':   // Scope loop
				no_wait = 1;
				printf("Scope Loop, press any key to Stop!\n");
				while(1){
					SED1356_REG_REV_and_MISC = 0;
					temp16 = SED1356_REG_REV_and_MISC;
					if (gotachar()) break;
				}
				break;
			default:	// test with current mode
				break;
		}
	}
	sed135x_init();
	if (sed135x_ok == 0) return -1;

	sed135x_on();

	if (init_only)
	{
		sed135x_tst = 0;
		return 0;
	}

	printf("Frame Buffer R/W...");
	// do an address=data read/write test on the frame buffer
	// PIXELS_PER_COL * PIXELS_PER_ROW is the highest pixel.  
	// Multiply by bits_per_pixel (sed_color_depth), then
	// divide by 8 to get the actual byte count.
	for (i = 0; i < SED_FB_SIZE(sed_color_depth); i += 4){	
		WR_FB16(i, (i & 0xffff));
		RD_FB16(i, rd16);
		if(rd16 != (i & 0xffff)){
			printf("Fail at 0x%08lx, WR 0x%08x, RD 0x%04x!\n",
				(long)(SED_MEM_BASE + i), i, rd16);
//			return -1;
		}
	} 

	printf("OK!\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -