-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gpboot: Add rudimentary ST7585 LCD driver
Add a basic, bit-banged ST7585 LCD driver, useful for showing a boot logo on the Hero4's front panel display. Signed-off-by: evilwombat <evilwombat@server.fake>
- Loading branch information
evilwombat
committed
Dec 30, 2015
1 parent
f1ab838
commit f967021
Showing
2 changed files
with
181 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
#include <libusb.h> | ||
#include "gp_api.h" | ||
|
||
#define GPIO_BIT(a) (1 << (a & 0x1f)) | ||
|
||
#define GPIO_AFSEL_OFFSET 0x18 | ||
#define GPIO_DIR_OFFSET 0x04 | ||
#define GPIO_DATA_OFFSET 0x00 | ||
|
||
static unsigned int hero4_gpio_offsets[] = { | ||
0x70009000, | ||
0x7000a000, | ||
0x7000e000, | ||
0x70010000, | ||
0x70011000, | ||
}; | ||
|
||
struct lcd_hw_info { | ||
int spi_clk_gpio; | ||
int spi_mosi_gpio; | ||
int spi_miso_gpio; | ||
int spi_cs_gpio; | ||
int enable_gpio; | ||
int *gpio_offsets; | ||
int last_addr, last_val; | ||
int spi_all_cs_gpios[]; | ||
}; | ||
|
||
static struct lcd_hw_info hero4_lcd_hw_info = { | ||
.spi_clk_gpio = 2, | ||
.spi_mosi_gpio = 3, | ||
.spi_miso_gpio = 4, | ||
.spi_cs_gpio = 6, | ||
.enable_gpio = 31, | ||
.gpio_offsets = hero4_gpio_offsets, | ||
.spi_all_cs_gpios = {5, 6, -1}, | ||
}; | ||
|
||
static void gpio_write_bit(libusb_device_handle *dev, struct lcd_hw_info *hw_info, | ||
int gpio, int offset, int bit_value) | ||
{ | ||
unsigned int addr; | ||
unsigned int val; | ||
|
||
addr = hw_info->gpio_offsets[gpio / 32] + offset; | ||
|
||
if (hw_info->last_addr == addr) | ||
val = hw_info->last_val; | ||
else | ||
val = gp_read_reg(dev, addr); | ||
|
||
val &= ~(GPIO_BIT(gpio)); | ||
|
||
if (bit_value) | ||
val |= GPIO_BIT(gpio); | ||
|
||
gp_write_reg(dev, addr, val); | ||
|
||
hw_info->last_addr = addr; | ||
hw_info->last_val = val; | ||
} | ||
|
||
static void st7585_spi_send_word(struct libusb_device_handle *dev, struct lcd_hw_info *hw_info, | ||
unsigned int w) | ||
{ | ||
int i; | ||
|
||
gpio_write_bit(dev, hw_info, hw_info->spi_cs_gpio, GPIO_DATA_OFFSET, 0); | ||
for (i = 0; i < 9; i++) { | ||
gpio_write_bit(dev, hw_info, hw_info->spi_clk_gpio, GPIO_DATA_OFFSET, 0); | ||
gpio_write_bit(dev, hw_info, hw_info->spi_mosi_gpio, GPIO_DATA_OFFSET, w & (1 << (8 - i))); | ||
gpio_write_bit(dev, hw_info, hw_info->spi_clk_gpio, GPIO_DATA_OFFSET, 1); | ||
} | ||
|
||
gpio_write_bit(dev, hw_info, hw_info->spi_cs_gpio, 0, 1); | ||
} | ||
|
||
static int st7585_upload_bitmap(libusb_device_handle *dev, struct lcd_hw_info *hw_info, | ||
const unsigned char *buffer) | ||
{ | ||
unsigned int row, col; | ||
|
||
for (col = 0; col < 8; col++) { | ||
st7585_spi_send_word(dev, hw_info, 0x40 | col); | ||
st7585_spi_send_word(dev, hw_info, 0x8d); | ||
|
||
for (row = 0; row < 75; row++) | ||
st7585_spi_send_word(dev, hw_info, 0x100 | (buffer[col + row * 8])); | ||
} | ||
|
||
} | ||
|
||
static int st7585_configure_panel(libusb_device_handle *dev, struct lcd_hw_info *hw_info) | ||
{ | ||
int i = 0; | ||
|
||
/* MISO as input */ | ||
gpio_write_bit(dev, &hero4_lcd_hw_info, hw_info->spi_miso_gpio, GPIO_DIR_OFFSET, 0); | ||
|
||
|
||
/* Initialize all chip selects */ | ||
while (hw_info->spi_all_cs_gpios[i] != -1) { | ||
gpio_write_bit(dev, &hero4_lcd_hw_info, hw_info->spi_all_cs_gpios[i], GPIO_AFSEL_OFFSET, 0); | ||
gpio_write_bit(dev, &hero4_lcd_hw_info, hw_info->spi_all_cs_gpios[i], GPIO_DIR_OFFSET, 1); | ||
gpio_write_bit(dev, &hero4_lcd_hw_info, hw_info->spi_all_cs_gpios[i], GPIO_DATA_OFFSET, 1); | ||
i++; | ||
} | ||
|
||
gpio_write_bit(dev, &hero4_lcd_hw_info, hw_info->spi_clk_gpio, GPIO_AFSEL_OFFSET, 0); | ||
gpio_write_bit(dev, &hero4_lcd_hw_info, hw_info->spi_clk_gpio, GPIO_DIR_OFFSET, 1); | ||
|
||
gpio_write_bit(dev, &hero4_lcd_hw_info, hw_info->spi_mosi_gpio, GPIO_AFSEL_OFFSET, 0); | ||
gpio_write_bit(dev, &hero4_lcd_hw_info, hw_info->spi_mosi_gpio, GPIO_DIR_OFFSET, 1); | ||
|
||
if (hw_info->enable_gpio >= 0) { | ||
gpio_write_bit(dev, &hero4_lcd_hw_info, hw_info->enable_gpio, GPIO_AFSEL_OFFSET, 0); | ||
gpio_write_bit(dev, &hero4_lcd_hw_info, hw_info->enable_gpio, GPIO_DIR_OFFSET, 1); | ||
gpio_write_bit(dev, &hero4_lcd_hw_info, hw_info->enable_gpio, GPIO_DATA_OFFSET, 1); | ||
} | ||
|
||
/* Initialize panel */ | ||
st7585_spi_send_word(dev, hw_info, 0x21); | ||
st7585_spi_send_word(dev, hw_info, 0x9c); | ||
st7585_spi_send_word(dev, hw_info, 0x20); | ||
st7585_spi_send_word(dev, hw_info, 0x08); | ||
} | ||
|
||
const unsigned char boot_logo[] = { | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x60,0x00,0x00,0x00, | ||
0x00,0x00,0x66,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x43,0xc1,0xb0,0x00,0x00,0x00, | ||
0x00,0x00,0xcf,0xff,0x10,0x00,0x00,0x00,0x00,0x00,0xc4,0x0f,0x30,0x00,0x00,0x00, | ||
0x00,0x00,0x40,0x02,0x18,0x00,0x00,0x00,0x00,0x00,0xc0,0x02,0x18,0x00,0x00,0x00, | ||
0x00,0x01,0x80,0x00,0x1c,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x06,0x00,0x00,0x00, | ||
0x00,0x03,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x03,0xc0,0x00,0x00, | ||
0x00,0x07,0xc0,0x00,0x00,0xe0,0x00,0x00,0x00,0x04,0x40,0x78,0x00,0x30,0x00,0x00, | ||
0x00,0x04,0x00,0x60,0x06,0x38,0x00,0x00,0x00,0x0c,0x00,0x00,0x77,0x7c,0x00,0x00, | ||
0x00,0x0c,0x00,0x00,0x7c,0xf6,0x00,0x00,0x00,0x0c,0x00,0x01,0xe4,0xf2,0x00,0x00, | ||
0x00,0x3c,0x00,0x01,0xe0,0xe3,0x00,0x00,0x01,0xbc,0x00,0x03,0x80,0x21,0x00,0x00, | ||
0x01,0xfc,0x00,0x06,0xc0,0x31,0x00,0x00,0x0f,0xe4,0x00,0x18,0x80,0x71,0x80,0x00, | ||
0x07,0xc7,0x20,0x71,0xff,0xf1,0x80,0x00,0x0e,0x03,0xf0,0xc1,0xd8,0x61,0x80,0x00, | ||
0x1c,0x01,0xe7,0x00,0x0c,0xc1,0x80,0x00,0x1c,0x07,0xf8,0x00,0x07,0x00,0xc0,0x00, | ||
0x07,0x0e,0x08,0x00,0x00,0x00,0x60,0x00,0x01,0xf0,0x08,0x00,0x00,0x00,0x30,0x00, | ||
0x00,0x00,0x0c,0x00,0x02,0x00,0x30,0x00,0x00,0x00,0x07,0x00,0x06,0x00,0x10,0x00, | ||
0x00,0x00,0x07,0xe0,0x1f,0x00,0x18,0x00,0x00,0x00,0x06,0x3f,0xf1,0x80,0x1c,0x00, | ||
0x00,0x00,0x06,0x01,0xc0,0xe0,0x04,0x00,0x00,0x00,0x06,0x00,0xc0,0x7e,0x06,0x00, | ||
0x00,0x00,0x02,0x00,0x40,0x1c,0x1e,0x00,0x00,0x00,0x03,0x00,0x60,0x18,0x7f,0x00, | ||
0x00,0x00,0x01,0x80,0x70,0x0d,0xbe,0x00,0x00,0x00,0x00,0xe0,0x10,0x07,0xf8,0x00, | ||
0x00,0x00,0x00,0x7c,0x10,0x01,0xe0,0x00,0x00,0x00,0x00,0x10,0x18,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x07,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xf0,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
}; | ||
|
||
int st7585_show_logo(libusb_device_handle *dev) | ||
{ | ||
st7585_configure_panel(dev, &hero4_lcd_hw_info); | ||
st7585_upload_bitmap(dev, &hero4_lcd_hw_info, boot_logo); | ||
|
||
/* Turn on panel */ | ||
st7585_spi_send_word(dev, &hero4_lcd_hw_info, 0x20); | ||
st7585_spi_send_word(dev, &hero4_lcd_hw_info, 0x0c); | ||
st7585_spi_send_word(dev, &hero4_lcd_hw_info, 0x8d); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/* Short and to the point */ | ||
|
||
int st7585_show_logo(libusb_device_handle *dev); |