mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
On our way to LTDC support
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user