From b97a816998997839fa35b47c2c6095c5ae2c04aa Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 27 May 2013 11:39:13 -0600 Subject: [PATCH] The SLCD driver is now fully functional for Sure PIC32MX board --- ChangeLog | 3 + configs/pcblogic-pic32mx/README.txt | 11 +- configs/sure-pic32mx/README.txt | 32 +- configs/sure-pic32mx/src/pic32mx_autoleds.c | 5 - configs/sure-pic32mx/src/pic32mx_lcd1602.c | 327 +++++++++++++++----- configs/sure-pic32mx/src/sure-pic32mx.h | 51 +++ configs/sure-pic32mx/usbnsh/Make.defs | 2 +- drivers/lcd/Kconfig | 5 +- include/nuttx/lcd/hd4478ou.h | 8 +- 9 files changed, 346 insertions(+), 98 deletions(-) diff --git a/ChangeLog b/ChangeLog index 26c71b5416..b2a6567316 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4814,3 +4814,6 @@ * include/nuttx/lcd/slcd_ioctl.h and all SLCD drivers: Rename geometry structure to attributes; Move MAX contrast to attributes. Add attribute and ioctl commands to get and set LCD brightness (2013-5-27). + * configs/sure-pic32mx/pic32mx_lcd1602.c: This driver appears to + fully functional (at least to the extent that it has been tested) + (2013-5-27). diff --git a/configs/pcblogic-pic32mx/README.txt b/configs/pcblogic-pic32mx/README.txt index 847f355fde..2db8aa5c8a 100644 --- a/configs/pcblogic-pic32mx/README.txt +++ b/configs/pcblogic-pic32mx/README.txt @@ -161,7 +161,7 @@ MAX3232 Connection GND -- POWER POINT: GND Vcc -- POWER POINT: Vdd (3.3V) -- Or P32_VBUS (+5V) Or +5V from a USB PC port. - + Toolchains ========== @@ -252,7 +252,7 @@ Toolchains Windows Native Toolchains ------------------------- - + NOTE: There are several limitations to using a Windows based toolchain in a Cygwin environment. The three biggest are: @@ -478,7 +478,7 @@ PIC32MX Configuration Options CONFIG_PIC32MX_CODEWP - Default 1 (disabled) DEVCFG1: (All settings determined by selections in board.h) DEVCFG2: (All settings determined by selections in board.h) - DEVCFG3: + DEVCFG3: CONFIG_PIC32MX_USBIDO - USB USBID Selection. Default 1 if USB enabled (USBID pin is controlled by the USB module), but 0 (GPIO) otherwise. CONFIG_PIC32MX_VBUSIO - USB VBUSON Selection (Default 1 if USB enabled @@ -670,7 +670,10 @@ Configuration sub-directories NOTES: a. I do not have the LCD1602 working. I may just be getting lost in the tangle of wires or perhaps there is something fundamentally wrong with - the code. + the code. If you decide to work on this, you might want to consider + the working, big-bang version of this driver at configs/sure-pic32mx/src/pic32mx_lcd1602.c. + A bit-bang driver is probably more appropriate for such a low performance + device (and a LOT easier to debug). b. At this point in time, testing of the SLCD is very limited because there is not much in apps/examples/slcd. Basically driver with a working test setup and ready to be tested and debugged. diff --git a/configs/sure-pic32mx/README.txt b/configs/sure-pic32mx/README.txt index 36abc7997e..02aa44ec9c 100644 --- a/configs/sure-pic32mx/README.txt +++ b/configs/sure-pic32mx/README.txt @@ -318,7 +318,7 @@ Toolchains Windows Native Toolchains ------------------------- - + NOTE: There are several limitations to using a Windows based toolchain in a Cygwin environment. The three biggest are: @@ -423,6 +423,8 @@ LCD1602 46 INT0/RD0 16. K Transistor circuit driven by PWM1 --------------------- ---------- ---------------------------------- + Vbus power also requires Vbuson/AN5/RB5 + PIC32MX Configuration Options ============================= @@ -455,7 +457,7 @@ PIC32MX Configuration Options CONFIG_ARCH_BOARD=sure-pic32mx - CONFIG_ARCH_DBDP11215 Distinguishes the DB_DP11215 PIC32 Storage + CONFIG_ARCH_DBDP11215 Distinguishes the DB_DP11215 PIC32 Storage Demo Board CONFIG_ARCH_DBDP11212 Distingustes the DB-DP11212 PIC32 General @@ -551,7 +553,7 @@ PIC32MX Configuration Options CONFIG_PIC32MX_CODEWP - Default 1 (disabled) DEVCFG1: (All settings determined by selections in board.h) DEVCFG2: (All settings determined by selections in board.h) - DEVCFG3: + DEVCFG3: CONFIG_PIC32MX_USBIDO - USB USBID Selection. Default 1 if USB enabled (USBID pin is controlled by the USB module), but 0 (GPIO) otherwise. CONFIG_PIC32MX_VBUSIO - USB VBUSON Selection (Default 1 if USB enabled @@ -698,7 +700,7 @@ Where is one of the following: Several USB device configurations can be enabled and included as NSH built-in built in functions. All require the following basic setup in your .config to enable USB device support: - + Drivers: CONFIG_USBDEV=y : Enable basic USB device support @@ -717,9 +719,9 @@ Where is one of the following: CONFIG_PL2303=y : Enable the Prolifics PL2303 emulation CONFIG_CDCACM=y : or the CDC/ACM serial driver (not both) - examples/cdcacm - The examples/cdcacm program can be included as an + examples/cdcacm - The examples/cdcacm program can be included as an function by uncommenting the following line in the appconfig file: - + Application Configuration->Examples: CONFIG_EXAMPLES_CDCACM=y : Select apps/examples/cdcacm @@ -766,28 +768,34 @@ Where is one of the following: 4. To enable LCD1602 support: - Device Drivers: + Device Drivers ->LCD Driver Support: CONFIG_LCD=y : Enable LCD menus CONFIG_LCD_LCD1602=y : Select LCD1602 + CONFIG_LCD_MAXCONTRAST=255 : (Or any large-ish value that you prefer) + CONFIG_LCD_MAXPOWER=255 : (Or any large-ish value that you prefer) Library Routines: CONFIG_LIB_SLCDCODEC=y : Enable the SLCD CODEC - System Type -> PIC32MX Peripheral Support: - CONFIG_PIC32MX_PMP=y : Enable PMP support + NOTE that is is not necessary to select the PMP peripheral; this LCD + driver is a bit-bang driver that just happens to use the PMP pins as + GPIOS. To enable apps/examples/slcd to test the LCD: - Application Configuration: + Application Configuration -> NSH Library: CONFIG_NSH_ARCHINIT=y : Needed to initialize the SLCD + + Application Configuration -> Examples: CONFIG_EXAMPLES_SLCD=y : Enable apps/examples/slcd use /dev/lcd1602 CONFIG_EXAMPLES_SLCD_DEVNAME="/dev/lcd1602" To enable LCD debug output: - Build Setup: + Build Setup -> Debug Options: CONFIG_DEBUG=y : Enable debug features - CONFIG_DEBUG_VERBOSE=y : Enable LCD debug + CONFIG_DEBUG_VERBOSE=y : Enable verbose debug output + CONFIG_DEBUG_LCD=y : Enable LCD debug output NOTES: a. I do not have the LCD1602 working. I may just be getting lost in the diff --git a/configs/sure-pic32mx/src/pic32mx_autoleds.c b/configs/sure-pic32mx/src/pic32mx_autoleds.c index 61ddfe71a4..dabbf679f7 100644 --- a/configs/sure-pic32mx/src/pic32mx_autoleds.c +++ b/configs/sure-pic32mx/src/pic32mx_autoleds.c @@ -79,11 +79,6 @@ * LED_PANIC 5 N/C N/C N/C ON N/C N/C N/C OFF */ -#define GPIO_USB_LED (GPIO_OUTPUT|GPIO_VALUE_ONE|GPIO_PORTD|GPIO_PIN7) -#define GPIO_SD_LED (GPIO_OUTPUT|GPIO_VALUE_ONE|GPIO_PORTD|GPIO_PIN6) -#define GPIO_FLASH_LED (GPIO_OUTPUT|GPIO_VALUE_ONE|GPIO_PORTF|GPIO_PIN0) -#define GPIO_ERROR_LED (GPIO_OUTPUT|GPIO_VALUE_ONE|GPIO_PORTF|GPIO_PIN1) - /* LED Management Definitions ***********************************************/ #define LED_OFF 0 diff --git a/configs/sure-pic32mx/src/pic32mx_lcd1602.c b/configs/sure-pic32mx/src/pic32mx_lcd1602.c index 9d48452b52..d12838b7d8 100644 --- a/configs/sure-pic32mx/src/pic32mx_lcd1602.c +++ b/configs/sure-pic32mx/src/pic32mx_lcd1602.c @@ -37,7 +37,7 @@ * ****************************************************************************/ - /* LCD pin mapping (see configs/pcblogic-pic32mx/README.txt) + /* LCD pin mapping (see configs/sure-pic32mx/README.txt) * * --------------------- ---------- ---------------------------------- * PIC32 Sure JP1 Sure Signal Description @@ -61,6 +61,8 @@ * 15. A +5V_DUSB * 46 INT0/RD0 16. K Transistor circuit driven by PWM1 * --------------------- ---------- ---------------------------------- + * + * Vbus power also requires Vbuson/AN5/RB5 */ /**************************************************************************** @@ -87,7 +89,7 @@ #include #include "up_arch.h" -#include "pic32mx-pmp.h" +#include "pic32mx-ioport.h" #include "pic32mx-int.h" #include "pic32mx-internal.h" #include "sure-pic32mx.h" @@ -99,10 +101,6 @@ ****************************************************************************/ /* Configuration ************************************************************/ -#ifndef CONFIG_PIC32MX_PMP -# error "CONFIG_PIC32MX_PMP is required to use the LCD" -#endif - #ifndef CONFIG_LCD_MAXCONTRAST # define CONFIG_LCD_MAXCONTRAST 100 #endif @@ -135,17 +133,14 @@ # define MAX(a,b) (a > b ? a : b) #endif -/* Pin configuration ********************************************************/ -/* RB15, RS -- High values selects data */ - -#define GPIO_LCD_RS (GPIO_OUTPUT|GPIO_VALUE_ZERO|GPIO_PORTB|GPIO_PIN15) - /* LCD **********************************************************************/ #define LCD_NROWS 2 #define LCD_NCOLUMNS 16 #define LCD_NCHARS (LCD_NROWS * LCD_NCOLUMNS) +#define NOP __asm__ __volatile__ ("nop"); + /* Debug ********************************************************************/ #ifdef CONFIG_DEBUG_LCD @@ -173,9 +168,10 @@ struct lcd_instream_s struct lcd1602_2 { - bool initialized; /* True: Completed initialization sequence */ - uint8_t currow; /* Current row */ - uint8_t curcol; /* Current column */ + bool initialized; /* True: Completed initialization sequence */ + uint8_t currow; /* Current row */ + uint8_t curcol; /* Current column */ + uint8_t brightness; /* Current brightness */ }; /**************************************************************************** @@ -195,9 +191,13 @@ static void lcd_dumpstream(FAR const char *msg, /* Internal functions */ static int lcd_getstream(FAR struct lib_instream_s *instream); +static void lcd_brightness(uint8_t brightness); +static void lcd_shortdelay(int delay); static void lcd_wrcommand(uint8_t cmd); static void lcd_wrdata(uint8_t data); static uint8_t lcd_rddata(void); +static uint8_t lcd_readstatus(void); +static void lcd_waitbusy(void); static uint8_t lcd_readch(uint8_t row, uint8_t column); static void lcd_writech(uint8_t ch, uint8_t row, uint8_t column); static void lcd_appendch(uint8_t ch); @@ -312,6 +312,66 @@ static int lcd_getstream(FAR struct lib_instream_s *instream) return EOF; } +/**************************************************************************** + * Name: lcd_brightness + * + * Description: + * Enable for disable LCD lighting. + * + ****************************************************************************/ + +static void lcd_brightness(uint8_t brightness) +{ + /* The LIGHT and COMP pins are label PWM1 and PWM2 and so are obviously + * intended to support modulated outputs. However, here for simplicity, + * they are just treated as on/off discretes outputs. + */ + + if (brightness > 0) + { + /* Turn the LCD light on */ + + pic32mx_gpiowrite(GPIO_LCD_LIGHT, true); + NOP;NOP;NOP; + pic32mx_gpiowrite(GPIO_LCD_COMP, true); + NOP;NOP; + pic32mx_gpiowrite(GPIO_LCD_PWR, true); + } + else + { + /* Turn the LCD light off */ + + pic32mx_gpiowrite(GPIO_LCD_PWR, false); + pic32mx_gpiowrite(GPIO_LCD_COMP, false); + pic32mx_gpiowrite(GPIO_LCD_LIGHT, false); + } + + g_lcd1602.brightness = brightness; +} + +/**************************************************************************** + * Name: lcd_shortdelay + * + * Description: + * Small delays are needed to make some of the LCD operations work. + * + ****************************************************************************/ + +static void lcd_shortdelay(int delay) +{ + volatile int loop; + + /* On a 32MHz MCU, this should amount to about 300NS per loop */ + + while (delay-- > 0) + { + for (loop = 0; loop < 1; loop++) + { + NOP; + } + } +} + /**************************************************************************** * Name: lcd_wrcommand * @@ -322,13 +382,28 @@ static int lcd_getstream(FAR struct lib_instream_s *instream) static void lcd_wrcommand(uint8_t cmd) { - /* Address bit A0 is RS. Set the address latch to A0=0 */ + /* Make sure that the LCD is available */ - putreg32(1, PIC32MX_PMP_ADDRCLR); + lcd_waitbusy(); - /* And write the command to the data out register */ + /* Select DB0-15 as outputs (only DB-0-7 are actually used) */ - putreg32((uint32_t)cmd, PIC32MX_PMP_DOUT); + putreg16(0, PIC32MX_IOPORTE_TRIS); + + /* Set up to write the commond */ + + pic32mx_gpiowrite(GPIO_LCD_RS, false); /* Select command */ + pic32mx_gpiowrite(GPIO_LCD_RW, false); /* Select write */ + lcd_shortdelay(2); + + pic32mx_gpiowrite(GPIO_LCD_E, true); /* Enable transfer */ + lcd_shortdelay(1); + + /* Write the command to the LCD */ + + putreg16(cmd, PIC32MX_IOPORTE_PORT); + lcd_shortdelay(1); + pic32mx_gpiowrite(GPIO_LCD_E, false); } /**************************************************************************** @@ -341,13 +416,28 @@ static void lcd_wrcommand(uint8_t cmd) static void lcd_wrdata(uint8_t data) { - /* Address bit A0 is RS. Set the address latch to A0=1 */ + /* Make sure that the LCD is available */ - putreg32(1, PIC32MX_PMP_ADDRSET); + lcd_waitbusy(); - /* And write the data to the data out register */ + /* Select DB0-15 as outputs (only DB-0-7 are actually used) */ - putreg32((uint32_t)data, PIC32MX_PMP_DOUT); + putreg16(0, PIC32MX_IOPORTE_TRIS); + + /* Set up to write the data */ + + pic32mx_gpiowrite(GPIO_LCD_RS, true); /* Select data */ + pic32mx_gpiowrite(GPIO_LCD_RW, false); /* Select write */ + lcd_shortdelay(2); + + pic32mx_gpiowrite(GPIO_LCD_E, true); /* Enable transfer */ + lcd_shortdelay(1); + + /* Write the data to the LCD */ + + putreg16(data, PIC32MX_IOPORTE_PORT); /* Write the data */ + lcd_shortdelay(1); + pic32mx_gpiowrite(GPIO_LCD_E, false); } /**************************************************************************** @@ -360,13 +450,69 @@ static void lcd_wrdata(uint8_t data) static uint8_t lcd_rddata(void) { - /* Address bit A0 is RS. Set the address latch to A0=1 */ + /* Make sure that the LCD is available */ - putreg32(1, PIC32MX_PMP_ADDRSET); + lcd_waitbusy(); - /* And read the data to the data in register */ + /* Setup to read data */ - return (uint8_t)getreg32(PIC32MX_PMP_DIN); + pic32mx_gpiowrite(GPIO_LCD_RS, true); /* Select data */ + pic32mx_gpiowrite(GPIO_LCD_RW, true); /* Select read */ + lcd_shortdelay(2); + + pic32mx_gpiowrite(GPIO_LCD_E, true); /* Enable transfer */ + lcd_shortdelay(1); + + putreg16(0xff, PIC32MX_IOPORTE_TRISSET); /* Set DB0-7 as inputs */ + pic32mx_gpiowrite(GPIO_LCD_E, false); /* Disable transfer */ + + /* Read the data from the LCD */ + + return (uint8_t)getreg16(PIC32MX_IOPORTE_PORT); +} + +/**************************************************************************** + * Name: lcd_readstatus + * + * Description: + * Read the DDRAM address and busy bit. + * + ****************************************************************************/ + +static uint8_t lcd_readstatus(void) +{ + uint8_t status; + + /* Set up to read BUSY/AD information */ + + putreg16(0xff, PIC32MX_IOPORTE_TRISSET); /* Set DB0-7 as inputs */ + pic32mx_gpiowrite(GPIO_LCD_RS, false); /* Select command */ + pic32mx_gpiowrite(GPIO_LCD_RW, true); /* Select read */ + lcd_shortdelay(2); + + pic32mx_gpiowrite(GPIO_LCD_E, true); /* Enable transfer */ + lcd_shortdelay(1); + + /* Read the status from the LCD */ + + status = (uint8_t)getreg16(PIC32MX_IOPORTE_PORT); + lcd_shortdelay(1); + pic32mx_gpiowrite(GPIO_LCD_E, false); + + return status; +} + +/**************************************************************************** + * Name: lcd_waitbusy + * + * Description: + * Check LCD status and wait until the BUSY flag is no long set. + * + ****************************************************************************/ + +static void lcd_waitbusy(void) +{ + while ((lcd_readstatus() & HD4478OU_BF) != 0); } /**************************************************************************** @@ -843,11 +989,46 @@ static int lcd_ioctl(FAR struct file *filp, int cmd, unsigned long arg) } break; + /* SLCDIOC_GETBRIGHTNESS: Get the current brightness setting + * + * argument: Pointer type int that will receive the current brightness + * setting + */ + + case SLCDIOC_GETBRIGHTNESS: + { + FAR int *brightness = (FAR int *)((uintptr_t)arg); + if (!brightness) + { + return -EINVAL; + } + + *brightness = (int)g_lcd1602.brightness; + lcdvdbg("SLCDIOC_GETCONTRAST: brightness=%d\n", *brightness); + } + break; + + /* SLCDIOC_SETBRIGHTNESS: Set the brightness to a new value + * + * argument: The new brightness value + */ + + case SLCDIOC_SETBRIGHTNESS: + { + lcdvdbg("SLCDIOC_SETCONTRAST: arg=%ld\n", arg); + + if (arg > CONFIG_LCD_MAXPOWER) + { + return -ERANGE; + } + + lcd_brightness((uint8_t)arg); + } + break; + case SLCDIOC_SETBAR: /* SLCDIOC_SETBAR: Set bars on a bar display */ case SLCDIOC_GETCONTRAST: /* SLCDIOC_GETCONTRAST: Get the current contrast setting */ case SLCDIOC_SETCONTRAST: /* SLCDIOC_SETCONTRAST: Set the contrast to a new value */ - case SLCDIOC_GETBRIGHTNESS: /* Get the current brightness setting */ - case SLCDIOC_SETBRIGHTNESS: /* Set the brightness to a new value */ default: return -ENOTTY; } @@ -892,7 +1073,6 @@ static int lcd_poll(FAR struct file *filp, FAR struct pollfd *fds, int up_lcd1602_initialize(void) { - uint32_t regval; int ret = OK; /* Only initialize the driver once. */ @@ -901,64 +1081,69 @@ int up_lcd1602_initialize(void) { lcdvdbg("Initializing\n"); - /* PMP Master mode configuration */ - /* Make sure that interrupts are disabled */ + /* Configure GPIO pins */ - putreg32(INT_PMP, PIC32MX_INT_IEC1CLR); + putreg16(0, PIC32MX_IOPORTE_TRIS); /* Set DB0-15 as outputs */ + pic32mx_configgpio(GPIO_LCD_RS); /* RS: Selects commnand or data */ + pic32mx_configgpio(GPIO_LCD_RW); /* RW: Selects read or write */ + pic32mx_configgpio(GPIO_LCD_E); /* E: Starts transfer */ - /* Stop and reset the PMP module and clear the mode and control registers. */ + /* Configure LCD power in the OFF state */ - putreg32(0, PIC32MX_PMP_MODE); - putreg32(0, PIC32MX_PMP_AEN); - putreg32(0, PIC32MX_PMP_CON); - putreg32(0, PIC32MX_PMP_ADDR); + pic32mx_configgpio(GPIO_LCD_LIGHT); /* K */ + pic32mx_configgpio(GPIO_LCD_COMP); /* Vo */ + pic32mx_configgpio(GPIO_LCD_PWR); /* Vbuson/AN5/RB5 controls +5V USB */ + g_lcd1602.brightness = 0; /* Remember tht the light is off */ - /* Set LCD timing values, PMP master mode 3, 8-bit mode, no address - * increment, and no interrupts. + /* A small delay is necessary between when GPIO_LCD_E was set up as an + * output with initial value of 0 and this operation. That delay should + * be well covered by the intervening GPIO configurations. */ - regval = (PMP_MODE_WAITE_RD(0) | PMP_MODE_WAITM(3) | PMP_MODE_WAITB_1TPB | - PMP_MODE_MODE_MODE1 | PMP_MODE_MODE8 | PMP_MODE_INCM_NONE | - PMP_MODE_IRQM_NONE); - putreg32(regval, PIC32MX_PMP_MODE); - - /* Enable the PMP for reading and writing - * PMRD/PMWR is active high (1=RD; 0=WR) - * PMENB is active high. - * No chip selects - * Address latch is active high - * Enable PMRD/PMWR, PMENB, and the PMP. - */ - - - regval = (PMP_CON_RDSP | PMP_CON_WRSP | PMP_CON_ALP | - PMP_CON_CSF_ADDR1415 | PMP_CON_PTRDEN | PMP_CON_PTWREN | - PMP_CON_ADRMUX_NONE | PMP_CON_ON); - putreg32(regval, PIC32MX_PMP_CON); + pic32mx_gpiowrite(GPIO_LCD_E, true); /* Enable transfer */ /* Configure and enable the LCD */ - /* Wait > 15 milliseconds afer Vdd > 4.5V */ + /* Delay for 4.1MS or more */ - up_mdelay(100); + up_mdelay(5); /* Select the 8-bit interface. BF cannot be checked before this command. * This needs to be done a few times with some magic delays. + * + * Function set: 5x7 Style | N=2R | DL=8D */ - lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_DL8D | HD4478OU_FUNC_N1); - up_mdelay(50); - lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_DL8D | HD4478OU_FUNC_N1); - up_udelay(50); - lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_DL8D | HD4478OU_FUNC_N1); - lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_DL8D | HD4478OU_FUNC_N1); + lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_F5x7 | HD4478OU_FUNC_N1 | HD4478OU_FUNC_DL8D); + up_udelay(100); /* Delay more than 100uS */ - /* Configure the display */ + lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_F5x7 | HD4478OU_FUNC_N1 | HD4478OU_FUNC_DL8D); + up_udelay(40); /* Delay more than 40uS */ + lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_F5x7 | HD4478OU_FUNC_N1 | HD4478OU_FUNC_DL8D); + lcd_waitbusy(); - lcd_wrcommand(HD4478OU_DISPLAY); /* Display, cursor, and blink off */ - lcd_wrcommand(HD4478OU_CLEAR); /* Clear the display */ - lcd_wrcommand(HD4478OU_INPUT | HD4478OU_INPUT_INCR); /* Increment mode */ - lcd_wrcommand(HD4478OU_DISPLAY | HD4478OU_DISPLAY_ON); /* Display on, cursor and blink off */ - lcd_wrcommand(HD4478OU_DDRAM_AD(0)); /* Select DDRAM RAM AD=0 */ + lcd_wrcommand(HD4478OU_FUNC | HD4478OU_FUNC_F5x7 | HD4478OU_FUNC_N1 | HD4478OU_FUNC_DL8D); + lcd_waitbusy(); + + /* Display ON, cursor OFF, blink OFF */ + + lcd_wrcommand(HD4478OU_DISPLAY | HD4478OU_DISPLAY_ON); + lcd_waitbusy(); + + /* Clear the display and home the cursor */ + + lcd_wrcommand(HD4478OU_CLEAR); /* Clear display */ + lcd_waitbusy(); + + lcd_wrcommand(HD4478OU_RETURN); /* Return home: AC=0 */ + lcd_waitbusy(); + + /* Entry Mode Set: + * + * - Increment address by one, + * - Shift cursor to right (display is not shifted) + */ + + lcd_wrcommand(HD4478OU_INPUT | HD4478OU_INPUT_INCR); /* Register the LCD device driver */ diff --git a/configs/sure-pic32mx/src/sure-pic32mx.h b/configs/sure-pic32mx/src/sure-pic32mx.h index 1d2be66ebf..f33b6e9267 100644 --- a/configs/sure-pic32mx/src/sure-pic32mx.h +++ b/configs/sure-pic32mx/src/sure-pic32mx.h @@ -47,6 +47,7 @@ ****************************************************************************/ /* Configuration ************************************************************/ +/* GPIO Pin Configurations **************************************************/ /* The Sure PIC32MX board has five LEDs. One (D4, lablel "Power") is not * controllable by software. Four are controllable by software: * @@ -54,8 +55,58 @@ * D8 "SD" Yellow RD6 Low illuminates * D9 "Flash" Yellow RF0 Low illuminates * D10 "Error" Red RF1 Low illuminates + * */ +#define GPIO_USB_LED (GPIO_OUTPUT | GPIO_VALUE_ONE | GPIO_PORTD | GPIO_PIN7) +#define GPIO_SD_LED (GPIO_OUTPUT | GPIO_VALUE_ONE | GPIO_PORTD | GPIO_PIN6) +#define GPIO_FLASH_LED (GPIO_OUTPUT | GPIO_VALUE_ONE | GPIO_PORTF | GPIO_PIN0) +#define GPIO_ERROR_LED (GPIO_OUTPUT | GPIO_VALUE_ONE | GPIO_PORTF | GPIO_PIN1) + + /* LCD pin mapping (see configs/sure-pic32mx/README.txt) + * + * --------------------- ---------- ---------------------------------- + * PIC32 Sure JP1 Sure Signal Description + * PIN SIGNAL NAME PIN NAME(s) + * --------------------- ---------- ---------------------------------- + * 34 Vbus 1. +5V +5V VBUS device mode + * To GND via capacitor + * 2. GND GND + * 49 RD1 3. Vo Transistor circuit driven by PWM2 + * 44 PMA0/AN15/RB15 4. RS PMA0, Selects registers + * 53 PMRD/RD5 5. RW PMRD/PMWR, Selects read or write + * 45 PMPCS1/RD11 6. E Starts data read/write + * 60 PMD0/RE0 7. DB0 PMD0 + * 61 PMD1/RE1 8. DB1 PMD1 + * 62 PMD2/RE2 9. DB2 PMD2 + * 63 PMD3/RE3 10. DB3 PMD3 + * 64 PMD4/RE4 11. DB4 PMD4 + * 1 PMD5/RE5 12. DB5 PMD5 + * 2 PMD6/RE6 13. DB6 PMD6 + * 3 PMD7/RE7 14. DB7 PMD7 + * 15. A +5V_DUSB + * 46 INT0/RD0 16. K Transistor circuit driven by PWM1 + * --------------------- ---------- ---------------------------------- + * + * Vbus power also requires Vbuson/AN5/RB5 + */ + +#define GPIO_LCD_RS (GPIO_OUTPUT | GPIO_VALUE_ZERO | GPIO_PORTB | GPIO_PIN15) +#define GPIO_LCD_RW (GPIO_OUTPUT | GPIO_VALUE_ZERO | GPIO_PORTD | GPIO_PIN5) +#define GPIO_LCD_E (GPIO_OUTPUT | GPIO_VALUE_ZERO | GPIO_PORTD | GPIO_PIN11) + +/* This pin drives the +5V needed by the LCD */ + +#define GPIO_LCD_PWR (GPIO_OUTPUT | GPIO_VALUE_ZERO | GPIO_PORTB | GPIO_PIN5) + +/* These pins are label PWM1 and PWM2 and so are obviously intended to + * support modulated outputs. However, here for simplicity, they are + * just treated as on/off discretes outputs. + */ + +#define GPIO_LCD_LIGHT (GPIO_OUTPUT | GPIO_VALUE_ZERO | GPIO_PORTD | GPIO_PIN0) +#define GPIO_LCD_COMP (GPIO_OUTPUT | GPIO_VALUE_ZERO | GPIO_PORTD | GPIO_PIN1) + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/configs/sure-pic32mx/usbnsh/Make.defs b/configs/sure-pic32mx/usbnsh/Make.defs index 79c47842ec..04224901fb 100644 --- a/configs/sure-pic32mx/usbnsh/Make.defs +++ b/configs/sure-pic32mx/usbnsh/Make.defs @@ -46,7 +46,7 @@ ifeq ($(WINTOOL),y) ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}" ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/ld.script}" else - # Linux/Cygwin-native toolchain + # Linux/Cygwin-native toolchain MKDEP = $(TOPDIR)/tools/mkdeps.sh ARCHINCLUDES = -I. -isystem $(TOPDIR)/include ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx diff --git a/drivers/lcd/Kconfig b/drivers/lcd/Kconfig index 7673ed5d15..7f08712013 100644 --- a/drivers/lcd/Kconfig +++ b/drivers/lcd/Kconfig @@ -32,6 +32,7 @@ config LCD_MAXCONTRAST config LCD_MAXPOWER int "LCD maximum power" + default 255 if LCD_LCD1602 default 1 range 1 255 ---help--- @@ -91,7 +92,7 @@ config P14201_FRAMEBUFFER endif config LCD_NOKIA6100 - bool "Nokia 6100 display support" + bool "Nokia 6100 display support" default n ---help--- nokia6100.c. Supports the Nokia 6100 display with either the Philips @@ -307,7 +308,7 @@ config LCD_UG2864AMBAG01 bool "UG-2864AMBAG01 OLED Display Module" default n ---help--- - OLED Display Module, UG-2864AMBAG01, Univision Technology Inc. + OLED Display Module, UG-2864AMBAG01, Univision Technology Inc. Required LCD driver settings: LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted. diff --git a/include/nuttx/lcd/hd4478ou.h b/include/nuttx/lcd/hd4478ou.h index 7f969379d3..38fa38e7cb 100644 --- a/include/nuttx/lcd/hd4478ou.h +++ b/include/nuttx/lcd/hd4478ou.h @@ -51,7 +51,7 @@ */ #define HD4478OU_CLEAR (0x01) /* Screen Clear, Set AC to 0 */ -#define HD4478OU_RETURN (0x02) /* DDRAM AD=0, return */ +#define HD4478OU_RETURN (0x03) /* DDRAM AD=0, return */ #define HD4478OU_INPUT (0x04) /* Set moving direction of cursor */ # define HD4478OU_INPUT_SHIFT (1 << 0) /* Shift */ # define HD4478OU_INPUT_INCR (1 << 1) /* Increment mode */ @@ -65,7 +65,7 @@ # define HD4478OU_SHIFT_LEFT (0x00) /* Shift right */ # define HD4478OU_SHIFT_DISPLAY (1 << 3) /* Display shift */ # define HD4478OU_SHIFT_CURSOR (0x00) /* Cursor shift */ -#define HD4478OU_FUNC (0x20) /* Set DL, display line, font */ +#define HD4478OU_FUNC (0x23) /* Set DL, display line, font */ # define HD4478OU_FUNC_F5x10 (1 << 2) /* 5x10 Style */ # define HD4478OU_FUNC_F5x7 (0x00) /* 5x7 Style */ # define HD4478OU_FUNC_N1 (1 << 3) /* N=2R */ @@ -77,7 +77,9 @@ /* RS=0 R/W=1 : Execute internal function, read AD of CT */ -#define HD4478OU_BUSY(bf,ac) ((bf) << 7 | (ac)) +#define HD4478OU_BF (1 << 7) /* Busy flag */ +#define HD4478OU_AC_SHIFT (0) /* AD of CT */ +#define HD4478OU_AC_MASK (0x7f << HD4478OU_BUSY_AC_SHIFT) /* DDRAM Addressing. *