diff --git a/ion/drivers/st7586/st7586.c b/ion/drivers/st7586/st7586.c index 5c5bab220..46f80c5f6 100644 --- a/ion/drivers/st7586/st7586.c +++ b/ion/drivers/st7586/st7586.c @@ -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 diff --git a/ion/drivers/st7586/st7586.h b/ion/drivers/st7586/st7586.h index 5d8ffa049..2373e98dd 100644 --- a/ion/drivers/st7586/st7586.h +++ b/ion/drivers/st7586/st7586.h @@ -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 diff --git a/ion/platform/device/Makefile b/ion/platform/device/Makefile index 359e59cea..7ec65619a 100644 --- a/ion/platform/device/Makefile +++ b/ion/platform/device/Makefile @@ -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) diff --git a/ion/platform/device/display.c b/ion/platform/device/display.c index a2be342aa..4ced05161 100644 --- a/ion/platform/device/display.c +++ b/ion/platform/device/display.c @@ -18,15 +18,19 @@ #include #include "platform.h" +#include "framebuffer.h" #include "registers/registers.h" #include - -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) { diff --git a/ion/platform/device/display/dma.c b/ion/platform/device/display/dma.c new file mode 100644 index 000000000..5bb85e6ec --- /dev/null +++ b/ion/platform/device/display/dma.c @@ -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; +} diff --git a/ion/platform/device/display/dma.h b/ion/platform/device/display/dma.h new file mode 100644 index 000000000..f986192be --- /dev/null +++ b/ion/platform/device/display/dma.h @@ -0,0 +1 @@ +void display_configure_dma(); diff --git a/ion/platform/device/framebuffer.c b/ion/platform/device/framebuffer.c index abdeb0b58..71f6b2bcd 100644 --- a/ion/platform/device/framebuffer.c +++ b/ion/platform/device/framebuffer.c @@ -1,13 +1,6 @@ #include #include - -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)) diff --git a/ion/platform/device/framebuffer.h b/ion/platform/device/framebuffer.h index 35465c5cb..592dede30 100644 --- a/ion/platform/device/framebuffer.h +++ b/ion/platform/device/framebuffer.h @@ -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 diff --git a/ion/platform/device/registers/dma.h b/ion/platform/device/registers/dma.h new file mode 100644 index 000000000..4d3d58b1c --- /dev/null +++ b/ion/platform/device/registers/dma.h @@ -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 diff --git a/ion/platform/device/registers/registers.h b/ion/platform/device/registers/registers.h index a26da9180..cb264e89b 100644 --- a/ion/platform/device/registers/registers.h +++ b/ion/platform/device/registers/registers.h @@ -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)) diff --git a/ion/platform/device/registers/spi.h b/ion/platform/device/registers/spi.h index 58b71af3b..0c876db22 100644 --- a/ion/platform/device/registers/spi.h +++ b/ion/platform/device/registers/spi.h @@ -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)