8 Commits

Author SHA1 Message Date
Christopher Anderson
a009b2b433 [acc] Change doubles to floats to make it lazily fit in a BT characteristic 2016-05-12 14:54:33 -07:00
Christopher Anderson
425a9de687 [demo] Have ST send ACC data every 100 MS over SPI5
- Revert to HAL spi since there's still a timing bug in the new WIP driver
- Add nrf_sensors app to poll the ACC and send data every 100 ms
2016-05-12 14:54:18 -07:00
Christopher Anderson
de971f8325 [spi] Fix warning on cs_val init 2016-05-12 10:47:03 -07:00
Gurjant Kalsi
f8f6aa3b0d Re-enable devices. 2016-05-11 18:10:02 -07:00
Gurjant Kalsi
359698b798 [eink] Wire e-ink driver into LK graphics stack 2016-05-11 15:53:45 -07:00
Eric Holland
ce057571d0 [eink] convert to 3wire interface to work with default dartuinoP2 config 2016-05-11 10:52:18 -07:00
Eric Holland
a9c8e7a6ea [eink] first cut at eink driver 2016-05-11 09:55:42 -07:00
Eric Holland
43d3ab809c [eink] early cut at eink driver 2016-05-10 17:04:23 -07:00
12 changed files with 2633 additions and 133 deletions

View File

@@ -0,0 +1,58 @@
#include <app.h>
#include <arch.h>
#include <assert.h>
#include <debug.h>
#include <err.h>
#include <kernel/event.h>
#include <lk/init.h>
#include <stdlib.h>
#include <trace.h>
#include <target/gpioconfig.h>
#include <stm32f7xx.h>
#include <stm32f7xx_hal_spi.h>
#include <dev/accelerometer.h>
/* This code reads from the accelerometer then sends the data over to the nRF chip
* every 100 milliseconds. */
static void nrf_sensors_init(const struct app_descriptor *app)
{
}
static void nrf_sensors_entry(const struct app_descriptor *app, void *args)
{
position_vector_t pos_vector;
SPI_HandleTypeDef spi_handle;
spi_handle.Instance = SPI5;
spi_handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
spi_handle.Init.Direction = SPI_DIRECTION_2LINES;
spi_handle.Init.CLKPhase = SPI_PHASE_1EDGE;
spi_handle.Init.CLKPolarity = SPI_POLARITY_LOW;
spi_handle.Init.DataSize = SPI_DATASIZE_8BIT;
spi_handle.Init.FirstBit = SPI_FIRSTBIT_MSB;
spi_handle.Init.TIMode = SPI_TIMODE_DISABLE;
spi_handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spi_handle.Init.CRCPolynomial = 7;
spi_handle.Init.NSS = SPI_NSS_SOFT;
spi_handle.Init.Mode = SPI_MODE_MASTER;
gpio_config(GPIO_NRF_CS, GPIO_OUTPUT);
gpio_set(GPIO_NRF_CS, 1);
for (;;) {
acc_read_xyz(&pos_vector);
gpio_set(GPIO_NRF_CS, 0);
status_t ret = HAL_SPI_Transmit(&spi_handle, (uint8_t *)&pos_vector, sizeof(pos_vector), 5000);
if (ret != NO_ERROR) {
printf("error on spi_write for sensors: %d\n", ret);
}
gpio_set(GPIO_NRF_CS, 1);
thread_sleep(100);
}
}
APP_START(sbb)
.init = nrf_sensors_init,
.entry = nrf_sensors_entry,
APP_END

9
app/nrf_sensors/rules.mk Normal file
View File

@@ -0,0 +1,9 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
MODULE_SRCS += \
$(LOCAL_DIR)/nrf_sensors.c \
include make/module.mk

View File

@@ -23,9 +23,9 @@
#ifndef __DEV_ACCELEROMETER_H
#define __DEV_ACCELEROMETER_H
typedef struct {
double x;
double y;
double z;
float x;
float y;
float z;
} position_vector_t;
status_t acc_read_xyz(position_vector_t *pos_vector);

View File

