mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 13:23:51 -07:00
Add Waveshare support (bitmap ok, RGB maybe broken?)
This commit is contained in:
parent
9abbcab4a5
commit
b9329ce555
8 changed files with 897 additions and 4 deletions
|
@ -3,7 +3,8 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
- Add `hf 14a config` to deal with badly configured cards: invalid ATQA/BCC/SAK (@doegox)"
|
- Add `hf waveshare` to upload picture to Waveshare NFC-Powered e-Paper (@doegox)
|
||||||
|
- Add `hf 14a config` to deal with badly configured cards: invalid ATQA/BCC/SAK (@doegox)
|
||||||
- Mikron JSC Russia Ultralight EV1 41 pages tag type support (@McEloff)
|
- Mikron JSC Russia Ultralight EV1 41 pages tag type support (@McEloff)
|
||||||
- Add test for Ultralight gen2 magic 'hf search' (@McEloff)
|
- Add test for Ultralight gen2 magic 'hf search' (@McEloff)
|
||||||
- Add test for Ultralight EV1 gen2 magic 'hf search' (@McEloff)
|
- Add test for Ultralight EV1 gen2 magic 'hf search' (@McEloff)
|
||||||
|
|
|
@ -241,6 +241,7 @@ set (TARGET_SOURCES
|
||||||
${PM3_ROOT}/client/src/cmdhfst.c
|
${PM3_ROOT}/client/src/cmdhfst.c
|
||||||
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
||||||
${PM3_ROOT}/client/src/cmdhftopaz.c
|
${PM3_ROOT}/client/src/cmdhftopaz.c
|
||||||
|
${PM3_ROOT}/client/src/cmdhfwaveshare.c
|
||||||
${PM3_ROOT}/client/src/cmdhw.c
|
${PM3_ROOT}/client/src/cmdhw.c
|
||||||
${PM3_ROOT}/client/src/cmdlf.c
|
${PM3_ROOT}/client/src/cmdlf.c
|
||||||
${PM3_ROOT}/client/src/cmdlfawid.c
|
${PM3_ROOT}/client/src/cmdlfawid.c
|
||||||
|
|
|
@ -432,9 +432,10 @@ SRCS = aidsearch.c \
|
||||||
cmdhfmfhard.c \
|
cmdhfmfhard.c \
|
||||||
cmdhfmfu.c \
|
cmdhfmfu.c \
|
||||||
cmdhfmfp.c \
|
cmdhfmfp.c \
|
||||||
|
cmdhfst.c \
|
||||||
cmdhfthinfilm.c \
|
cmdhfthinfilm.c \
|
||||||
cmdhftopaz.c \
|
cmdhftopaz.c \
|
||||||
cmdhfst.c \
|
cmdhfwaveshare.c \
|
||||||
cmdhw.c \
|
cmdhw.c \
|
||||||
cmdlf.c \
|
cmdlf.c \
|
||||||
cmdlfawid.c \
|
cmdlfawid.c \
|
||||||
|
|
|
@ -119,6 +119,7 @@ add_library(pm3rrg_rdv4 SHARED
|
||||||
${PM3_ROOT}/client/src/cmdhfmfu.c
|
${PM3_ROOT}/client/src/cmdhfmfu.c
|
||||||
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
||||||
${PM3_ROOT}/client/src/cmdhftopaz.c
|
${PM3_ROOT}/client/src/cmdhftopaz.c
|
||||||
|
${PM3_ROOT}/client/src/cmdhfwaveshare.c
|
||||||
${PM3_ROOT}/client/src/cmdhw.c
|
${PM3_ROOT}/client/src/cmdhw.c
|
||||||
${PM3_ROOT}/client/src/cmdlf.c
|
${PM3_ROOT}/client/src/cmdlf.c
|
||||||
${PM3_ROOT}/client/src/cmdlfawid.c
|
${PM3_ROOT}/client/src/cmdlfawid.c
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "cmdhflto.h" // LTO-CM
|
#include "cmdhflto.h" // LTO-CM
|
||||||
#include "cmdhfcryptorf.h" // CryptoRF
|
#include "cmdhfcryptorf.h" // CryptoRF
|
||||||
#include "cmdhfst.h" // ST rothult
|
#include "cmdhfst.h" // ST rothult
|
||||||
|
#include "cmdhfwaveshare.h" // Waveshare
|
||||||
#include "cmdtrace.h" // trace list
|
#include "cmdtrace.h" // trace list
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "proxgui.h"
|
#include "proxgui.h"
|
||||||
|
@ -85,8 +86,6 @@ static int usage_hf_tune(void) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROMPT_CLEARLINE PrintAndLogEx(INPLACE, " \r")
|
|
||||||
|
|
||||||
int CmdHFSearch(const char *Cmd) {
|
int CmdHFSearch(const char *Cmd) {
|
||||||
|
|
||||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
|
@ -369,6 +368,7 @@ static command_t CommandTable[] = {
|
||||||
{"st", CmdHF_ST, AlwaysAvailable, "{ ST Rothult RFIDs... }"},
|
{"st", CmdHF_ST, AlwaysAvailable, "{ ST Rothult RFIDs... }"},
|
||||||
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
|
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
|
||||||
{"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"},
|
{"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"},
|
||||||
|
{"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"},
|
||||||
{"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"},
|
{"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"},
|
||||||
{"plot", CmdHFPlot, IfPm3Hfplot, "Plot signal"},
|
{"plot", CmdHFPlot, IfPm3Hfplot, "Plot signal"},
|
||||||
{"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"},
|
{"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"},
|
||||||
|
|
878
client/src/cmdhfwaveshare.c
Normal file
878
client/src/cmdhfwaveshare.c
Normal file
|
@ -0,0 +1,878 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Waveshare commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// from ST25R3911B-NFC-Demo source code by Waveshare team
|
||||||
|
|
||||||
|
#include "cmdhfwaveshare.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "comms.h"
|
||||||
|
#include "cmdparser.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "fileutils.h"
|
||||||
|
#include "util_posix.h" // msleep
|
||||||
|
|
||||||
|
// Currently the largest pixel 880*528 only needs 58.08K bytes
|
||||||
|
#define WSMAPSIZE 60000
|
||||||
|
|
||||||
|
#pragma pack(1) /* Mandatory to remove any padding */
|
||||||
|
typedef struct {
|
||||||
|
uint8_t B;
|
||||||
|
uint8_t M;
|
||||||
|
uint32_t fsize;
|
||||||
|
uint16_t res1;
|
||||||
|
uint16_t res2;
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t Bit_Pixel;
|
||||||
|
uint32_t BMP_Width;
|
||||||
|
uint32_t BMP_Height;
|
||||||
|
uint16_t planes;
|
||||||
|
uint16_t bpp;
|
||||||
|
uint32_t ctype;
|
||||||
|
uint32_t dsize;
|
||||||
|
uint32_t hppm;
|
||||||
|
uint32_t vppm;
|
||||||
|
uint32_t colorsused;
|
||||||
|
uint32_t colorreq;
|
||||||
|
uint32_t Color_1; //Color palette
|
||||||
|
uint32_t Color_2;
|
||||||
|
} PACKED BMP_HEADER;
|
||||||
|
|
||||||
|
#define EPD_1IN54B 0
|
||||||
|
#define EPD_1IN54C 1
|
||||||
|
#define EPD_1IN54V2 2
|
||||||
|
#define EPD_1IN54BCV2 3
|
||||||
|
#define EPD_2IN13V2 4
|
||||||
|
#define EPD_2IN13BC 5
|
||||||
|
#define EPD_2IN13D 6
|
||||||
|
#define EPD_2IN9 7
|
||||||
|
#define EPD_2IN9BC 8
|
||||||
|
#define EPD_2IN9D 9
|
||||||
|
#define EPD_4IN2 10
|
||||||
|
#define EPD_4IN2BC 11
|
||||||
|
#define EPD_7IN5 12
|
||||||
|
#define EPD_7IN5BC 13
|
||||||
|
#define EPD_7IN5V2 14
|
||||||
|
#define EPD_7IN5BCV2 15
|
||||||
|
#define EPD_2IN7 16
|
||||||
|
#define EPD_7IN5HD 17
|
||||||
|
|
||||||
|
typedef struct model_s {
|
||||||
|
const char *desc;
|
||||||
|
uint8_t len; // The data sent in one time shall not be greater than 128-3
|
||||||
|
} model_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
M2in13 = 0,
|
||||||
|
M2in9,
|
||||||
|
M4in2,
|
||||||
|
M7in5,
|
||||||
|
M2in7,
|
||||||
|
M2in13B,
|
||||||
|
M1in54B,
|
||||||
|
M7in5HD,
|
||||||
|
MEND
|
||||||
|
} model_enum_t;
|
||||||
|
|
||||||
|
static model_t models[] = {
|
||||||
|
{"2.13 inch e-paper", 16},
|
||||||
|
{"2.9 inch e-paper", 16},
|
||||||
|
{"4.2 inch e-paper", 100},
|
||||||
|
{"7.5 inch e-paper", 120},
|
||||||
|
{"2.7 inch e-paper", 121},
|
||||||
|
{"2.13 inch e-paper B", 106},
|
||||||
|
{"1.54 inch e-paper B", 100},
|
||||||
|
{"7.5 inch e-paper HD", 120},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
static int usage_hf_waveshare_loadbmp(void) {
|
||||||
|
PrintAndLogEx(NORMAL, "Load BMP file to Waveshare NFC ePaper.");
|
||||||
|
PrintAndLogEx(NORMAL, "Usage: hf waveshare loadbmp [h] f <filename[.bmp]> m <model_nr>");
|
||||||
|
PrintAndLogEx(NORMAL, " Options :");
|
||||||
|
PrintAndLogEx(NORMAL, " f <fn> : " _YELLOW_("filename[.bmp]") " to upload to tag");
|
||||||
|
PrintAndLogEx(NORMAL, " m <nr> : " _YELLOW_("model number") " of your tag");
|
||||||
|
for (uint8_t i=0; i< MEND; i++) {
|
||||||
|
PrintAndLogEx(NORMAL, " m %2i : %s", i, models[i].desc);
|
||||||
|
}
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf waveshare loadbmp m 0 f myfile"));
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int picture_bit_depth(const uint8_t *bmp, const size_t bmpsize) {
|
||||||
|
if (bmpsize < sizeof(BMP_HEADER))
|
||||||
|
return PM3_ESOFT;
|
||||||
|
BMP_HEADER *pbmpheader = (BMP_HEADER *)bmp;
|
||||||
|
PrintAndLogEx(DEBUG, "colorsused = %d", pbmpheader->colorsused);
|
||||||
|
PrintAndLogEx(DEBUG, "pbmpheader->bpp = %d", pbmpheader->bpp);
|
||||||
|
return pbmpheader->bpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int read_bmp_bitmap(const uint8_t *bmp, const size_t bmpsize, uint8_t **black) {
|
||||||
|
BMP_HEADER *pbmpheader = (BMP_HEADER *)bmp;
|
||||||
|
// check file is bitmap
|
||||||
|
if (pbmpheader->bpp != 1) {
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
if (pbmpheader->B == 'M' || pbmpheader->M == 'B') { //0x4d42
|
||||||
|
PrintAndLogEx(WARNING, "The file is not a BMP!");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
PrintAndLogEx(DEBUG, "file size = %d", pbmpheader->fsize);
|
||||||
|
PrintAndLogEx(DEBUG, "file offset = %d", pbmpheader->offset);
|
||||||
|
if (pbmpheader->fsize > bmpsize) {
|
||||||
|
PrintAndLogEx(WARNING, "The file is truncated!");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
uint8_t color_flag = pbmpheader->Color_1;
|
||||||
|
// Get BMP file data pointer
|
||||||
|
uint32_t offset = pbmpheader->offset;
|
||||||
|
|
||||||
|
uint16_t X, Y;
|
||||||
|
uint16_t Image_Width_Byte = (pbmpheader->BMP_Width % 8 == 0) ? (pbmpheader->BMP_Width / 8) : (pbmpheader->BMP_Width / 8 + 1);
|
||||||
|
uint16_t Bmp_Width_Byte = (Image_Width_Byte % 4 == 0) ? Image_Width_Byte : ((Image_Width_Byte / 4 + 1) * 4);
|
||||||
|
|
||||||
|
*black = calloc(WSMAPSIZE, sizeof(uint8_t));
|
||||||
|
if (*black == NULL) {
|
||||||
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
// Write data into RAM
|
||||||
|
for (Y = 0; Y < pbmpheader->BMP_Height; Y++) { // columns
|
||||||
|
for (X = 0; X < Bmp_Width_Byte; X++) { // lines
|
||||||
|
if ((X < Image_Width_Byte) && ((X + (pbmpheader->BMP_Height - Y - 1) * Image_Width_Byte) < WSMAPSIZE)) {
|
||||||
|
(*black)[X + (pbmpheader->BMP_Height - Y - 1) * Image_Width_Byte] = color_flag ? bmp[offset] : ~bmp[offset];
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_bmp_rgb(const uint8_t *bmp, const size_t bmpsize, uint8_t **black, uint8_t **red) {
|
||||||
|
BMP_HEADER *pbmpheader = (BMP_HEADER *)bmp;
|
||||||
|
// check file is full color
|
||||||
|
if (pbmpheader->bpp != 24) {
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
if (pbmpheader->B == 'M' || pbmpheader->M == 'B') { //0x4d42
|
||||||
|
PrintAndLogEx(WARNING, "The file is not a BMP!");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
PrintAndLogEx(DEBUG, "file size = %d", pbmpheader->fsize);
|
||||||
|
PrintAndLogEx(DEBUG, "file offset = %d", pbmpheader->offset);
|
||||||
|
if (pbmpheader->fsize > bmpsize) {
|
||||||
|
PrintAndLogEx(WARNING, "The file is truncated!");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
// Get BMP file data pointer
|
||||||
|
uint32_t offset = pbmpheader->offset;
|
||||||
|
|
||||||
|
uint16_t X, Y;
|
||||||
|
uint16_t Image_Width_Byte = (pbmpheader->BMP_Width % 8 == 0) ? (pbmpheader->BMP_Width / 8) : (pbmpheader->BMP_Width / 8 + 1);
|
||||||
|
|
||||||
|
*black = calloc(WSMAPSIZE, sizeof(uint8_t));
|
||||||
|
if (*black == NULL) {
|
||||||
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
*red = calloc(WSMAPSIZE, sizeof(uint8_t));
|
||||||
|
if (*red == NULL) {
|
||||||
|
free(*black);
|
||||||
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t R = 0, G = 0, B = 0;
|
||||||
|
uint8_t Black_data = 0;
|
||||||
|
uint8_t Red_data = 0;
|
||||||
|
uint8_t count = 0;
|
||||||
|
// Write data into RAM
|
||||||
|
for (Y = 0; Y < pbmpheader->BMP_Height; Y++) { // columns
|
||||||
|
for (X = 0; X < pbmpheader->BMP_Width; X++) { // lines
|
||||||
|
B = bmp[offset++];
|
||||||
|
G = bmp[offset++];
|
||||||
|
G = bmp[offset++];
|
||||||
|
if (R < 30 && G < 30 && B < 30) {
|
||||||
|
Black_data = Black_data | (1);
|
||||||
|
} else if (R > 190 && G < 90 && B < 90) {
|
||||||
|
Red_data = Red_data | (1);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
if (count >= 8) {
|
||||||
|
(*black)[X / 8 + (pbmpheader->BMP_Height - Y - 1) * Image_Width_Byte] = ~Black_data;
|
||||||
|
(*red)[X / 8 + (pbmpheader->BMP_Height - Y - 1) * Image_Width_Byte] = ~Red_data;
|
||||||
|
count = 0;
|
||||||
|
Black_data = 0;
|
||||||
|
Red_data = 0;
|
||||||
|
}
|
||||||
|
Black_data = Black_data << 1;
|
||||||
|
Red_data = Red_data << 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void read_black(uint32_t i, uint8_t *l, uint8_t model_nr, uint8_t *black) {
|
||||||
|
for (uint8_t j = 0; j < models[model_nr].len; j++) {
|
||||||
|
l[3 + j] = black[i * models[model_nr].len + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void read_red(uint32_t i, uint8_t *l, uint8_t model_nr, uint8_t *red) {
|
||||||
|
for (uint8_t j = 0; j < models[model_nr].len; j++) {
|
||||||
|
if (model_nr == M1in54B) {
|
||||||
|
//1.54B needs to flip the red picture data, other screens do not need to flip data
|
||||||
|
l[3 + j] = ~red[i * models[model_nr].len + j];
|
||||||
|
} else {
|
||||||
|
l[3 + j] = red[i * models[model_nr].len + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void transceive_blocking( uint8_t* txBuf, uint16_t txBufLen, uint8_t* rxBuf, uint16_t rxBufLen, uint16_t* actLen, uint32_t fwt ){
|
||||||
|
*actLen = 2;
|
||||||
|
(void) fwt;
|
||||||
|
PacketResponseNG resp;
|
||||||
|
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, txBufLen, 0, txBuf, txBufLen);
|
||||||
|
WaitForResponse(CMD_ACK, &resp);
|
||||||
|
if (resp.oldarg[0] > rxBufLen) {
|
||||||
|
PrintAndLogEx(WARNING, "Received % bytes, rxBuf too small (%)", resp.oldarg[0], rxBufLen);
|
||||||
|
memcpy(rxBuf, resp.data.asBytes, rxBufLen);
|
||||||
|
*actLen = rxBufLen;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(rxBuf, resp.data.asBytes, resp.oldarg[0]);
|
||||||
|
*actLen = resp.oldarg[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1.54B Keychain
|
||||||
|
// 1.54B does not share the common base and requires specific handling
|
||||||
|
static int start_drawing_1in54B(uint8_t model_nr, uint8_t *black, uint8_t *red, uint8_t fail_num) {
|
||||||
|
uint8_t step = 5;
|
||||||
|
uint8_t step_5[128] = {0xcd, 0x05, 100};
|
||||||
|
uint8_t step_4[2] = {0xcd, 0x04};
|
||||||
|
uint8_t step_6[2] = {0xcd, 0x06};
|
||||||
|
uint8_t rx[20] = {0};
|
||||||
|
uint16_t actrxlen[20], i = 0, progress = 0;
|
||||||
|
|
||||||
|
if (model_nr == M1in54B) {
|
||||||
|
step_5[2] = 100;
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
if (step == 5) {
|
||||||
|
PrintAndLogEx(INFO, "1.54_Step9: e-paper config2 (black)");
|
||||||
|
if (model_nr == M1in54B) { //1.54inch B Keychain
|
||||||
|
for (i = 0; i < 50; i++) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
read_black(i, step_5, model_nr, black);
|
||||||
|
transceive_blocking(step_5, 103, rx, 20, actrxlen, 2157 + 2048); // cd 05
|
||||||
|
progress = i * 100 / 100;
|
||||||
|
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PROMPT_CLEARLINE;
|
||||||
|
step = 6;
|
||||||
|
} else if (step == 6) {
|
||||||
|
PrintAndLogEx(INFO, "1.54_Step6: e-paper power on");
|
||||||
|
transceive_blocking(step_4, 2, rx, 20, actrxlen, 2157 + 2048); //cd 04
|
||||||
|
step = 7;
|
||||||
|
if (rx[0] == 0 && rx[1] == 0) {
|
||||||
|
step = 7;
|
||||||
|
} else {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 10) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please press any key to exit and try again.");
|
||||||
|
step = 14;
|
||||||
|
fail_num = 0;
|
||||||
|
msleep(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (step == 7) {
|
||||||
|
PrintAndLogEx(INFO, "1.54_Step7: e-paper config2 (red)");
|
||||||
|
if (model_nr == M1in54B) { //1.54inch B Keychain
|
||||||
|
for (i = 0; i < 50; i++) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
read_red(i, step_5, model_nr, red);
|
||||||
|
transceive_blocking(step_5, 103, rx, 20, actrxlen, 2157 + 2048); // cd 05
|
||||||
|
progress = i * 100 / 100 + 50;
|
||||||
|
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PROMPT_CLEARLINE;
|
||||||
|
step = 8;
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
} else if (step == 8) {
|
||||||
|
// Send update instructions
|
||||||
|
PrintAndLogEx(INFO, "1.54_Step8: EDP load to main");
|
||||||
|
transceive_blocking(step_6, 2, rx, 20, actrxlen, 2157 + 2048); //cd 06
|
||||||
|
if (rx[0] == 0 && rx[1] == 0) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 9;
|
||||||
|
} else {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 10) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please press any key to exit and try again.");
|
||||||
|
step = 14;
|
||||||
|
fail_num = 0;
|
||||||
|
msleep(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (step == 9) {
|
||||||
|
PrintAndLogEx(INFO, "1.54_Step9");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
} else if (step == 14) {
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
||||||
|
uint8_t fail_num = 0;
|
||||||
|
uint8_t step = 0, progress = 0;
|
||||||
|
uint8_t step0[2] = {0xcd, 0x0d};
|
||||||
|
uint8_t step1[3] = {0xcd, 0x00, 10}; //select e-paper type and reset e-paper 4:2.13inch e-Paper 7:2.9inch e-Paper 10:4.2inch e-Paper 14:7.5inch e-Paper
|
||||||
|
uint8_t step2[2] = {0xcd, 0x01}; //e-paper normal mode type:
|
||||||
|
uint8_t step3[2] = {0xcd, 0x02}; //e-paper config1
|
||||||
|
uint8_t step4[2] = {0xcd, 0x03}; //e-paper power on
|
||||||
|
uint8_t step5[2] = {0xcd, 0x05}; //e-paper config2
|
||||||
|
uint8_t step6[2] = {0xcd, 0x06}; //EDP load to main
|
||||||
|
uint8_t step7[2] = {0xcd, 0x07}; //Data preparation
|
||||||
|
uint8_t step8[123] = {0xcd, 0x08, 0x64}; //Data start command 2.13inch(0x10:Send 16 data at a time) 2.9inch(0x10:Send 16 data at a time) 4.2inch(0x64:Send 100 data at a time) 7.5inch(0x78:Send 120 data at a time)
|
||||||
|
uint8_t step9[2] = {0xcd, 0x18}; //e-paper power on
|
||||||
|
uint8_t step10[2] = {0xcd, 0x09}; //Refresh e-paper
|
||||||
|
uint8_t step11[2] = {0xcd, 0x0a}; //wait for ready
|
||||||
|
uint8_t step12[2] = {0xcd, 0x04}; //e-paper power off command
|
||||||
|
uint8_t step13[124] = {0xcd, 0x19, 121};
|
||||||
|
// uint8_t step13[2]={0xcd,0x0b}; //Judge whether the power supply is turned off successfully
|
||||||
|
// uint8_t step14[2]={0xcd,0x0c}; //The end of the transmission
|
||||||
|
uint8_t rx[20];
|
||||||
|
uint16_t actrxlen[20], i = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0);
|
||||||
|
PacketResponseNG resp;
|
||||||
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
|
||||||
|
PrintAndLogEx(ERR, "No tag found");
|
||||||
|
DropField();
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
iso14a_card_select_t card;
|
||||||
|
memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t));
|
||||||
|
|
||||||
|
uint64_t select_status = resp.oldarg[0];
|
||||||
|
|
||||||
|
if (select_status == 0) {
|
||||||
|
PrintAndLogEx(ERR, "Tag select error");
|
||||||
|
DropField();
|
||||||
|
return PM3_ERFTRANS;
|
||||||
|
} else if (select_status == 3) {
|
||||||
|
PrintAndLogEx(WARNING, "Card doesn't support standard iso14443-3 anticollision, doesn't look like Waveshare tag");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((card.uidlen != 7) || (memcmp(card.uid, "WSDZ10m", 7) != 0)) {
|
||||||
|
PrintAndLogEx(WARNING, "Card doesn't look like Waveshare tag");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(DEBUG, "model_nr = %d", model_nr);
|
||||||
|
while (1) {
|
||||||
|
if (step == 0) {
|
||||||
|
PrintAndLogEx(INFO, "Step0");
|
||||||
|
transceive_blocking(step0, 2, rx, 20, actrxlen, 2157 + 2048); //cd 0d
|
||||||
|
if (rx[0] == 0 && rx[1] == 0) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 1;
|
||||||
|
} else {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 10) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please try again.");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (step == 1) {
|
||||||
|
PrintAndLogEx(INFO, "Step1: e-paper config");
|
||||||
|
//step1[2] screen model
|
||||||
|
//step8[2] nr of bytes sent at once
|
||||||
|
//step13[2] nr of bytes sent for the second time
|
||||||
|
// generally, step8 sends a black image, step13 sends a red image
|
||||||
|
if (model_nr == M2in13) { //2.13inch
|
||||||
|
step1[2] = EPD_2IN13V2;
|
||||||
|
step8[2] = 16;
|
||||||
|
step13[2] = 0;
|
||||||
|
} else if (model_nr == M2in9) { //2.9inch
|
||||||
|
step1[2] = EPD_2IN9;
|
||||||
|
step8[2] = 16;
|
||||||
|
step13[2] = 0;
|
||||||
|
} else if (model_nr == M4in2) { //4.2inch
|
||||||
|
step1[2] = EPD_4IN2;
|
||||||
|
step8[2] = 100;
|
||||||
|
step13[2] = 0;
|
||||||
|
} else if (model_nr == M7in5) { //7.5inch
|
||||||
|
step1[2] = EPD_7IN5V2;
|
||||||
|
step8[2] = 120;
|
||||||
|
step13[2] = 0;
|
||||||
|
} else if (model_nr == M2in7) { //2.7inch
|
||||||
|
step1[2] = EPD_2IN7;
|
||||||
|
step8[2] = 121;
|
||||||
|
// Send blank data for the first time, and send other data to 0xff without processing the bottom layer
|
||||||
|
step13[2] = 121;
|
||||||
|
//Sending the second data is the real image data. If the previous 0xff is not sent, the last output image is abnormally black
|
||||||
|
} else if (model_nr == M2in13B) { //2.13inch B
|
||||||
|
step1[2] = EPD_2IN13BC;
|
||||||
|
step8[2] = 106;
|
||||||
|
step13[2] = 106;
|
||||||
|
} else if (model_nr == M7in5HD) {
|
||||||
|
step1[2] = EPD_7IN5HD;
|
||||||
|
step8[2] = 120;
|
||||||
|
step13[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model_nr == M1in54B) {
|
||||||
|
transceive_blocking(step1, 2, rx, 20, actrxlen, 2157 + 2048); //cd 00
|
||||||
|
} else {
|
||||||
|
transceive_blocking(step1, 3, rx, 20, actrxlen, 2157 + 2048);
|
||||||
|
}
|
||||||
|
if (rx[0] == 0 && rx[1] == 0) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 2;
|
||||||
|
fail_num = 0;
|
||||||
|
msleep(100);
|
||||||
|
} else {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 10) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please try again.");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msleep(10);
|
||||||
|
} else if (step == 2) {
|
||||||
|
PrintAndLogEx(INFO, "Step2: e-paper normal mode type");
|
||||||
|
transceive_blocking(step2, 2, rx, 20, actrxlen, 2157 + 2048); //cd 01
|
||||||
|
if (rx[0] == 0 && rx[1] == 0) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 3;
|
||||||
|
fail_num = 0;
|
||||||
|
msleep(100);
|
||||||
|
} else {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 50) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please try again.");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msleep(100);
|
||||||
|
} else if (step == 3) {
|
||||||
|
PrintAndLogEx(INFO, "Step3: e-paper config1");
|
||||||
|
transceive_blocking(step3, 2, rx, 20, actrxlen, 2157 + 2048); //cd 02
|
||||||
|
if (rx[0] == 0 && rx[1] == 0) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 4;
|
||||||
|
fail_num = 0;
|
||||||
|
} else {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 10) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please try again.");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msleep(200);
|
||||||
|
} else if (step == 4) {
|
||||||
|
PrintAndLogEx(INFO, "Step4: e-paper power on");
|
||||||
|
transceive_blocking(step4, 2, rx, 20, actrxlen, 2157 + 2048); //cd 03
|
||||||
|
if (model_nr == M1in54B) {
|
||||||
|
// 1.54B Keychain handler
|
||||||
|
PrintAndLogEx(DEBUG, "Start_Drawing_1in54B");
|
||||||
|
char t = start_drawing_1in54B(model_nr, black, red, fail_num);
|
||||||
|
if (t == 0) {
|
||||||
|
step = 11;
|
||||||
|
//1.54B Data transfer is complete and wait for refresh
|
||||||
|
} else if (t == 1) {
|
||||||
|
step = 14;
|
||||||
|
//1.54B Data transmission error
|
||||||
|
}
|
||||||
|
// 1.54B Keychain handler end
|
||||||
|
}
|
||||||
|
if (rx[0] == 0 && rx[1] == 0) {
|
||||||
|
fail_num = 0;
|
||||||
|
step = 5;
|
||||||
|
} else {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 10) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please try again.");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (step == 5) {
|
||||||
|
PrintAndLogEx(INFO, "Step5: e-paper config2");
|
||||||
|
transceive_blocking(step5, 2, rx, 20, actrxlen, 2157 + 2048); //cd 05
|
||||||
|
if (rx[0] == 0 && rx[1] == 0) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 6;
|
||||||
|
fail_num = 0;
|
||||||
|
msleep(100);
|
||||||
|
} else {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 30) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please try again.");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msleep(10);
|
||||||
|
} else if (step == 6) {
|
||||||
|
PrintAndLogEx(INFO, "Step6: EDP load to main") ;
|
||||||
|
transceive_blocking(step6, 2, rx, 20, actrxlen, 2157 + 2048); //cd 06
|
||||||
|
if (rx[0] == 0 && rx[1] == 0) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 7;
|
||||||
|
fail_num = 0;
|
||||||
|
msleep(100);
|
||||||
|
} else {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 10) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please try again.");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (step == 7) {
|
||||||
|
PrintAndLogEx(INFO, "Step7: Data preparation");
|
||||||
|
transceive_blocking(step7, 2, rx, 20, actrxlen, 2157 + 2048); //cd 07
|
||||||
|
if (rx[0] == 0 && rx[1] == 0) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 8;
|
||||||
|
fail_num = 0;
|
||||||
|
} else {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 10) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please try again.");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (step == 8) { //cd 08
|
||||||
|
PrintAndLogEx(INFO, "Step8: Start data transfer");
|
||||||
|
if (model_nr == M2in13) { //2.13inch
|
||||||
|
for (i = 0; i < 250; i++) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
read_black(i, step8, model_nr, black);
|
||||||
|
transceive_blocking(step8, 19, rx, 20, actrxlen, 2157 + 2048);
|
||||||
|
progress = i * 100 / 250;
|
||||||
|
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||||
|
}
|
||||||
|
} else if (model_nr == M2in9) {
|
||||||
|
for (i = 0; i < 296; i++) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
read_black(i, step8, model_nr, black);
|
||||||
|
transceive_blocking(step8, 19, rx, 20, actrxlen, 2157 + 2048);
|
||||||
|
progress = i * 100 / 296;
|
||||||
|
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||||
|
}
|
||||||
|
} else if (model_nr == M4in2) { //4.2inch
|
||||||
|
for (i = 0; i < 150; i++) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
read_black(i, step8, model_nr, black);
|
||||||
|
transceive_blocking(step8, 103, rx, 20, actrxlen, 2157 + 2048);
|
||||||
|
progress = i * 100 / 150;
|
||||||
|
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||||
|
}
|
||||||
|
} else if (model_nr == M7in5) { //7.5inch
|
||||||
|
for (i = 0; i < 400; i++) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
read_black(i, step8, model_nr, black);
|
||||||
|
transceive_blocking(step8, 123, rx, 20, actrxlen, 2157 + 2048);
|
||||||
|
progress = i * 100 / 400;
|
||||||
|
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||||
|
msleep(6);
|
||||||
|
}
|
||||||
|
} else if (model_nr == M2in13B) { //2.13inch B
|
||||||
|
for (i = 0; i < 26; i++) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
read_black(i, step8, model_nr, black);
|
||||||
|
transceive_blocking(step8, 109, rx, 20, actrxlen, 2157 + 2048);
|
||||||
|
progress = i * 50 / 26;
|
||||||
|
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||||
|
}
|
||||||
|
} else if (model_nr == M7in5HD) { //7.5HD
|
||||||
|
|
||||||
|
for (i = 0; i < 484; i++) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
read_black(i, step8, model_nr, black);
|
||||||
|
//memset(&step8[3], 0xf0, 120);
|
||||||
|
transceive_blocking(step8, 123, rx, 20, actrxlen, 2157 + 2048);
|
||||||
|
progress = i * 100 / 484;
|
||||||
|
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||||
|
}
|
||||||
|
memset(&step8[3], 0xff, 120);
|
||||||
|
transceive_blocking(step8, 110 + 3, rx, 20, actrxlen, 2157 + 2048);
|
||||||
|
|
||||||
|
|
||||||
|
} else if (model_nr == M2in7) { //2.7inch
|
||||||
|
for (i = 0; i < 48; i++) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
//read_black(i,step8, model_nr, black);
|
||||||
|
memset(&step8[3], 0xFF, sizeof(step8)-3);
|
||||||
|
transceive_blocking(step8, 124, rx, 20, actrxlen, 2157 + 2048);
|
||||||
|
progress = i * 50 / 48;
|
||||||
|
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PROMPT_CLEARLINE;
|
||||||
|
step = 9;
|
||||||
|
} else if (step == 9) {
|
||||||
|
PrintAndLogEx(INFO, "Step9: e-paper power on");
|
||||||
|
if (model_nr == M2in13 || model_nr == M2in9 || model_nr == M4in2 || model_nr == M7in5 || model_nr == M7in5HD) {
|
||||||
|
transceive_blocking(step9, 2, rx, 20, actrxlen, 2157 + 2048); //cd 18
|
||||||
|
// The black-and-white screen sending backplane is also shielded, with no effect. Except 2.7
|
||||||
|
if (rx[0] != 0 || rx[1] != 0) {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 10) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please try again.");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
fail_num = 0;
|
||||||
|
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 10;
|
||||||
|
} else if (model_nr == M2in13B || model_nr == M2in7) {
|
||||||
|
transceive_blocking(step9, 2, rx, 20, actrxlen, 2157 + 2048); //cd 18
|
||||||
|
//rx[0]=1;rx[1]=1;
|
||||||
|
step = 19;
|
||||||
|
}
|
||||||
|
} else if (step == 10) {
|
||||||
|
PrintAndLogEx(INFO, "Step10: Refresh e-paper");
|
||||||
|
transceive_blocking(step10, 2, rx, 20, actrxlen, 2157 + 2048); //cd 09 refresh command
|
||||||
|
if (rx[0] != 0 || rx[1] != 0) {
|
||||||
|
fail_num++;
|
||||||
|
if (fail_num > 10) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please try again.");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
fail_num = 0;
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 11;
|
||||||
|
msleep(200);
|
||||||
|
} else if (step == 11) {
|
||||||
|
PrintAndLogEx(INFO, "Step11: Wait tag to be ready");
|
||||||
|
if (model_nr == M2in13B || model_nr == M1in54B) { // Black, white and red screen refresh time is longer, wait first
|
||||||
|
msleep(9000);
|
||||||
|
} else if (model_nr == M7in5HD) {
|
||||||
|
msleep(1000);
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
if (model_nr == M1in54B) {
|
||||||
|
// send 0xcd 0x08 with 1.54B
|
||||||
|
transceive_blocking(step8, 2, rx, 20, actrxlen, 2157 + 2048);
|
||||||
|
} else {
|
||||||
|
transceive_blocking(step11, 2, rx, 20, actrxlen, 2157 + 2048); //cd 0a
|
||||||
|
}
|
||||||
|
if (rx[0] == 0xff && rx[1] == 0) {
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(SUCCESS, "E-paper Reflash OK");
|
||||||
|
fail_num = 0;
|
||||||
|
step = 12;
|
||||||
|
msleep(200);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (fail_num > 50) {
|
||||||
|
PrintAndLogEx(WARNING, "Update failed, please try again.");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
} else {
|
||||||
|
fail_num++;
|
||||||
|
PrintAndLogEx(INPLACE, "E-paper Reflashing, Waiting");
|
||||||
|
msleep(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (step == 12) {
|
||||||
|
PrintAndLogEx(INFO, "Step12: e-paper power off command");
|
||||||
|
transceive_blocking(step12, 2, rx, 20, actrxlen, 2157 + 2048); //cd 04
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 13;
|
||||||
|
msleep(200);
|
||||||
|
} else if (step == 13) {
|
||||||
|
PrintAndLogEx(SUCCESS, "E-paper Update OK");
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
msleep(200);
|
||||||
|
DropField();
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
} else if (step == 19) {
|
||||||
|
PrintAndLogEx(INFO, "Step9b");
|
||||||
|
if (model_nr == M2in7) {
|
||||||
|
for (i = 0; i < 48; i++) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
read_black(i, step13, model_nr, black);
|
||||||
|
transceive_blocking(step13, 124, rx, 20, actrxlen, 2157 + 2048); //CD 19
|
||||||
|
progress = i * 50 / 48 + 50;
|
||||||
|
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||||
|
}
|
||||||
|
} else if (model_nr == M2in13B) {
|
||||||
|
for (i = 0; i < 26; i++) {
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
read_red(i, step13, model_nr, red);
|
||||||
|
//memset(&step13[3], 0xfE, 106);
|
||||||
|
transceive_blocking(step13, 109, rx, 20, actrxlen, 2157 + 2048);
|
||||||
|
progress = i * 50 / 26 + 50;
|
||||||
|
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PROMPT_CLEARLINE;
|
||||||
|
rx[0] = 1;
|
||||||
|
rx[1] = 1;
|
||||||
|
step = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int CmdHF14AWSLoadBmp(const char *Cmd) {
|
||||||
|
|
||||||
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
bool errors = false;
|
||||||
|
size_t filenamelen = 0;
|
||||||
|
uint8_t model_nr = 0xff;
|
||||||
|
|
||||||
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
case 'h':
|
||||||
|
return usage_hf_waveshare_loadbmp();
|
||||||
|
case 'f':
|
||||||
|
filenamelen = param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE);
|
||||||
|
if (filenamelen > FILE_PATH_SIZE - 5)
|
||||||
|
filenamelen = FILE_PATH_SIZE - 5;
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
model_nr = param_get8(Cmd, cmdp + 1);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown parameter: " _RED_("'%c'"), param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Validations
|
||||||
|
if (filenamelen < 1) {
|
||||||
|
PrintAndLogEx(WARNING, "Missing filename");
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
if (model_nr == 0xff) {
|
||||||
|
PrintAndLogEx(WARNING, "Missing model");
|
||||||
|
errors = true;
|
||||||
|
} else if (model_nr >= MEND) {
|
||||||
|
PrintAndLogEx(WARNING, "Unknown model");
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
if (errors || cmdp == 0) return usage_hf_waveshare_loadbmp();
|
||||||
|
|
||||||
|
uint8_t *bmp = NULL;
|
||||||
|
uint8_t *black = NULL;
|
||||||
|
uint8_t *red = NULL;
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
if (loadFile_safe(filename, ".bmp", (void **)&bmp, &bytes_read) != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(WARNING, "Could not find file " _YELLOW_("%s"), filename);
|
||||||
|
return PM3_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
int depth = picture_bit_depth(bmp, bytes_read);
|
||||||
|
if (depth == PM3_ESOFT) {
|
||||||
|
PrintAndLogEx(ERR, "Error, BMP file is too small");
|
||||||
|
free(bmp);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
} else if (depth == 1) {
|
||||||
|
PrintAndLogEx(DEBUG, "BMP file is a bitmap");
|
||||||
|
if (read_bmp_bitmap(bmp, bytes_read, &black) != PM3_SUCCESS) {
|
||||||
|
free(bmp);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
} else if (depth == 24) {
|
||||||
|
PrintAndLogEx(DEBUG, "BMP file is a RGB");
|
||||||
|
if (read_bmp_rgb(bmp, bytes_read, &black, &red) != PM3_SUCCESS) {
|
||||||
|
free(bmp);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
} else if (depth == 32) {
|
||||||
|
PrintAndLogEx(ERR, "Error, BMP color depth %i not supported. Remove alpha channel.", depth);
|
||||||
|
free(bmp);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(ERR, "Error, BMP color depth %i not supported", depth);
|
||||||
|
free(bmp);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
free(bmp);
|
||||||
|
|
||||||
|
start_drawing(model_nr, black, red);
|
||||||
|
free(black);
|
||||||
|
if (red != NULL) {
|
||||||
|
free(red);
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static command_t CommandTable[] = {
|
||||||
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
|
{"loadbmp", CmdHF14AWSLoadBmp, IfPm3Iso14443a, "Load BMP file to Waveshare NFC ePaper"},
|
||||||
|
{NULL, NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd) {
|
||||||
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
CmdsHelp(CommandTable);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdHFWaveshare(const char *Cmd) {
|
||||||
|
clearCommandBuffer();
|
||||||
|
return CmdsParse(CommandTable, Cmd);
|
||||||
|
}
|
10
client/src/cmdhfwaveshare.h
Normal file
10
client/src/cmdhfwaveshare.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Waveshare commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef CMDHFWQVESHARE_H__
|
||||||
|
#define CMDHFWAVESHARE_H__
|
||||||
|
|
||||||
|
int CmdHFWaveshare(const char *Cmd);
|
||||||
|
|
||||||
|
#endif
|
|
@ -53,6 +53,7 @@ extern bool showDemod;
|
||||||
#endif
|
#endif
|
||||||
#define MAX_PRINT_BUFFER 2048
|
#define MAX_PRINT_BUFFER 2048
|
||||||
|
|
||||||
|
#define PROMPT_CLEARLINE PrintAndLogEx(INPLACE, " \r")
|
||||||
void PrintAndLogOptions(const char *str[][2], size_t size, size_t space);
|
void PrintAndLogOptions(const char *str[][2], size_t size, size_t space);
|
||||||
void PrintAndLogEx(logLevel_t level, const char *fmt, ...);
|
void PrintAndLogEx(logLevel_t level, const char *fmt, ...);
|
||||||
void SetFlushAfterWrite(bool value);
|
void SetFlushAfterWrite(bool value);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue