mirror of
https://github.com/jam422470459/EPD-nRF52-hema213.git
synced 2025-12-06 16:42:49 +08:00
add write image cmd
This commit is contained in:
@@ -37,6 +37,8 @@ typedef struct
|
||||
void (*sleep)(void); /**< Enter sleep mode */
|
||||
int8_t (*read_temp)(void); /**< Read temperature from driver chip */
|
||||
void (*force_temp)(int8_t value); /**< Force temperature (will trigger OTP LUT switch) */
|
||||
uint8_t cmd_write_ram1; /**< Command to write black ram */
|
||||
uint8_t cmd_write_ram2; /**< Command to write red ram */
|
||||
} epd_driver_t;
|
||||
|
||||
typedef enum
|
||||
|
||||
@@ -151,6 +151,15 @@ static void epd_service_on_write(ble_epd_t * p_epd, uint8_t * p_data, uint16_t l
|
||||
ble_epd_on_timer(p_epd, timestamp, true);
|
||||
} break;
|
||||
|
||||
case EPD_CMD_WRITE_IMAGE: // MSB=0000: ram begin, LSB=1111: black
|
||||
if (length < 3) return;
|
||||
if ((p_data[1] >> 4) == 0x00) {
|
||||
bool black = (p_data[1] & 0x0F) == 0x0F;
|
||||
EPD_WriteCommand(black ? p_epd->epd->drv->cmd_write_ram1 : p_epd->epd->drv->cmd_write_ram2);
|
||||
}
|
||||
EPD_WriteData(&p_data[2], length - 2);
|
||||
break;
|
||||
|
||||
case EPD_CMD_SET_CONFIG:
|
||||
if (length < 2) return;
|
||||
memcpy(&p_epd->config, &p_data[1], (length - 1 > EPD_CONFIG_SIZE) ? EPD_CONFIG_SIZE : length - 1);
|
||||
|
||||
@@ -72,6 +72,8 @@ enum EPD_CMDS
|
||||
|
||||
EPD_CMD_SET_TIME = 0x20, /** < set time with unix timestamp */
|
||||
|
||||
EPD_CMD_WRITE_IMAGE = 0x30, /** < write image data to EPD ram */
|
||||
|
||||
EPD_CMD_SET_CONFIG = 0x90, /**< set full EPD config */
|
||||
EPD_CMD_SYS_RESET = 0x91, /**< MCU reset */
|
||||
EPD_CMD_SYS_SLEEP = 0x92, /**< MCU enter sleep mode */
|
||||
|
||||
@@ -183,6 +183,8 @@ static epd_driver_t epd_drv_ssd1619 = {
|
||||
.sleep = SSD1619_Sleep,
|
||||
.read_temp = SSD1619_Read_Temp,
|
||||
.force_temp = SSD1619_Force_Temp,
|
||||
.cmd_write_ram1 = CMD_WRITE_RAM1,
|
||||
.cmd_write_ram2 = CMD_WRITE_RAM2,
|
||||
};
|
||||
|
||||
// SSD1619 400x300 Black/White/Red
|
||||
|
||||
@@ -230,6 +230,8 @@ static epd_driver_t epd_drv_uc8176 = {
|
||||
.sleep = UC8176_Sleep,
|
||||
.read_temp = UC8176_Read_Temp,
|
||||
.force_temp = UC8176_Force_Temp,
|
||||
.cmd_write_ram1 = CMD_DTM1,
|
||||
.cmd_write_ram2 = CMD_DTM2,
|
||||
};
|
||||
|
||||
// UC8176 400x300 Black/White
|
||||
|
||||
@@ -82,7 +82,7 @@ function dithering(ctx, width, height, threshold, type) {
|
||||
}
|
||||
|
||||
// white: 1, black/red: 0
|
||||
function canvas2bytes(canvas, type='bw', invert = false) {
|
||||
function canvas2bytes(canvas, step = 'bw', invert = false) {
|
||||
const ctx = canvas.getContext("2d");
|
||||
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
|
||||
@@ -92,7 +92,7 @@ function canvas2bytes(canvas, type='bw', invert = false) {
|
||||
for (let y = 0; y < canvas.height; y++) {
|
||||
for (let x = 0; x < canvas.width; x++) {
|
||||
const i = (canvas.width * y + x) * 4;
|
||||
if (type !== 'red') {
|
||||
if (step === 'bw') {
|
||||
buffer.push(imageData.data[i] === 0 && imageData.data[i+1] === 0 && imageData.data[i+2] === 0 ? 0 : 1);
|
||||
} else {
|
||||
buffer.push(imageData.data[i] > 0 && imageData.data[i+1] === 0 && imageData.data[i+2] === 0 ? 0 : 1);
|
||||
|
||||
@@ -14,6 +14,8 @@ const EpdCmd = {
|
||||
|
||||
SET_TIME: 0x20,
|
||||
|
||||
WRITE_IMG: 0x30, // v1.6
|
||||
|
||||
SET_CONFIG: 0x90,
|
||||
SYS_RESET: 0x91,
|
||||
SYS_SLEEP: 0x92,
|
||||
@@ -77,6 +79,32 @@ async function epdWrite(cmd, data) {
|
||||
}
|
||||
}
|
||||
|
||||
async function epdWriteImage(step = 'bw') {
|
||||
const data = canvas2bytes(canvas, step);
|
||||
const chunkSize = document.getElementById('mtusize').value - 2;
|
||||
const interleavedCount = document.getElementById('interleavedcount').value;
|
||||
const count = Math.round(data.length / chunkSize);
|
||||
let chunkIdx = 0;
|
||||
let noReplyCount = interleavedCount;
|
||||
|
||||
for (let i = 0; i < data.length; i += chunkSize) {
|
||||
let currentTime = (new Date().getTime() - startTime) / 1000.0;
|
||||
setStatus(`${step == 'bw' ? '黑白' : '红色'}块: ${chunkIdx+1}/${count+1}, 总用时: ${currentTime}s`);
|
||||
const payload = [
|
||||
(step == 'bw' ? 0x0F : 0x00) | ( i == 0 ? 0x00 : 0xF0),
|
||||
...data.slice(i, i + chunkSize),
|
||||
];
|
||||
if (noReplyCount > 0) {
|
||||
await write(EpdCmd.WRITE_IMG, payload, false);
|
||||
noReplyCount--;
|
||||
} else {
|
||||
await write(EpdCmd.WRITE_IMG, payload, true);
|
||||
noReplyCount = interleavedCount;
|
||||
}
|
||||
chunkIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
async function setDriver() {
|
||||
await write(EpdCmd.SET_PINS, document.getElementById("epdpins").value);
|
||||
await write(EpdCmd.INIT, document.getElementById("epddriver").value);
|
||||
@@ -123,12 +151,16 @@ async function sendimg() {
|
||||
startTime = new Date().getTime();
|
||||
status.parentElement.style.display = "block";
|
||||
|
||||
if (mode.startsWith('bwr')) {
|
||||
const invert = (appVersion < 0x16) ? (driver === '02') : false;
|
||||
await epdWrite(driver === "02" ? 0x24 : 0x10, canvas2bytes(canvas, 'bw'));
|
||||
await epdWrite(driver === "02" ? 0x26 : 0x13, canvas2bytes(canvas, 'red', invert));
|
||||
if (appVersion < 0x16) {
|
||||
if (mode.startsWith('bwr')) {
|
||||
await epdWrite(driver === "02" ? 0x24 : 0x10, canvas2bytes(canvas, 'bw'));
|
||||
await epdWrite(driver === "02" ? 0x26 : 0x13, canvas2bytes(canvas, 'red', driver === '02'));
|
||||
} else {
|
||||
await epdWrite(driver === "04" ? 0x24 : 0x13, canvas2bytes(canvas, 'bw'));
|
||||
}
|
||||
} else {
|
||||
await epdWrite(driver === "04" ? 0x24 : 0x13, canvas2bytes(canvas, 'bw'));
|
||||
await epdWriteImage('bw');
|
||||
if (mode.startsWith('bwr')) await epdWriteImage('red');
|
||||
}
|
||||
|
||||
await write(EpdCmd.REFRESH);
|
||||
|
||||
Reference in New Issue
Block a user