mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[ion] FB sent to LCD by DMA
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
56
ion/platform/device/display/dma.c
Normal file
56
ion/platform/device/display/dma.c
Normal 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;
|
||||
}
|
||||
1
ion/platform/device/display/dma.h
Normal file
1
ion/platform/device/display/dma.h
Normal file
@@ -0,0 +1 @@
|
||||
void display_configure_dma();
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
63
ion/platform/device/registers/dma.h
Normal file
63
ion/platform/device/registers/dma.h
Normal 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
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user