On our way to LTDC support

This commit is contained in:
Romain Goyet
2015-05-09 22:06:26 +02:00
parent a646d30b26
commit 3986953524
4 changed files with 117 additions and 53 deletions

View File

@@ -17,7 +17,9 @@ enum {
DISPON = 0x29, // Display on
RAMWR = 0x2C, // Memory write
PIXSET = 0x3A, // Pixel format set
FRMCTR1 = 0xB1A // Frame rate control in normal/full-color mode
IFMODE = 0xB0, // RGB interface signal control
FRMCTR1 = 0xB1, // Frame rate control in normal/full-color mode
IFCTL = 0xF6 // Interface control
};
typedef struct {
@@ -47,6 +49,11 @@ static instruction_t initialisation_sequence[] = {
//FIXME
// Display
// RGB Interface mode //FIXME: explain
COMMAND(IFMODE), DATA(0xC0),
COMMAND(IFCTL), DATA(0x01), DATA(0x00), DATA(0x06),
// Entry mode set, skipped
COMMAND(SLPOUT), DELAY(100),
@@ -66,7 +73,7 @@ void perform_instruction(ili9341_t * c, instruction_t * instruction) {
}
}
void ili9341_initialize(ili9341_t * c) {
void ili9341_initialize(ili9341_t * c, bool rgb) {
// Falling edge on CSX
c->chip_select_pin_write(0);
@@ -76,7 +83,7 @@ void ili9341_initialize(ili9341_t * c) {
perform_instruction(c, instruction++);
}
#define FILL_SCREEN_UPON_INIT 0
#define FILL_SCREEN_UPON_INIT 1
#if FILL_SCREEN_UPON_INIT
// This would draw stuff on the screen

View File

@@ -14,6 +14,6 @@ typedef struct {
void (*spi_write)(char * data, size_t size);
} ili9341_t;
void ili9341_initialize(ili9341_t * controller);
void ili9341_initialize(ili9341_t * controller, bool enable_rgb_interface);
void ili9341_set_gamma(ili9341_t * controller);
#endif

View File

@@ -91,11 +91,16 @@ static void init_spi_port() {
static void init_rgb_gpios();
static void init_rgb_clocks();
static void init_rgb_timings();
//static void init_rgb_layers();
static void init_rgb_interface() {
init_rgb_gpios();
init_rgb_clocks();
init_rgb_timings();
// init_rgb_layers();
// Now let's actually enable the LTDC
LTDC_GCR |= LTDC_LTDCEN;
}
struct gpio_pin {
@@ -229,10 +234,17 @@ static void init_rgb_timings() {
LTDC_GCR = LTDC_LTDCEN;
// Not setting the "Active low" bits since they are 0 by default, which we want
// Same for the pixel clock, we don't want it inverted
/*
}
static void init_rgb_layers() {
#if 0
*/
/* STEP 7: Configure the Layer1/2 parameters by programming:
The Layer window horizontal and vertical position in the LTDC_LxWHPCR and LTDC_WVPCR registers. The layer window must be in the active data area.
The pixel input format in the LTDC_LxPFCR register
@@ -243,52 +255,34 @@ static void init_rgb_layers() {
If needed, configure the default color and the blending factors respectively in the LTDC_LxDCCR and LTDC_LxBFCR registers
*/
long * LTDC_L1WHPCR = (long *)(LCD_TFT_BASE + 0x88); // Window horizontal position config
*LTDC_L1WHPCR = set_bits(*LTDC_L1WHPCR, 11, 0, lcd_panel_hsync+lcd_panel_hbp);
*LTDC_L1WHPCR = set_bits(*LTDC_L1WHPCR, 27, 16, lcd_panel_hsync+lcd_panel_hbp+lcd_panel_hadr);
LTDC_LWHPCR(LTDC_LAYER1) =
LTDC_WHSTPOS(lcd_panel_hsync+lcd_panel_hbp) |
LTDC_WHSPPOS(lcd_panel_hsync+lcd_panel_hbp+lcd_panel_hadr);
long * LTDC_L1WVPCR = (long *)(LCD_TFT_BASE + 0x8C); // Window vertical position config
*LTDC_L1WVPCR = set_bits(*LTDC_L1WVPCR, 11, 0, lcd_panel_vsync+lcd_panel_vbp);
*LTDC_L1WVPCR = set_bits(*LTDC_L1WVPCR, 27, 16, lcd_panel_vsync+lcd_panel_vbp+lcd_panel_vadr);
LTDC_LWVPCR(LTDC_LAYER1) =
LTDC_WVSTPOS(lcd_panel_vsync+lcd_panel_vbp) |
LTDC_WVSPPOS(lcd_panel_vsync+lcd_panel_vbp+lcd_panel_vadr);
long * LTDC_L1PFCR = (long *)(LCD_TFT_BASE + 0x94); // Frame buffer pixel format
*LTDC_L1PFCR = set_bits(*LTDC_L1PFCR, 2, 0, 0x0); // 0x0 = ARGB8888
LTDC_LPFCR(LTDC_LAYER1) = LTDC_PF_ARGB8888;
long * LTDC_L1CFBAR = (long *)(LCD_TFT_BASE + 0xAC); // Frame buffer address
*LTDC_L1CFBAR = 0x2000000;
// long * LTDC_L1CFBAR = (long *)(LCD_TFT_BASE + 0xAC); // Frame buffer address
// *LTDC_L1CFBAR = 0x2000000;
long * LTDC_L1CFBLR = (long *)(LCD_TFT_BASE + 0xB0); // Frame buffer length
*LTDC_L1CFBLR = set_bits(*LTDC_L1CFBLR, 28, 16, 960); // Number of bytes per lines in the framebuffer. 240 * 4 (RGBA888)
*LTDC_L1CFBLR = set_bits(*LTDC_L1CFBLR, 12, 0, 963); // The doc says "length + 3". Here goes...
LTDC_LCFBLR(LTDC_LAYER1) =
LTDC_CFBLL(963) | // Number of bytes per lines in the framebuffer. 240 * 4 (RGBA888)
LTDC_CFBP(960); // The doc says "length + 3". Here goes...
long * LTDC_L1CFBLNR = (long *)(LCD_TFT_BASE + 0xB4);
*LTDC_L1CFBLNR = set_bits(*LTDC_L1CFBLNR, 10, 0, 320); // Number of lines
/*
long * LTDC_L2WHPCR = (long *)(LCD_TFT_BASE + 0x108);
*LTDC_L2WHPCR = set_bits(*LTDC_L2WHPCR, 11, 0, lcd_panel_hsync+lcd_panel_hbp);
*LTDC_L2WHPCR = set_bits(*LTDC_L2WHPCR, 27, 16, lcd_panel_hsync+lcd_panel_hbp+lcd_panel_hadr);
long * LTDC_L2WWPCR = (long *)(LCD_TFT_BASE + 0x10C);
*LTDC_L2WVPCR = set_bits(*LTDC_L2WVPCR, 11, 0, lcd_panel_vsync+lcd_panel_vbp);
*LTDC_L2WVPCR = set_bits(*LTDC_L2WVPCR, 27, 16, lcd_panel_vsync+lcd_panel_vbp+lcd_panel_vadr);
long * LTDC_L2PFCR = (long *)(LCD_TFT_BASE + 0x114);
long * LTDC_L2CFBAR = (long *)(LCD_TFT_BASE + 0x12C);
long * LTDC_L2CFBLNR = (long *)(LCD_TFT_BASE + 0x134);
long * LTDC_L2CR = (long *)(LCD_TFT_BASE + 0x104);
*/
LTDC_LCFBLNR(LTDC_LAYER1) = LTDC_CFBLNR(320); // Number of lines
// STEP 8 : Enable layer 1
long * LTDC_L1CR = (long *)(LCD_TFT_BASE + 0x84);
*LTDC_L1CR = set_bits(*LTDC_L1CR, 4, 4, 0x0); // bit 4 = CLUTEN: Disable color look-up table
*LTDC_L1CR = set_bits(*LTDC_L1CR, 1, 1, 0x0); // bit 1 = COLKEN: Color keying, disabledd
*LTDC_L1CR = set_bits(*LTDC_L1CR, 0, 0, 0x1); // bit 1 = LEN, LayerENable: Enable
// Don't enable color keying nor color look-up table
LTDC_LCR(LTDC_LAYER1) = LTDC_LEN;
// STEP 9 : If needed, enable color keing and dithering
// STEP 10: Reload the shadow register
long * LTDC_SRCR = (long *)(LCD_TFT_BASE + 0x24);
*LTDC_SRCR = set_bits(*LTDC_SRCR, 1, 1, 0x1); // Ask for reload on next VBLANK
#endif
// Ask for immediate reload
LTDC_SRCR = LTDC_IMR;
}
// Panel
@@ -304,7 +298,7 @@ static ili9341_t panel = {
};
static void init_panel() {
ili9341_initialize(&panel);
ili9341_initialize(&panel, 1);
}
static void spi_5_write(char * data, size_t size) {

View File

@@ -5,7 +5,11 @@
#define LTDC_BASE 0x40016800
#define LTDC_LAYER1 0
#define LTDC_LAYER2 1
#define LTDC_REGISTER_AT(offset) (*(volatile uint32_t *)(LTDC_BASE+offset))
#define LTDC_LAYER_REGISTER_AT(layer, offset) LTDC_REGISTER_AT(offset+(0x80*layer))
// LTDC synchronization size configuration register
@@ -13,10 +17,10 @@
#define LOW_BIT_VSH 0
#define HIGH_BIT_VSH 10
#define LTDC_VSH(v) REGISTER_FIELD_VALUE(VSH, v)
#define LTDC_VSH(v) REGISTER_FIELD_VALUE(VSH,v)
#define LOW_BIT_HSW 16
#define HIGH_BIT_HSW 27
#define LTDC_HSW(v) REGISTER_FIELD_VALUE(HSW, v)
#define LTDC_HSW(v) REGISTER_FIELD_VALUE(HSW,v)
// LTDC back porch configuration register
@@ -24,10 +28,10 @@
#define LOW_BIT_AVBP 0
#define HIGH_BIT_AVBP 10
#define LTDC_AVBP(v) REGISTER_FIELD_VALUE(AVBP, v)
#define LTDC_AVBP(v) REGISTER_FIELD_VALUE(AVBP,v)
#define LOW_BIT_AHBP 16
#define HIGH_BIT_AHBP 27
#define LTDC_AHBP(v) REGISTER_FIELD_VALUE(AHBP, v)
#define LTDC_AHBP(v) REGISTER_FIELD_VALUE(AHBP,v)
// LTDC active width configuration register
@@ -35,10 +39,10 @@
#define LOW_BIT_AAH 0
#define HIGH_BIT_AAH 10
#define LTDC_AAH(v) REGISTER_FIELD_VALUE(AAH, v)
#define LTDC_AAH(v) REGISTER_FIELD_VALUE(AAH,v)
#define LOW_BIT_AAW 16
#define HIGH_BIT_AAW 27
#define LTDC_AAW(v) REGISTER_FIELD_VALUE(AAW, v)
#define LTDC_AAW(v) REGISTER_FIELD_VALUE(AAW,v)
// LTDC total width configuration register
@@ -46,10 +50,10 @@
#define LOW_BIT_TOTALH 0
#define HIGH_BIT_TOTALH 10
#define LTDC_TOTALH(v) REGISTER_FIELD_VALUE(TOTALH, v)
#define LTDC_TOTALH(v) REGISTER_FIELD_VALUE(TOTALH,v)
#define LOW_BIT_TOTALW 16
#define HIGH_BIT_TOTALW 27
#define LTDC_TOTALW(v) REGISTER_FIELD_VALUE(TOTALW, v)
#define LTDC_TOTALW(v) REGISTER_FIELD_VALUE(TOTALW,v)
// LTDC global control register
@@ -75,17 +79,76 @@
#define LTDC_IMR (1<<0)
#define LTDC_VBR (1<<1)
// LTDC layer control register
#define LTDC_LAYER1 0
#define LTDC_LAYER2 1
// LTDC layer control registers
#define LTDC_LCR(layer) LTDC_REGISTER_AT(0x84+(0x80*layer))
#define LTDC_LCR(layer) LTDC_LAYER_REGISTER_AT(layer,0x84)
#define LTDC_LEN (1<<0)
#define LTDC_COLKEN (1<<1)
#define LTDC_CLUTEN (1<<4)
// LTDC layer window horizontal position configuration registers
#define LTDC_LWHPCR(layer) LTDC_LAYER_REGISTER_AT(layer,0x88)
#define LOW_BIT_LTDC_WHSTPOS 0
#define HIGH_BIT_LTDC_WHSTPOS 11
#define LTDC_WHSTPOS(v) REGISTER_FIELD_VALUE(LTDC_WHSTPOS,v)
#define LOW_BIT_LTDC_WHSPPOS 16
#define HIGH_BIT_LTDC_WHSPPOS 27
#define LTDC_WHSPPOS(v) REGISTER_FIELD_VALUE(LTDC_WHSPPOS,v)
// LTDC layer window vertical position configuration registers
#define LTDC_LWVPCR(layer) LTDC_LAYER_REGISTER_AT(layer,0x8C)
#define LOW_BIT_LTDC_WVSTPOS 0
#define HIGH_BIT_LTDC_WVSTPOS 11
#define LTDC_WVSTPOS(v) REGISTER_FIELD_VALUE(LTDC_WVSTPOS,v)
#define LOW_BIT_LTDC_WVSPPOS 16
#define HIGH_BIT_LTDC_WVSPPOS 27
#define LTDC_WVSPPOS(v) REGISTER_FIELD_VALUE(LTDC_WVSPPOS,v)
// LTDC layer pixel format configuration registers
#define LTDC_LPFCR(layer) LTDC_LAYER_REGISTER_AT(layer,0x88)
#define LTDC_PF_ARGB8888 0
#define LTDC_PF_RGB888 1
#define LTDC_PF_RGB565 2
#define LTDC_PF_ARGB1555 3
#define LTDC_PF_ARGB4444 4
#define LTDC_PF_L8 5
#define LTDC_PF_AL44 6
#define LTDC_PF_AL88 7
#define LOW_BIT_LTDC_PF 0
#define HIGH_BIT_LTDC_PF 2
// LTDC layer color frame buffer address registers
#define LTDC_LCFBAR(layer) LTDC_LAYER_REGISTER_AT(layer,0xAC)
// LTDC layer color frame buffer length registers
#define LTDC_LCFBLR(layer) LTDC_LAYER_REGISTER_AT(layer,0xB0)
#define LOW_BIT_LTDC_CFBLL 0
#define HIGH_BIT_LTDC_CFBLL 12
#define LTDC_CFBLL(v) REGISTER_FIELD_VALUE(LTDC_CFBLL,v)
#define LOW_BIT_LTDC_CFBP 16
#define HIGH_BIT_LTDC_CFBP 28
#define LTDC_CFBP(v) REGISTER_FIELD_VALUE(LTDC_CFBP,v)
// LTDC layer color frame buffer line registers
#define LTDC_LCFBLNR(layer) LTDC_LAYER_REGISTER_AT(layer,0xB4)
#define LOW_BIT_LTDC_CFBLNR 0
#define HIGH_BIT_LTDC_CFBLNR 10
#define LTDC_CFBLNR(v) REGISTER_FIELD_VALUE(LTDC_CFBLNR,v)
#if 0
typedef struct {