Skip to content

Commit 0a4bfd1

Browse files
committed
LCD RGB disco with SDRAM on F7-Discovery
1 parent 0e7cc0c commit 0a4bfd1

File tree

8 files changed

+516
-0
lines changed

8 files changed

+516
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
tar ext :3333
2+
file lcd_ram_demo.elf
3+
mon reset halt
4+
foc c
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#
2+
# This file is part of the libopencm3 project.
3+
#
4+
# This library is free software: you can redistribute it and/or modify
5+
# it under the terms of the GNU Lesser General Public License as published by
6+
# the Free Software Foundation, either version 3 of the License, or
7+
# (at your option) any later version.
8+
#
9+
# This library is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU Lesser General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU Lesser General Public License
15+
# along with this library. If not, see <http://www.gnu.org/licenses/>.
16+
#
17+
18+
OBJS = clock.o \
19+
sdram.o \
20+
21+
BINARY = lcd_ram_demo
22+
23+
LDSCRIPT = ../stm32f7-discovery.ld
24+
25+
include ../../Makefile.include
26+
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* This file is part of the libopencm3 project.
3+
*
4+
* Copyright (C) 2013 Chuck McManis <[email protected]>
5+
* Copyright (C) 2016 Maxime Vincent <[email protected]>
6+
*
7+
* This library is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public License
18+
* along with this library. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
/*
22+
* Now this is just the clock setup code from systick-blink as it is the
23+
* transferrable part.
24+
*/
25+
26+
#include <libopencm3/stm32/rcc.h>
27+
#include <libopencm3/stm32/gpio.h>
28+
#include <libopencm3/cm3/nvic.h>
29+
#include <libopencm3/cm3/systick.h>
30+
31+
/* Common function descriptions */
32+
#include "clock.h"
33+
34+
/* milliseconds since boot */
35+
static volatile uint32_t system_millis;
36+
37+
/* Called when systick fires */
38+
void sys_tick_handler(void)
39+
{
40+
system_millis++;
41+
}
42+
43+
/* simple sleep for delay milliseconds */
44+
void msleep(uint32_t delay)
45+
{
46+
uint32_t wake = system_millis + delay;
47+
while (wake > system_millis);
48+
}
49+
50+
/* Getter function for the current time */
51+
uint32_t mtime(void)
52+
{
53+
return system_millis;
54+
}
55+
56+
/*
57+
* clock_setup(void)
58+
*
59+
* This function sets up both the base board clock rate
60+
* and a 1khz "system tick" count. The SYSTICK counter is
61+
* a standard feature of the Cortex-M series.
62+
*/
63+
void clock_setup(void)
64+
{
65+
/* Base board frequency, set to 216MHz */
66+
rcc_clock_setup_hse_3v3(&hse_25mhz_3v3[CLOCK_3V3_216MHZ]);
67+
68+
/* clock rate / 216000 to get 1mS interrupt rate */
69+
systick_set_reload(216000);
70+
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
71+
systick_counter_enable();
72+
73+
/* this done last */
74+
systick_interrupt_enable();
75+
}
76+
77+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* This include file describes the functions exported by clock.c
3+
*/
4+
#ifndef __CLOCK_H
5+
#define __CLOCK_H
6+
7+
/*
8+
* Definitions for functions being abstracted out
9+
*/
10+
void msleep(uint32_t);
11+
uint32_t mtime(void);
12+
void clock_setup(void);
13+
14+
#endif /* generic header protector */
15+
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/* Includes ------------------------------------------------------------------*/
2+
#include <libopencm3/stm32/rcc.h>
3+
#include <libopencm3/stm32/gpio.h>
4+
#include <libopencm3/stm32/ltdc.h>
5+
#include "rk043fn48h.h"
6+
#include "clock.h"
7+
#include "sdram.h"
8+
9+
/* Private function prototypes -----------------------------------------------*/
10+
static void lcd_config(void);
11+
static void lcd_pinmux(void);
12+
static void lcd_clock(void);
13+
static void lcd_config_layer(void);
14+
15+
/* Private functions ---------------------------------------------------------*/
16+
17+
void lcd_pinmux(void)
18+
{
19+
/* Enable the LTDC Clock */
20+
rcc_periph_clock_enable(RCC_LTDC);
21+
22+
/* Enable GPIOs clock */
23+
rcc_periph_clock_enable(RCC_GPIOE);
24+
rcc_periph_clock_enable(RCC_GPIOG);
25+
rcc_periph_clock_enable(RCC_GPIOI);
26+
rcc_periph_clock_enable(RCC_GPIOJ);
27+
rcc_periph_clock_enable(RCC_GPIOK);
28+
29+
/*** LTDC Pins configuration ***/
30+
gpio_mode_setup(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO4);
31+
gpio_set_output_options(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO4);
32+
gpio_set_af(GPIOE, GPIO_AF14, GPIO4);
33+
34+
/* GPIOG configuration */
35+
gpio_mode_setup(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO12);
36+
gpio_set_output_options(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO12);
37+
gpio_set_af(GPIOG, GPIO_AF9, GPIO12);
38+
39+
/* GPIOI LTDC alternate configuration */
40+
gpio_mode_setup(GPIOI, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8 | GPIO9 | GPIO10 | GPIO14 | GPIO15);
41+
gpio_set_output_options(GPIOI, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO8 | GPIO9 | GPIO10 | GPIO14 | GPIO15);
42+
gpio_set_af(GPIOI, GPIO_AF14, GPIO8 | GPIO9 | GPIO10 | GPIO14 | GPIO15);
43+
44+
/* GPIOJ configuration */
45+
gpio_mode_setup(GPIOJ, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 |
46+
GPIO5 | GPIO6 | GPIO7 | GPIO8 | GPIO9 |
47+
GPIO10 | GPIO11 | GPIO13 | GPIO14 | GPIO15);
48+
gpio_set_output_options(GPIOJ, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 |
49+
GPIO5 | GPIO6 | GPIO7 | GPIO8 | GPIO9 |
50+
GPIO10 | GPIO11 | GPIO13 | GPIO14 | GPIO15);
51+
gpio_set_af(GPIOJ, GPIO_AF14, GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 |
52+
GPIO5 | GPIO6 | GPIO7 | GPIO8 | GPIO9 |
53+
GPIO10 | GPIO11 | GPIO13 | GPIO14 | GPIO15);
54+
55+
/* GPIOK configuration */
56+
gpio_mode_setup(GPIOK, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO0 | GPIO1 | GPIO2 | GPIO4 | GPIO5 | GPIO6 | GPIO7);
57+
gpio_set_output_options(GPIOK, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO0 | GPIO1 | GPIO2 | GPIO4 | GPIO5 | GPIO6 | GPIO7);
58+
gpio_set_af(GPIOK, GPIO_AF14, GPIO0 | GPIO1 | GPIO2 | GPIO4 | GPIO5 | GPIO6 | GPIO7);
59+
60+
/* LCD_DISP GPIO configuration */
61+
gpio_mode_setup(GPIOI, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO12);
62+
gpio_set_output_options(GPIOI, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO12);
63+
64+
/* LCD_BL_CTRL GPIO configuration */
65+
gpio_mode_setup(GPIOK, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO3);
66+
gpio_set_output_options(GPIOK, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO3);
67+
68+
/* Assert display enable LCD_DISP pin */
69+
gpio_set(GPIOI, GPIO12);
70+
71+
/* Assert backlight LCD_BL_CTRL pin */
72+
gpio_set(GPIOK, GPIO3);
73+
}
74+
75+
static void lcd_config_layer(void)
76+
{
77+
/* Windowing configuration */
78+
ltdc_setup_windowing(LTDC_LAYER_2, 480, 272);
79+
80+
/* Specifies the pixel format */
81+
ltdc_set_pixel_format(LTDC_LAYER_2, LTDC_LxPFCR_RGB565);
82+
83+
/* Default color values */
84+
ltdc_set_default_colors(LTDC_LAYER_2, 0, 0, 0, 0);
85+
/* Constant alpha */
86+
ltdc_set_constant_alpha(LTDC_LAYER_2, 255);
87+
88+
/* Blending factors */
89+
ltdc_set_blending_factors(LTDC_LAYER_2, LTDC_LxBFCR_BF1_CONST_ALPHA, LTDC_LxBFCR_BF2_CONST_ALPHA);
90+
91+
/* Framebuffer address */
92+
ltdc_set_fbuffer_address(LTDC_LAYER_2, (uint32_t)0xC0000000); // XXX SDRAM ADDR!
93+
94+
/* Configures the color frame buffer pitch in byte */
95+
ltdc_set_fb_line_length(LTDC_LAYER_2, 2*480, 2*480); /* RGB565 is 2 bytes/pixel */
96+
97+
/* Configures the frame buffer line number */
98+
ltdc_set_fb_line_count(LTDC_LAYER_2, 272);
99+
100+
/* Enable layer 1 */
101+
ltdc_layer_ctrl_enable(LTDC_LAYER_2, LTDC_LxCR_LAYER_ENABLE);
102+
103+
/* Sets the Reload type */
104+
ltdc_reload(LTDC_SRCR_IMR);
105+
}
106+
107+
/**
108+
* @brief LCD Configuration.
109+
* @note This function Configure tha LTDC peripheral :
110+
* 1) Configure the Pixel Clock for the LCD
111+
* 2) Configure the LTDC Timing and Polarity
112+
* 3) Configure the LTDC Layer 1 :
113+
* - The frame buffer is located at FLASH memory
114+
* - The Layer size configuration : 480x272
115+
* @retval
116+
* None
117+
*/
118+
static void lcd_config(void)
119+
{
120+
/* LTDC Initialization */
121+
ltdc_ctrl_disable(LTDC_GCR_HSPOL_ACTIVE_HIGH); /* Active Low Horizontal Sync */
122+
ltdc_ctrl_disable(LTDC_GCR_VSPOL_ACTIVE_HIGH); /* Active Low Vertical Sync */
123+
ltdc_ctrl_disable(LTDC_GCR_DEPOL_ACTIVE_HIGH); /* Active Low Date Enable */
124+
ltdc_ctrl_disable(LTDC_GCR_PCPOL_ACTIVE_HIGH); /* Active Low Pixel Clock */
125+
126+
/* Configure the LTDC */
127+
ltdc_set_tft_sync_timings(RK043FN48H_HSYNC, RK043FN48H_VSYNC,
128+
RK043FN48H_HBP, RK043FN48H_VBP,
129+
RK043FN48H_WIDTH, RK043FN48H_HEIGHT,
130+
RK043FN48H_HFP, RK043FN48H_VFP);
131+
132+
ltdc_set_background_color(0, 0, 0);
133+
ltdc_ctrl_enable(LTDC_GCR_LTDC_ENABLE);
134+
135+
/* Configure the Layer*/
136+
lcd_config_layer();
137+
138+
}
139+
140+
141+
static void lcd_clock(void)
142+
{
143+
/* LCD clock configuration */
144+
/* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
145+
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 Mhz */
146+
/* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/5 = 38.4 Mhz */
147+
/* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_4 = 38.4/4 = 9.6Mhz */
148+
149+
/* Disable PLLSAI */
150+
RCC_CR &= ~RCC_CR_PLLSAION;
151+
while((RCC_CR & (RCC_CR_PLLSAIRDY))) {};
152+
153+
/* N and R are needed,
154+
* P and Q are not needed for LTDC */
155+
RCC_PLLSAICFGR &= ~RCC_PLLSAICFGR_PLLSAIN_MASK;
156+
RCC_PLLSAICFGR |= 192 << RCC_PLLSAICFGR_PLLSAIN_SHIFT;
157+
RCC_PLLSAICFGR &= ~RCC_PLLSAICFGR_PLLSAIR_MASK;
158+
RCC_PLLSAICFGR |= 5 << RCC_PLLSAICFGR_PLLSAIR_SHIFT;
159+
RCC_DCKCFGR1 &= ~RCC_DCKCFGR1_PLLSAIDIVR_MASK;
160+
RCC_DCKCFGR1 |= RCC_DCKCFGR1_PLLSAIDIVR_DIVR_4;
161+
162+
/* Enable PLLSAI */
163+
RCC_CR |= RCC_CR_PLLSAION;
164+
while(!(RCC_CR & (RCC_CR_PLLSAIRDY))) {};
165+
}
166+
167+
int main(void)
168+
{
169+
/* init timers. */
170+
clock_setup();
171+
/* init sdram */
172+
sdram_init();
173+
/* init LCD */
174+
lcd_pinmux();
175+
lcd_clock();
176+
lcd_config(); /* Configure LCD : Only one layer is used */
177+
178+
while (1) {
179+
int x;
180+
uint16_t * rgb565;
181+
182+
// write stuff to the framebuffer
183+
rgb565 = (uint16_t *)SDRAM_BASE_ADDRESS;
184+
for (x = 0; x < (480*272*2)/2; x++)
185+
{
186+
*(rgb565++) = 0x1F; // Blue only
187+
}
188+
msleep(200);
189+
190+
rgb565 = (uint16_t *)SDRAM_BASE_ADDRESS;
191+
for (x = 0; x < (480*272*2)/2; x++)
192+
{
193+
*(rgb565++) = 0x7E0; // Green only
194+
}
195+
msleep(200);
196+
197+
rgb565 = (uint16_t *)SDRAM_BASE_ADDRESS;
198+
for (x = 0; x < (480*272*2)/2; x++)
199+
{
200+
*(rgb565++) = 0xF800; // Red only
201+
}
202+
msleep(200);
203+
}
204+
}
205+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef __RK043FN48H_H
2+
#define __RK043FN48H_H
3+
4+
#include <stdint.h>
5+
6+
#define RK043FN48H_WIDTH ((uint16_t)480) /* LCD PIXEL WIDTH */
7+
#define RK043FN48H_HEIGHT ((uint16_t)272) /* LCD PIXEL HEIGHT */
8+
#define RK043FN48H_HSYNC ((uint16_t)41) /* Horizontal synchronization */
9+
#define RK043FN48H_HBP ((uint16_t)13) /* Horizontal back porch */
10+
#define RK043FN48H_HFP ((uint16_t)32) /* Horizontal front porch */
11+
#define RK043FN48H_VSYNC ((uint16_t)10) /* Vertical synchronization */
12+
#define RK043FN48H_VBP ((uint16_t)2) /* Vertical back porch */
13+
#define RK043FN48H_VFP ((uint16_t)2) /* Vertical front porch */
14+
#define RK043FN48H_FREQUENCY_DIVIDER 5 /* LCD Frequency divider */
15+
16+
#endif /* __RK043FN48H_H */

0 commit comments

Comments
 (0)