mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
Cleaner registers for stm32f429
This commit is contained in:
2
kandinsky/Makefile
Normal file
2
kandinsky/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
CFLAGS += -Ikandinsky/include
|
||||
objs += $(addprefix kandinsky/src/, line.o)
|
||||
7
kandinsky/include/kandinsky.h
Normal file
7
kandinsky/include/kandinsky.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef KANDINSKY_KANDINSKY_H
|
||||
#define KANDINSKY_KANDINSKY_H
|
||||
|
||||
#include <kandinsky/point.h>
|
||||
#include <kandinsky/line.h>
|
||||
|
||||
#endif
|
||||
8
kandinsky/include/kandinsky/line.h
Normal file
8
kandinsky/include/kandinsky/line.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef KANDINSKY_LINE_H
|
||||
#define KANDINSKY_LINE_H
|
||||
|
||||
#include <kandinsky/point.h>
|
||||
|
||||
void KDDrawLine(kdpoint_t * p1, kdpoint_t * p2);
|
||||
|
||||
#endif
|
||||
11
kandinsky/include/kandinsky/point.h
Normal file
11
kandinsky/include/kandinsky/point.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef KANDINSKY_POINT_H
|
||||
#define KANDINSKY_POINT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} kdpoint_t;
|
||||
|
||||
#endif
|
||||
7
kandinsky/src/framebuffer.h
Normal file
7
kandinsky/src/framebuffer.h
Normal file
@@ -0,0 +1,7 @@
|
||||
typedef uint8_t kdpixel_t;
|
||||
|
||||
#define FRAMEBUFFER_WIDTH 240
|
||||
#define FRAMEBUFFER_HEIGHT 320
|
||||
#define FRAMEBUFFER_ADDRESS (kdpixel_t *)(0x2001D400)
|
||||
|
||||
#define PIXEL(x,y) *(kdpixel_t *)(FRAMEBUFFER_ADDRESS + y*FRAMEBUFFER_WIDTH + x)
|
||||
8
kandinsky/src/line.c
Normal file
8
kandinsky/src/line.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <kandinsky/line.h>
|
||||
#include "framebuffer.h"
|
||||
|
||||
void KDDrawLine(kdpoint_t * p1, kdpoint_t * p2) {
|
||||
for (int i=0; i<10; i++) {
|
||||
PIXEL(i,i) = 0xFF;
|
||||
}
|
||||
}
|
||||
@@ -99,8 +99,6 @@ static void init_rgb_interface() {
|
||||
init_rgb_timings();
|
||||
// init_rgb_layers();
|
||||
|
||||
// Now let's actually enable the LTDC
|
||||
LTDC_GCR |= LTDC_LTDCEN;
|
||||
}
|
||||
|
||||
struct gpio_pin {
|
||||
@@ -157,20 +155,29 @@ static void init_rgb_clocks() {
|
||||
|
||||
// STEP 2 : Configure the required Pixel clock following the panel datasheet
|
||||
//
|
||||
// We're setting PLLSAIN = 192, PLLSAIR = 4, and PLLSAIDIVR = 0x2 meaning divide-by-8
|
||||
// So with a f(PLLSAI clock input) = 1MHz
|
||||
// we get f(VCO clock) = PLLSAIN * fPPLSAI = 192 MHz
|
||||
// and f(PLL LCD clock) = fVCO / PLLSAIR = 48 MHz
|
||||
// and eventually f(LCD_CLK) = fPLLLCD/8 = 6 MHz
|
||||
// The pixel clock derives from the PLLSAI clock through various multipliers/dividers.
|
||||
// Here is the exact sequence :
|
||||
// PXL = PLL_LCD/RCC_DCKCFGR.PLLSAIDIVR;
|
||||
// PLL_LCD = VCO/RCC_PLLSAICFGR.PLLSAIR;
|
||||
// VCO = PLLSAI * (RCC_PLLSAICFG.PLLSAIN / RCC_PLLCFGR.PLLM);
|
||||
// PLLSAI = HSE or HSI
|
||||
//
|
||||
// The multipliers have the following constraints :
|
||||
// 2 <= PLLM <= 63
|
||||
// 49 <= PLLSAIN <= 432
|
||||
// 2 <= PLLSAIR <= 7
|
||||
// 2 ≤ PLLSAIDIVR ≤ 16, (set as a power of two, use macro)
|
||||
//
|
||||
// By default, PLLSAI = HSI = 16MHz and RCC_PLLCFGR.PLLM = 16. This gives, in MHZ:
|
||||
// PXL = SAIN/(SAIR*SAIDIVR);
|
||||
//
|
||||
// // FIXME: Maybe make this calculation dynamic?
|
||||
// Per the panel doc, we want a clock of 6 MHz.
|
||||
// 6 = 192/(4*8), hence:
|
||||
|
||||
int pllsain = 192;
|
||||
int pllsair = 4;
|
||||
int pllsaidivr = 0x2; // This value means "divide by 8"
|
||||
//FIXME: A macro here
|
||||
|
||||
REGISTER_SET_VALUE(RCC_PLLSAICFGR, PLLSAIR, pllsair);
|
||||
REGISTER_SET_VALUE(RCC_PLLSAICFGR, PLLSAIN, pllsain);
|
||||
REGISTER_SET_VALUE(RCC_DCKCFGR, PLLSAIDIVR, pllsaidivr);
|
||||
REGISTER_SET_VALUE(RCC_PLLSAICFGR, PLLSAIN, 192);
|
||||
REGISTER_SET_VALUE(RCC_PLLSAICFGR, PLLSAIR, 4);
|
||||
REGISTER_SET_VALUE(RCC_DCKCFGR, PLLSAIDIVR, RCC_PLLSAIDIVR_DIV8);
|
||||
|
||||
// Now let's enable the PLL/PLLSAI clocks
|
||||
RCC_CR |= (PLLSAION | PLLON);
|
||||
@@ -204,6 +211,7 @@ static void init_rgb_timings() {
|
||||
/*- HSYNC and VSYNC Width: Horizontal and Vertical Synchronization width configured by
|
||||
programming a value of HSYNC Width - 1 and VSYNC Width - 1 in the LTDC_SSCR register. */
|
||||
|
||||
|
||||
LTDC_SSCR =
|
||||
LTDC_VSH(lcd_panel_vsync-1) |
|
||||
LTDC_HSW(lcd_panel_hsync-1);
|
||||
@@ -238,10 +246,13 @@ static void init_rgb_timings() {
|
||||
|
||||
/* STEP 4 : Configure the synchronous signals and clock polarity in the LTDC_GCR register */
|
||||
|
||||
LTDC_GCR = LTDC_LTDCEN;
|
||||
LTDC_GCR |= LTDC_PCPOL;
|
||||
|
||||
// FIXME: Later: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
|
||||
|
||||
LTDC_BCCR = 0x00FF00FF;
|
||||
|
||||
|
||||
/*
|
||||
@@ -264,15 +275,15 @@ static void init_rgb_layers() {
|
||||
|
||||
LTDC_LWHPCR(LTDC_LAYER1) =
|
||||
LTDC_WHSTPOS(lcd_panel_hsync+lcd_panel_hbp) |
|
||||
LTDC_WHSPPOS(lcd_panel_hsync+lcd_panel_hbp+lcd_panel_hadr);
|
||||
LTDC_WHSPPOS(lcd_panel_hsync+lcd_panel_hbp+lcd_panel_hadr-1); //FIXME: Why -1?
|
||||
|
||||
LTDC_LWVPCR(LTDC_LAYER1) =
|
||||
LTDC_WVSTPOS(lcd_panel_vsync+lcd_panel_vbp) |
|
||||
LTDC_WVSPPOS(lcd_panel_vsync+lcd_panel_vbp+lcd_panel_vadr);
|
||||
LTDC_WVSPPOS(lcd_panel_vsync+lcd_panel_vbp+lcd_panel_vadr-1);
|
||||
|
||||
LTDC_LPFCR(LTDC_LAYER1) = LTDC_PF_L8;
|
||||
|
||||
LTDC_LCFBAR(LTDC_LAYER1) = (uint32_t)&_framebuffer_start;
|
||||
LTDC_LCFBAR(LTDC_LAYER1) = (uint32_t)(&_framebuffer_start);
|
||||
|
||||
LTDC_LCFBLR(LTDC_LAYER1) =
|
||||
LTDC_CFBLL(243) | // Number of bytes per lines in the framebuffer. 240 * 4 (RGBA888). +3, per doc;
|
||||
@@ -289,6 +300,9 @@ static void init_rgb_layers() {
|
||||
// STEP 10: Reload the shadow register
|
||||
// Ask for immediate reload
|
||||
LTDC_SRCR = LTDC_IMR;
|
||||
|
||||
// Now let's actually enable the LTDC
|
||||
LTDC_GCR |= LTDC_LTDCEN;
|
||||
}
|
||||
|
||||
// Panel
|
||||
|
||||
@@ -68,6 +68,8 @@
|
||||
#define HIGH_BIT_DRW 14
|
||||
#define LTDC_DEN (1<<16)
|
||||
#define LTDC_PCPOL (1<<28)
|
||||
// When PCPOL=0, data is on the rising-edge
|
||||
// When PCPOL=1, data is on the falling-edge
|
||||
#define LTDC_DEPOL (1<<29)
|
||||
#define LTDC_VSPOL (1<<30)
|
||||
#define LTDC_HSPOL (1<<31)
|
||||
@@ -79,6 +81,16 @@
|
||||
#define LTDC_IMR (1<<0)
|
||||
#define LTDC_VBR (1<<1)
|
||||
|
||||
// LTDC background color configuration register
|
||||
|
||||
#define LTDC_BCCR LTDC_REGISTER_AT(0x2C)
|
||||
|
||||
#define LOW_BIT_BCBLUE 0
|
||||
#define HIGH_BIT_BCBLUE 7
|
||||
#define LOW_BIT_BCGREEN 8
|
||||
#define HIGH_BIT_BCGREEN 15
|
||||
#define LOW_BIT_BCRED 16
|
||||
#define HIGH_BIT_BCRED 23
|
||||
|
||||
// LTDC layer control registers
|
||||
|
||||
@@ -112,7 +124,7 @@
|
||||
|
||||
// LTDC layer pixel format configuration registers
|
||||
|
||||
#define LTDC_LPFCR(layer) LTDC_LAYER_REGISTER_AT(layer,0x88)
|
||||
#define LTDC_LPFCR(layer) LTDC_LAYER_REGISTER_AT(layer,0x94)
|
||||
|
||||
#define LTDC_PF_ARGB8888 0
|
||||
#define LTDC_PF_RGB888 1
|
||||
@@ -150,16 +162,6 @@
|
||||
#define LTDC_CFBLNR(v) REGISTER_FIELD_VALUE(LTDC_CFBLNR,v)
|
||||
|
||||
#if 0
|
||||
|
||||
typedef struct {
|
||||
unsigned int BCBLUE:8;
|
||||
unsigned int BCGREEN:8;
|
||||
unsigned int BCRED:8;
|
||||
unsigned int :8;
|
||||
} LTDC_BCCR_t;
|
||||
|
||||
extern LTDC_BCCR_t * LTDC_BCCR;
|
||||
|
||||
typedef struct {
|
||||
unsigned int LIE:1;
|
||||
unsigned int FUIE:1;
|
||||
|
||||
@@ -97,6 +97,11 @@
|
||||
|
||||
#define RCC_DCKCFGR RCC_REGISTER_AT(0x8C)
|
||||
|
||||
#define RCC_PLLSAIDIVR_DIV2 0
|
||||
#define RCC_PLLSAIDIVR_DIV4 1
|
||||
#define RCC_PLLSAIDIVR_DIV8 2
|
||||
#define RCC_PLLSAIDIVR_DIV16 3
|
||||
|
||||
#define LOW_BIT_PLLIS2DIVQ 0
|
||||
#define HIGH_BIT_PLLIS2DIVQ 4
|
||||
#define LOW_BIT_PLLSAIDIVQ 8
|
||||
|
||||
Reference in New Issue
Block a user