@@ -67,7 +67,7 @@ status_t spi_write(SPI_HandleTypeDef *handle, uint8_t *data, size_t len, uint32_
status_t ret = NO_ERROR;
int bus = get_bus_idx(handle->Instance);
int cs_val;
int cs_val = 0;
bool use_soft_nss = ((handle->Init.NSS == SPI_NSS_SOFT) && cs);
if (bus == INVALID_SPI_BUS) {

View File

@@ -13,6 +13,7 @@ MODULES += \
MODULE_DEPS += \
app/accelerometer \
app/nrf_sensors \
MODULE_SRCS += \
$(LOCAL_DIR)/sensor_bus.c \

View File

@@ -9,6 +9,8 @@
#include <platform/timer.h>
#include <platform/gpio.h>
#include <target/gpioconfig.h>
#include <target/tqlogo.h>
#include <target/et011tt2v1.h>
#include <string.h>
// TODO The eink driver should not include stm headers. We likely need INIT to store
// a spihandle and then spi functions use it some other way
@@ -16,6 +18,11 @@
#include <platform/spi.h>
#include <platform.h>
static uint8_t framebuffer[FBSIZE];
/* The following tables are copied verbatim with comments from the verily driver */
// TODO(nicholasewalt): Update LUTs once they are provided by Eink.
// TODO(nicholasewalt): Investigate truncating and compressing LUTs. Current
@@ -201,75 +208,59 @@ typedef struct {
} panel_setting_t;
typedef struct {
union {
uint8_t byte0;
// Gate power selection
// 0: External gate power from VGH/VGL pins
// 1: Internal DC/DC function for generating VGH/VGL
uint8_t vg_en:1;
// Source power selection
// 0: External source power from VDH/VDL pins
// 1: Internal DC/DC function for generating VDH/VDL
uint8_t vs_en:1;
uint8_t __rs0:6;
};
union {
uint8_t byte1;
// VG_LVL[1:0]: Gate Voltage Level selection
// Bit definitions in power settings enum.
uint8_t vg_lvl:2;
// VCOM_HV: VCOM Voltage Level
// 0: VCOMH=VSH+VCOMDC, VCOML=VSL+VCOMDC (default)
// 1: VCOML=VGH, VCOML=VGL
uint8_t vcom_hv:1;
uint8_t __rs1:5;
};
union {
uint8_t byte2;
// VSH_LVL[5:0]: Internal positive source voltage level for K/W
// (range: +2.4V ~ +11.0V / step:0.2V / default : +10.0V)
uint8_t vsh_lvl:6;
uint8_t __rs2:2;
};
union {
uint8_t byte3;
// VSL_LVL[5:0]: Internal negative source voltage level for K/W
// (range: -2.4V ~ -11.0V / step:0.2V / default : -10.0V)
uint8_t vsl_lvl:6;
uint8_t __rs3:2;
};
union {
uint8_t byte4;
uint8_t vshr_lvl:6;
uint8_t __rs4:2;
};
union {
struct {
// Gate power selection
// 0: External gate power from VGH/VGL pins
// 1: Internal DC/DC function for generating VGH/VGL
uint8_t vg_en:1;
// Source power selection
// 0: External source power from VDH/VDL pins
// 1: Internal DC/DC function for generating VDH/VDL
uint8_t vs_en:1;
uint8_t __rs0:6;
// VG_LVL[1:0]: Gate Voltage Level selection
// Bit definitions in power settings enum.
uint8_t vg_lvl:2;
// VCOM_HV: VCOM Voltage Level
// 0: VCOMH=VSH+VCOMDC, VCOML=VSL+VCOMDC (default)
// 1: VCOML=VGH, VCOML=VGL
uint8_t vcom_hv:1;
uint8_t __rs1:5;
// VSH_LVL[5:0]: Internal positive source voltage level for K/W
// (range: +2.4V ~ +11.0V / step:0.2V / default : +10.0V)
uint8_t vsh_lvl:6;
uint8_t __rs2:2;
// VSL_LVL[5:0]: Internal negative source voltage level for K/W
// (range: -2.4V ~ -11.0V / step:0.2V / default : -10.0V)
uint8_t vsl_lvl:6;
uint8_t __rs3:2;
uint8_t vshr_lvl:6;
uint8_t __rs4:2;
} bits;
struct {
uint8_t byte0;
uint8_t byte1;
uint8_t byte2;
uint8_t byte3;
uint8_t byte4;
} bytes;
};
} pwr_settings_t;
typedef struct {
union {
uint8_t byte0;
uint8_t btpha_min_off:3;
uint8_t btpha_drive_strength:3;
uint8_t btpha_soft_start:2;
};
union {
uint8_t byte1;
uint8_t btphb_min_off:3;
uint8_t btphb_drive_strength:3;
uint8_t btphb_soft_start:2;
};
union {
uint8_t byte2;
uint8_t btphc_min_off:3;
uint8_t btphc_drive_strength:3;
uint8_t __rs0:2;
};
} booster_settings_t;
typedef struct {
@@ -512,6 +503,7 @@ enum {
PowerOn = 0x04,
BoosterSoftStart = 0x06,
DeepSleep = 0x07,
DataStartTranmission1 = 0x10,
DisplayRefresh = 0x12,
DataStartTransmission2 = 0x13,
DataStartTransmissionWindow = 0x14,
@@ -616,21 +608,22 @@ static inline void set_data_parameter_mode(void) {
}
void write_cmd(uint8_t cmd) {
uint8_t cmd_buf[1];
uint16_t cmd16;
cmd_buf[0] = cmd;
cmd16 = (uint16_t) cmd;
set_data_command_mode();
#if 0
gpio_set(GPIO_DISP_CS, 0);
HAL_SPI_Transmit(&SpiHandle, cmd_buf, sizeof(cmd_buf), HAL_MAX_DELAY);
gpio_set(GPIO_DISP_CS, 1);
#else
spi_write(&SpiHandle, cmd_buf, sizeof(cmd_buf), GPIO_DISP_CS);
spi_write(&SpiHandle, (uint8_t *)&cmd16,1, GPIO_DISP_CS);
#endif
}
void write_data(uint8_t *buf, size_t len) {
set_data_parameter_mode();
//set_data_parameter_mode();
uint16_t txbyte;
//enter_critical_section;
#if 0
gpio_set(GPIO_DISP_CS, 0);
@@ -639,7 +632,8 @@ void write_data(uint8_t *buf, size_t len) {
#else
//spin_lock_irqsave(&lock, state);
for (size_t i = 0; i < len; i++) {
spi_write(&SpiHandle, buf + i, 1, GPIO_DISP_CS);
txbyte = ((uint16_t) buf[i]) | 0x0100;
spi_write(&SpiHandle, (uint8_t *)&txbyte, 1, GPIO_DISP_CS);
}
//spin_unlock_irqrestore(&lock, state);
#endif
@@ -694,7 +688,7 @@ status_t eink_init(void) {
SpiHandle.Init.Direction = SPI_DIRECTION_1LINE;
SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
SpiHandle.Init.DataSize = SPI_DATASIZE_9BIT;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
@@ -710,24 +704,38 @@ status_t eink_init(void) {
spi_inited = true;
}
// kPanelSetting
panel_setting_t panel = {
.byte0 = 0x0F, .byte1 = 0x06,
};
panel.reg_en = 1;
pwr_settings_t pwr = {
.byte0 = 0x03, .byte1 = 0x00, .byte2 = 0x26, .byte3 = 0x26, .byte4 = 0x03,
};
pwr.vsh_lvl = 0x1C; // +8V
pwr.vsl_lvl = 0x1C; // -8V
pwr.vshr_lvl = 0x00; // +2.4V
booster_settings_t booster = {
.byte0 = 0x1F, .byte1 = 0x1E, .byte2 = 0x25,
};
pwr_settings_t pwr;
pwr.bytes.byte0 = 0x03;
pwr.bytes.byte1 = 0x00;
pwr.bytes.byte2 = 0x26;
pwr.bytes.byte3 = 0x26;
pwr.bytes.byte4 = 0x03;
pwr.bits.vsh_lvl = 0x1C; // +8V
pwr.bits.vsl_lvl = 0x1C; // -8V
pwr.bits.vshr_lvl = 0x00; // +2.4V
// kBoosterSoftStart
booster_settings_t booster ;//= {
//.byte0 = 0x1F, .byte1 = 0x1E, .byte2 = 0x25,
// .byte0 = 0x00, .byte1 = 0x00, .byte2 = 0x00,
//};
booster.btpha_min_off = soft_start_min_off_3p34us;
booster.btpha_drive_strength = drive_strength_8;
@@ -738,6 +746,13 @@ status_t eink_init(void) {
booster.btphc_min_off = soft_start_min_off_3p34us;
booster.btphc_drive_strength = drive_strength_8;
uint8_t * temp;
temp = &booster;
printf("booster bytes: %02X %02X %02X\n",temp[0], temp[1], temp[2]);
vcom_data_int_settings_t vdi = {
.byte0 = 0x31, .byte1 = 0x30, .cdi_low = 0x18,
};
@@ -815,104 +830,281 @@ status_t eink_init(void) {
return ERR_GENERIC;
}
uint8_t data;
// Configure power settings
write_cmd(PowerSetting);
write_data((uint8_t *)&pwr, sizeof(pwr));
data = 0x03;
write_data(&data,1);
data = 0x00;
write_data(&data,1);
data = 0x1C;
write_data(&data,1);
data = 0x1C;
write_data(&data,1);
data = 0x00;
write_data(&data,1);
// Power on display
write_cmd(PowerOn);
//printf("Power On\n");
//return 0;
// Configure panel settings
write_cmd(PanelSetting);
write_data((uint8_t *)&panel, sizeof(panel));
data = 0x0F;
write_data(&data,1);
data = 0x86; //was 86
write_data(&data,1);
// Configure Boost
write_cmd(BoosterSoftStart);
write_data((uint8_t *)&booster, sizeof(booster));
data = 0x3e;
write_data(&data,1);
data = 0x3e;
write_data(&data,1);
data = 0x3e;
write_data(&data,1);
// Initialize -> Check_Busy
write_cmd(VcomAndDataIntervalSetting);
write_data((uint8_t *)&vdi, sizeof(vdi));
data = 0x01;
write_data(&data,1);
data = 0x20;
write_data(&data,1);
data = 0x10;
write_data(&data,1);
write_cmd(ResolutionSetting);
write_data((uint8_t *)&rs, sizeof(rs));
data = (240-1);
write_data(&data,1);
data = 0x00;
write_data(&data,1);
data = 240-1;
write_data(&data,1);
write_cmd(GateGroupSetting);
write_data((uint8_t *)&ggs, sizeof(ggs));
data = 0x89;
write_data(&data,1);
data = 0x89;
write_data(&data,1);
data = 0xcb;
write_data(&data,1);
data = 0xcb;
write_data(&data,1);
data = 0x03;
write_data(&data,1);
write_cmd(BorderDcVoltageSetting);
write_data((uint8_t *)&bdvs, sizeof(bdvs));
data = 0x4e;
write_data(&data,1);
write_cmd(LpdSelect);
write_data((uint8_t *)&lpds, sizeof(lpds));
data = 0x02;
write_data(&data,1);
write_cmd(FtLutRegister);
write_data(lut_ft, sizeof(lut_ft));
write_cmd(KwgVcomLutRegister);
write_data(lut_kwg_vcom, sizeof(lut_kwg_vcom));
write_cmd(KwgLutRegister);
write_data(lut_kwg, sizeof(lut_kwg));
uint8_t vcominit;
vcominit = 0x02;
write_cmd(VcomDcSetting);
write_data(&vcominit,1);
if (!check_busy()) {
printf("Device is still busy after Power On and configuration\n");
return ERR_GENERIC;
}
/* Quick buffer to toss at it */
#define fbsize (240 * 240 / 4)
uint8_t *buf = malloc(fbsize);
if (!buf) {
printf("Couldn't allocate framebuffer\n");
return ERR_GENERIC;
}
memset(buf, 0b00001111, fbsize);
// DTMW
write_cmd(DataStartTransmissionWindow);
write_data((uint8_t *) &dtw, sizeof(dtw));
// DTM2
write_cmd(DataStartTransmission2);
write_data(buf, fbsize);
// DRF
write_cmd(DisplayRefresh);
write_data((uint8_t *)&dr, sizeof(dr));
// Check_Busy
if (!check_busy()) {
printf("Device is still busy after Display Refresh!\n");
return ERR_GENERIC;
}
// POF
write_cmd(PowerOff);
// Check_Busy
if (!check_busy()) {
printf("Device is still busy after Power Off!\n");
return ERR_GENERIC;
}
// DSLP
uint8_t sleepbuf = 0b10100101;
write_cmd(DeepSleep);
write_data(&sleepbuf, sizeof(sleepbuf));
memset(framebuffer, 0xff, sizeof(framebuffer));
return eink_refresh();
err:
TRACE_EXIT;
return err;
}
static int eink_dumpfb(uint8_t * buff, uint32_t count)
{
uint8_t data;
// DTMW
write_cmd(DataStartTransmissionWindow);
data = 0x00;
write_data(&data,1);
data = 0x00;
write_data(&data,1);
data = 0x00;
write_data(&data,1);
data = 240-1;
write_data(&data,1);
data = 0x00;
write_data(&data,1);
data = 240-1;
write_data(&data,1);
// DTM2
write_cmd(DataStartTransmission2);
write_data(buff, count);
// DRF
write_cmd(DisplayRefresh);
data = 0x00;
write_data(&data,1);
data = 0x00;
write_data(&data,1);
data = 0x00;
write_data(&data,1);
data = 0x00;
write_data(&data,1);
data = 240-1;
write_data(&data,1);
data = 0x00;
write_data(&data,1);
data = 240-1;
write_data(&data,1);
return 0;
}
static int cmd_eink_fill(int argc, const cmd_args *argv)
{
uint16_t x,y,count,val;
x = argv[1].i;
y = argv[2].i;
val = argv[3].i;
count = argv[4].i;
memset(framebuffer, 0xff, FBSIZE);
memset(framebuffer+ x + y*(240>>2), val,count);
//memset(framebuffer+(240>>4)*10, 0xcc, 10 );
eink_dumpfb(framebuffer,FBSIZE);
return 0;
}
static int cmd_eink1(int argc, const cmd_args *argv)
{
memset(framebuffer, 0xff, FBSIZE);
return eink_dumpfb(framebuffer, FBSIZE);
}
static int cmd_eink0(int argc, const cmd_args *argv)
{
memset(framebuffer, 0x00, sizeof(framebuffer));
return eink_dumpfb(framebuffer,sizeof(framebuffer));
}
int eink_refresh(void) {
return eink_dumpfb(framebuffer, sizeof(framebuffer));
}
static int cmd_eink_logo(int argc, const cmd_args *argv)
{
return eink_dumpfb(logo,sizeof(logo));
}
static int cmd_eink(int argc, const cmd_args *argv)
{
return eink_init();
}
uint8_t * get_eink_framebuffer(void) {
return framebuffer;
}
static struct display_framebuffer eink_framebuffer;
static uint8_t clamp_px(uint8_t px)
{
if (px) return 0x3;
return 0x0;
}
status_t display_present(struct display_image *image, uint starty, uint endy)
{
DEBUG_ASSERT(image);
// Convert the framebuffer into something that the e-ink display will
// understand.
// TODO(gkalsi): Note that we're ignoring starty and endy right now. Just
// dump the whole display for now and we can worry about
// partial updates later.
// memset(framebuffer, 0, FBSIZE);
uint8_t *fb = (uint8_t *)framebuffer;
uint8_t *px = (uint8_t *)image->pixels;
for (unsigned int col = 0; col < 60; col++) {
for (unsigned int row = 0; row < 240; row++) {
fb[col + row * 60] = clamp_px((px[col * 2 + row * 120] & 0xC0) >> 6) << 6;
fb[col + row * 60] |= clamp_px((px[col * 2 + row * 120] & 0x0C) >> 2) << 4;
fb[col + row * 60] |= clamp_px((px[col * 2 + row * 120 + 1] & 0xC0) >> 6) << 2;
fb[col + row * 60] |= clamp_px((px[col * 2 + row * 120 + 1] & 0x0C) >> 2);
}
}
return eink_dumpfb(framebuffer, FBSIZE);
}
static void eink_flush(uint starty, uint endy)
{
display_present(&eink_framebuffer.image, starty, endy);
}
status_t display_get_framebuffer(struct display_framebuffer *fb)
{
DEBUG_ASSERT(fb);
// Build the framebuffer.
eink_framebuffer.image.format = IMAGE_FORMAT_MONO_8;
eink_framebuffer.image.stride = PHYSICAL_WIDTH;
eink_framebuffer.image.rowbytes = PHYSICAL_WIDTH;
eink_framebuffer.image.pixels = malloc(PHYSICAL_WIDTH * PHYSICAL_HEIGHT);
eink_framebuffer.image.width = PHYSICAL_WIDTH;
eink_framebuffer.image.height = PHYSICAL_WIDTH;
eink_framebuffer.flush = eink_flush;
eink_framebuffer.format = DISPLAY_FORMAT_RGB_111; // TODO(gkalsi): This is not RGB, we're lying
*fb = eink_framebuffer;
return NO_ERROR;
}
status_t display_get_info(struct display_info *info)
{
DEBUG_ASSERT(info);
info->format = IMAGE_FORMAT_MONO_8;
info->width = PHYSICAL_WIDTH;
info->height = PHYSICAL_WIDTH;
return NO_ERROR;
}
STATIC_COMMAND_START
STATIC_COMMAND("eink", "eink commands", &cmd_eink)
STATIC_COMMAND("eink", "eink init", &cmd_eink)
STATIC_COMMAND("eink1", "eink fill white", &cmd_eink1)
STATIC_COMMAND("eink0", "eink fill black", &cmd_eink0)
STATIC_COMMAND("einkfill", "eink fill x y val count", &cmd_eink_fill)
STATIC_COMMAND("einklogo", "tqlogo", &cmd_eink_logo)
STATIC_COMMAND_END(eink);
#endif

View File

@@ -0,0 +1,308 @@
typedef struct {
// Gate power selection
// 0: External gate power from VGH/VGL pins
// 1: Internal DC/DC function for generating VGH/VGL
uint8_t vg_en:1;
// Source power selection
// 0: External source power from VDH/VDL pins
// 1: Internal DC/DC function for generating VDH/VDL
uint8_t vs_en:1;
uint8_t __rs0:6;
//---- new byte
// VG_LVL[1:0]: Gate Voltage Level selection
// Bit definitions in power settings enum.
uint8_t vg_lvl:2;
// VCOM_HV: VCOM Voltage Level
// 0: VCOMH=VSH+VCOMDC, VCOML=VSL+VCOMDC (default)
// 1: VCOML=VGH, VCOML=VGL
uint8_t vcom_hv:1;
uint8_t __rs1:5;
//---- new byte
// VSH_LVL[5:0]: Internal positive source voltage level for K/W
// (range: +2.4V ~ +11.0V / step:0.2V / default : +10.0V)
uint8_t vsh_lvl:6;
uint8_t __rs2:2;
//---- new byte
// VSL_LVL[5:0]: Internal negative source voltage level for K/W
// (range: -2.4V ~ -11.0V / step:0.2V / default : -10.0V)
uint8_t vsl_lvl:6;
uint8_t __rs3:2;
//---- new byte
uint8_t vshr_lvl:6;
uint8_t __rs4:2;
} pwr_settings_t;
typedef struct {
uint8_t btpha_min_off:3;
uint8_t btpha_drive_strength:3;
uint8_t btpha_soft_start:2;
//---- new byte
uint8_t btphb_min_off:3;
uint8_t btphb_drive_strength:3;
uint8_t btphb_soft_start:2;
//---- new byte
uint8_t btphc_min_off:3;
uint8_t btphc_drive_strength:3;
} booster_settings_t;
typedef struct {
uint8_t busy_n:1;
uint8_t pof:1;
uint8_t pon:1;
uint8_t data_flag:1;
uint8_t i2c_busyn:1;
uint8_t i2c_err:1;
uint8_t __rs0:2;
} et011tt2_status_t;
typedef struct {
// DDX[1:0]: Data polarity
// 0: Inverted
// 1: Normal (default)
uint8_t ddx:1;
uint8_t __rs0:3;
// VBD[1:0]: Border output selection
uint8_t bdd:2;
// BDV: Border DC Voltage control
// 0: Border Output DC Voltage Function disabled (default)
// 1: Border Output DC Voltage Function enabled
uint8_t bdv:1;
// BDZ: Border Hi-Z control
// 0: Border Output Hi-Z disabled (default)
// 1: Border Output Hi-Z enabled
uint8_t bdz:1;
//---- new byte
// CDI[9:0]: VCOM to Source interval. Interval time setting from VCOM to
// source dat.
// 000 0000 000b ~ 11 1111 1111b: 1 Hsync ~ 1023 Hsync, respectively.
// (Default: 018h: 25 Hsync)
uint8_t cdi_high:2;
uint8_t __rs1:2;
// DCI[3:0]: Source to VCOM interval. Interval time setting from source
// data to VCOM.
// 0000b ~ 1111b: 1 Hsync ~ 16 Hsync, respectively. (Default: 011b: 4
// Hsync)
uint8_t dci:4;
//---- new byte
uint8_t cdi_low;
} vcom_data_int_settings_t;
typedef struct {
uint8_t __rs0:2;
// HRES[7:2]: Horizontal display resolution.
// 00000b ~ 11111b: 4 ~ 256 lines
uint8_t hres:6;
//---- new byte
// VRES[9:0]: Vertical display resolution
// 0000000000b ~ 1111111111b: 1 ~ 1024 lines
uint8_t vres_high:2;
uint8_t __rs1:6;
//---- new byte
uint8_t vres_low;
} resolution_settings_t;
typedef struct {
// G1~4NUM[3:0]: Channel Number used for Gate Group 1~4. For example:
// 2: GGx[2:0] ON
// 15: GGx[15:0] ON
uint8_t g1num:4;
uint8_t __rs0:1;
// G1~4UD: Gate Group 1~4 Up/Down Selection
// 0: Down scan within Gate Group
// 1: Up scan within Gate Group (default)
uint8_t g1ud:1;
// G1~4BS: Gate Group 1~4 Block/Select Selection
// 0: Gate Select
// 1: Gate Block
uint8_t g1bs:1;
// G1~4EN: Gate Group 1~4 Enable
// 0: Disable
// 1: Enable
uint8_t g1en:1;
//---- new byte
uint8_t g2num:4;
uint8_t __rs1:1;
uint8_t g2ud:1;
uint8_t g2bs:1;
uint8_t g2en:1;
//---- new byte
uint8_t g3num:4;
uint8_t __rs2:1;
uint8_t g3ud:1;
uint8_t g3bs:1;
uint8_t g3en:1;
//---- new byte
uint8_t g4num:4;
uint8_t __rs3:1;
uint8_t g4ud:1;
uint8_t g4bs:1;
uint8_t g4en:1;
//---- new byte
// GSFB: Gate Select Forward/Backward
// 0: Gate select backward
// 1: Gate select forward
uint8_t gsfb:1;
// GBFB: Gate Block Forward/Backward
// 0: Gate block backward
// 1: Gate block forward
uint8_t gbfb:1;
uint8_t __rs4:2;
// XOPT: XON Option
// 0: No all gate on during vertical blanking in XON mode (default)
// 1: All gate on during vertical blanking in XON mode
uint8_t xopt:1;
uint8_t __rs5:3;
} gate_group_settings_t;
typedef struct {
uint8_t vbds:7;
uint8_t __rs0:1;
} border_dc_v_settings_t;
typedef struct {
// Low Power Voltage Selection
uint8_t lpd_sel:2;
uint8_t __rs0:6;
} lpdselect_t;
typedef struct {
uint8_t pixel3:2;
uint8_t pixel2:2;
uint8_t pixel1:2;
uint8_t pixel0:2;
} data_tranmission_t;
typedef struct {
// X[7:0]: X-axis Start Point. X-axis start point for update display window.
// NOTE: The X-axis start point needs to be a multiple of 4.
uint8_t x;
// Y[9:0]: Y-axis Start Point. Y-axis start point for update display window.
uint8_t y_high:2;
uint8_t __rs0:6;
uint8_t y_low;
// W[7:0]: X-axis Window Width. X-axis width for update display window.
// NOTE: The width needs to be a multiple of 4.
// NOTE: This needs to be set to W - 1.
uint8_t w;
uint8_t l_high:2;
uint8_t __rs1:6;
// L[9:0]: Y-axis Window Width. Y-axis width for update display window
// NOTE: This needs to be set to L - 1.
uint8_t l_low;
} data_transmission_window_t;
typedef struct {
uint8_t mode:2;
// DN_EN: Do-nothing function enabled
// 0: Data follow VCOM function disable
// 1: Data output follows VCOM LUT if new pixel data equal to old pixel
// data inside Update Display Area
// NOTE: Do-nothing function is always active outside Update Display Area.
uint8_t dn_en:1;
// RGL_EN: REGAL function control
// 0: REGAL function disable
// 1: REGAL function enable
uint8_t rgl_en:1;
// PSCAN: Partial Scan control
// 0: Partial Scan disable
// 1: Partial Scan enable (Gate Scan within Display Window only)
uint8_t pscan:1;
uint8_t __rs0:3;
//---- new byte
// X[7:0]: X-axis Start Point. X-axis start point for update display window.
// NOTE: The X-axis start point needs to be a multiple of 4.
uint8_t x;
// Y[9:0]: Y-axis Start Point. Y-axis start point for update display window.
uint8_t y_high:2;
uint8_t __rs1:6;
//---- new byte
uint8_t y_low;
// W[7:0]: X-axis Window Width. X-axis width for update display window.
// NOTE: The width needs to be a multiple of 4.
// NOTE: This needs to be set to W - 1.
uint8_t w;
// L[9:0]: Y-axis Window Width. Y-axis width for update display window
// NOTE: This needs to be set to L - 1.
uint8_t l_high:2;
uint8_t __rs2:6;
uint8_t l_low;
} display_refresh_t;
enum {
PanelSetting = 0x00,
PowerSetting = 0x01,
PowerOff = 0x02,
PowerOffSequenceSetting = 0x03,
PowerOn = 0x04,
BoosterSoftStart = 0x06,
DeepSleep = 0x07,
DisplayRefresh = 0x12,
DataStartTransmission2 = 0x13,
DataStartTransmissionWindow = 0x14,
KwgVcomLutRegister = 0x20,
KwgLutRegister = 0x22,
FtLutRegister = 0x26,
PllControl = 0x30,
TemperatureSensor = 0x40,
TemperatureSensorEnable = 0x41,
TemperatureSensorWrite = 0x42,
TemperatureSensorRead = 0x43,
VcomAndDataIntervalSetting = 0x50,
LowPowerDetection = 0x51,
ResolutionSetting = 0x61,
GateGroupSetting = 0x62,
GateBlockSetting = 0x63,
GateSelectSetting = 0x64,
Revision = 0x70,
GetStatus = 0x71,
AutoMeasureVcom = 0x80,
VcomValue = 0x81,
VcomDcSetting = 0x82,
BorderDcVoltageSetting = 0x84,
LpdSelect = 0xE4,
};
enum booster_soft_start_min_off {
soft_start_min_off_0p27us = 0b000,
soft_start_min_off_0p34us = 0b001,
soft_start_min_off_0p40us = 0b010,
soft_start_min_off_0p50us = 0b011,
soft_start_min_off_0p80us = 0b100,
soft_start_min_off_1p54us = 0b101,
soft_start_min_off_3p34us = 0b110,
soft_start_min_off_6p58us = 0b111,
};
enum drive_strength {
drive_strength_1 = 0b000,
drive_strength_2 = 0b001,
drive_strength_3 = 0b010,
drive_strength_4 = 0b011,
drive_strength_5 = 0b100,
drive_strength_6 = 0b101,
drive_strength_7 = 0b110,
drive_strength_8 = 0b111, // (strongest)
};
enum soft_start_period {
soft_start_period_10ms = 0b00,
soft_start_period_20ms = 0b01,
soft_start_period_30ms = 0b10,
soft_start_period_40ms = 0b11,
};
enum lpd_select_lpdsel {
LPDSEL_2p2v = 0b00,
LPDSEL_2p3v = 0b01,
LPDSEL_2p4v = 0b10,
LPDSEL_2p5v = 0b11, // (default)
};
#define PHYSICAL_WIDTH 240
#define PHYSICAL_HEIGHT 240
#define EINK_WHITE 0xFF
#define EINK_BLACK 0x00

View File

@@ -0,0 +1,10 @@
#define FBSIZE 240*240>>2
int eink_refresh(void);
status_t eink_init(void);
uint8_t * get_eink_framebuffer(void); // returns pointer to eink framebuffer

File diff suppressed because it is too large Load Diff

View File

@@ -38,6 +38,7 @@
#include <target/bmi055.h>
#include <target/debugconfig.h>
#include <target/gpioconfig.h>
#include <target/et011tt2v1.h>
#include <reg.h>
#if ENABLE_LCD
@@ -128,9 +129,9 @@ void target_init(void)
{
stm32_debug_init();
//qspi_flash_init(N25Q128A_FLASH_SIZE);
qspi_flash_init(N25Q128A_FLASH_SIZE);
#if 0 //ENABLE_LCD
#if ENABLE_LCD
memory_lcd_init();
#endif
@@ -149,7 +150,7 @@ void target_init(void)
minip_init(stm32_eth_send_minip_pkt, NULL, ip_addr, ip_mask, ip_gateway);
#endif
#if 0 //WITH_LIB_FS_SPIFS
#if WITH_LIB_FS_SPIFS
status_t mount_success = fs_mount(DEAULT_SPIFS_MOUNT_POINT,
DEAULT_SPIFS_NAME, SPIFS_TARGET_DEVICE);
if (mount_success != NO_ERROR) {
@@ -162,11 +163,13 @@ void target_init(void)
#endif
// start usb
//target_usb_setup();
target_usb_setup();
#if 0 //ENABLE_SENSORBUS
#if ENABLE_SENSORBUS
sensor_bus_init();
#endif
eink_init();
}
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)

View File

@@ -39,9 +39,6 @@ MODULE_DEPS += \
ifneq ($(DISPLAY_PANEL_TYPE),)
MODULE_SRCS += \
$(LOCAL_DIR)/memory_lcd.c
GLOBAL_DEFINES += \
ENABLE_LCD=0

View File

@@ -86,7 +86,7 @@ status_t sensor_bus_init_early(void)
spi_handle.Init.NSS = SPI_NSS_SOFT;
spi_handle.Init.Mode = SPI_MODE_MASTER;
if (HAL_SPI_Init(&spi_handle) != HAL_OK) {
if (spi_init(&spi_handle) != HAL_OK) {
return ERR_GENERIC;
}
return NO_ERROR;