diff --git a/sys/pic32/st7781.c b/sys/pic32/st7781.c index c1b0ce3..442a7e9 100644 --- a/sys/pic32/st7781.c +++ b/sys/pic32/st7781.c @@ -45,13 +45,41 @@ */ static int _col, _row; +/* + * ID of the LCD controller chip. + */ +static int _chip_id; + +/* + * Delay for 100 nanoseconds. + * Needed to match the /WR and /RD timing requirements. + */ +#if CPU_KHZ <= 10000 +# define delay100ns() /* empty */ +#elif CPU_KHZ <= 20000 +# define delay100ns() asm volatile("nop") +#elif CPU_KHZ <= 30000 +# define delay100ns() asm volatile("nop; nop") +#elif CPU_KHZ <= 40000 +# define delay100ns() asm volatile("nop; nop; nop") +#elif CPU_KHZ <= 50000 +# define delay100ns() asm volatile("nop; nop; nop; nop") +#elif CPU_KHZ <= 60000 +# define delay100ns() asm volatile("nop; nop; nop; nop; nop") +#elif CPU_KHZ <= 70000 +# define delay100ns() asm volatile("nop; nop; nop; nop; nop; nop") +#else +# define delay100ns() asm volatile("nop; nop; nop; nop; nop; nop; nop; nop") +#endif + /* * Signal mappings: * /RESET - reset and initialize the chip. * /CS - chip select when low. - * /RS - data or command selection. * /RD - read operation enable. * /WR - write operation enable. + * RS - command or data mode selection. + * D0-D7 - data bus, bidirectional. */ #define RST_IDLE() LAT_SET(LCD_RST_PORT) = 1< 0) - asm volatile ("nop"); -} +#define RS_DATA() LAT_SET(LCD_RS_PORT) = 1<\n"); + break; + + default: + /* Disable outputs. */ + setReadDir(); + TRIS_SET(LCD_CS_PORT) = 1 << LCD_CS_PIN; + TRIS_SET(LCD_RS_PORT) = 1 << LCD_RS_PIN; + TRIS_SET(LCD_WR_PORT) = 1 << LCD_WR_PIN; + TRIS_SET(LCD_RD_PORT) = 1 << LCD_RD_PIN; + TRIS_SET(LCD_RST_PORT) = 1 << LCD_RST_PIN; + printf("swtft0: Unknown chip ID = 0x%x\n", _chip_id); + return -1; + } /* Initialization of LCD controller. */ CS_ACTIVE(); @@ -257,19 +289,15 @@ static void initDisplay() writeReg(0x11, 0x0005); writeReg(0x12, 0x0000); writeReg(0x13, 0x0000); - //udelay(50000); /* Power supply startup 1 settings. */ writeReg(0x10, 0x12B0); - //udelay(50000); writeReg(0x11, 0x0007); - //udelay(50000); /* Power supply startup 2 settings. */ writeReg(0x12, 0x008C); writeReg(0x13, 0x1700); writeReg(0x29, 0x0022); - //udelay(50000); /* Gamma cluster settings. */ writeReg(0x30, 0x0000); @@ -296,59 +324,7 @@ static void initDisplay() /* Display on. */ writeReg(0x07, 0x0133); -#if 0 - writeReg(0x01, 0x0100); - writeReg(0x02, 0x0700); - writeReg(0x03, 0x1030); - writeReg(0x08, 0x0302); - writeReg(0x09, 0x0000); - writeReg(0x0A, 0x0008); - - /* Power control registers. */ - writeReg(0x10, 0x0790); - writeReg(0x11, 0x0005); - writeReg(0x12, 0x0000); - writeReg(0x13, 0x0000); - //udelay(50000); - - /* Power supply startup 1 settings. */ - writeReg(0x10, 0x12B0); - //udelay(50000); - writeReg(0x11, 0x0007); - //udelay(50000); - - /* Power supply startup 2 settings. */ - writeReg(0x12, 0x008C); - writeReg(0x13, 0x1700); - writeReg(0x29, 0x0022); - //udelay(50000); - - /* Gamma cluster settings. */ - writeReg(0x30, 0x0000); - writeReg(0x31, 0x0505); - writeReg(0x32, 0x0205); - writeReg(0x35, 0x0206); - writeReg(0x36, 0x0408); - writeReg(0x37, 0x0000); - writeReg(0x38, 0x0504); - writeReg(0x39, 0x0206); - writeReg(0x3C, 0x0206); - writeReg(0x3D, 0x0408); - - /* Display window 240*320. */ - writeReg(0x50, 0x0000); - writeReg(0x51, 0x00EF); - writeReg(0x52, 0x0000); - writeReg(0x53, 0x013F); - - /* Frame rate settings. */ - writeReg(0x60, 0xA700); - writeReg(0x61, 0x0001); - writeReg(0x90, 0x0033); // RTNI setting - - /* Display on. */ - writeReg(0x07, 0x0133); -#endif + return 0; } static void setAddrWindow(int x0, int y0, int x1, int y1) @@ -374,9 +350,9 @@ static void setPixel(int x, int y, int color) if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) return; CS_ACTIVE(); - writeReg(0x0020, x); - writeReg(0x0021, y); - writeReg(0x0022, color); + writeReg(0x20, x); + writeReg(0x21, y); + writeReg(0x22, color); CS_IDLE(); } @@ -412,14 +388,20 @@ static void flood(int color, int npixels) /* 64 pixels/block / 4 pixels/pass. */ for (i = 16; i > 0; i--) { /* 2 bytes/pixel x 4 pixels. */ - WR_STROBE(); WR_STROBE(); WR_STROBE(); WR_STROBE(); - WR_STROBE(); WR_STROBE(); WR_STROBE(); WR_STROBE(); + delay100ns(); WR_STROBE(); + delay100ns(); WR_STROBE(); + delay100ns(); WR_STROBE(); + delay100ns(); WR_STROBE(); + delay100ns(); WR_STROBE(); + delay100ns(); WR_STROBE(); + delay100ns(); WR_STROBE(); + delay100ns(); WR_STROBE(); } } /* Fill any remaining pixels (1 to 64). */ for (i = npixels & 63; i > 0; i--) { - WR_STROBE(); - WR_STROBE(); + delay100ns(); WR_STROBE(); + delay100ns(); WR_STROBE(); } } else { while (blocks--) { @@ -760,8 +742,8 @@ int gpanel_ioctl(dev_t dev, register u_int cmd, caddr_t addr, int flag) struct gpanel_clear_t *param = (struct gpanel_clear_t*) addr; CS_ACTIVE(); - writeReg(0x0020, 0); - writeReg(0x0021, 0); + writeReg(0x20, 0); + writeReg(0x21, 0); flood(param->color, WIDTH * HEIGHT); param->xsize = WIDTH; param->ysize = HEIGHT; @@ -863,13 +845,10 @@ static int swtftprobe(config) struct conf_device *config; { - unsigned id; + if (initDisplay() < 0) + return 0; - initDisplay(); printf("swtft0: display %ux%u\n", HEIGHT, WIDTH); - id = readDeviceId(); - if (id == 0x7783) - printf("swtft0: Sitronix ST7781 TFT controller\n"); setAddrWindow(0, 0, WIDTH-1, HEIGHT-1); return 1; } diff --git a/sys/pic32/wf32/Config b/sys/pic32/wf32/Config index c40c17d..f48d6a6 100644 --- a/sys/pic32/wf32/Config +++ b/sys/pic32/wf32/Config @@ -49,14 +49,14 @@ options "SD_MHZ=10" # speed 10 MHz # RG6, RG7, RG8, RD4 - spi2, SD card # RA14, RB0, RB2, RB4, # RB8, RB10, RD0, RD1, -# RD2, RD3, RE8, RE9, RF0 - LCD display +# RD2, RD3, RE8, RE9, RF1 - LCD display # device gpio0 flags 0x86ff # port A device gpio1 flags 0xfaea # port B device gpio2 flags 0xf01e # port C device gpio3 flags 0xffe0 # port D device gpio4 flags 0x00ff # port E -device gpio5 flags 0x303a # port F +device gpio5 flags 0x3039 # port F device gpio6 flags 0xf20f # port G # ADC driver @@ -64,3 +64,19 @@ device adc # PWM driver device pwm + +# ST7781 TFT display driver +device swtft +signal "LCD_RST" pin RB10 +signal "LCD_CS" pin RB0 +signal "LCD_RD" pin RB2 +signal "LCD_RS" pin RB8 +signal "LCD_WR" pin RB4 +signal "LCD_D0" pin RA14 +signal "LCD_D1" pin RD3 +signal "LCD_D2" pin RE8 +signal "LCD_D3" pin RD0 +signal "LCD_D4" pin RF1 +signal "LCD_D5" pin RD1 +signal "LCD_D6" pin RD2 +signal "LCD_D7" pin RE9 diff --git a/sys/pic32/wf32/Config-swtft b/sys/pic32/wf32/Config-swtft deleted file mode 100644 index b4bb984..0000000 --- a/sys/pic32/wf32/Config-swtft +++ /dev/null @@ -1,82 +0,0 @@ -# -# chipKIT WF32 board with microSD card on 2.4" LCD TFT display shield -# -# To build the kernel, use: -# cd sys/pic32/wf32 -# kconfig Config -# make clean -# make -# -# Format of this file is described on page: -# http://retrobsd.org/wiki/doku.php/doc/kconfig -# -architecture "pic32" -cpu "PIC32MX7" # Processor variant -board "WF32" # Board type -ldscript "max32/bootloader.ld" # Linker script - -# Standard system options -options "CPU_KHZ=80000" # Oscillator frequency of CPU core -options "BUS_KHZ=80000" # Frequency of peripheral bus -options "BUS_DIV=1" # Bus clock divisor 1/2/4/8 - -# LEDs -signal "LED_KERNEL" pin RA0 # kernel activity indicator -signal "LED_DISK" pin RA1 # disk activity indicator - -# Root filesystem at /dev/sd0a, swap at /dev/sd0b -config unix root on sd0a - swap on sd0b - -# Serial UART ports -device uart1 # Serial-to-USB converter - -# Console options -options "CONS_MAJOR=UART_MAJOR" # UART device -options "CONS_MINOR=0" # /dev/tty0 - -# SPI ports -controller spi2 # SD card - -# microSD card -device sd0 at spi2 pin RD4 # select pin RD4 -options "SD_MHZ=10" # speed 10 MHz - -# General purpose I/O ports -# Flags define a mask of available pins -# The following pins excluded: -# RF2, RF8 - uart1 -# RG6, RG7, RG8, RD4 - spi2, SD card -# RA14, RB0, RB2, RB4, -# RB8, RB10, RD0, RD1, -# RD2, RD3, RE8, RE9, RF0 - LCD display -# -device gpio0 flags 0x86ff # port A -device gpio1 flags 0xfaea # port B -device gpio2 flags 0xf01e # port C -device gpio3 flags 0xffe0 # port D -device gpio4 flags 0x00ff # port E -device gpio5 flags 0x303a # port F -device gpio6 flags 0xf20f # port G - -# ADC driver -device adc - -# PWM driver -device pwm - -# ST7781 TFT display driver -device swtft -signal "LCD_RST" pin RB10 -signal "LCD_CS" pin RB0 -signal "LCD_RD" pin RB2 -signal "LCD_RS" pin RB8 -signal "LCD_WR" pin RB4 -signal "LCD_D0" pin RA14 -signal "LCD_D1" pin RD3 -signal "LCD_D2" pin RE8 -signal "LCD_D3" pin RD0 -signal "LCD_D4" pin RF0 -signal "LCD_D5" pin RD1 -signal "LCD_D6" pin RD2 -signal "LCD_D7" pin RE9 diff --git a/sys/pic32/wf32/Makefile b/sys/pic32/wf32/Makefile index ebf4807..2575b61 100644 --- a/sys/pic32/wf32/Makefile +++ b/sys/pic32/wf32/Makefile @@ -12,6 +12,20 @@ PARAM += -DGPIO5_ENABLED PARAM += -DGPIO6_ENABLED PARAM += -DADC_ENABLED PARAM += -DPWM_ENABLED +PARAM += -DSWTFT_ENABLED +PARAM += -DLCD_D7_PORT=TRISE -DLCD_D7_PIN=9 +PARAM += -DLCD_D6_PORT=TRISD -DLCD_D6_PIN=2 +PARAM += -DLCD_D5_PORT=TRISD -DLCD_D5_PIN=1 +PARAM += -DLCD_D4_PORT=TRISF -DLCD_D4_PIN=1 +PARAM += -DLCD_D3_PORT=TRISD -DLCD_D3_PIN=0 +PARAM += -DLCD_D2_PORT=TRISE -DLCD_D2_PIN=8 +PARAM += -DLCD_D1_PORT=TRISD -DLCD_D1_PIN=3 +PARAM += -DLCD_D0_PORT=TRISA -DLCD_D0_PIN=14 +PARAM += -DLCD_WR_PORT=TRISB -DLCD_WR_PIN=4 +PARAM += -DLCD_RS_PORT=TRISB -DLCD_RS_PIN=8 +PARAM += -DLCD_RD_PORT=TRISB -DLCD_RD_PIN=2 +PARAM += -DLCD_CS_PORT=TRISB -DLCD_CS_PIN=0 +PARAM += -DLCD_RST_PORT=TRISB -DLCD_RST_PIN=10 PARAM += -DLED_DISK_PORT=TRISA -DLED_DISK_PIN=1 PARAM += -DLED_KERNEL_PORT=TRISA -DLED_KERNEL_PIN=0 PARAM += -DSD_MHZ=10 @@ -65,7 +79,7 @@ OBJS = exec_aout.o exec_conf.o exec_elf.o exec_script.o exec_subr.o \ ufs_namei.o ufs_subr.o ufs_syscalls.o ufs_syscalls2.o \ vfs_vnops.o vm_sched.o vm_swap.o vm_swp.o clock.o cons.o devsw.o \ exception.o machdep.o mem.o signal.o swap.o sysctl.o adc.o \ - gpio.o pwm.o sd.o spi.o spi_bus.o uart.o + gpio.o pwm.o sd.o st7781.o spi.o spi_bus.o uart.o CFILES = $S/kernel/exec_aout.c $S/kernel/exec_conf.c $S/kernel/exec_elf.c \ $S/kernel/exec_script.c $S/kernel/exec_subr.c \ @@ -91,8 +105,8 @@ CFILES = $S/kernel/exec_aout.c $S/kernel/exec_conf.c $S/kernel/exec_elf.c \ $S/pic32/devsw.c $S/pic32/exception.c $S/pic32/machdep.c \ $S/pic32/mem.c $S/pic32/signal.c $S/pic32/swap.c \ $S/pic32/sysctl.c $S/pic32/adc.c $S/pic32/gpio.c $S/pic32/pwm.c \ - $S/pic32/sd.c $S/pic32/spi.c $S/pic32/spi_bus.c $S/pic32/uart.c \ - swapunix.c + $S/pic32/sd.c $S/pic32/st7781.c $S/pic32/spi.c \ + $S/pic32/spi_bus.c $S/pic32/uart.c swapunix.c # load lines for config "xxx" will be emitted as: # xxx: ${SYSTEM_DEP} swapxxx.o @@ -336,6 +350,9 @@ pwm.o: $S/pic32/pwm.c sd.o: $S/pic32/sd.c ${COMPILE_C} +st7781.o: $S/pic32/st7781.c + ${COMPILE_C} + spi.o: $S/pic32/spi.c ${COMPILE_C}