Commit 60d149a2 authored by Projects's avatar Projects

Groundwork for DMA transfers in LCD driver.

parent 1f88c062
...@@ -30,8 +30,20 @@ ...@@ -30,8 +30,20 @@
#include <em_rtc.h> #include <em_rtc.h>
#include <udelay.h> #include <udelay.h>
#define LCD_NODMA
// Additional bytes to control the LCD; required for DMA transfers
#ifdef LCD_NODMA
#define CONTROL_BYTES 0
#else
#define CONTROL_BYTES 2
#endif
// Number of bytes to store one line
#define LCD_STRIDE (LCD_WIDTH / 8 + CONTROL_BYTES)
// Framebuffer - pixels are stored as consecutive rows // Framebuffer - pixels are stored as consecutive rows
static uint8_t buffer[LCD_WIDTH / 8 * LCD_HEIGHT]; static uint8_t buffer[LCD_STRIDE * LCD_HEIGHT];
static void spi_init(void) static void spi_init(void)
{ {
...@@ -44,7 +56,7 @@ static void spi_init(void) ...@@ -44,7 +56,7 @@ static void spi_init(void)
LCD_SPI_UNIT->ROUTE = (USART_ROUTE_CLKPEN | USART_ROUTE_TXPEN | LCD_SPI_LOCATION); LCD_SPI_UNIT->ROUTE = (USART_ROUTE_CLKPEN | USART_ROUTE_TXPEN | LCD_SPI_LOCATION);
} }
static void spi_transmit(uint8_t *data, uint8_t length) static void spi_transmit(uint8_t *data, uint16_t length)
{ {
while(length > 0) while(length > 0)
{ {
...@@ -155,11 +167,29 @@ void lcd_power(uint8_t enable) ...@@ -155,11 +167,29 @@ void lcd_power(uint8_t enable)
void lcd_clear(void) void lcd_clear(void)
{ {
uint16_t cmd, i; uint16_t cmd;
uint8_t *p = buffer;
#ifdef LCD_NODMA
uint16_t i;
// Clear pixel buffer // Clear pixel buffer
for(i = 0; i < sizeof(buffer); ++i) for(i = 0; i < sizeof(buffer); ++i)
buffer[i] = 0x00; *p++ = 0x00;
#else
uint8_t x, y;
for(y = 0; y < LCD_HEIGHT; ++y)
{
// Clear framebuffer
for(x = 0; x < LCD_WIDTH / 8; ++x)
*p++ = 0x00;
// Add control codes
*p++ = 0xff; // Dummy
*p++ = (y + 2); // Address of next line
}
#endif
// Send command to clear the display // Send command to clear the display
GPIO_PinOutSet(LCD_PORT_SCS, LCD_PIN_SCS); GPIO_PinOutSet(LCD_PORT_SCS, LCD_PIN_SCS);
...@@ -180,7 +210,7 @@ void lcd_update(void) ...@@ -180,7 +210,7 @@ void lcd_update(void)
// TODO use DMA // TODO use DMA
uint16_t cmd; uint16_t cmd;
uint8_t i; uint16_t i;
uint8_t *p = (uint8_t*) buffer; uint8_t *p = (uint8_t*) buffer;
GPIO_PinOutSet(LCD_PORT_SCS, LCD_PIN_SCS); GPIO_PinOutSet(LCD_PORT_SCS, LCD_PIN_SCS);
...@@ -190,6 +220,7 @@ void lcd_update(void) ...@@ -190,6 +220,7 @@ void lcd_update(void)
cmd = LCD_CMD_UPDATE | (START_ROW << 8); cmd = LCD_CMD_UPDATE | (START_ROW << 8);
spi_transmit((uint8_t*) &cmd, 2); spi_transmit((uint8_t*) &cmd, 2);
#ifdef LCD_NODMA
for(i = 0; i < LCD_HEIGHT; ++i) for(i = 0; i < LCD_HEIGHT; ++i)
{ {
// Send pixels for this line // Send pixels for this line
...@@ -204,6 +235,14 @@ void lcd_update(void) ...@@ -204,6 +235,14 @@ void lcd_update(void)
spi_transmit((uint8_t*) &cmd, 2); spi_transmit((uint8_t*) &cmd, 2);
} }
#else
spi_transmit(p, LCD_STRIDE * LCD_HEIGHT);
/*for(i = 0; i < LCD_STRIDE * LCD_HEIGHT / 2; i += 2)
{
spi_transmit(p, 2);
p += 2;
}*/
#endif
timer_delay(2); timer_delay(2);
GPIO_PinOutClear(LCD_PORT_SCS, LCD_PIN_SCS); GPIO_PinOutClear(LCD_PORT_SCS, LCD_PIN_SCS);
...@@ -211,8 +250,11 @@ void lcd_update(void) ...@@ -211,8 +250,11 @@ void lcd_update(void)
void lcd_set_pixel(uint8_t x, uint8_t y, uint8_t value) void lcd_set_pixel(uint8_t x, uint8_t y, uint8_t value)
{ {
uint8_t mask = 1 << (x & 0x07); // == 1 << (x % 8) x %= LCD_WIDTH;
uint16_t offset = (y * LCD_WIDTH >> 3) + (x >> 3); // == (y * LCD_WIDTH / 8) + x / 8 y %= LCD_HEIGHT;
uint8_t mask = 1 << (x & 0x07); // == 1 << (x % 8)
uint16_t offset = (y * LCD_STRIDE) + (x >> 3); // == y * LCD_STRIDE + x / 8
if(value) if(value)
buffer[offset] |= mask; buffer[offset] |= mask;
...@@ -222,16 +264,22 @@ void lcd_set_pixel(uint8_t x, uint8_t y, uint8_t value) ...@@ -222,16 +264,22 @@ void lcd_set_pixel(uint8_t x, uint8_t y, uint8_t value)
void lcd_toggle_pixel(uint8_t x, uint8_t y) void lcd_toggle_pixel(uint8_t x, uint8_t y)
{ {
uint8_t mask = 1 << (x & 0x07); // == 1 << (x % 8) x %= LCD_WIDTH;
uint16_t offset = (y * LCD_WIDTH >> 3) + (x >> 3); // == (y * LCD_WIDTH / 8) + x / 8 y %= LCD_HEIGHT;
uint8_t mask = 1 << (x & 0x07); // == 1 << (x % 8)
uint16_t offset = (y * LCD_STRIDE) + (x >> 3); // == y * LCD_STRIDE + x / 8
buffer[offset] ^= mask; buffer[offset] ^= mask;
} }
uint8_t lcd_get_pixel(uint8_t x, uint8_t y) uint8_t lcd_get_pixel(uint8_t x, uint8_t y)
{ {
uint8_t mask = 1 << (x & 0x07); // == 1 << (x % 8) x %= LCD_WIDTH;
uint16_t offset = (y * LCD_WIDTH >> 3) + (x >> 3); // == (y * LCD_WIDTH / 8) + x / 8 y %= LCD_HEIGHT;
uint8_t mask = 1 << (x & 0x07); // == 1 << (x % 8)
uint16_t offset = (y * LCD_STRIDE) + (x >> 3); // == y * LCD_STRIDE + x / 8
return buffer[offset] & mask; return buffer[offset] & mask;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment