Skip to content

Commit 9cee61f

Browse files
kbobesden
authored andcommitted
[stm32f429i-discovery] Added LTDC DMA example.
This example is just using buffers and built in alpha overlay functionality to animate a dmond floating on a checker board. After initializing of the frame buffers only 7 registers are being modified to implement the animation.
1 parent 408ba8c commit 9cee61f

File tree

11 files changed

+1514
-1
lines changed

11 files changed

+1514
-1
lines changed

examples/Makefile.rules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,4 +236,4 @@ endif
236236

237237
.PHONY: images clean stylecheck styleclean elf bin hex srec list
238238

239-
-include $(OBJS:.o=.d)
239+
-include $(OBJS:.o=.d)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
OBJS = sdram.o clock.o console.o lcd-spi.o
2+
3+
BINARY = lcd-dma
4+
5+
# we use sin/cos from the library
6+
LDLIBS += -lm
7+
8+
LDSCRIPT = ../stm32f429i-discovery.ld
9+
10+
include ../../Makefile.include
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* This file is part of the libopencm3 project.
3+
*
4+
* Copyright (C) 2014 Chuck McManis <[email protected]>
5+
*
6+
* This library is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Lesser General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This library is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this library. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
/*
21+
* Now this is just the clock setup code from systick-blink as it is the
22+
* transferrable part.
23+
*/
24+
25+
#include <libopencm3/stm32/rcc.h>
26+
#include <libopencm3/cm3/nvic.h>
27+
#include <libopencm3/cm3/systick.h>
28+
29+
/* Common function descriptions */
30+
#include "clock.h"
31+
32+
/* milliseconds since boot */
33+
static volatile uint32_t system_millis;
34+
35+
/* Called when systick fires */
36+
void sys_tick_handler(void)
37+
{
38+
system_millis++;
39+
}
40+
41+
/* simple sleep for delay milliseconds */
42+
void milli_sleep(uint32_t delay)
43+
{
44+
uint32_t wake = system_millis + delay;
45+
while (wake > system_millis) {
46+
continue;
47+
}
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 168Mhz */
66+
rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_168MHZ]);
67+
68+
/* clock rate / 168000 to get 1mS interrupt rate */
69+
systick_set_reload(168000);
70+
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
71+
systick_counter_enable();
72+
73+
/* this done last */
74+
systick_interrupt_enable();
75+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* This include file describes the functions exported by clock.c
3+
*/
4+
#ifndef __CLOCK_H
5+
#define __CLOCK_H
6+
7+
#include <stdint.h>
8+
9+
/*
10+
* Definitions for functions being abstracted out
11+
*/
12+
void milli_sleep(uint32_t);
13+
uint32_t mtime(void);
14+
void clock_setup(void);
15+
16+
#endif /* generic header protector */
17+
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
/*
2+
* This file is part of the libopencm3 project.
3+
*
4+
* Copyright (C) 2014 Chuck McManis <[email protected]>
5+
*
6+
* This library is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Lesser General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This library is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this library. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
/*
21+
* Interrupt drive Console code (extracted from the usart-irq example)
22+
*
23+
*/
24+
25+
#include <stdint.h>
26+
#include <stdio.h>
27+
#include <setjmp.h>
28+
#include <libopencm3/stm32/gpio.h>
29+
#include <libopencm3/stm32/rcc.h>
30+
#include <libopencm3/stm32/usart.h>
31+
#include <libopencm3/cm3/nvic.h>
32+
#include <libopencm3/stm32/iwdg.h>
33+
#include <libopencm3/cm3/scb.h>
34+
#include <libopencm3/cm3/cortex.h>
35+
#include "clock.h"
36+
#include "console.h"
37+
38+
39+
/* This is a ring buffer to holding characters as they are typed
40+
* it maintains both the place to put the next character received
41+
* from the UART, and the place where the last character was
42+
* read by the program. See the README file for a discussion of
43+
* the failure semantics.
44+
*/
45+
#define RECV_BUF_SIZE 128 /* Arbitrary buffer size */
46+
char recv_buf[RECV_BUF_SIZE];
47+
static volatile int recv_ndx_nxt; /* Next place to store */
48+
static volatile int recv_ndx_cur; /* Next place to read */
49+
50+
/* For interrupt handling we add a new function which is called
51+
* when receive interrupts happen. The name (usart1_isr) is created
52+
* by the irq.json file in libopencm3 calling this interrupt for
53+
* USART1 'usart1', adding the suffix '_isr', and then weakly binding
54+
* it to the 'do nothing' interrupt function in vec.c.
55+
*
56+
* By defining it in this file the linker will override that weak
57+
* binding and instead bind it here, but you have to get the name
58+
* right or it won't work. And you'll wonder where your interrupts
59+
* are going.
60+
*/
61+
void usart1_isr(void)
62+
{
63+
uint32_t reg;
64+
int i;
65+
66+
do {
67+
reg = USART_SR(CONSOLE_UART);
68+
if (reg & USART_SR_RXNE) {
69+
recv_buf[recv_ndx_nxt] = USART_DR(CONSOLE_UART);
70+
#ifdef RESET_ON_CTRLC
71+
/* Check for "reset" */
72+
if (recv_buf[recv_ndx_nxt] == '\003') {
73+
scb_reset_system();
74+
}
75+
#endif
76+
/* Check for "overrun" */
77+
i = (recv_ndx_nxt + 1) % RECV_BUF_SIZE;
78+
if (i != recv_ndx_cur) {
79+
recv_ndx_nxt = i;
80+
}
81+
}
82+
} while ((reg & USART_SR_RXNE) != 0);
83+
/* can read back-to-back interrupts */
84+
}
85+
86+
/*
87+
* console_putc(char c)
88+
*
89+
* Send the character 'c' to the USART, wait for the USART
90+
* transmit buffer to be empty first.
91+
*/
92+
void console_putc(char c)
93+
{
94+
uint32_t reg;
95+
do {
96+
reg = USART_SR(CONSOLE_UART);
97+
} while ((reg & USART_SR_TXE) == 0);
98+
USART_DR(CONSOLE_UART) = (uint16_t) c & 0xff;
99+
}
100+
101+
/*
102+
* char = console_getc(int wait)
103+
*
104+
* Check the console for a character. If the wait flag is
105+
* non-zero. Continue checking until a character is received
106+
* otherwise return 0 if called and no character was available.
107+
*
108+
* The implementation is a bit different however, now it looks
109+
* in the ring buffer to see if a character has arrived.
110+
*/
111+
char console_getc(int wait)
112+
{
113+
char c = 0;
114+
115+
while ((wait != 0) && (recv_ndx_cur == recv_ndx_nxt));
116+
if (recv_ndx_cur != recv_ndx_nxt) {
117+
c = recv_buf[recv_ndx_cur];
118+
recv_ndx_cur = (recv_ndx_cur + 1) % RECV_BUF_SIZE;
119+
}
120+
return c;
121+
}
122+
123+
/*
124+
* void console_puts(char *s)
125+
*
126+
* Send a string to the console, one character at a time, return
127+
* after the last character, as indicated by a NUL character, is
128+
* reached.
129+
*/
130+
void console_puts(char *s)
131+
{
132+
while (*s != '\000') {
133+
console_putc(*s);
134+
/* Add in a carraige return, after sending line feed */
135+
if (*s == '\n') {
136+
console_putc('\r');
137+
}
138+
s++;
139+
}
140+
}
141+
142+
/*
143+
* int console_gets(char *s, int len)
144+
*
145+
* Wait for a string to be entered on the console, limited
146+
* support for editing characters (back space and delete)
147+
* end when a <CR> character is received.
148+
*/
149+
int console_gets(char *s, int len)
150+
{
151+
char *t = s;
152+
char c;
153+
154+
*t = '\000';
155+
/* read until a <CR> is received */
156+
while ((c = console_getc(1)) != '\r') {
157+
if ((c == '\010') || (c == '\127')) {
158+
if (t > s) {
159+
/* send ^H ^H to erase previous character */
160+
console_puts("\010 \010");
161+
t--;
162+
}
163+
} else {
164+
*t = c;
165+
console_putc(c);
166+
if ((t - s) < len) {
167+
t++;
168+
}
169+
}
170+
/* update end of string with NUL */
171+
*t = '\000';
172+
}
173+
return t - s;
174+
}
175+
176+
/*
177+
* console_setup(int baudrate)
178+
*
179+
* Set the pins and clocks to create a console that we can
180+
* use for serial messages and getting text from the user.
181+
*/
182+
void console_setup(int baud)
183+
{
184+
/* MUST enable the GPIO clock in ADDITION to the USART clock */
185+
rcc_periph_clock_enable(RCC_GPIOA);
186+
187+
/* This example uses PD5 and PD6 for Tx and Rx respectively
188+
* but other pins are available for this role on USART1 (our chosen
189+
* USART) as well, such as PA2 and PA3. You can also split them
190+
* so PA2 for Tx, PD6 for Rx but you would have to enable both
191+
* the GPIOA and GPIOD clocks in that case
192+
*/
193+
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9 | GPIO10);
194+
195+
/* Actual Alternate function number (in this case 7) is part
196+
* depenedent, CHECK THE DATA SHEET for the right number to
197+
* use.
198+
*/
199+
gpio_set_af(GPIOA, GPIO_AF7, GPIO9 | GPIO10);
200+
201+
202+
/* This then enables the clock to the USART1 peripheral which is
203+
* attached inside the chip to the APB2 bus. Different peripherals
204+
* attach to different buses, and even some UARTS are attached to
205+
* APB1 and some to APB2, again the data sheet is useful here.
206+
*/
207+
rcc_periph_clock_enable(RCC_USART1);
208+
209+
/* Set up USART/UART parameters using the libopencm3 helper functions */
210+
usart_set_baudrate(CONSOLE_UART, baud);
211+
usart_set_databits(CONSOLE_UART, 8);
212+
usart_set_stopbits(CONSOLE_UART, USART_STOPBITS_1);
213+
usart_set_mode(CONSOLE_UART, USART_MODE_TX_RX);
214+
usart_set_parity(CONSOLE_UART, USART_PARITY_NONE);
215+
usart_set_flow_control(CONSOLE_UART, USART_FLOWCONTROL_NONE);
216+
usart_enable(CONSOLE_UART);
217+
218+
/* Enable interrupts from the USART */
219+
nvic_enable_irq(NVIC_USART1_IRQ);
220+
221+
/* Specifically enable receive interrupts */
222+
usart_enable_rx_interrupt(CONSOLE_UART);
223+
}
224+
225+
static ssize_t console_read(void *cookie, char *buf, size_t size)
226+
{
227+
cookie = cookie; /* -Wunused-parameter */
228+
size_t i;
229+
for (i = 0; i < size; i++) {
230+
char c = console_getc(1);
231+
buf[i] = c;
232+
if (c == '\r') {
233+
buf[i] = '\n';
234+
i++;
235+
break;
236+
}
237+
}
238+
return i;
239+
}
240+
241+
static ssize_t console_write(void *cookie, const char *buf, size_t size)
242+
{
243+
cookie = cookie; /* -Wunused-parameter */
244+
size_t i;
245+
for (i = 0; i < size; i++) {
246+
char c = buf[i];
247+
if (c == '\n') {
248+
console_putc('\r');
249+
}
250+
console_putc(c);
251+
}
252+
return size;
253+
}
254+
255+
void console_stdio_setup()
256+
{
257+
cookie_io_functions_t console_input_fns = {
258+
.read = console_read,
259+
.write = NULL,
260+
.seek = NULL,
261+
.close = NULL
262+
};
263+
cookie_io_functions_t console_output_fns = {
264+
.read = NULL,
265+
.write = console_write,
266+
.seek = NULL,
267+
.close = NULL
268+
};
269+
stdin = fopencookie(NULL, "r", console_input_fns);
270+
stdout = fopencookie(NULL, "w", console_output_fns);
271+
stderr = fopencookie(NULL, "w", console_output_fns);
272+
setlinebuf(stdout);
273+
setbuf(stderr, NULL);
274+
}

0 commit comments

Comments
 (0)