Module17: updated display drivers to new SPI subsystem
This commit is contained in:
parent
5e94d2fef6
commit
5cc38316ea
|
|
@ -26,9 +26,11 @@
|
||||||
#include <peripherals/gpio.h>
|
#include <peripherals/gpio.h>
|
||||||
#include <interfaces/delays.h>
|
#include <interfaces/delays.h>
|
||||||
#include <hwconfig.h>
|
#include <hwconfig.h>
|
||||||
#include <SPI2.h>
|
#include <spi_stm32.h>
|
||||||
#include "SH110x_Mod17.h"
|
#include "SH110x_Mod17.h"
|
||||||
|
|
||||||
|
extern const struct spiDevice spi2;
|
||||||
|
|
||||||
void SH110x_init()
|
void SH110x_init()
|
||||||
{
|
{
|
||||||
gpio_setPin(LCD_CS);
|
gpio_setPin(LCD_CS);
|
||||||
|
|
@ -39,37 +41,46 @@ void SH110x_init()
|
||||||
gpio_setPin(LCD_RST);
|
gpio_setPin(LCD_RST);
|
||||||
delayMs(50);
|
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 */
|
gpio_clearPin(LCD_DC); /* DC low -> command mode */
|
||||||
spi2_sendRecv(0xAE); /* SH110X_DISPLAYOFF */
|
spi_send(&spi2, init, sizeof(init));
|
||||||
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 */
|
|
||||||
gpio_setPin(LCD_CS);
|
gpio_setPin(LCD_CS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SH110x_terminate()
|
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)
|
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++)
|
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 */
|
gpio_clearPin(LCD_DC); /* RS low -> command mode */
|
||||||
(void) spi2_sendRecv(y & 0x0F); /* Set Y position */
|
spi_send(&spi2, cmd, sizeof(cmd));
|
||||||
(void) spi2_sendRecv(0x10 | ((y >> 4) & 0x07));
|
|
||||||
(void) spi2_sendRecv(0xB0 | x); /* Set X position */
|
|
||||||
gpio_setPin(LCD_DC); /* RS high -> data mode */
|
gpio_setPin(LCD_DC); /* RS high -> data mode */
|
||||||
|
|
||||||
size_t pos = x + y * (CONFIG_SCREEN_WIDTH/8);
|
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)
|
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_CS);
|
||||||
|
gpio_clearPin(LCD_DC); /* RS low -> command mode */
|
||||||
gpio_clearPin(LCD_DC); /* RS low -> command mode */
|
spi_send(&spi2, cmd, sizeof(cmd));
|
||||||
(void) spi2_sendRecv(0x81); /* Set Electronic Volume */
|
|
||||||
(void) spi2_sendRecv(contrast); /* Controller contrast range is 0 - 63 */
|
|
||||||
|
|
||||||
gpio_setPin(LCD_CS);
|
gpio_setPin(LCD_CS);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,9 @@
|
||||||
#include <interfaces/display.h>
|
#include <interfaces/display.h>
|
||||||
#include <interfaces/delays.h>
|
#include <interfaces/delays.h>
|
||||||
#include <hwconfig.h>
|
#include <hwconfig.h>
|
||||||
#include <SPI2.h>
|
#include <spi_stm32.h>
|
||||||
|
|
||||||
|
extern const struct spiDevice spi2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \internal
|
* \internal
|
||||||
|
|
@ -50,7 +51,7 @@ void SSD1306_renderRow(uint8_t row, uint8_t *frameBuffer)
|
||||||
out |= ((tmp >> (7-j)) & 0x01) << j;
|
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);
|
gpio_setPin(LCD_RST);
|
||||||
delayMs(50);
|
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
|
gpio_clearPin(LCD_CS);
|
||||||
spi2_sendRecv(0xAE); // SH110X_DISPLAYOFF,
|
gpio_clearPin(LCD_DC);
|
||||||
spi2_sendRecv(0xd5); // SH110X_SETDISPLAYCLOCKDIV, 0x51,
|
spi_send(&spi2, init, sizeof(init));
|
||||||
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_setPin(LCD_CS);
|
gpio_setPin(LCD_CS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD1306_terminate()
|
void SSD1306_terminate()
|
||||||
{
|
{
|
||||||
spi2_terminate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD1306_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
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++)
|
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 */
|
gpio_clearPin(LCD_RS); /* RS low -> command mode */
|
||||||
(void) spi2_sendRecv(0xB0 | row); /* Set Y position */
|
spi_send(&spi2, cmd, sizeof(cmd));
|
||||||
(void) spi2_sendRecv(0x00); /* Set X position */
|
|
||||||
(void) spi2_sendRecv(0x10);
|
|
||||||
gpio_setPin(LCD_RS); /* RS high -> data mode */
|
gpio_setPin(LCD_RS); /* RS high -> data mode */
|
||||||
SSD1306_renderRow(row, (uint8_t *) fb);
|
SSD1306_renderRow(row, (uint8_t *) fb);
|
||||||
}
|
}
|
||||||
|
|
@ -122,11 +130,12 @@ void SSD1306_render(void *fb)
|
||||||
|
|
||||||
void SSD1306_setContrast(uint8_t contrast)
|
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_CS);
|
||||||
|
gpio_clearPin(LCD_DC); /* RS low -> command mode */
|
||||||
gpio_clearPin(LCD_RS); /* RS low -> command mode */
|
spi_send(&spi2, cmd, sizeof(cmd));
|
||||||
(void) spi2_sendRecv(0x81); /* Set Electronic Volume */
|
|
||||||
(void) spi2_sendRecv(contrast); /* Controller contrast range is 0 - 63 */
|
|
||||||
|
|
||||||
gpio_setPin(LCD_CS);
|
gpio_setPin(LCD_CS);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,11 @@
|
||||||
#include <peripherals/gpio.h>
|
#include <peripherals/gpio.h>
|
||||||
#include <interfaces/delays.h>
|
#include <interfaces/delays.h>
|
||||||
#include <hwconfig.h>
|
#include <hwconfig.h>
|
||||||
#include <SPI2.h>
|
#include <spi_stm32.h>
|
||||||
#include "SSD1309_Mod17.h"
|
#include "SSD1309_Mod17.h"
|
||||||
|
|
||||||
|
extern const struct spiDevice spi2;
|
||||||
|
|
||||||
void SSD1309_init()
|
void SSD1309_init()
|
||||||
{
|
{
|
||||||
gpio_setPin(LCD_CS);
|
gpio_setPin(LCD_CS);
|
||||||
|
|
@ -39,28 +41,36 @@ void SSD1309_init()
|
||||||
gpio_setPin(LCD_RST);
|
gpio_setPin(LCD_RST);
|
||||||
delayMs(50);
|
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_CS);
|
||||||
|
gpio_clearPin(LCD_DC);
|
||||||
gpio_clearPin(LCD_DC);// DC low -> command mode
|
spi_send(&spi2, init, sizeof(init));
|
||||||
|
|
||||||
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_setPin(LCD_CS);
|
gpio_setPin(LCD_CS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD1309_terminate()
|
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)
|
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
|
// Convert rows to pages
|
||||||
uint8_t startPage = startRow / 8;
|
uint8_t startPage = startRow / 8;
|
||||||
uint8_t endPage = endRow / 8;
|
uint8_t endPage = endRow / 8;
|
||||||
|
uint8_t cmd[3];
|
||||||
|
|
||||||
gpio_clearPin(LCD_DC);
|
gpio_clearPin(LCD_DC);
|
||||||
spi2_sendRecv(0x20); // Set page addressing mode
|
cmd[0] = 0x20; // Set page addressing mode
|
||||||
spi2_sendRecv(0x02);
|
cmd[1] = 0x02;
|
||||||
|
spi_send(&spi2, cmd, 2);
|
||||||
|
|
||||||
uint8_t *framebuffer = (uint8_t *)fb;
|
uint8_t *framebuffer = (uint8_t *)fb;
|
||||||
|
|
||||||
for(uint8_t page = startPage; page < endPage; page++)
|
for(uint8_t page = startPage; page < endPage; page++)
|
||||||
{
|
{
|
||||||
gpio_clearPin(LCD_DC);
|
gpio_clearPin(LCD_DC);
|
||||||
spi2_sendRecv(0xB0 | page);
|
cmd[0] = 0xB0 | page;
|
||||||
spi2_sendRecv(0x00);
|
cmd[1] = 0x00;
|
||||||
spi2_sendRecv(0x10);
|
cmd[1] = 0x10;
|
||||||
|
spi_send(&spi2, cmd, 3);
|
||||||
gpio_setPin(LCD_DC); // DC high -> data mode
|
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++)
|
for(uint8_t col = 0; col < CONFIG_SCREEN_WIDTH; col++)
|
||||||
{
|
{
|
||||||
uint8_t data = 0;
|
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
|
// Gather the 8 rows of data
|
||||||
for(uint8_t row = 0; row < 8; row++)
|
for(uint8_t row = 0; row < 8; row++)
|
||||||
{
|
{
|
||||||
uint8_t cell = framebuffer[((topRow+row)*CONFIG_SCREEN_WIDTH+col)/8];
|
size_t pos = ((topRow + row) * CONFIG_SCREEN_WIDTH + col) / 8;
|
||||||
data |= ((cell>>bit_offset)&0x01) << row;
|
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)
|
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);
|
gpio_clearPin(LCD_DC);
|
||||||
spi2_sendRecv(0xB0);
|
spi_send(&spi2, cmd, sizeof(cmd));
|
||||||
spi2_sendRecv(0x20); // Set horizontal addressing mode
|
|
||||||
spi2_sendRecv(0x00);
|
|
||||||
spi2_sendRecv(0x00);
|
|
||||||
spi2_sendRecv(0x10);
|
|
||||||
gpio_setPin(LCD_DC); // DC high -> data mode
|
gpio_setPin(LCD_DC); // DC high -> data mode
|
||||||
|
|
||||||
uint8_t *framebuffer = (uint8_t *)fb;
|
uint8_t *framebuffer = (uint8_t *)fb;
|
||||||
|
|
@ -124,14 +142,16 @@ void SSD1309_render(void *fb)
|
||||||
for(uint8_t col = 0; col < CONFIG_SCREEN_WIDTH; col++)
|
for(uint8_t col = 0; col < CONFIG_SCREEN_WIDTH; col++)
|
||||||
{
|
{
|
||||||
uint8_t data = 0;
|
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
|
// Gather the 8 rows of data
|
||||||
for(uint8_t subRow = 0; subRow < 8; subRow++)
|
for(uint8_t subRow = 0; subRow < 8; subRow++)
|
||||||
{
|
{
|
||||||
uint8_t cell = framebuffer[((topRow+subRow)*CONFIG_SCREEN_WIDTH+col)/8];
|
size_t pos = ((topRow + subRow) * CONFIG_SCREEN_WIDTH + col) / 8;
|
||||||
data |= ((cell>>bit_offset)&0x01) << subRow;
|
uint8_t cell = framebuffer[pos];
|
||||||
|
data |= ((cell >> bit_offset) & 0x01) << subRow;
|
||||||
}
|
}
|
||||||
spi2_sendRecv(data);
|
|
||||||
|
spi_send(&spi2, &data, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,11 +160,12 @@ void SSD1309_render(void *fb)
|
||||||
|
|
||||||
void SSD1309_setContrast(uint8_t contrast)
|
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_CS);
|
||||||
|
gpio_clearPin(LCD_DC); /* RS low -> command mode */
|
||||||
gpio_clearPin(LCD_DC); /* DC low -> command mode */
|
spi_send(&spi2, cmd, sizeof(cmd));
|
||||||
(void) spi2_sendRecv(0x81); /* Set Electronic Volume */
|
|
||||||
(void) spi2_sendRecv(contrast); /* Controller contrast range is 0 - 63 */
|
|
||||||
|
|
||||||
gpio_setPin(LCD_CS);
|
gpio_setPin(LCD_CS);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,11 @@
|
||||||
#include <peripherals/gpio.h>
|
#include <peripherals/gpio.h>
|
||||||
#include <hwconfig.h>
|
#include <hwconfig.h>
|
||||||
#include <interfaces/platform.h>
|
#include <interfaces/platform.h>
|
||||||
#include <SPI2.h>
|
#include <spi_stm32.h>
|
||||||
#include "SH110x_Mod17.h"
|
#include "SH110x_Mod17.h"
|
||||||
#include "SSD1309_Mod17.h"
|
#include "SSD1309_Mod17.h"
|
||||||
|
|
||||||
|
SPI_STM32_DEVICE_DEFINE(spi2, SPI2, NULL)
|
||||||
|
|
||||||
struct displayFuncs
|
struct displayFuncs
|
||||||
{
|
{
|
||||||
|
|
@ -73,7 +74,7 @@ void display_init()
|
||||||
gpio_setMode(SPI2_SCK, ALTERNATE | ALTERNATE_FUNC(5));
|
gpio_setMode(SPI2_SCK, ALTERNATE | ALTERNATE_FUNC(5));
|
||||||
gpio_setMode(SPI2_MOSI, ALTERNATE | ALTERNATE_FUNC(5));
|
gpio_setMode(SPI2_MOSI, ALTERNATE | ALTERNATE_FUNC(5));
|
||||||
gpio_setMode(SPI2_MISO, ALTERNATE | ALTERNATE_FUNC(5));
|
gpio_setMode(SPI2_MISO, ALTERNATE | ALTERNATE_FUNC(5));
|
||||||
spi2_init();
|
spiStm32_init(&spi2, 1300000, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialise GPIOs for LCD control
|
* Initialise GPIOs for LCD control
|
||||||
|
|
@ -88,7 +89,7 @@ void display_init()
|
||||||
void display_terminate()
|
void display_terminate()
|
||||||
{
|
{
|
||||||
display.terminate();
|
display.terminate();
|
||||||
spi2_terminate();
|
spiStm32_terminate(&spi2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
void display_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue