Changed allocation of display framebuffers from dynamic to static. Reorganised code in some of the display drivers.
This commit is contained in:
parent
f1dbfbfe1f
commit
57349cba80
|
|
@ -87,13 +87,14 @@
|
|||
#define LCD_FSMC_ADDR_DATA 0x60040000
|
||||
|
||||
/*
|
||||
* LCD framebuffer, dynamically allocated.
|
||||
* Pixel format is RGB565, 16 bit per pixel
|
||||
* LCD framebuffer, statically allocated and placed in the "large" RAM block
|
||||
* starting at 0x20000000 and accessible by the DMA.
|
||||
* Pixel format is RGB565, 16 bit per pixel.
|
||||
*/
|
||||
static uint16_t *frameBuffer;
|
||||
static uint16_t __attribute__((section(".bss2"))) frameBuffer[SCREEN_WIDTH * SCREEN_HEIGHT];
|
||||
|
||||
using namespace miosix;
|
||||
Thread *lcdWaiting = 0;
|
||||
static Thread *lcdWaiting = 0;
|
||||
|
||||
void __attribute__((used)) DmaImpl()
|
||||
{
|
||||
|
|
@ -126,14 +127,8 @@ static inline __attribute__((__always_inline__)) void writeData(uint8_t val)
|
|||
|
||||
void display_init()
|
||||
{
|
||||
|
||||
/* Allocate and clear framebuffer, setting all pixels to 0xFFFF makes the
|
||||
* screen white.
|
||||
*
|
||||
* TODO: handle the case when memory allocation fails!
|
||||
*/
|
||||
frameBuffer = ((uint16_t *) malloc(SCREEN_WIDTH * SCREEN_HEIGHT * sizeof(uint16_t)));
|
||||
memset(frameBuffer, 0xFF, SCREEN_WIDTH * SCREEN_HEIGHT * sizeof(uint16_t));
|
||||
/* Clear framebuffer, setting all pixels to 0x00 makes the screen white */
|
||||
memset(frameBuffer, 0x00, SCREEN_WIDTH * SCREEN_HEIGHT * sizeof(uint16_t));
|
||||
|
||||
/*
|
||||
* Turn on DMA2 and configure its interrupt. DMA is used to transfer the
|
||||
|
|
@ -435,8 +430,6 @@ void display_init()
|
|||
|
||||
void display_terminate()
|
||||
{
|
||||
free(frameBuffer);
|
||||
|
||||
/* Shut off FSMC and deallocate framebuffer */
|
||||
RCC->AHB3ENR &= ~RCC_AHB3ENR_FSMCEN;
|
||||
__DSB();
|
||||
|
|
|
|||
|
|
@ -30,32 +30,18 @@
|
|||
#include <SPI2.h>
|
||||
|
||||
/*
|
||||
* LCD framebuffer, allocated on the heap by display_init().
|
||||
* Pixel format is black and white, one bit per pixel
|
||||
* LCD framebuffer, statically allocated and placed in the "large" RAM block
|
||||
* starting at 0x20000000.
|
||||
* Pixel format is black and white, one bit per pixel.
|
||||
*/
|
||||
static uint8_t *frameBuffer;
|
||||
#define FB_SIZE (((SCREEN_HEIGHT * SCREEN_WIDTH) / 8 ) + 1)
|
||||
static uint8_t __attribute__((section(".bss2"))) frameBuffer[FB_SIZE];
|
||||
|
||||
|
||||
void display_init()
|
||||
{
|
||||
|
||||
/*
|
||||
* Framebuffer size, in bytes, with compensating for eventual truncation
|
||||
* error in division by rounding to the nearest greater integer.
|
||||
*/
|
||||
unsigned int fbSize = (SCREEN_HEIGHT * SCREEN_WIDTH)/8;
|
||||
if((fbSize * 8) < (SCREEN_HEIGHT * SCREEN_WIDTH)) fbSize += 1;
|
||||
fbSize *= sizeof(uint8_t);
|
||||
|
||||
/* Allocate framebuffer */
|
||||
frameBuffer = (uint8_t *) malloc(fbSize);
|
||||
if(frameBuffer == NULL)
|
||||
{
|
||||
puts("*** LCD ERROR: cannot allocate framebuffer! ***");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear framebuffer, setting all pixels to 0x00 makes the screen white */
|
||||
memset(frameBuffer, 0x00, fbSize);
|
||||
memset(frameBuffer, 0x00, FB_SIZE);
|
||||
|
||||
/*
|
||||
* Initialise SPI2 for external flash and LCD
|
||||
|
|
@ -114,11 +100,6 @@ void display_init()
|
|||
|
||||
void display_terminate()
|
||||
{
|
||||
if(frameBuffer != NULL)
|
||||
{
|
||||
free(frameBuffer);
|
||||
}
|
||||
|
||||
spi2_terminate();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,33 +29,44 @@
|
|||
#include <hwconfig.h>
|
||||
#include <SPI2.h>
|
||||
|
||||
|
||||
/*
|
||||
* LCD framebuffer, allocated on the heap by display_init().
|
||||
* Pixel format is black and white, one bit per pixel
|
||||
* LCD framebuffer, statically allocated and placed in the "large" RAM block
|
||||
* starting at 0x20000000.
|
||||
* Pixel format is black and white, one bit per pixel.
|
||||
*/
|
||||
static uint8_t *frameBuffer;
|
||||
#define FB_SIZE (((SCREEN_HEIGHT * SCREEN_WIDTH) / 8 ) + 1)
|
||||
static uint8_t __attribute__((section(".bss2"))) frameBuffer[FB_SIZE];
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* Send one row of pixels to the display.
|
||||
* Pixels in framebuffer are stored "by rows", while display needs data to be
|
||||
* sent "by columns": this function performs the needed conversion.
|
||||
*
|
||||
* @param row: pixel row to be be sent.
|
||||
*/
|
||||
void display_renderRow(uint8_t row)
|
||||
{
|
||||
for(uint16_t i = 0; i < 64; i++)
|
||||
{
|
||||
uint8_t out = 0;
|
||||
uint8_t tmp = frameBuffer[(i * 16) + (15 - row)];
|
||||
|
||||
for(uint8_t j = 0; j < 8; j++)
|
||||
{
|
||||
out |= ((tmp >> (7-j)) & 0x01) << j;
|
||||
}
|
||||
|
||||
spi2_sendRecv(out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void display_init()
|
||||
{
|
||||
|
||||
/*
|
||||
* Framebuffer size, in bytes, with compensating for eventual truncation
|
||||
* error in division by rounding to the nearest greater integer.
|
||||
*/
|
||||
unsigned int fbSize = (SCREEN_HEIGHT * SCREEN_WIDTH)/8;
|
||||
if((fbSize * 8) < (SCREEN_HEIGHT * SCREEN_WIDTH)) fbSize += 1;
|
||||
fbSize *= sizeof(uint8_t);
|
||||
|
||||
/* Allocate framebuffer */
|
||||
frameBuffer = (uint8_t *) malloc(fbSize);
|
||||
if(frameBuffer == NULL)
|
||||
{
|
||||
puts("*** LCD ERROR: cannot allocate framebuffer! ***");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear framebuffer, setting all pixels to 0x00 makes the screen white */
|
||||
memset(frameBuffer, 0x00, fbSize);
|
||||
memset(frameBuffer, 0x00, FB_SIZE);
|
||||
|
||||
/*
|
||||
* Initialise SPI2 for external flash and LCD
|
||||
|
|
@ -79,18 +90,17 @@ void display_init()
|
|||
gpio_setPin(LCD_CS);
|
||||
gpio_clearPin(LCD_RS);
|
||||
|
||||
gpio_clearPin(LCD_RST); /* Reset controller */
|
||||
gpio_clearPin(LCD_RST); // Reset controller
|
||||
delayMs(50);
|
||||
gpio_setPin(LCD_RST);
|
||||
delayMs(50);
|
||||
|
||||
gpio_clearPin(LCD_CS);
|
||||
|
||||
gpio_clearPin(LCD_RS); /* RS low -> command mode */
|
||||
gpio_clearPin(LCD_RS);// RS low -> command mode
|
||||
spi2_sendRecv(0xAE); // SH110X_DISPLAYOFF,
|
||||
spi2_sendRecv(0xd5); // SH110X_SETDISPLAYCLOCKDIV, 0x51,
|
||||
spi2_sendRecv(0x51);
|
||||
//spi2_sendRecv(0x20); // SH110X_MEMORYMODE,
|
||||
spi2_sendRecv(0x81); // SH110X_SETCONTRAST, 0x4F,
|
||||
spi2_sendRecv(0x4F);
|
||||
spi2_sendRecv(0xAD); // SH110X_DCDC, 0x8A,
|
||||
|
|
@ -115,31 +125,9 @@ void display_init()
|
|||
|
||||
void display_terminate()
|
||||
{
|
||||
if(frameBuffer != NULL)
|
||||
{
|
||||
free(frameBuffer);
|
||||
}
|
||||
|
||||
spi2_terminate();
|
||||
}
|
||||
|
||||
void display_renderRow(uint8_t row)
|
||||
{
|
||||
uint8_t *buf = (frameBuffer);
|
||||
|
||||
for(uint16_t i=0; i<64; i++)
|
||||
{
|
||||
uint8_t out=0, tmp=buf[i*16 + 15-row];
|
||||
|
||||
for(uint8_t j=0; j<8; j++)
|
||||
{
|
||||
out|=((tmp>>(7-j))&1)<<j;
|
||||
}
|
||||
|
||||
spi2_sendRecv(out);
|
||||
}
|
||||
}
|
||||
|
||||
void display_renderRows(uint8_t startRow, uint8_t endRow)
|
||||
{
|
||||
gpio_clearPin(LCD_CS);
|
||||
|
|
@ -159,7 +147,7 @@ void display_renderRows(uint8_t startRow, uint8_t endRow)
|
|||
|
||||
void display_render()
|
||||
{
|
||||
display_renderRows(0, SCREEN_WIDTH / 8 - 1);
|
||||
display_renderRows(0, (SCREEN_WIDTH / 8) - 1);
|
||||
}
|
||||
|
||||
bool display_renderingInProgress()
|
||||
|
|
|
|||
|
|
@ -29,28 +29,53 @@
|
|||
#include <SPI2.h>
|
||||
|
||||
/*
|
||||
* LCD framebuffer, allocated on the heap by display_init().
|
||||
* Pixel format is black and white, one bit per pixel
|
||||
* LCD framebuffer, statically allocated and placed in the "large" RAM block
|
||||
* starting at 0x20000000.
|
||||
* Pixel format is black and white, one bit per pixel.
|
||||
*/
|
||||
static uint8_t *frameBuffer;
|
||||
#define FB_SIZE (((SCREEN_HEIGHT * SCREEN_WIDTH) / 8 ) + 1)
|
||||
static uint8_t __attribute__((section(".bss2"))) frameBuffer[FB_SIZE];
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* Send one row of pixels to the display.
|
||||
* Pixels in framebuffer are stored "by rows", while display needs data to be
|
||||
* sent "by columns": this function performs the needed conversion.
|
||||
*
|
||||
* @param row: pixel row to be be sent.
|
||||
*/
|
||||
static void display_renderRow(uint8_t row)
|
||||
{
|
||||
/* magic stuff */
|
||||
uint8_t *buf = (frameBuffer + 128 * row);
|
||||
for (uint8_t i = 0; i<16; i++)
|
||||
{
|
||||
uint8_t tmp[8] = {0};
|
||||
for (uint8_t j = 0; j < 8; j++)
|
||||
{
|
||||
uint8_t tmp_buf = buf[j*16 + i];
|
||||
int count = __builtin_popcount(tmp_buf);
|
||||
while (count > 0)
|
||||
{
|
||||
int pos = __builtin_ctz(tmp_buf);
|
||||
tmp[pos] |= 1UL << j;
|
||||
tmp_buf &= ~(1 << pos);
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t s = 0; s < 8; s++)
|
||||
{
|
||||
(void) spi2_sendRecv(tmp[s]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void display_init()
|
||||
{
|
||||
/* Framebuffer size, in bytes */
|
||||
unsigned int fbSize = (SCREEN_HEIGHT * SCREEN_WIDTH)/8;
|
||||
if((fbSize * 8) < (SCREEN_HEIGHT * SCREEN_WIDTH)) fbSize += 1; /* Compensate for eventual truncation error in division */
|
||||
fbSize *= sizeof(uint8_t);
|
||||
|
||||
/* Allocate framebuffer */
|
||||
frameBuffer = (uint8_t *) malloc(fbSize);
|
||||
if(frameBuffer == NULL)
|
||||
{
|
||||
puts("*** LCD ERROR: cannot allocate framebuffer! ***");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear framebuffer, setting all pixels to 0x00 makes the screen white */
|
||||
memset(frameBuffer, 0x00, fbSize);
|
||||
memset(frameBuffer, 0x00, FB_SIZE);
|
||||
|
||||
gpio_setMode(LCD_CS, OUTPUT);
|
||||
gpio_setMode(LCD_RST, OUTPUT);
|
||||
|
|
@ -83,37 +108,7 @@ void display_init()
|
|||
|
||||
void display_terminate()
|
||||
{
|
||||
if(frameBuffer != NULL)
|
||||
{
|
||||
free(frameBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void display_renderRow(uint8_t row)
|
||||
{
|
||||
/* magic stuff */
|
||||
uint8_t *buf = (frameBuffer + 128 * row);
|
||||
for (uint8_t i = 0; i<16; i++)
|
||||
{
|
||||
uint8_t tmp[8] = {0};
|
||||
for (uint8_t j = 0; j < 8; j++)
|
||||
{
|
||||
uint8_t tmp_buf = buf[j*16 + i];
|
||||
int count = __builtin_popcount(tmp_buf);
|
||||
while (count > 0)
|
||||
{
|
||||
int pos = __builtin_ctz(tmp_buf);
|
||||
tmp[pos] |= 1UL << j;
|
||||
tmp_buf &= ~(1 << pos);
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t s = 0; s < 8; s++)
|
||||
{
|
||||
(void) spi2_sendRecv(tmp[s]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display_renderRows(uint8_t startRow, uint8_t endRow)
|
||||
|
|
|
|||
|
|
@ -28,12 +28,19 @@
|
|||
#include "hwconfig.h"
|
||||
|
||||
/*
|
||||
* LCD framebuffer, allocated on the heap by display_init().
|
||||
* LCD framebuffer, statically allocated.
|
||||
* Pixel format is black and white, one bit per pixel
|
||||
*/
|
||||
static uint8_t *frameBuffer;
|
||||
#define FB_SIZE (((SCREEN_HEIGHT * SCREEN_WIDTH) / 8 ) + 1)
|
||||
static uint8_t frameBuffer[FB_SIZE];
|
||||
|
||||
void sendByteToController(uint8_t value)
|
||||
/**
|
||||
* \internal
|
||||
* Send one byte to display controller, via bit banging.
|
||||
*
|
||||
* @param value: byte to be sent.
|
||||
*/
|
||||
static void sendByteToController(uint8_t value)
|
||||
{
|
||||
for(uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
|
|
@ -53,24 +60,44 @@ void sendByteToController(uint8_t value)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* Send one row of pixels to the display.
|
||||
* Pixels in framebuffer are stored "by rows", while display needs data to be
|
||||
* sent "by columns": this function performs the needed conversion.
|
||||
*
|
||||
* @param row: pixel row to be be sent.
|
||||
*/
|
||||
static void display_renderRow(uint8_t row)
|
||||
{
|
||||
/* magic stuff */
|
||||
uint8_t *buf = (frameBuffer + 128 * row);
|
||||
for (uint8_t i = 0; i<16; i++)
|
||||
{
|
||||
uint8_t tmp[8] = {0};
|
||||
for (uint8_t j = 0; j < 8; j++)
|
||||
{
|
||||
uint8_t tmp_buf = buf[j*16 + i];
|
||||
int count = __builtin_popcount(tmp_buf);
|
||||
while (count > 0)
|
||||
{
|
||||
int pos = __builtin_ctz(tmp_buf);
|
||||
tmp[pos] |= 1UL << j;
|
||||
tmp_buf &= ~(1 << pos);
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t s = 0; s < 8; s++)
|
||||
{
|
||||
sendByteToController(tmp[s]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void display_init()
|
||||
{
|
||||
/* Framebuffer size, in bytes */
|
||||
unsigned int fbSize = (SCREEN_HEIGHT * SCREEN_WIDTH)/8;
|
||||
if((fbSize * 8) < (SCREEN_HEIGHT * SCREEN_WIDTH)) fbSize += 1; /* Compensate for eventual truncation error in division */
|
||||
fbSize *= sizeof(uint8_t);
|
||||
|
||||
/* Allocate framebuffer */
|
||||
frameBuffer = (uint8_t *) malloc(fbSize);
|
||||
if(frameBuffer == NULL)
|
||||
{
|
||||
puts("*** LCD ERROR: cannot allocate framebuffer! ***");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear framebuffer, setting all pixels to 0x00 makes the screen white */
|
||||
memset(frameBuffer, 0x00, fbSize);
|
||||
|
||||
gpio_setMode(LCD_CS, OUTPUT);
|
||||
gpio_setMode(LCD_RST, OUTPUT);
|
||||
gpio_setMode(LCD_RS, OUTPUT);
|
||||
|
|
@ -102,37 +129,11 @@ void display_init()
|
|||
|
||||
void display_terminate()
|
||||
{
|
||||
if(frameBuffer != NULL)
|
||||
{
|
||||
free(frameBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void display_renderRow(uint8_t row)
|
||||
{
|
||||
/* magic stuff */
|
||||
uint8_t *buf = (frameBuffer + 128 * row);
|
||||
for (uint8_t i = 0; i<16; i++)
|
||||
{
|
||||
uint8_t tmp[8] = {0};
|
||||
for (uint8_t j = 0; j < 8; j++)
|
||||
{
|
||||
uint8_t tmp_buf = buf[j*16 + i];
|
||||
int count = __builtin_popcount(tmp_buf);
|
||||
while (count > 0)
|
||||
{
|
||||
int pos = __builtin_ctz(tmp_buf);
|
||||
tmp[pos] |= 1UL << j;
|
||||
tmp_buf &= ~(1 << pos);
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t s = 0; s < 8; s++)
|
||||
{
|
||||
sendByteToController(tmp[s]);
|
||||
}
|
||||
}
|
||||
gpio_setMode(LCD_CS, INPUT);
|
||||
gpio_setMode(LCD_RST, INPUT);
|
||||
gpio_setMode(LCD_RS, INPUT);
|
||||
gpio_setMode(LCD_CLK, INPUT);
|
||||
gpio_setMode(LCD_DAT, INPUT);
|
||||
}
|
||||
|
||||
void display_renderRows(uint8_t startRow, uint8_t endRow)
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ _main_stack_top = 0x20000000 + _main_stack_size;
|
|||
ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error");
|
||||
|
||||
/* Mapping the heap into the large 128KB RAM */
|
||||
_end = _main_stack_top;
|
||||
_heap_end = 0x20020000; /* end of available ram */
|
||||
|
||||
/* identify the Entry Point */
|
||||
|
|
@ -176,6 +175,12 @@ SECTIONS
|
|||
} > smallram
|
||||
_bss_end = .;
|
||||
|
||||
/*_end = .;*/
|
||||
/*PROVIDE(end = .);*/
|
||||
.bss2 :
|
||||
{
|
||||
*(.bss2)
|
||||
. = ALIGN(8);
|
||||
} > largeram
|
||||
|
||||
_end = .;
|
||||
PROVIDE(end = .);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ _main_stack_top = 0x10000000 + _main_stack_size;
|
|||
ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error");
|
||||
|
||||
/* Mapping the heap into the large 128KB RAM */
|
||||
_end = 0x20000000;
|
||||
_heap_end = 0x20020000; /* end of available ram */
|
||||
|
||||
/* identify the Entry Point */
|
||||
|
|
@ -175,6 +174,12 @@ SECTIONS
|
|||
} > smallram
|
||||
_bss_end = .;
|
||||
|
||||
/*_end = .;*/
|
||||
/*PROVIDE(end = .);*/
|
||||
.bss2 :
|
||||
{
|
||||
*(.bss2)
|
||||
. = ALIGN(8);
|
||||
} > largeram
|
||||
|
||||
_end = .;
|
||||
PROVIDE(end = .);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue