[ion] FB sent to LCD by DMA

This commit is contained in:
Romain Goyet
2015-09-12 13:46:47 +02:00
parent 9d4ca437c1
commit 3a06ada1e1
11 changed files with 167 additions and 40 deletions

View File

@@ -148,7 +148,7 @@ static void perform_instructions(st7586_t * c, instruction_t * instructions, siz
}
}
void st7586_set_display_area(st7586_t * c, uint16_t x_start, uint16_t x_length, uint16_t y_start, uint16_t y_length) {
void st7586_set_display_area(st7586_t * controller, uint16_t x_start, uint16_t x_length, uint16_t y_start, uint16_t y_length) {
/* The datasheet says the panel counts in "columns", groups of 3 pixels.
* It says 3, but from my understanding pixels are grouped by 2, not by 3. So
* so let's make this 2 instead of 3. Seems to be working fine! */
@@ -172,8 +172,8 @@ void st7586_set_display_area(st7586_t * c, uint16_t x_start, uint16_t x_length,
DATA(y_end >> 8),
DATA(y_end),
};
perform_instructions(c, sequence, sizeof(sequence)/sizeof(sequence[0]));
perform_instructions(controller, sequence, sizeof(sequence)/sizeof(sequence[0]));
}
// p1 = 0, 1, 2, or 3
@@ -191,17 +191,17 @@ void st7586_initialize(st7586_t * c) {
st7586_set_display_area(c, 0, 160, 0, 160);
/*
// Put the screen in "receive frame data"
perform_instruction(c, &COMMAND(WRITE_DISPLAY_DATA));
c->data_command_pin_write(DATA_MODE);
unsigned char pixel = two_pixels(0x0, 0x3);
for (int i=0; i<160*160/2; i++) {
c->spi_write(&pixel, 1);
for (int i=0;i<1000;i++) {
}
}
*/
char pixels[3] = {
two_pixels(0x0,0x3),
two_pixels(0x0,0x3),
two_pixels(0x0,0x3)
};
c->spi_write(&pixels, 3);
#define FILL_SCREEN_UPON_INIT 0
#if FILL_SCREEN_UPON_INIT

View File

@@ -15,9 +15,8 @@ typedef struct {
} st7586_t;
void st7586_initialize(st7586_t * controller);
void st7586_set_display_area(st7586_t * controller, uint16_t x_start, uint16_t x_length, uint16_t y_start, uint16_t y_length);
//TODO: Remove this API, it is ugly
void st7586_display_buffer(st7586_t * controller, char * buffer, size_t length);
#endif

View File

@@ -1,2 +1,2 @@
objs += $(addprefix ion/platform/device/, platform.o init.o display.o framebuffer.o init_kbd.o)
objs += $(addprefix ion/platform/device/, platform.o init.o display.o framebuffer.o init_kbd.o display/dma.o)
objs += $(addprefix ion/drivers/, st7586/st7586.o fx92kbd/fx92kbd.o)

View File

@@ -18,15 +18,19 @@
#include <ion.h>
#include "platform.h"
#include "framebuffer.h"
#include "registers/registers.h"
#include <ion/drivers/st7586/st7586.h>
extern char _framebuffer_start, _framebuffer_end;
#include "display/dma.h"
void ion_display_on() {
// Initialize panel
// Start DMA transfer
}
void ion_display_off() {
// Stop DMA transfer
// Turn off panel
}
static void init_spi_pins();
@@ -42,6 +46,10 @@ void init_display() {
init_spi_port();
init_panel();
display_configure_dma();
}
static void init_spi_pins() {
@@ -86,17 +94,15 @@ static void init_panel() {
Platform.display.spi_write = spi_2_write;
st7586_initialize(&(Platform.display));
char * framebuffer = &_framebuffer_start;
for (int i=0;i<1000; i++) {
framebuffer[i] = 0;
}
st7586_set_display_area(0, FRAMEBUFFER_WIDTH, 0, FRAMEBUFFER_HEIGHT);
st7586_display_buffer
for(int i=0;i<10;i++) {
ion_set_pixel(i,i,i%4);
}
//for(int i=0;i<10;i++) {
// ion_set_pixel(i,i,i%4);
//}
//framebuffer[0] = 0xD8;
//st7586_display_buffer(&(Platform.display), &_framebuffer_start, &_framebuffer_end-&_framebuffer_start);
st7586_display_buffer(&(Platform.display), &_framebuffer_start, 1000);
//st7586_display_buffer(&(Platform.display), &_framebuffer_start, 1000);
}
static void spi_2_write(char * data, size_t size) {

View File

@@ -0,0 +1,56 @@
#include "../registers/registers.h"
// DMA 1, channel 0, stream 4 = SPI2_TX
#define LCD_DMA_CHANNEL 0
#define LCD_DMA_STREAM 4
extern char _framebuffer_start, _framebuffer_end;
void display_configure_dma() {
// 0 - ENable DMA clock!
RCC_AHB1ENR |= DMA1EN;
// 1 - Reset DMA
// Stuff like this, and a wait loop...
//DMA_SCR(DMA1,4) |= DMA_EN;
//DMA_SCR(DMA1,4) ~= DMA_EN;
// 2 - Set the peripheral address
DMA_SPAR(DMA1,LCD_DMA_STREAM) = (uint32_t)&SPI_DR(SPI2);
// 3 - Set the memory address
DMA_SMA0R(DMA1,LCD_DMA_STREAM) = (uint32_t)&_framebuffer_start;
// 4 - Number of data items
//DMA_SNDTR(DMA1,LCD_DMA_STREAM) = &_framebuffer_end-&_framebuffer_start;
REGISTER_SET_VALUE(DMA_SNDTR(DMA1,LCD_DMA_STREAM), DMA_SNDTR, &_framebuffer_end-&_framebuffer_start);
// 5 - Select the DMA channel
REGISTER_SET_VALUE(DMA_SCR(DMA1,LCD_DMA_STREAM), DMA_CHSEL, LCD_DMA_CHANNEL);
// 6 - Set peripheral flow control
// Does not apply, only for SD/MMC
// 7 - Stream priority
// We don't care yet
// 8 - Configure FIFO usage
// I think we don't care
// 9 - Data transfer direction, peripheral/memory increment, single burst or transaction, peripheral and memory data width
REGISTER_SET_VALUE(DMA_SCR(DMA1,LCD_DMA_STREAM), DMA_DIR, DMA_DIR_MEMORY_TO_PERIPHERAL);
//DMA_SCR(DMA1,LCD_DMA_STREAM) |= DMA_CIRC;
// Memory address is incremented
DMA_SCR(DMA1,LCD_DMA_STREAM) |= DMA_MINC;
// Peripheral expects 8 bits values, default
//REGISTER_SET_VALUE(DMA_SCR(DMA1,LCD_DMA_STREAM), DMA_DIR, DMA_DIR_MEMORY_TO_PERIPHERAL);
// 10 - Enable DMA transfer!
DMA_SCR(DMA1,LCD_DMA_STREAM) |= DMA_EN;
// 11 - Bonux: enable DMA requests on SPI
SPI_CR2(SPI2) |= SPI_TXDMAEN;
}

View File

@@ -0,0 +1 @@
void display_configure_dma();

View File

@@ -1,13 +1,6 @@
#include <ion.h>
#include <assert.h>
extern char _framebuffer_start;
extern char _framebuffer_end;
#define FRAMEBUFFER_ADDRESS (&_framebuffer_start)
#define FRAMEBUFFER_WIDTH 160
#define FRAMEBUFFER_HEIGHT 160
#define FRAMEBUFFER_BITS_PER_PIXEL 4
#include "framebuffer.h"
#define BIT_MASK(high, low) ((((uint32_t)1<<((high)-(low)+1))-1)<<(low))
#define BIT_VALUE(value, high, low) (((value)<<(low))&BIT_MASK(high, low))

View File

@@ -1,11 +1,7 @@
#ifndef ION_STM32F429_FRAMEBUFFER_H
#define ION_STM32F429_FRAMEBUFFER_H
extern char _framebuffer_start;
extern char _framebuffer_end;
#define ION_FRAMEBUFFER_ADDRESS ((void *)(&_framebuffer_start))
#define ION_FRAMEBUFFER_WIDTH 240
#define ION_FRAMEBUFFER_HEIGHT 160
#define ION_FRAMEBUFFER_BITS_PER_PIXEL 2
#endif
#define FRAMEBUFFER_ADDRESS (&_framebuffer_start)
#define FRAMEBUFFER_WIDTH 160
#define FRAMEBUFFER_HEIGHT 160
#define FRAMEBUFFER_BITS_PER_PIXEL 4

View File

@@ -0,0 +1,63 @@
#ifndef STM32_REGISTERS_DMA_H
#define STM32_REGISTERS_DMA_H 1
#define DMA1_BASE 0x40026000
#define DMA2_BASE 0x40026400
#define DMA_REGISTER_AT(dma,offset) (*(volatile uint32_t *)(dma##_BASE+offset))
#define DMA_STREAM_REGISTER_AT(dma,stream,offset) DMA_REGISTER_AT(dma,offset+(0x18*stream))
// DMA stream configuration register
#define DMA_SCR(dma,stream) DMA_STREAM_REGISTER_AT(dma,stream,0x10)
#define DMA_DIR_PERIPHERAL_TO_MEMORY 0
#define DMA_DIR_MEMORY_TO_PERIPHERAL 1
#define DMA_DIR_MEMORY_TO_MEMORY 2
#define DMA_PSIZE_8_BITS 0
#define DMA_PSIZE_16_BITS 1
#define DMA_PSIZE 32_BITS 2
#define DMA_EN (1<<0)
#define DMA_DMEIE (1<<1)
#define DMA_TEIE (1<<2)
#define DMA_HTIE (1<<3)
#define DMA_TCIE (1<<4)
#define DMA_PFCTRL (1<<5)
#define LOW_BIT_DMA_DIR 6
#define HIGH_BIT_DMA_DIR 7
#define DMA_CIRC (1<<8)
#define DMA_PINC (1<<9)
#define DMA_MINC (1<<10)
#define LOW_BIT_DMA_PSIZE 11
#define HIGH_BIT_DMA_PSIZE 12
#define LOW_BIT_DMA_MSIZE 13
#define HIGH_BIT_DMA_MSIZE 14
#define DMA_PINCOS (1<<15)
#define LOW_BIT_DMA_PL 16
#define HIGH_BIT_DMA_PL 17
#define DMA_DBM (1<<18)
#define DMA_CT (1<<19)
#define LOW_BIT_DMA_PBURST 21
#define HIGH_BIT_DMA_PBURST 22
#define LOW_BIT_DMA_MBURST 23
#define HIGH_BIT_DMA_MBURST 24
#define LOW_BIT_DMA_CHSEL 25
#define HIGH_BIT_DMA_CHSEL 27
// DMA stream number of data register
#define DMA_SNDTR(dma,stream) DMA_STREAM_REGISTER_AT(dma,stream,0x14)
#define LOW_BIT_DMA_SNDTR 0
#define HIGH_BIT_DMA_SNDTR 15
// DMA stream peripheral address register
#define DMA_SPAR(dma,stream) DMA_STREAM_REGISTER_AT(dma,stream,0x18)
// DMA stream memory 0 address register
#define DMA_SMA0R(dma,stream) DMA_STREAM_REGISTER_AT(dma,stream,0x1C)
#endif

View File

@@ -13,6 +13,7 @@
#include "rcc.h"
#include "gpio.h"
#include "spi.h"
#include "dma.h"
//#include "ltdc.h"
#define REGISTER_FIELD_MASK(field) (BIT_MASK(HIGH_BIT_##field,LOW_BIT_##field))

View File

@@ -47,6 +47,18 @@
#define SPI_BIDIOE (1<<14)
#define SPI_BIDIMODE (1<<15)
// SPI control registers 2
#define SPI_CR2(spi_port) SPI_REGISTER_AT(spi_port,0x04)
#define SPI_RXDMAEN (1<<0)
#define SPI_TXDMAEN (1<<1)
#define SPI_SSOE (1<<2)
#define SPI_FRF (1<<4)
#define SPI_ERRIE (1<<5)
#define SPI_RXNEIE (1<<6)
#define SPI_TXEIE (1<<7)
// SPI status registers
#define SPI_SR(spi_port) SPI_REGISTER_AT(spi_port, 0x08)