# For more options and information see
# http://www.raspberrypi.org/documentation/configuration/config-txt.md
# Some settings may impact device functionality. See link above for details
# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1
# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
#disable_overscan=1
# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16
# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720
# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1
# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1
# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2
# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4
# uncomment for composite PAL
#sdtv_mode=2
#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800
# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi
# Additional overlays and parameters are documented /boot/overlays/README
# Enable audio (loads snd_bcm2835)
#dtparam=audio=on
# Disable spi and i2c, we need these pins.
dtparam=spi=off
dtparam=i2c_arm=off
# This is the bit for the display
dtoverlay=dpi18
overscan_left=0
overscan_right=0
overscan_top=0
overscan_bottom=0
framebuffer_width=320
framebuffer_height=240
enable_dpi_lcd=1
display_default_lcd=1
dpi_group=2
dpi_mode=87
dpi_output_format=3605013
hdmi_timings=240 0 20 10 10 320 0 6 2 0 0 0 0 60 0 6400000 6
display_rotate=0x10003
/plugin/;
/{
compatible = "brcm,bcm2708";
// There is no DPI driver module, but we need a platform device
// node (that doesn't already use pinctrl) to hang the pinctrl
// reference on - leds will do
fragment@0 {
target = <&leds>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <&dpi18_pins>;
};
};
fragment@1 {
target = <&gpio>;
__overlay__ {
dpi18_pins: dpi18_pins {
brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11
12 13 14 15 16 17 18 19 20
21>;
brcm,function = <6>; /* alt2 */
brcm,pull = <0>; /* no pull */
};
};
};
};
#include <msp430.h>
#include <stdint.h>
#define CSDIR P1DIR
#define CSOUT P1OUT
#define CSIN P1IN
#define CSPIN BIT7
#define SCLDIR P1DIR
#define SCLOUT P1OUT
#define SCLIN P1IN
#define SCLPIN BIT6
#define SDADIR P1DIR
#define SDAOUT P1OUT
#define SDAIN P1IN
#define SDAPIN BIT5
void il9341_init()
{
CSDIR |= CSPIN;
SCLDIR |= SCLPIN;
SDADIR |= SDAPIN;
CSOUT |= CSPIN;
SCLOUT &= ~SCLPIN;
SDAOUT &= ~SDAPIN;
}
#define DELAY __delay_cycles(5)
// Write a word + DC bit
void il9341_write8_internal(int command, uint8_t b)
{
if(command != 0)
SDAOUT &= ~SDAPIN;
else
SDAOUT |= SDAPIN;
DELAY;
SCLOUT |= SCLPIN;
DELAY;
SCLOUT &= ~SCLPIN;
int i;
for(i = 7; i >= 0; i--)
{
if(b & (1 << i))
{
SDAOUT |= SDAPIN;
}
else
{
SDAOUT &= ~SDAPIN;
}
DELAY;
SCLOUT |= SCLPIN;
DELAY;
SCLOUT &= ~SCLPIN;
}
}
uint8_t il9341_read8_internal()
{
uint8_t value = 0;
int i;
for(i = 7; i >= 0; i--)
{
DELAY;
if(SDAIN & SDAPIN)
value |= (1 << i);
SCLOUT |= SCLPIN;
DELAY;
SCLOUT &= ~SCLPIN;
}
return value;
}
uint8_t il9341_read8(uint8_t command)
{
// Reset clock before enabling LCD interface
SCLOUT &= ~SCLPIN;
CSOUT &= ~CSPIN;
// Switch to write
SDADIR |= SDAPIN;
il9341_write8_internal(1, command);
// Switch to read
SDADIR &= ~SDAPIN;
uint8_t value = il9341_read8_internal();
// Disable LCD interface
CSOUT |= CSPIN;
return value;
}
uint32_t il9341_read24(uint8_t command)
{
// Reset clock before enabling LCD interface
SCLOUT &= ~SCLPIN;
CSOUT &= ~CSPIN;
// Switch to write
SDADIR |= SDAPIN;
il9341_write8_internal(1, command);
// Dummy clock cycle
DELAY;
SCLOUT |= SCLPIN;
DELAY;
SCLOUT &= ~SCLPIN;
// Switch to read
SDADIR &= ~SDAPIN;
uint32_t value = il9341_read8_internal() << 16;
value |= il9341_read8_internal() << 8;
value |= il9341_read8_internal();
// Disable LCD interface
CSOUT |= CSPIN;
return value;
}
uint32_t il9341_read32(uint8_t command)
{
// Reset clock before enabling LCD interface
SCLOUT &= ~SCLPIN;
CSOUT &= ~CSPIN;
// Switch to write
SDADIR |= SDAPIN;
il9341_write8_internal(1, command);
// Dummy clock cycle
DELAY;
SCLOUT |= SCLPIN;
DELAY;
SCLOUT &= ~SCLPIN;
// Switch to read
SDADIR &= ~SDAPIN;
uint32_t v[4];
v[3] = il9341_read8_internal();
v[2] = il9341_read8_internal();
v[1] = il9341_read8_internal();
v[0] = il9341_read8_internal();
// Disable LCD interface
CSOUT |= CSPIN;
return *(uint32_t *)v;
}
void il9341_write(uint8_t command, uint8_t *data, int num)
{
// Reset clock before enabling LCD interface
SCLOUT &= ~SCLPIN;
CSOUT &= ~CSPIN;
// Switch to write
SDADIR |= SDAPIN;
il9341_write8_internal(1, command);
int i;
for(i = 0; i < num; i++)
il9341_write8_internal(0, data[i]);
// Disable LCD interface
CSOUT |= CSPIN;
}
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= 0x01; // Set P1.0 to output direction
il9341_init();
il9341_write(0x01, (void*)0, 0);
__delay_cycles(120000);
il9341_write(0x28, (void*)0, 0);
il9341_write(0xB0, (uint8_t[]){0b11100000}, 1);
il9341_write(0x3A, (uint8_t[]){0b01100110}, 1);
il9341_write(0xF6, (uint8_t[]){0b00001001, 0b00100001, 0b00000110}, 3);
il9341_write(0xB5, (uint8_t[]){0b00000100, 0b00000010, 0b00001010, 0b00010100}, 4);
il9341_write(0xB6, (uint8_t[]){0x0A, 0x82, 0x27, 0x05}, 4);
il9341_write(0x51, (uint8_t[]){0}, 1);
il9341_write(0x11, (void*)0, 0);
il9341_write(0x29, (void*)0, 0);
for(;;);
}
- Modify the config.txt to have the display settings above
- Hook up the display to the Raspberry Pi, ignore the display enable pin. You will need the full RGB18 interface + vsync, hsync and pclk.
- Compile the overlay using the dtc (should have packages for most Linux distros), make sure you compile as an overlay. Put it in overlays on the SD card.
- Use something to configure the display, you should be able to use the Raspberry Pi, but I used an MSP430 Launchpad with the code above. The config interface depends upon the config pins on the ILI9341 chip.
The display module used MUST be configured for the RGB interface, not SPI or the 8080 interface. IM pins in the ILI9341 datasheet.
Different controllers/resolutions will mean you need to tweak the configuration code and the DPI settings in the config.txt , this should work with any ILI9341 display though.
Let’s add a dirt cheap screen to the Raspberry Pi B+ - Same interface, different screen
DPI pinout - Useful to find where the pins are on the GPIO header (less useful for the compute module)
Compatible display - Has a controller and module datasheet easily avaliable, gives all the pins needed, handles the LCD backlight voltage. Bit more expensive than the eBay panels but most of those will not work. NOTE: Ask for the display with the RGB interface (send an email) and you probably want pin headers, not the flat flex connector. Make sure you get the 3.3V option.
Question, once the display is set to rgb mode using SPI, can the setting be saved to eeprom of the display? Or do I need to set the mode after each power up.
When I ask for an rgb version, will the mode RGB by default?
Thanks,
W