kopia lustrzana https://github.com/OpenRTX/OpenRTX
Module17: updated display drivers to new SPI subsystem
rodzic
5e94d2fef6
commit
5cc38316ea
|
@ -26,9 +26,11 @@
|
|||
#include <peripherals/gpio.h>
|
||||
#include <interfaces/delays.h>
|
||||
#include <hwconfig.h>
|
||||
#include <SPI2.h>
|
||||
#include <spi_stm32.h>
|
||||
#include "SH110x_Mod17.h"
|
||||
|
||||
extern const struct spiDevice spi2;
|
||||
|
||||
void SH110x_init()
|
||||
{
|
||||
gpio_setPin(LCD_CS);
|
||||
|
@ -39,37 +41,46 @@ void SH110x_init()
|
|||
gpio_setPin(LCD_RST);
|
||||
delayMs(50);
|
||||
|
||||
gpio_clearPin(LCD_CS);
|
||||
static const uint8_t init[] =
|
||||
{
|
||||
0xAE, /* SH110X_DISPLAYOFF */
|
||||
0xD5, /* SH110X_SETDISPLAYCLOCKDIV, 0x51 */
|
||||
0x51,
|
||||
0x81, /* SH110X_SETCONTRAST, 0x4F */
|
||||
0x4F,
|
||||
0xAD, /* SH110X_DCDC, 0x8A */
|
||||
0x8A,
|
||||
0xA1, /* SH110X_SEGREMAP */
|
||||
0xC0, /* SH110X_COMSCANINC */
|
||||
0xDC, /* SH110X_SETDISPSTARTLINE, 0x0 */
|
||||
0x00,
|
||||
0xD3, /* SH110X_SETDISPLAYOFFSET, 0x60 */
|
||||
0x60,
|
||||
0xD9, /* SH110X_SETPRECHARGE, 0x22 */
|
||||
0x22,
|
||||
0xDB, /* SH110X_SETVCOMDETECT, 0x35 */
|
||||
0x35,
|
||||
0xA8, /* SH110X_SETMULTIPLEX, 0x3F */
|
||||
0x3F,
|
||||
0xA4, /* SH110X_DISPLAYALLON_RESUME */
|
||||
0xA6, /* SH110X_NORMALDISPLAY */
|
||||
0xAF /* SH110x_DISPLAYON */
|
||||
};
|
||||
|
||||
gpio_clearPin(LCD_CS);
|
||||
gpio_clearPin(LCD_DC); /* DC low -> command mode */
|
||||
spi2_sendRecv(0xAE); /* SH110X_DISPLAYOFF */
|
||||
spi2_sendRecv(0xD5); /* SH110X_SETDISPLAYCLOCKDIV, 0x51 */
|
||||
spi2_sendRecv(0x51);
|
||||
spi2_sendRecv(0x81); /* SH110X_SETCONTRAST, 0x4F */
|
||||
spi2_sendRecv(0x4F);
|
||||
spi2_sendRecv(0xAD); /* SH110X_DCDC, 0x8A */
|
||||
spi2_sendRecv(0x8A);
|
||||
spi2_sendRecv(0xA1); /* SH110X_SEGREMAP */
|
||||
spi2_sendRecv(0xC0); /* SH110X_COMSCANINC */
|
||||
spi2_sendRecv(0xDC); /* SH110X_SETDISPSTARTLINE, 0x0 */
|
||||
spi2_sendRecv(0x00);
|
||||
spi2_sendRecv(0xD3); /* SH110X_SETDISPLAYOFFSET, 0x60 */
|
||||
spi2_sendRecv(0x60);
|
||||
spi2_sendRecv(0xD9); /* SH110X_SETPRECHARGE, 0x22 */
|
||||
spi2_sendRecv(0x22);
|
||||
spi2_sendRecv(0xDB); /* SH110X_SETVCOMDETECT, 0x35 */
|
||||
spi2_sendRecv(0x35);
|
||||
spi2_sendRecv(0xA8); /* SH110X_SETMULTIPLEX, 0x3F */
|
||||
spi2_sendRecv(0x3F);
|
||||
spi2_sendRecv(0xA4); /* SH110X_DISPLAYALLON_RESUME */
|
||||
spi2_sendRecv(0xA6); /* SH110X_NORMALDISPLAY */
|
||||
spi2_sendRecv(0xAF); /* SH110x_DISPLAYON */
|
||||
spi_send(&spi2, init, sizeof(init));
|
||||
gpio_setPin(LCD_CS);
|
||||
}
|
||||
|
||||
void SH110x_terminate()
|
||||
{
|
||||
spi2_sendRecv(0xAE);
|
||||
uint8_t dispOff = 0xAE;
|
||||
|
||||
gpio_clearPin(LCD_CS);
|
||||
gpio_clearPin(LCD_DC); /* DC low -> command mode */
|
||||
spi_send(&spi2, &dispOff, 1);
|
||||
gpio_setPin(LCD_CS);
|
||||
}
|
||||
|
||||
void SH110x_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
||||
|
@ -81,14 +92,17 @@ void SH110x_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
|||
{
|
||||
for(uint8_t x = 0; x < CONFIG_SCREEN_WIDTH/8; x++)
|
||||
{
|
||||
uint8_t cmd[3];
|
||||
cmd[0] = (y & 0x0F); /* Set Y position */
|
||||
cmd[1] = (0x10 | ((y >> 4) & 0x07));
|
||||
cmd[2] = (0xB0 | x); /* Set X position */
|
||||
|
||||
gpio_clearPin(LCD_DC); /* RS low -> command mode */
|
||||
(void) spi2_sendRecv(y & 0x0F); /* Set Y position */
|
||||
(void) spi2_sendRecv(0x10 | ((y >> 4) & 0x07));
|
||||
(void) spi2_sendRecv(0xB0 | x); /* Set X position */
|
||||
spi_send(&spi2, cmd, sizeof(cmd));
|
||||
gpio_setPin(LCD_DC); /* RS high -> data mode */
|
||||
|
||||
size_t pos = x + y * (CONFIG_SCREEN_WIDTH/8);
|
||||
spi2_sendRecv(frameBuffer[pos]);
|
||||
spi_send(&spi2, &frameBuffer[pos], 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,11 +116,12 @@ void SH110x_render(void *fb)
|
|||
|
||||
void SH110x_setContrast(uint8_t contrast)
|
||||
{
|
||||
uint8_t cmd[2];
|
||||
cmd[0] = 0x81; /* Set Electronic Volume */
|
||||
cmd[0] = contrast; /* Controller contrast range is 0 - 63 */
|
||||
|
||||
gpio_clearPin(LCD_CS);
|
||||
|
||||
gpio_clearPin(LCD_DC); /* RS low -> command mode */
|
||||
(void) spi2_sendRecv(0x81); /* Set Electronic Volume */
|
||||
(void) spi2_sendRecv(contrast); /* Controller contrast range is 0 - 63 */
|
||||
|
||||
gpio_clearPin(LCD_DC); /* RS low -> command mode */
|
||||
spi_send(&spi2, cmd, sizeof(cmd));
|
||||
gpio_setPin(LCD_CS);
|
||||
}
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
#include <interfaces/display.h>
|
||||
#include <interfaces/delays.h>
|
||||
#include <hwconfig.h>
|
||||
#include <SPI2.h>
|
||||
#include <spi_stm32.h>
|
||||
|
||||
extern const struct spiDevice spi2;
|
||||
|
||||
/**
|
||||
* \internal
|
||||
|
@ -50,7 +51,7 @@ void SSD1306_renderRow(uint8_t row, uint8_t *frameBuffer)
|
|||
out |= ((tmp >> (7-j)) & 0x01) << j;
|
||||
}
|
||||
|
||||
spi2_sendRecv(out);
|
||||
spi_send(&spi2, &out, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,37 +66,41 @@ void SSD1306_init()
|
|||
gpio_setPin(LCD_RST);
|
||||
delayMs(50);
|
||||
|
||||
gpio_clearPin(LCD_CS);
|
||||
static const uint8_t init[] =
|
||||
{
|
||||
0xAE, // SH110X_DISPLAYOFF
|
||||
0xD5, // SH110X_SETDISPLAYCLOCKDIV, 0x51
|
||||
0x51,
|
||||
0x81, // SH110X_SETCONTRAST, 0x4F
|
||||
0x4F,
|
||||
0xAD, // SH110X_DCDC, 0x8A
|
||||
0x8A,
|
||||
0xA0, // SH110X_SEGREMAP
|
||||
0xC0, // SH110X_COMSCANINC
|
||||
0xDC, // SH110X_SETDISPSTARTLINE, 0x0
|
||||
0x00,
|
||||
0xD3, // SH110X_SETDISPLAYOFFSET, 0x60
|
||||
0x60,
|
||||
0xD9, // SH110X_SETPRECHARGE, 0x22
|
||||
0x22,
|
||||
0xDB, // SH110X_SETVCOMDETECT, 0x35
|
||||
0x35,
|
||||
0xA8, // SH110X_SETMULTIPLEX, 0x3F
|
||||
0x3F,
|
||||
0xA4, // SH110X_DISPLAYALLON_RESUME
|
||||
0xA6, // SH110X_NORMALDISPLAY
|
||||
0xAF // SH110x_DISPLAYON
|
||||
};
|
||||
|
||||
gpio_clearPin(LCD_RS);// RS low -> command mode
|
||||
spi2_sendRecv(0xAE); // SH110X_DISPLAYOFF,
|
||||
spi2_sendRecv(0xd5); // SH110X_SETDISPLAYCLOCKDIV, 0x51,
|
||||
spi2_sendRecv(0x51);
|
||||
spi2_sendRecv(0x81); // SH110X_SETCONTRAST, 0x4F,
|
||||
spi2_sendRecv(0x4F);
|
||||
spi2_sendRecv(0xAD); // SH110X_DCDC, 0x8A,
|
||||
spi2_sendRecv(0x8A);
|
||||
spi2_sendRecv(0xA0); // SH110X_SEGREMAP,
|
||||
spi2_sendRecv(0xC0); // SH110X_COMSCANINC,
|
||||
spi2_sendRecv(0xDC); // SH110X_SETDISPSTARTLINE, 0x0,
|
||||
spi2_sendRecv(0x00);
|
||||
spi2_sendRecv(0xd3); // SH110X_SETDISPLAYOFFSET, 0x60,
|
||||
spi2_sendRecv(0x60);
|
||||
spi2_sendRecv(0xd9); // SH110X_SETPRECHARGE, 0x22,
|
||||
spi2_sendRecv(0x22);
|
||||
spi2_sendRecv(0xdb); // SH110X_SETVCOMDETECT, 0x35,
|
||||
spi2_sendRecv(0x35);
|
||||
spi2_sendRecv(0xa8); // SH110X_SETMULTIPLEX, 0x3F,
|
||||
spi2_sendRecv(0x3f);
|
||||
spi2_sendRecv(0xa4); // SH110X_DISPLAYALLON_RESUME,
|
||||
spi2_sendRecv(0xa6); // SH110X_NORMALDISPLAY,
|
||||
spi2_sendRecv(0xAF); // SH110x_DISPLAYON
|
||||
gpio_clearPin(LCD_CS);
|
||||
gpio_clearPin(LCD_DC);
|
||||
spi_send(&spi2, init, sizeof(init));
|
||||
gpio_setPin(LCD_CS);
|
||||
}
|
||||
|
||||
void SSD1306_terminate()
|
||||
{
|
||||
spi2_terminate();
|
||||
|
||||
}
|
||||
|
||||
void SSD1306_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
||||
|
@ -104,10 +109,13 @@ void SSD1306_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
|||
|
||||
for(uint8_t row = startRow; row <= endRow; row++)
|
||||
{
|
||||
uint8_t cmd[3];
|
||||
cmd[0] = 0xB0 | row; /* Set Y position */
|
||||
cmd[1] = 0x00; /* Set X position */
|
||||
cmd[2] = 0x10;
|
||||
|
||||
gpio_clearPin(LCD_RS); /* RS low -> command mode */
|
||||
(void) spi2_sendRecv(0xB0 | row); /* Set Y position */
|
||||
(void) spi2_sendRecv(0x00); /* Set X position */
|
||||
(void) spi2_sendRecv(0x10);
|
||||
spi_send(&spi2, cmd, sizeof(cmd));
|
||||
gpio_setPin(LCD_RS); /* RS high -> data mode */
|
||||
SSD1306_renderRow(row, (uint8_t *) fb);
|
||||
}
|
||||
|
@ -122,11 +130,12 @@ void SSD1306_render(void *fb)
|
|||
|
||||
void SSD1306_setContrast(uint8_t contrast)
|
||||
{
|
||||
uint8_t cmd[2];
|
||||
cmd[0] = 0x81; /* Set Electronic Volume */
|
||||
cmd[0] = contrast; /* Controller contrast range is 0 - 63 */
|
||||
|
||||
gpio_clearPin(LCD_CS);
|
||||
|
||||
gpio_clearPin(LCD_RS); /* RS low -> command mode */
|
||||
(void) spi2_sendRecv(0x81); /* Set Electronic Volume */
|
||||
(void) spi2_sendRecv(contrast); /* Controller contrast range is 0 - 63 */
|
||||
|
||||
gpio_clearPin(LCD_DC); /* RS low -> command mode */
|
||||
spi_send(&spi2, cmd, sizeof(cmd));
|
||||
gpio_setPin(LCD_CS);
|
||||
}
|
||||
|
|
|
@ -26,9 +26,11 @@
|
|||
#include <peripherals/gpio.h>
|
||||
#include <interfaces/delays.h>
|
||||
#include <hwconfig.h>
|
||||
#include <SPI2.h>
|
||||
#include <spi_stm32.h>
|
||||
#include "SSD1309_Mod17.h"
|
||||
|
||||
extern const struct spiDevice spi2;
|
||||
|
||||
void SSD1309_init()
|
||||
{
|
||||
gpio_setPin(LCD_CS);
|
||||
|
@ -39,28 +41,36 @@ void SSD1309_init()
|
|||
gpio_setPin(LCD_RST);
|
||||
delayMs(50);
|
||||
|
||||
static const uint8_t init[] =
|
||||
{
|
||||
0xAE, // SSD1309_DISPLAYOFF,
|
||||
0xD5, // Set display clock division
|
||||
0xF0,
|
||||
0xA8, // Set multiplex ratio, 1/64
|
||||
0x3F,
|
||||
0x81, // Set contrast control
|
||||
0x32,
|
||||
0xD9, // Set pre-charge period
|
||||
0xF1,
|
||||
0xDB, // Set VCOMH Deselect level
|
||||
0x30,
|
||||
0xAF
|
||||
};
|
||||
|
||||
gpio_clearPin(LCD_CS);
|
||||
|
||||
gpio_clearPin(LCD_DC);// DC low -> command mode
|
||||
|
||||
spi2_sendRecv(0xAE); // SSD1309_DISPLAYOFF,
|
||||
spi2_sendRecv(0xD5); // Set display clock division
|
||||
spi2_sendRecv(0xF0);
|
||||
spi2_sendRecv(0xA8); // Set multiplex ratio, 1/64
|
||||
spi2_sendRecv(0x3F);
|
||||
spi2_sendRecv(0x81); // Set contrast control
|
||||
spi2_sendRecv(0x32);
|
||||
spi2_sendRecv(0xD9); // Set pre-charge period
|
||||
spi2_sendRecv(0xF1);
|
||||
spi2_sendRecv(0xDB); // Set VCOMH Deselect level
|
||||
spi2_sendRecv(0x30);
|
||||
spi2_sendRecv(0xAF);
|
||||
gpio_clearPin(LCD_DC);
|
||||
spi_send(&spi2, init, sizeof(init));
|
||||
gpio_setPin(LCD_CS);
|
||||
}
|
||||
|
||||
void SSD1309_terminate()
|
||||
{
|
||||
spi2_sendRecv(0xAE);
|
||||
uint8_t dispOff = 0xAE;
|
||||
|
||||
gpio_clearPin(LCD_CS);
|
||||
gpio_clearPin(LCD_DC); /* DC low -> command mode */
|
||||
spi_send(&spi2, &dispOff, 1);
|
||||
gpio_setPin(LCD_CS);
|
||||
}
|
||||
|
||||
void SSD1309_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
||||
|
@ -70,34 +80,38 @@ void SSD1309_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
|||
// Convert rows to pages
|
||||
uint8_t startPage = startRow / 8;
|
||||
uint8_t endPage = endRow / 8;
|
||||
uint8_t cmd[3];
|
||||
|
||||
gpio_clearPin(LCD_DC);
|
||||
spi2_sendRecv(0x20); // Set page addressing mode
|
||||
spi2_sendRecv(0x02);
|
||||
cmd[0] = 0x20; // Set page addressing mode
|
||||
cmd[1] = 0x02;
|
||||
spi_send(&spi2, cmd, 2);
|
||||
|
||||
uint8_t *framebuffer = (uint8_t *)fb;
|
||||
|
||||
for(uint8_t page = startPage; page < endPage; page++)
|
||||
{
|
||||
gpio_clearPin(LCD_DC);
|
||||
spi2_sendRecv(0xB0 | page);
|
||||
spi2_sendRecv(0x00);
|
||||
spi2_sendRecv(0x10);
|
||||
cmd[0] = 0xB0 | page;
|
||||
cmd[1] = 0x00;
|
||||
cmd[1] = 0x10;
|
||||
spi_send(&spi2, cmd, 3);
|
||||
gpio_setPin(LCD_DC); // DC high -> data mode
|
||||
|
||||
uint8_t topRow = page*8;
|
||||
|
||||
uint8_t topRow = page * 8;
|
||||
for(uint8_t col = 0; col < CONFIG_SCREEN_WIDTH; col++)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
uint8_t bit_offset = col%8; // Bit offset in the fb for the column we are refreshing
|
||||
uint8_t bit_offset = col % 8; // Bit offset in the fb for the column we are refreshing
|
||||
// Gather the 8 rows of data
|
||||
for(uint8_t row = 0; row < 8; row++)
|
||||
{
|
||||
uint8_t cell = framebuffer[((topRow+row)*CONFIG_SCREEN_WIDTH+col)/8];
|
||||
data |= ((cell>>bit_offset)&0x01) << row;
|
||||
size_t pos = ((topRow + row) * CONFIG_SCREEN_WIDTH + col) / 8;
|
||||
uint8_t cell = framebuffer[pos];
|
||||
data |= ((cell >> bit_offset) & 0x01) << row;
|
||||
}
|
||||
spi2_sendRecv(data);
|
||||
|
||||
spi_send(&spi2, &data, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,14 +120,18 @@ void SSD1309_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
|||
|
||||
void SSD1309_render(void *fb)
|
||||
{
|
||||
gpio_clearPin(LCD_CS);
|
||||
static const uint8_t cmd[] =
|
||||
{
|
||||
0xB0,
|
||||
0x20, // Set horizontal addressing mode
|
||||
0x00,
|
||||
0x00,
|
||||
0x10
|
||||
};
|
||||
|
||||
gpio_clearPin(LCD_CS);
|
||||
gpio_clearPin(LCD_DC);
|
||||
spi2_sendRecv(0xB0);
|
||||
spi2_sendRecv(0x20); // Set horizontal addressing mode
|
||||
spi2_sendRecv(0x00);
|
||||
spi2_sendRecv(0x00);
|
||||
spi2_sendRecv(0x10);
|
||||
spi_send(&spi2, cmd, sizeof(cmd));
|
||||
gpio_setPin(LCD_DC); // DC high -> data mode
|
||||
|
||||
uint8_t *framebuffer = (uint8_t *)fb;
|
||||
|
@ -124,27 +142,30 @@ void SSD1309_render(void *fb)
|
|||
for(uint8_t col = 0; col < CONFIG_SCREEN_WIDTH; col++)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
uint8_t bit_offset = col%8; // Bit offset in the fb for the column we are refreshing
|
||||
uint8_t bit_offset = col % 8; // Bit offset in the fb for the column we are refreshing
|
||||
// Gather the 8 rows of data
|
||||
for(uint8_t subRow = 0; subRow < 8; subRow++)
|
||||
{
|
||||
uint8_t cell = framebuffer[((topRow+subRow)*CONFIG_SCREEN_WIDTH+col)/8];
|
||||
data |= ((cell>>bit_offset)&0x01) << subRow;
|
||||
size_t pos = ((topRow + subRow) * CONFIG_SCREEN_WIDTH + col) / 8;
|
||||
uint8_t cell = framebuffer[pos];
|
||||
data |= ((cell >> bit_offset) & 0x01) << subRow;
|
||||
}
|
||||
spi2_sendRecv(data);
|
||||
|
||||
spi_send(&spi2, &data, 1);
|
||||
}
|
||||
}
|
||||
|
||||
gpio_setPin(LCD_CS);
|
||||
gpio_setPin(LCD_CS);
|
||||
}
|
||||
|
||||
void SSD1309_setContrast(uint8_t contrast)
|
||||
{
|
||||
uint8_t cmd[2];
|
||||
cmd[0] = 0x81; /* Set Electronic Volume */
|
||||
cmd[0] = contrast; /* Controller contrast range is 0 - 63 */
|
||||
|
||||
gpio_clearPin(LCD_CS);
|
||||
|
||||
gpio_clearPin(LCD_DC); /* DC low -> command mode */
|
||||
(void) spi2_sendRecv(0x81); /* Set Electronic Volume */
|
||||
(void) spi2_sendRecv(contrast); /* Controller contrast range is 0 - 63 */
|
||||
|
||||
gpio_clearPin(LCD_DC); /* RS low -> command mode */
|
||||
spi_send(&spi2, cmd, sizeof(cmd));
|
||||
gpio_setPin(LCD_CS);
|
||||
}
|
||||
|
|
|
@ -22,10 +22,11 @@
|
|||
#include <peripherals/gpio.h>
|
||||
#include <hwconfig.h>
|
||||
#include <interfaces/platform.h>
|
||||
#include <SPI2.h>
|
||||
#include <spi_stm32.h>
|
||||
#include "SH110x_Mod17.h"
|
||||
#include "SSD1309_Mod17.h"
|
||||
|
||||
SPI_STM32_DEVICE_DEFINE(spi2, SPI2, NULL)
|
||||
|
||||
struct displayFuncs
|
||||
{
|
||||
|
@ -73,7 +74,7 @@ void display_init()
|
|||
gpio_setMode(SPI2_SCK, ALTERNATE | ALTERNATE_FUNC(5));
|
||||
gpio_setMode(SPI2_MOSI, ALTERNATE | ALTERNATE_FUNC(5));
|
||||
gpio_setMode(SPI2_MISO, ALTERNATE | ALTERNATE_FUNC(5));
|
||||
spi2_init();
|
||||
spiStm32_init(&spi2, 1300000, 0);
|
||||
|
||||
/*
|
||||
* Initialise GPIOs for LCD control
|
||||
|
@ -88,7 +89,7 @@ void display_init()
|
|||
void display_terminate()
|
||||
{
|
||||
display.terminate();
|
||||
spi2_terminate();
|
||||
spiStm32_terminate(&spi2);
|
||||
}
|
||||
|
||||
void display_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
||||
|
|
Ładowanie…
Reference in New Issue