From 42fc2bb2bdc4f27d6253942f5b815933e18e870a Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Sat, 22 Apr 2023 11:51:22 -0400 Subject: [PATCH] hiti: Add support for the P461 'Prinhome' There are still some unknowns: * Matte mode * Ribbon vendor/subtype (needed for color correction / heat table selection) --- README | 5 ++- backend_hiti.c | 104 ++++++++++++++++++++++++++++++++++++---------- regression-gp.csv | 4 ++ 3 files changed, 88 insertions(+), 25 deletions(-) diff --git a/README b/README index a8f864c..c17aacd 100644 --- a/README +++ b/README @@ -37,6 +37,7 @@ DNP DS820 / DS820A / Citizen CX-02W DNP QW410 / Citizen CZ-01 Fujifilm ASK-300 + HiTi P461 (aka Prinhome) HiTi P510 series HiTi P520L HiTi P525L @@ -86,7 +87,6 @@ DNP M8 Fujifilm ASK-500 HiTi M610 (not X610!) - HiTi P461 (aka Prinhome) HiTi P530D HiTi P710L HiTi P720L / P728L @@ -1273,6 +1273,7 @@ Notes: Model IDs recognized: + hiti-p461 hiti-p510k hiti-p510l hiti-p510s hiti-p510si hiti-p518a hiti-p518s hiti-p520l hiti-p525l hiti-p52x hiti-p530 @@ -1282,6 +1283,7 @@ Notes: Verified supported printers: + HiTi P461 (aka Prinhome) HiTi P510 series HiTi P520L HiTi P525L @@ -1295,7 +1297,6 @@ Notes: Work-in-progress printers: HiTi CS2x0 series - HiTi P461 (aka Prinhome) HiTi P530D This backend supports additional commands: diff --git a/backend_hiti.c b/backend_hiti.c index 2015d4c..cd09e55 100644 --- a/backend_hiti.c +++ b/backend_hiti.c @@ -189,7 +189,7 @@ struct hiti_rpidm { /* CMD_EDRC_RS */ struct hiti_erdc_rs { /* All are BIG endian */ uint8_t unk; // 1e == 30, but struct is 29 length. - uint16_t stride; /* fixed at 0x0780/1920? Head width? */ + uint16_t stride; /* Head width: 1920 (6" models) 1280 (4" models) */ uint16_t dpi_cols; /* fixed at 300 */ uint16_t dpi_rows; /* fixed at 300 */ uint16_t cols; /* 1844 for 6" media */ @@ -346,7 +346,7 @@ struct hiti_efd_sf { /*@11*/ uint8_t colorSeq; /* always 0x87, but |= 0xc0 for matte. */ /*@12*/ uint8_t copies; /*@13*/ uint8_t printMode; /* 0x08 baseline, |= 0x02 fine mode */ -// XXX on P461, uint8_t zero[4]; +/*@14*/ uint8_t zero[4]; /* P461 only */ } __attribute__((packed)); /* CMD_ESD_SEPD -- Note it's different from the usual command flow */ @@ -619,6 +619,41 @@ static int hiti_docmd_resp(struct hiti_ctx *ctx, uint16_t cmdid, return CUPS_BACKEND_OK; } +static int hiti_shptc(struct hiti_ctx *ctx, uint8_t *buf, uint16_t buf_len) +{ + uint8_t cmdbuf[sizeof(struct hiti_cmd)]; + struct hiti_cmd *cmd = (struct hiti_cmd *)cmdbuf; + int ret, num = 0; + + cmd->hdr = 0xa5; + cmd->len = cpu_to_be16(buf_len + 3); + cmd->status = CMD_STATUS_OK; + cmd->cmd = cpu_to_be16(CMD_ESD_SHPTC); + + /* Send over command */ + if ((ret = send_data(ctx->conn, (uint8_t*) cmd, sizeof(*cmd)))) { + return ret; + } + + __usleep(10*1000); + + /* Read back command */ + ret = read_data(ctx->conn, cmdbuf, 6, &num); + if (ret) + return ret; + + if (num != 6) { + ERROR("CMD Readback length mismatch (%d vs %d)!\n", num, 6); + return CUPS_BACKEND_FAILED; + } + + ret = send_data(ctx->conn, buf, buf_len); + if (ret) + return CUPS_BACKEND_FAILED; + + return CUPS_BACKEND_OK; +} + static int hiti_sepd(struct hiti_ctx *ctx, uint32_t buf_len, uint16_t startLine, uint16_t numLines) { @@ -949,10 +984,6 @@ static int hiti_get_info(struct hiti_ctx *ctx) ctx->hilight_adj[1], ctx->hilight_adj[2], ctx->hilight_adj[3]); } - ret = hiti_query_summary(ctx, &ctx->erdc_rs); - if (ret) - return CUPS_BACKEND_FAILED; - INFO("Status Summary: %d %dx%d %dx%d\n", ctx->erdc_rs.stride, ctx->erdc_rs.cols, @@ -1030,6 +1061,10 @@ static int hiti_get_status(struct hiti_ctx *ctx) if (ret) return ret; + INFO("Printer ID: %s\n", ctx->id); + INFO("Printer Version: %s\n", ctx->version); + INFO("Serial Number: %s\n", ctx->serno); + INFO("Printer Status: %s (%02x %02x %02x)\n", hiti_status(sts), sts[0], sts[1], sts[2]); INFO("Printer Error: %s (%08x)\n", @@ -1135,6 +1170,10 @@ static int hiti_attach(void *vctx, struct dyesub_connection *conn, uint8_t jobid if (ret) return ret; + ret = hiti_query_summary(ctx, &ctx->erdc_rs); + if (ret) + return CUPS_BACKEND_FAILED; + switch (ctx->conn->type) { case P_HITI_461: if (strncmp(ctx->version, "1.12.0", 8) < 0) @@ -1162,7 +1201,7 @@ static int hiti_attach(void *vctx, struct dyesub_connection *conn, uint8_t jobid ctx->paper.type = PAPER_TYPE_6INCH; ctx->ribbon.type = RIBBON_TYPE_4x6; - if (getenv("MEDIA_CODE")) { + if (getenv("MEDIA_CODE") && strlen(getenv("MEDIA_CODE"))) { // set fake fw version? ctx->ribbon.type = atoi(getenv("MEDIA_CODE")); if (ctx->ribbon.type == RIBBON_TYPE_5x7) @@ -1172,10 +1211,14 @@ static int hiti_attach(void *vctx, struct dyesub_connection *conn, uint8_t jobid ctx->marker.color = "#00FFFF#FF00FF#FFFF00"; ctx->marker.name = hiti_ribbontypes(ctx->ribbon.type); - ctx->marker.numtype = ctx->ribbon.type; ctx->marker.levelmax = hiti_ribboncounts(ctx->ribbon.type, ctx->conn->type); ctx->marker.levelnow = 0; + if (ctx->conn->type == P_HITI_461) + ctx->marker.numtype = -1; + else + ctx->marker.numtype = ctx->ribbon.type; + return CUPS_BACKEND_OK; } @@ -1199,9 +1242,6 @@ static uint8_t *hiti_get_correction_data(struct hiti_ctx *ctx, uint8_t mode) int mediaver = ctx->ribbonvendor & 0x3f; int mediatype = ctx->ribbonvendor & 0xf000; - DEBUG("Locating correction data for model %d, mode %02x, media %02x, ver %02x\n", - ctx->conn->type, mode, mediatype >> 4, mediaver); - switch (ctx->conn->type) { case P_HITI_CS2XX: @@ -1493,6 +1533,10 @@ static uint8_t *hiti_get_correction_data(struct hiti_ctx *ctx, uint8_t mode) fname = NULL; break; } + + DEBUG("Locating correction data for model %d, mode %02x, media %02x, ver %02x = '%s'\n", + ctx->conn->type, mode, mediatype >> 4, mediaver, fname); + if (!fname) return NULL; @@ -2223,7 +2267,7 @@ static int hiti_read_parse(void *vctx, const void **vjob, int data_fd, int copie } break; default: - ERROR("Unknown ribbon type!\n"); + ERROR("Unknown ribbon type (%d)!\n", ctx->ribbon.type); hiti_cleanup_job(job); return CUPS_BACKEND_CANCEL; } @@ -2386,11 +2430,20 @@ static int hiti_main_loop(void *vctx, const void *vjob, int wait_for_return) sf.cols_offset = calc_offset(ctx->calibration.horiz, 6, 11, 4); sf.colorSeq = 0x87 + (job->hdr.overcoat ? 0xc0 : 0); sf.copies = job->common.copies; - sf.printMode = 0x08 + (job->hdr.quality ? 0x02 : 0); - ret = hiti_docmd(ctx, CMD_EFD_SF, (uint8_t*) &sf, sizeof(sf), &resplen); + sf.printMode = (ctx->conn->type == P_HITI_461) + ? 0 : 0x08 + (job->hdr.quality ? 0x02 : 0); + memset(sf.zero, 0, sizeof(sf.zero)); + ret = hiti_docmd(ctx, CMD_EFD_SF, (uint8_t*) &sf, + ctx->conn->type == P_HITI_461 ? sizeof(sf) : sizeof(sf)-4 , + &resplen); if (ret) return CUPS_BACKEND_FAILED; + // XXX on P461: + // request warning + // QJC + // then SF again + // XXX msg 8011 sent here on P52x (and maybe others?) /* Initialize jobid structure */ @@ -2452,13 +2505,9 @@ static int hiti_main_loop(void *vctx, const void *vjob, int wait_for_return) } /* Send ESC_SHPTC with entire file contents */ - uint16_t resp_len = 0; - - ret = hiti_docmd(ctx, CMD_ESD_SHPTC, ctx->heattable_buf, len, &resp_len); - if (ret || resp_len) { - ERROR("Unexpected response to ESD_SHPTC (%d %d)\n", ret, resp_len); + ret = hiti_shptc(ctx, ctx->heattable_buf, len); + if (ret) return CUPS_BACKEND_FAILED; - } } else { ret = hiti_read_heattable_v2(ctx, fname); if (ret) @@ -2986,7 +3035,12 @@ static int hiti_query_markers(void *vctx, struct marker **markers, int *count) if (ret) return ret; - ctx->marker.levelnow = ctx->media_remain; + if (ctx->conn->type == P_HITI_461) { + ctx->marker.levelnow = CUPS_MARKER_UNKNOWN_OK; + // XXX alter this, check for errors and return 0 instead. + } else { + ctx->marker.levelnow = ctx->media_remain; + } return CUPS_BACKEND_OK; } @@ -3108,7 +3162,7 @@ static const char *hiti_prefixes[] = { const struct dyesub_backend hiti_backend = { .name = "HiTi Photo Printers", - .version = "0.52", + .version = "0.53", .uri_prefixes = hiti_prefixes, .cmdline_usage = hiti_cmdline, .cmdline_arg = hiti_cmdline_arg, @@ -3182,7 +3236,11 @@ const struct dyesub_backend hiti_backend = { - More "Matrix table" decoding work - Start working on "sheet type" models - P110S - - P461 Prinhome + - Others + - More work on P461 Prinhome + - Matte support + - Media version/type + - Anything else? - Pull in updated heat tables & LUTs from windows drivers - Figure out what to send from v2 heattables diff --git a/regression-gp.csv b/regression-gp.csv index 6d52783..4d62722 100644 --- a/regression-gp.csv +++ b/regression-gp.csv @@ -769,6 +769,10 @@ dnp-qw410,0x1452,0x9201,161,PageSize=w324h576;StpPrintSpeed=LowSpeed dnp-qw410,0x1452,0x9201,161,PageSize=w324h576;StpDeCurl=True dnp-qw410,0x1452,0x9201,161,PageSize=w324h576;StpDeCurl=False # +hiti-p461,0x0d16,0x0509,,PageSize=w288h432 +hiti-p461,0x0d16,0x0509,,PageSize=w288h432;StpLaminate=Matte +hiti-p461,0x0d16,0x0509,,PageSize=w288h432;StePrintSpeed=Fine +# hiti-p510l,0x0d16,0x000b,1,PageSize=w288h432 hiti-p510l,0x0d16,0x000b,1,PageSize=w288h432-div2 hiti-p510l,0x0d16,0x000b,2,PageSize=B7