From 985e556556409ca3db5e8041387ea3fc60a85a16 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Sun, 5 Jun 2016 22:51:28 -0500 Subject: [PATCH 01/25] Most amusingly I am achieving novel results with this ATmega2560 --- avr/Makefile | 4 +- avr/send.c | 111 +++++++++++++++++++++++++++++++++++--------- bin/main.c | 3 ++ include/tabby/avr.h | 16 +++---- 4 files changed, 101 insertions(+), 33 deletions(-) diff --git a/avr/Makefile b/avr/Makefile index fd4725f..6751637 100644 --- a/avr/Makefile +++ b/avr/Makefile @@ -7,7 +7,7 @@ HEADER_SUBDIR = tabby CROSS = avr- CC = $(CROSS)gcc -CFLAGS = $(CGFLAGS) -Wall -Os -mmcu=atmega328p -I$(INCLUDE_PATH) \ +CFLAGS = $(CGFLAGS) -Wall -Os -mmcu=atmega2560 -I$(INCLUDE_PATH) \ -DF_CPU=$(CLOCK_SPEED) -DUSE_2X LDFLAGS = @@ -16,7 +16,7 @@ OBJCOPY_FLAGS = -S AVRDUDE = avrdude AVRDUDE_DEVICE = /dev/cu.usbmodem1411 -AVRDUDE_FLAGS = -c arduino -p atmega328p -b 115200 -D -P $(AVRDUDE_DEVICE) +AVRDUDE_FLAGS = -c wiring -p atmega2560 -b 115200 -D -P $(AVRDUDE_DEVICE) HEADERS_LOCAL = HEADERS_BUILD = $(HEADERS_LOCAL) \ diff --git a/avr/send.c b/avr/send.c index aa65eb3..c91f3c7 100644 --- a/avr/send.c +++ b/avr/send.c @@ -7,15 +7,6 @@ #include #include -static tabby_printer_packet header; -static tabby_printer_response response; - -static uint8_t body[TABBY_PRINTER_PACKET_MAX_SIZE]; - -static uint8_t sheet[TABBY_PRINTER_SHEET_SIZE]; - -static uint16_t sum; - static void spi_init() { SC_OUTPUT(); SO_OUTPUT(); @@ -56,30 +47,95 @@ static uint8_t spi_send_byte(uint8_t value) { return ret; } -static void spi_send_packet() { +static uint16_t checksum(tabby_printer_packet *header, uint8_t *body) { + uint16_t sum = 0; + + int i; + + for (i=2; idata[i]; + } + + for (i=0; isize; i++) { + sum += body[i]; + } + + return sum; +} + +static void spi_send_packet(uint8_t type, uint8_t *body, uint16_t size) { + tabby_printer_packet header = { + .preamble = { TABBY_PRINTER_SYNC_1, TABBY_PRINTER_SYNC_2 }, + .type = type, + .compression = TABBY_PRINTER_COMPRESSION_NONE, + .size = size + }; + + uint16_t sum = checksum(&header, body); + int i; for (i=0; i> 8); - response.device = spi_send_byte(0); - response.status = spi_send_byte(0); + (void)spi_send_byte(0); + (void)spi_send_byte(0); +} + +static void spi_send_init() { + spi_send_packet(TABBY_PRINTER_PACKET_INIT, NULL, 0); +} + +static void spi_send_job(uint8_t sheets, + uint8_t linefeeds, + uint8_t palette, + uint8_t density) { + uint8_t job[4] = { + sheets, linefeeds, palette, density + }; + + spi_send_packet(TABBY_PRINTER_PACKET_JOB, job, sizeof(job)); +} + +static void spi_send_data(uint8_t *data, uint16_t size) { + spi_send_packet(TABBY_PRINTER_PACKET_DATA, data, size); +} + +static void spi_send_sheet(uint8_t *sheet, uint16_t size) { + int i; + + spi_send_init(); + + for (i=0; i Date: Sun, 5 Jun 2016 22:54:31 -0500 Subject: [PATCH 02/25] HOLY SHIT YES --- src/printer.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/printer.c b/src/printer.c index 79dd00f..6520598 100644 --- a/src/printer.c +++ b/src/printer.c @@ -230,27 +230,12 @@ int tabby_printer_send_sheet(int fd, void *data, goto error_packet_send; } - init_header(&header, TABBY_PRINTER_PACKET_DATA, 0); - - tabby_printer_packet_send(fd, &header, NULL, response); - - if (i == 0) { - tabby_printer_job_start(fd, 1, 0x10, 0x00, 0x40, ¤t); - } else if (i < TABBY_PRINTER_SHEET_BANDS - 1) { - tabby_printer_job_start(fd, 1, 0x00, 0x00, 0x40, ¤t); - } else if (i == TABBY_PRINTER_SHEET_BANDS - 1) { - tabby_printer_job_start(fd, 1, 0x03, 0x00, 0x40, ¤t); - } - offset += TABBY_PRINTER_BAND_SIZE; - - while (current.status) { - tabby_printer_send_inquiry(fd, ¤t); - usleep(1000000); - } } - return 0; + init_header(&header, TABBY_PRINTER_PACKET_DATA, 0); + + return tabby_printer_packet_send(fd, &header, NULL, response); error_packet_send: return -1; From f8a3cf8d6b2ced9b141c9cdc005987bc20414d19 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Sun, 5 Jun 2016 23:52:28 -0500 Subject: [PATCH 03/25] Symmetry is important --- avr/send.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avr/send.c b/avr/send.c index c91f3c7..4178196 100644 --- a/avr/send.c +++ b/avr/send.c @@ -32,8 +32,8 @@ static uint8_t spi_send_byte(uint8_t value) { _delay_us(SPI_PULSE_USEC); - ret <<= 1; value <<= 1; + ret <<= 1; if (SI_IS_HIGH()) { ret |= 1; From 7059d688ac8fde74092a8b55450737f60376fe7a Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 6 Jun 2016 01:42:17 -0500 Subject: [PATCH 04/25] A totally not-working WIP --- avr/send.c | 82 +++++++++++++++++++++++++---------------- bin/main.c | 2 + include/tabby/printer.h | 16 +++++++- 3 files changed, 67 insertions(+), 33 deletions(-) diff --git a/avr/send.c b/avr/send.c index 4178196..5610fed 100644 --- a/avr/send.c +++ b/avr/send.c @@ -63,7 +63,10 @@ static uint16_t checksum(tabby_printer_packet *header, uint8_t *body) { return sum; } -static void spi_send_packet(uint8_t type, uint8_t *body, uint16_t size) { +static void spi_send_packet(uint8_t type, + uint8_t *body, + uint16_t size, + tabby_printer_response *response) { tabby_printer_packet header = { .preamble = { TABBY_PRINTER_SYNC_1, TABBY_PRINTER_SYNC_2 }, .type = type, @@ -86,41 +89,44 @@ static void spi_send_packet(uint8_t type, uint8_t *body, uint16_t size) { (void)spi_send_byte( sum & 0x00ff); (void)spi_send_byte((sum & 0xff00) >> 8); - (void)spi_send_byte(0); - (void)spi_send_byte(0); + response->device = spi_send_byte(0); + response->status = spi_send_byte(0); } -static void spi_send_init() { - spi_send_packet(TABBY_PRINTER_PACKET_INIT, NULL, 0); +static void spi_send_init(tabby_printer_response *response) { + spi_send_packet(TABBY_PRINTER_PACKET_INIT, NULL, 0, response); } -static void spi_send_job(uint8_t sheets, - uint8_t linefeeds, - uint8_t palette, - uint8_t density) { - uint8_t job[4] = { - sheets, linefeeds, palette, density - }; - - spi_send_packet(TABBY_PRINTER_PACKET_JOB, job, sizeof(job)); +static void spi_send_inquiry(tabby_printer_response *response) { + spi_send_packet(TABBY_PRINTER_PACKET_INQUIRY, NULL, 0, response); } -static void spi_send_data(uint8_t *data, uint16_t size) { - spi_send_packet(TABBY_PRINTER_PACKET_DATA, data, size); +static void spi_send_job(tabby_printer_job *job, + tabby_printer_response *response) { + spi_send_packet(TABBY_PRINTER_PACKET_JOB, + job->data, + sizeof(job), + response); } -static void spi_send_sheet(uint8_t *sheet, uint16_t size) { +static void spi_send_data(uint8_t *data, + uint16_t size, + tabby_printer_response *response) { + spi_send_packet(TABBY_PRINTER_PACKET_DATA, data, size, response); +} + +static void spi_send_sheet(uint8_t *sheet, + uint16_t size, + tabby_printer_response *response) { int i; - spi_send_init(); + spi_send_init(response); for (i=0; i Date: Mon, 6 Jun 2016 01:49:19 -0500 Subject: [PATCH 05/25] whoops --- avr/send.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avr/send.c b/avr/send.c index 5610fed..ff129dc 100644 --- a/avr/send.c +++ b/avr/send.c @@ -105,7 +105,7 @@ static void spi_send_job(tabby_printer_job *job, tabby_printer_response *response) { spi_send_packet(TABBY_PRINTER_PACKET_JOB, job->data, - sizeof(job), + sizeof(*job), response); } From 3fa06b40d71ab4a2e71be3e4ff6aba7d115384d5 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 6 Jun 2016 02:04:18 -0500 Subject: [PATCH 06/25] Ahh that was my problem. At least now we can service inquiries! --- avr/send.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avr/send.c b/avr/send.c index ff129dc..50793c6 100644 --- a/avr/send.c +++ b/avr/send.c @@ -193,11 +193,11 @@ int main() { case 2: { switch (c) { case TABBY_PRINTER_PACKET_INIT: - case TABBY_PRINTER_PACKET_JOB: case TABBY_PRINTER_PACKET_CANCEL: { sheet_offset = 0; } + case TABBY_PRINTER_PACKET_JOB: case TABBY_PRINTER_PACKET_DATA: case TABBY_PRINTER_PACKET_INQUIRY: { header.type = c; From 33bf45149e8cfeeb474ae55eb346239f4f4fb8aa Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 6 Jun 2016 19:16:05 -0500 Subject: [PATCH 07/25] Prevent packet body overflow --- avr/recv.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/avr/recv.c b/avr/recv.c index 55b6634..7de9035 100644 --- a/avr/recv.c +++ b/avr/recv.c @@ -22,7 +22,7 @@ ISR(SPI_STC_vect) { switch (i) { case 0: { if (in == TABBY_PRINTER_SYNC_1) { - header.data[0] = in; + header.preamble[0] = in; i++; b = 0; @@ -33,7 +33,7 @@ ISR(SPI_STC_vect) { case 1: { if (in == TABBY_PRINTER_SYNC_2) { - header.data[1] = in; + header.preamble[1] = in; i++; } else { i = 0; @@ -67,6 +67,10 @@ ISR(SPI_STC_vect) { header.size |= in << 8; i++; + if (header.size > TABBY_PRINTER_PACKET_MAX_SIZE) { + i = 0; + } + break; } @@ -79,6 +83,8 @@ ISR(SPI_STC_vect) { out = TABBY_PRINTER_DEVICE_ID; } else if (b == header.size + 2) { b++; + + out = TABBY_PRINTER_OK; } else if (b == header.size + 3) { i = 0; } From 319b17c8b2633451fdd903f0e3c64091f431e991 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 6 Jun 2016 19:42:15 -0500 Subject: [PATCH 08/25] Who loves refactoring? Xan loves refactoring --- avr/Makefile | 8 +-- avr/link.c | 71 +++++++++++++++++++ avr/printer.c | 98 ++++++++++++++++++++++++++ avr/recv.c | 27 +------- avr/send.c | 135 +++--------------------------------- bin/main.c | 67 +++++------------- include/tabby/avr/link.h | 12 ++++ include/tabby/avr/printer.h | 28 ++++++++ 8 files changed, 241 insertions(+), 205 deletions(-) create mode 100644 avr/link.c create mode 100644 avr/printer.c create mode 100644 include/tabby/avr/link.h create mode 100644 include/tabby/avr/printer.h diff --git a/avr/Makefile b/avr/Makefile index 6751637..e368e72 100644 --- a/avr/Makefile +++ b/avr/Makefile @@ -22,18 +22,18 @@ HEADERS_LOCAL = HEADERS_BUILD = $(HEADERS_LOCAL) \ $(addprefix $(INCLUDE_PATH)/$(HEADER_SUBDIR)/,$(HEADERS)) -HEADERS = avr.h avr/uart.h link.h -OBJS = send.o recv.o uart.o +HEADERS = avr.h avr/uart.h avr/link.h avr/printer.h link.h printer.h +OBJS = send.o recv.o printer.o link.o uart.o RECV_NAME = recv RECV_BIN = $(RECV_NAME).bin RECV_ELF = $(RECV_NAME).elf -RECV_OBJS = recv.o uart.o +RECV_OBJS = recv.o link.o uart.o SEND_NAME = send SEND_BIN = $(SEND_NAME).bin SEND_ELF = $(SEND_NAME).elf -SEND_OBJS = send.o uart.o +SEND_OBJS = send.o printer.o link.o uart.o IMAGES_BIN = $(RECV_BIN) $(SEND_BIN) IMAGES_ELF = $(RECV_ELF) $(SEND_ELF) diff --git a/avr/link.c b/avr/link.c new file mode 100644 index 0000000..6d61d9a --- /dev/null +++ b/avr/link.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include + +#include +#include +#include + +void tabby_avr_link_init_master() { + SC_OUTPUT(); + SO_OUTPUT(); + + SI_INPUT(); + SI_PULLUP(); + + SC_HIGH(); + SO_LOW(); +} + +void tabby_avr_link_init_slave() { + SS_INPUT(); + SC_INPUT(); + SI_INPUT(); + SO_OUTPUT(); + + /* + * Set SPI slave mode, and shift in/out most significant bit first + */ + SPCR &= ~((1 << MSTR) | (1 << DORD)); + + /* + * Enable SPI in Mode 3 with interrupts, clock nominally high, output on + * falling edge, input on rising edge + */ + SPCR |= (1 << CPOL) | (1 << CPHA) | (1 << SPIE) | (1 << SPE); + + /* + * Initialize the SPI Data Register and serial buffer + */ + SPDR = 0; +} + +uint8_t tabby_avr_link_send_byte(uint8_t value) { + uint8_t i, ret = 0; + + for (i=0; i<8; i++) { + SC_LOW(); + + if (value & 0x80) { + SO_HIGH(); + } else { + SO_LOW(); + } + + _delay_us(SPI_PULSE_USEC); + + value <<= 1; + ret <<= 1; + + if (SI_IS_HIGH()) { + ret |= 1; + } + + SC_HIGH(); + + _delay_us(SPI_PULSE_USEC); + } + + return ret; +} diff --git a/avr/printer.c b/avr/printer.c new file mode 100644 index 0000000..3fed9c1 --- /dev/null +++ b/avr/printer.c @@ -0,0 +1,98 @@ +#include + +#include +#include + +static uint16_t checksum(tabby_printer_packet *header, uint8_t *body) { + uint16_t sum = 0; + + int i; + + for (i=2; idata[i]; + } + + for (i=0; isize; i++) { + sum += body[i]; + } + + return sum; +} + +void tabby_avr_printer_send_packet(uint8_t type, + uint8_t *body, + uint16_t size, + tabby_printer_response *response) { + tabby_printer_packet header = { + .preamble = { TABBY_PRINTER_SYNC_1, TABBY_PRINTER_SYNC_2 }, + .type = type, + .compression = TABBY_PRINTER_COMPRESSION_NONE, + .size = size + }; + + uint16_t sum = checksum(&header, body); + + int i; + + for (i=0; i> 8); + + response->device = tabby_avr_link_send_byte(0); + response->status = tabby_avr_link_send_byte(0); +} + +void tabby_avr_printer_init(tabby_printer_response *response) { + tabby_avr_printer_send_packet(TABBY_PRINTER_PACKET_INIT, + NULL, + 0, + response); +} + +void tabby_avr_printer_send_inquiry(tabby_printer_response *response) { + tabby_avr_printer_send_packet(TABBY_PRINTER_PACKET_INQUIRY, + NULL, + 0, + response); +} + +void tabby_avr_printer_job_start(tabby_printer_job *job, + tabby_printer_response *response) { + tabby_avr_printer_send_packet(TABBY_PRINTER_PACKET_JOB, + job->data, + sizeof(*job), + response); +} + +void tabby_avr_printer_send_data(uint8_t *data, + uint16_t size, + tabby_printer_response *response) { + tabby_avr_printer_send_packet(TABBY_PRINTER_PACKET_DATA, + data, + size, + response); +} + +void tabby_avr_printer_send_sheet(uint8_t *sheet, + uint16_t size, + tabby_printer_response *response) { + int i; + + tabby_avr_printer_init(response); + + for (i=0; i #include +#include #include static volatile tabby_printer_packet header; @@ -94,32 +95,10 @@ ISR(SPI_STC_vect) { SPDR = out; } -static void spi_init() { - SS_INPUT(); - SC_INPUT(); - SI_INPUT(); - SO_OUTPUT(); - - /* - * Set SPI slave mode, and shift in/out most significant bit first - */ - SPCR &= ~((1 << MSTR) | (1 << DORD)); - - /* - * Enable SPI in Mode 3 with interrupts, clock nominally high, output on - * falling edge, input on rising edge - */ - SPCR |= (1 << CPOL) | (1 << CPHA) | (1 << SPIE) | (1 << SPE); - - /* - * Initialize the SPI Data Register and serial buffer - */ - SPDR = 0; -} - int main() { uart_init(); - spi_init(); + + tabby_avr_link_init_slave(); sei(); diff --git a/avr/send.c b/avr/send.c index 50793c6..59bcb16 100644 --- a/avr/send.c +++ b/avr/send.c @@ -5,130 +5,10 @@ #include #include +#include +#include #include -static void spi_init() { - SC_OUTPUT(); - SO_OUTPUT(); - - SI_INPUT(); - SI_PULLUP(); - - SC_HIGH(); - SO_LOW(); -} - -static uint8_t spi_send_byte(uint8_t value) { - uint8_t i, ret = 0; - - for (i=0; i<8; i++) { - SC_LOW(); - - if (value & 0x80) { - SO_HIGH(); - } else { - SO_LOW(); - } - - _delay_us(SPI_PULSE_USEC); - - value <<= 1; - ret <<= 1; - - if (SI_IS_HIGH()) { - ret |= 1; - } - - SC_HIGH(); - - _delay_us(SPI_PULSE_USEC); - } - - return ret; -} - -static uint16_t checksum(tabby_printer_packet *header, uint8_t *body) { - uint16_t sum = 0; - - int i; - - for (i=2; idata[i]; - } - - for (i=0; isize; i++) { - sum += body[i]; - } - - return sum; -} - -static void spi_send_packet(uint8_t type, - uint8_t *body, - uint16_t size, - tabby_printer_response *response) { - tabby_printer_packet header = { - .preamble = { TABBY_PRINTER_SYNC_1, TABBY_PRINTER_SYNC_2 }, - .type = type, - .compression = TABBY_PRINTER_COMPRESSION_NONE, - .size = size - }; - - uint16_t sum = checksum(&header, body); - - int i; - - for (i=0; i> 8); - - response->device = spi_send_byte(0); - response->status = spi_send_byte(0); -} - -static void spi_send_init(tabby_printer_response *response) { - spi_send_packet(TABBY_PRINTER_PACKET_INIT, NULL, 0, response); -} - -static void spi_send_inquiry(tabby_printer_response *response) { - spi_send_packet(TABBY_PRINTER_PACKET_INQUIRY, NULL, 0, response); -} - -static void spi_send_job(tabby_printer_job *job, - tabby_printer_response *response) { - spi_send_packet(TABBY_PRINTER_PACKET_JOB, - job->data, - sizeof(*job), - response); -} - -static void spi_send_data(uint8_t *data, - uint16_t size, - tabby_printer_response *response) { - spi_send_packet(TABBY_PRINTER_PACKET_DATA, data, size, response); -} - -static void spi_send_sheet(uint8_t *sheet, - uint16_t size, - tabby_printer_response *response) { - int i; - - spi_send_init(response); - - for (i=0; i #include #include -#include #include #include @@ -20,34 +19,20 @@ static void usage(int argc, char **argv, char *message, ...) { va_end(args); } - fprintf(stderr, "usage: %s device sheet.tile\n", argv[0]); + fprintf(stderr, "usage: %s device\n", argv[0]); exit(1); } int main(int argc, char **argv) { - int fd, tile_fd; + int fd, status; - tabby_printer_response response; - void *tile; + tabby_printer_packet header; - if (argc != 3) { - usage(argc, argv, "Must specify device and tile"); - } + uint8_t body[TABBY_PRINTER_PACKET_MAX_SIZE]; - if ((tile = malloc(TABBY_PRINTER_SHEET_SIZE)) == NULL) { - goto error_malloc_tile; - } - - if ((tile_fd = open(argv[2], O_RDONLY)) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "open()", argv[2], strerror(errno)); - - goto error_open_tile; - } - - if (read(tile_fd, tile, TABBY_PRINTER_SHEET_SIZE) < 0) { - goto error_read_tile; + if (argc != 2) { + usage(argc, argv, "No device specified"); } if ((fd = tabby_link_open(argv[1])) < 0) { @@ -57,32 +42,19 @@ int main(int argc, char **argv) { goto error_link_open; } - printf("Waiting for AVR to reboot after CTS\n"); + while (1) { + status = tabby_printer_packet_recv(fd, &header, &body); - sleep(1); + if (status < 0) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "tabby_printer_packet_recv()", strerror(errno)); - tabby_printer_link_init(fd); + continue; + } - printf("Link initialized\n"); - - do { - tabby_printer_init(fd, &response); - - usleep(100000); - printf("Got response %02x%02x\n", response.device, response.status); - } while (response.device != TABBY_PRINTER_DEVICE_ID); - - tabby_printer_send_sheet(fd, tile, &response); - - printf("Sent sheet, got response %02x%02x\n", - response.device, response.status); - - tabby_printer_job_start(fd, 1, 0x13, 0x00, 0x40, &response); - - while (response.status & TABBY_PRINTER_UNTRAN) { - tabby_printer_send_inquiry(fd, &response); - - usleep(100000); + if (header.type == 0x04) { + write(1, &body, header.size); + } } tabby_link_close(fd); @@ -90,12 +62,5 @@ int main(int argc, char **argv) { return 0; error_link_open: -error_read_tile: - close(tile_fd); - -error_open_tile: - free(tile); - -error_malloc_tile: return 1; } diff --git a/include/tabby/avr/link.h b/include/tabby/avr/link.h new file mode 100644 index 0000000..7817d65 --- /dev/null +++ b/include/tabby/avr/link.h @@ -0,0 +1,12 @@ +#ifndef _TABBY_AVR_LINK_H +#define _TABBY_AVR_LINK_H + +#include + +void tabby_avr_link_init_master(); + +void tabby_avr_link_init_slave(); + +uint8_t tabby_avr_link_send_byte(uint8_t value); + +#endif /* _TABBY_AVR_LINK_H */ diff --git a/include/tabby/avr/printer.h b/include/tabby/avr/printer.h new file mode 100644 index 0000000..d12074e --- /dev/null +++ b/include/tabby/avr/printer.h @@ -0,0 +1,28 @@ +#ifndef _TABBY_AVR_PRINTER_H +#define _TABBY_AVR_PRINTER_H + +#include + +#include + +void tabby_avr_printer_send_packet(uint8_t type, + uint8_t *body, + uint16_t size, + tabby_printer_response *response); + +void tabby_avr_printer_init(tabby_printer_response *response); + +void tabby_avr_printer_send_inquiry(tabby_printer_response *response); + +void tabby_avr_printer_job_start(tabby_printer_job *job, + tabby_printer_response *response); + +void tabby_avr_printer_send_data(uint8_t *data, + uint16_t size, + tabby_printer_response *response); + +void tabby_avr_printer_send_sheet(uint8_t *sheet, + uint16_t size, + tabby_printer_response *response); + +#endif /* _TABBY_AVR_PRINTER_H */ From fc19701ec4319255f2f46415ee632822c3b706b9 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 6 Jun 2016 19:58:39 -0500 Subject: [PATCH 09/25] Ask gcc nicely to aggresively remove unwanted functions from output --- avr/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/avr/Makefile b/avr/Makefile index e368e72..46b910a 100644 --- a/avr/Makefile +++ b/avr/Makefile @@ -7,8 +7,9 @@ HEADER_SUBDIR = tabby CROSS = avr- CC = $(CROSS)gcc -CFLAGS = $(CGFLAGS) -Wall -Os -mmcu=atmega2560 -I$(INCLUDE_PATH) \ - -DF_CPU=$(CLOCK_SPEED) -DUSE_2X +CFLAGS = $(CGFLAGS) -Wall -Os -mmcu=atmega2560 \ + -fdata-sections -ffunction-sections -Wl,--gc-sections \ + -I$(INCLUDE_PATH) -DF_CPU=$(CLOCK_SPEED) -DUSE_2X LDFLAGS = OBJCOPY = $(CROSS)objcopy From be84cecfeb560a013857fa9a5326eca7b785cb5d Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 6 Jun 2016 20:28:19 -0500 Subject: [PATCH 10/25] I hate overflows as much as the next person --- avr/Makefile | 2 +- avr/printer.c | 18 ++++++++++++++++++ avr/recv.c | 7 ++++--- avr/send.c | 7 +++++++ include/tabby/avr/printer.h | 2 ++ 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/avr/Makefile b/avr/Makefile index 46b910a..f85ac71 100644 --- a/avr/Makefile +++ b/avr/Makefile @@ -29,7 +29,7 @@ OBJS = send.o recv.o printer.o link.o uart.o RECV_NAME = recv RECV_BIN = $(RECV_NAME).bin RECV_ELF = $(RECV_NAME).elf -RECV_OBJS = recv.o link.o uart.o +RECV_OBJS = recv.o printer.o link.o uart.o SEND_NAME = send SEND_BIN = $(SEND_NAME).bin diff --git a/avr/printer.c b/avr/printer.c index 3fed9c1..17000d6 100644 --- a/avr/printer.c +++ b/avr/printer.c @@ -3,6 +3,24 @@ #include #include +int tabby_avr_printer_packet_toolarge(uint8_t type, uint16_t size) { + switch (type) { + case TABBY_PRINTER_PACKET_JOB: { + if (size > sizeof(tabby_printer_job)) { + return 1; + } + } + + case TABBY_PRINTER_PACKET_DATA: { + if (size > TABBY_PRINTER_PACKET_MAX_SIZE) { + return 1; + } + } + } + + return 0; +} + static uint16_t checksum(tabby_printer_packet *header, uint8_t *body) { uint16_t sum = 0; diff --git a/avr/recv.c b/avr/recv.c index 27392b7..6d5046a 100644 --- a/avr/recv.c +++ b/avr/recv.c @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -66,12 +66,13 @@ ISR(SPI_STC_vect) { case 5: { header.size |= in << 8; - i++; - if (header.size > TABBY_PRINTER_PACKET_MAX_SIZE) { + if (tabby_avr_printer_packet_toolarge(header.type, header.size)) { i = 0; } + i++; + break; } diff --git a/avr/send.c b/avr/send.c index 59bcb16..91476ab 100644 --- a/avr/send.c +++ b/avr/send.c @@ -115,6 +115,13 @@ int main() { header.size |= c << 8; i++; + if (tabby_avr_printer_packet_toolarge(header.type, + header.size)) { + i = 0; + b = 0; + sheet_offset = 0; + } + break; } diff --git a/include/tabby/avr/printer.h b/include/tabby/avr/printer.h index d12074e..390423e 100644 --- a/include/tabby/avr/printer.h +++ b/include/tabby/avr/printer.h @@ -5,6 +5,8 @@ #include +int tabby_avr_printer_packet_toolarge(uint8_t type, uint16_t size); + void tabby_avr_printer_send_packet(uint8_t type, uint8_t *body, uint16_t size, From c18eb40c465fa205e3de8cb3fb3f9dda0e9e6858 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 6 Jun 2016 20:46:25 -0500 Subject: [PATCH 11/25] Whoops --- avr/recv.c | 4 ++-- avr/send.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/avr/recv.c b/avr/recv.c index 6d5046a..27fbce0 100644 --- a/avr/recv.c +++ b/avr/recv.c @@ -69,10 +69,10 @@ ISR(SPI_STC_vect) { if (tabby_avr_printer_packet_toolarge(header.type, header.size)) { i = 0; + } else { + i++; } - i++; - break; } diff --git a/avr/send.c b/avr/send.c index 91476ab..fcbfffb 100644 --- a/avr/send.c +++ b/avr/send.c @@ -113,13 +113,14 @@ int main() { case 5: { header.size |= c << 8; - i++; if (tabby_avr_printer_packet_toolarge(header.type, header.size)) { i = 0; b = 0; sheet_offset = 0; + } else { + i++; } break; From d5aea747d0e3efafc952f46b4dc87a77f21e9a8c Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 6 Jun 2016 20:49:43 -0500 Subject: [PATCH 12/25] Just a little less nuts --- avr/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avr/recv.c b/avr/recv.c index 27fbce0..8447356 100644 --- a/avr/recv.c +++ b/avr/recv.c @@ -67,7 +67,7 @@ ISR(SPI_STC_vect) { case 5: { header.size |= in << 8; - if (tabby_avr_printer_packet_toolarge(header.type, header.size)) { + if (header.size > TABBY_PRINTER_PACKET_MAX_SIZE) { i = 0; } else { i++; From 06503a351038d12e08f70e4805f8895edac24535 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 6 Jun 2016 21:04:19 -0500 Subject: [PATCH 13/25] HAHAHA I DON'T FUCKING NEED YOU ANY LONGER --- avr/send.c | 10 ---------- include/tabby/printer.h | 2 -- src/link.c | 2 +- src/printer.c | 17 ----------------- 4 files changed, 1 insertion(+), 30 deletions(-) diff --git a/avr/send.c b/avr/send.c index fcbfffb..b3d1c17 100644 --- a/avr/send.c +++ b/avr/send.c @@ -35,16 +35,6 @@ int main() { sei(); - while (1) { - uart_putchar('O', NULL); - - c = uart_getchar(NULL); - - if (c == 'K') { - break; - } - } - while (1) { c = uart_getchar(NULL); diff --git a/include/tabby/printer.h b/include/tabby/printer.h index 3fbbcde..6fab3bf 100644 --- a/include/tabby/printer.h +++ b/include/tabby/printer.h @@ -81,8 +81,6 @@ typedef struct _tabby_printer_response { uint8_t status; } tabby_printer_response; -int tabby_printer_link_init(int fd); - /* * For receiving printer data packets from a Game Boy Camera */ diff --git a/src/link.c b/src/link.c index 7f52ac6..f52b2f5 100644 --- a/src/link.c +++ b/src/link.c @@ -25,7 +25,7 @@ int tabby_link_open(const char *dev) { attr.c_cc[VTIME] = 0; attr.c_cc[VMIN] = 1; - if (tcsetattr(fd, TCSANOW, &attr) < 0) { + if (tcsetattr(fd, TCSAFLUSH, &attr) < 0) { goto error_io; } diff --git a/src/printer.c b/src/printer.c index 6520598..d33d394 100644 --- a/src/printer.c +++ b/src/printer.c @@ -9,23 +9,6 @@ #define PACKET_RECV_ERROR_THRESHOLD 30 -int tabby_printer_link_init(int fd) { - uint8_t out = 'K', - in; - - while (1) { - read(fd, &in, 1); - - if (in == 'O') { - write(fd, &out, 1); - - break; - } - } - - return 0; -} - static uint16_t checksum(tabby_printer_packet *header, void *body) { uint16_t checksum = header->data[2] + header->data[3] From eb8ac6acb649e26359abbc7ce1583272d8f4f301 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Tue, 7 Jun 2016 17:05:49 -0500 Subject: [PATCH 14/25] Wow, Tiffany, refactoring is like, so crazy sexy cool --- avr/recv.c | 59 +++++++++++++++--------------------- avr/send.c | 89 +++++++++++++++++++++++++++++++++--------------------- 2 files changed, 79 insertions(+), 69 deletions(-) diff --git a/avr/recv.c b/avr/recv.c index 8447356..da9fc95 100644 --- a/avr/recv.c +++ b/avr/recv.c @@ -7,9 +7,9 @@ #include #include -static volatile tabby_printer_packet header; - -static volatile uint16_t i, b; +static volatile uint16_t offset_header = 0, + offset_body = 0, + size_body = 0; /* * SPI byte receipt interrupt vector @@ -20,13 +20,11 @@ ISR(SPI_STC_vect) { uart_putchar(in, NULL); - switch (i) { + switch (offset_header) { case 0: { if (in == TABBY_PRINTER_SYNC_1) { - header.preamble[0] = in; - i++; - - b = 0; + offset_header++; + offset_body = 0; } break; @@ -34,61 +32,54 @@ ISR(SPI_STC_vect) { case 1: { if (in == TABBY_PRINTER_SYNC_2) { - header.preamble[1] = in; - i++; + offset_header++; } else { - i = 0; + offset_header = 0; } break; } - case 2: { - header.type = in; - i++; - - break; - } - + case 2: case 3: { - header.compression = in; - i++; + offset_header++; break; } case 4: { - header.size = in; - i++; + size_body = in; + + offset_header++; break; } case 5: { - header.size |= in << 8; + size_body |= in << 8; - if (header.size > TABBY_PRINTER_PACKET_MAX_SIZE) { - i = 0; + if (size_body > TABBY_PRINTER_PACKET_MAX_SIZE) { + offset_header = 0; } else { - i++; + offset_header++; } break; } default: { - if (b <= header.size) { - b++; - } else if (b == header.size + 1) { - b++; + if (offset_body <= size_body) { + offset_body++; + } else if (offset_body == size_body + 1) { + offset_body++; out = TABBY_PRINTER_DEVICE_ID; - } else if (b == header.size + 2) { - b++; + } else if (offset_body == size_body + 2) { + offset_body++; out = TABBY_PRINTER_OK; - } else if (b == header.size + 3) { - i = 0; + } else if (offset_body == size_body + 3) { + offset_header = 0; } } } diff --git a/avr/send.c b/avr/send.c index b3d1c17..aef40d9 100644 --- a/avr/send.c +++ b/avr/send.c @@ -10,12 +10,6 @@ #include int main() { - uint16_t i = 0, - b = 0, - sheet_offset = 0; - - uint8_t c; - tabby_printer_packet header = { .size = 0 }; @@ -29,22 +23,28 @@ int main() { uint8_t sheet[TABBY_PRINTER_SHEET_SIZE]; + uint16_t offset_header = 0, + offset_body = 0, + offset_sheet = 0; + + uint16_t sum_calc = 0, + sum_footer = 0; + uart_init(); tabby_avr_link_init_master(); - sei(); - while (1) { - c = uart_getchar(NULL); + uint8_t c = uart_getchar(NULL); - switch (i) { + switch (offset_header) { case 0: { if (c == TABBY_PRINTER_SYNC_1) { header.data[0] = c; - i++; + offset_header++; - b = 0; + offset_body = 0; + sum_calc = 0; } break; @@ -53,9 +53,9 @@ int main() { case 1: { if (c == TABBY_PRINTER_SYNC_2) { header.data[1] = c; - i++; + offset_header++; } else { - i = 0; + offset_header = 0; } break; @@ -65,38 +65,45 @@ int main() { switch (c) { case TABBY_PRINTER_PACKET_INIT: case TABBY_PRINTER_PACKET_CANCEL: { - sheet_offset = 0; + response.status = TABBY_PRINTER_OK; + offset_sheet = 0; } case TABBY_PRINTER_PACKET_JOB: case TABBY_PRINTER_PACKET_DATA: case TABBY_PRINTER_PACKET_INQUIRY: { header.type = c; - i++; + offset_header++; break; } default: { - i = 0; + offset_header = 0; break; } } + sum_calc += c; + break; } case 3: { header.compression = c; - i++; + offset_header++; + + sum_calc += c; break; } case 4: { header.size = c; - i++; + offset_header++; + + sum_calc += c; break; } @@ -106,43 +113,55 @@ int main() { if (tabby_avr_printer_packet_toolarge(header.type, header.size)) { - i = 0; - b = 0; - sheet_offset = 0; + offset_header = 0; + + response.status |= TABBY_PRINTER_FULL; + + goto respond; } else { - i++; + offset_header++; } + sum_calc += c; + break; } default: { - if (b < header.size) { + if (offset_body < header.size) { if (header.type == TABBY_PRINTER_PACKET_JOB) { - job.data[b] = c; + job.data[offset_body] = c; } else if (header.type == TABBY_PRINTER_PACKET_DATA) { - sheet[sheet_offset++] = c; + sheet[offset_sheet++] = c; } - b++; - } else if (b == header.size) { - b++; - } else if (b == header.size + 1) { - i = 0; - b = 0; + offset_body++; - if (header.type == TABBY_PRINTER_PACKET_JOB) { + sum_calc += c; + } else if (offset_body == header.size) { + sum_footer = c; + + offset_body++; + } else if (offset_body == header.size + 1) { + sum_footer |= c << 8; + + offset_header = 0; + + if (sum_footer != sum_calc) { + response.status |= TABBY_PRINTER_SUM; + } else if (header.type == TABBY_PRINTER_PACKET_JOB) { tabby_avr_printer_send_sheet(sheet, - sheet_offset, + offset_sheet, &response); tabby_avr_printer_job_start(&job, &response); - sheet_offset = 0; + offset_sheet = 0; } else if (header.type == TABBY_PRINTER_PACKET_INQUIRY) { tabby_avr_printer_send_inquiry(&response); } +respond: uart_putchar(response.device, NULL); uart_putchar(response.status, NULL); } From 5b27cf9c79fa22544e3aa98c702f0496a7e2a6e7 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Tue, 7 Jun 2016 17:59:23 -0500 Subject: [PATCH 15/25] Refactor print receiver to calculate checksums and raise CRC error when necessary --- avr/recv.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/avr/recv.c b/avr/recv.c index da9fc95..924d03d 100644 --- a/avr/recv.c +++ b/avr/recv.c @@ -9,7 +9,14 @@ static volatile uint16_t offset_header = 0, offset_body = 0, - size_body = 0; + size_body = 0, + sum_calc = 0, + sum_footer = 0; + +static volatile tabby_printer_response response = { + .device = TABBY_PRINTER_DEVICE_ID, + .status = TABBY_PRINTER_OK +}; /* * SPI byte receipt interrupt vector @@ -25,6 +32,9 @@ ISR(SPI_STC_vect) { if (in == TABBY_PRINTER_SYNC_1) { offset_header++; offset_body = 0; + sum_calc = 0; + + response.status = TABBY_PRINTER_OK; } break; @@ -43,6 +53,7 @@ ISR(SPI_STC_vect) { case 2: case 3: { offset_header++; + sum_calc += in; break; } @@ -50,6 +61,7 @@ ISR(SPI_STC_vect) { case 4: { size_body = in; + sum_calc += in; offset_header++; break; @@ -64,20 +76,32 @@ ISR(SPI_STC_vect) { offset_header++; } + sum_calc += in; + break; } default: { - if (offset_body <= size_body) { + if (offset_body < size_body) { offset_body++; + sum_calc += in; + } else if (offset_body == size_body) { + offset_body++; + sum_footer = in; } else if (offset_body == size_body + 1) { offset_body++; - out = TABBY_PRINTER_DEVICE_ID; + sum_footer |= in << 8; + + if (sum_footer != sum_calc) { + response.status |= TABBY_PRINTER_SUM; + } + + out = response.device; } else if (offset_body == size_body + 2) { offset_body++; - out = TABBY_PRINTER_OK; + out = response.status; } else if (offset_body == size_body + 3) { offset_header = 0; } From 629f3e00492aa5958f750c22be5244b30c5f08f4 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Tue, 7 Jun 2016 18:08:32 -0500 Subject: [PATCH 16/25] Gank retry mechanism; instead, if sending sheet fails, initialize printer and start over --- include/tabby/printer.h | 1 - src/printer.c | 40 +++++++++++++++++++--------------------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/include/tabby/printer.h b/include/tabby/printer.h index 6fab3bf..dfe319c 100644 --- a/include/tabby/printer.h +++ b/include/tabby/printer.h @@ -5,7 +5,6 @@ #define TABBY_PRINTER_SYNC_2 0x33 #define TABBY_PRINTER_DEVICE_ID 0x81 -#define TABBY_PRINTER_RETRY_COUNT 5 #define TABBY_PRINTER_PACKET_MAX_SIZE 640 diff --git a/src/printer.c b/src/printer.c index d33d394..29f612f 100644 --- a/src/printer.c +++ b/src/printer.c @@ -107,33 +107,24 @@ int tabby_printer_packet_send(int fd, void *body, tabby_printer_response *response) { uint16_t sum = checksum(header, body); - int tries = TABBY_PRINTER_RETRY_COUNT; - do { - if (tries-- == 0) { - errno = EIO; + if (write(fd, header, sizeof(*header)) < 0) { + goto error_io; + } + if (header->size) { + if (write(fd, body, header->size) < 0) { goto error_io; } + } - if (write(fd, header, sizeof(*header)) < 0) { - goto error_io; - } + if (write(fd, &sum, sizeof(sum)) < 0) { + goto error_io; + } - if (header->size) { - if (write(fd, body, header->size) < 0) { - goto error_io; - } - } - - if (write(fd, &sum, sizeof(sum)) < 0) { - goto error_io; - } - - if (read(fd, response, sizeof(*response)) < 0) { - goto error_io; - } - } while (resend(response)); + if (read(fd, response, sizeof(*response)) < 0) { + goto error_io; + } return 0; @@ -213,6 +204,13 @@ int tabby_printer_send_sheet(int fd, void *data, goto error_packet_send; } + if (resend(¤t)) { + tabby_printer_init(fd, ¤t); + i = -1; + + continue; + } + offset += TABBY_PRINTER_BAND_SIZE; } From fdd550844bce6da6705606ef866c2917c4b1ae46 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Wed, 8 Jun 2016 19:44:13 -0500 Subject: [PATCH 17/25] That's just way more expedient --- src/link.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/link.c b/src/link.c index f52b2f5..c5e7495 100644 --- a/src/link.c +++ b/src/link.c @@ -15,15 +15,8 @@ int tabby_link_open(const char *dev) { goto error_open; } - attr.c_cflag = CS8 | CREAD | HUPCL; - attr.c_ispeed = TABBY_LINK_BAUD; - attr.c_ospeed = TABBY_LINK_BAUD; - attr.c_iflag = IGNPAR; - attr.c_oflag = 0; - attr.c_lflag = 0; - - attr.c_cc[VTIME] = 0; - attr.c_cc[VMIN] = 1; + cfmakeraw(&attr); + cfsetspeed(&attr, TABBY_LINK_BAUD); if (tcsetattr(fd, TCSAFLUSH, &attr) < 0) { goto error_io; From 6ba12e1f3839ecadeebaae36141749324a4ca3b7 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Fri, 10 Jun 2016 03:20:20 +0000 Subject: [PATCH 18/25] I'm a fookin' NINJA --- bin/Makefile | 4 +- bin/commands.h | 7 ++ bin/grab.c | 63 ++++++++++++++++++ bin/main.c | 52 ++++++--------- bin/print.c | 95 ++++++++++++++++++++++++++ include/tabby/printer.h | 60 +++++++++++------ src/link.c | 3 +- src/printer.c | 143 ++++++++++++++++++++++++++-------------- 8 files changed, 321 insertions(+), 106 deletions(-) create mode 100644 bin/commands.h create mode 100644 bin/grab.c create mode 100644 bin/print.c diff --git a/bin/Makefile b/bin/Makefile index a27d05a..f27db7b 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -8,9 +8,9 @@ CFLAGS += -I$(INCLUDE_PATH) LDFLAGS = TABBY = tabby -TABBY_OBJS = main.o +TABBY_OBJS = main.o grab.o print.o TABBY_STATIC = ../src/lib$(LIBNAME).a -TABBY_HEADERS = +TABBY_HEADERS = commands.h TABBY_LDFLAGS = LIBNAME = tabby diff --git a/bin/commands.h b/bin/commands.h new file mode 100644 index 0000000..aae6d7f --- /dev/null +++ b/bin/commands.h @@ -0,0 +1,7 @@ +#ifndef _COMMANDS_H +#define _COMMANDS_H + +int tabby_command_grab(int argc, char **argv); +int tabby_command_print(int argc, char **argv); + +#endif /* _COMMANDS_H */ diff --git a/bin/grab.c b/bin/grab.c new file mode 100644 index 0000000..46a96fa --- /dev/null +++ b/bin/grab.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static void usage(int argc, char **argv, char *message, ...) { + if (message) { + va_list args; + + va_start(args, message); + vfprintf(stderr, message, args); + fprintf(stderr, "\n"); + va_end(args); + } + + fprintf(stderr, "usage: %s grab device\n", argv[0]); + + exit(1); +} + +int tabby_command_grab(int argc, char **argv) { + tabby_printer *printer; + tabby_printer_packet header; + + uint8_t body[TABBY_PRINTER_PACKET_MAX_SIZE]; + + if (argc != 2) { + usage(argc, argv, "No device specified"); + } + + if ((printer = tabby_printer_open(argv[1])) == NULL) { + fprintf(stderr, "%s: %s: %s: %s\n", argv[0], "tabby_printer_open()", + argv[1], strerror(errno)); + + goto error_printer_open; + } + + while (1) { + if (tabby_printer_packet_recv(printer, &header, &body) < 0) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "tabby_printer_packet_recv()", strerror(errno)); + + continue; + } + + if (header.type == 0x04) { + write(1, &body, header.size); + } + } + + tabby_printer_close(printer); + + return 0; + +error_printer_open: + return 1; +} diff --git a/bin/main.c b/bin/main.c index 9d8bb48..f38c587 100644 --- a/bin/main.c +++ b/bin/main.c @@ -9,6 +9,8 @@ #include #include +#include "commands.h" + static void usage(int argc, char **argv, char *message, ...) { if (message) { va_list args; @@ -19,48 +21,36 @@ static void usage(int argc, char **argv, char *message, ...) { va_end(args); } - fprintf(stderr, "usage: %s device\n", argv[0]); + fprintf(stderr, "usage: %1$s print ...\n" + " %1$s grab ...\n", + argv[0]); exit(1); } +static struct { + char *name; + int (*fun)(int, char **); +} commands[] = { + { "print", tabby_command_print }, + { "grab", tabby_command_grab }, + { NULL, NULL } +}; + int main(int argc, char **argv) { - int fd, status; + int i; - tabby_printer_packet header; - - uint8_t body[TABBY_PRINTER_PACKET_MAX_SIZE]; - - if (argc != 2) { - usage(argc, argv, "No device specified"); + if (argc < 2) { + usage(argc, argv, "No command specified"); } - if ((fd = tabby_link_open(argv[1])) < 0) { - fprintf(stderr, "%s: %s: %s: %s\n", argv[0], "tabby_link_open()", - argv[1], strerror(errno)); - - goto error_link_open; - } - - while (1) { - status = tabby_printer_packet_recv(fd, &header, &body); - - if (status < 0) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], "tabby_printer_packet_recv()", strerror(errno)); - - continue; - } - - if (header.type == 0x04) { - write(1, &body, header.size); + for (i=0; commands[i].name; i++) { + if (strcmp(argv[1], commands[i].name) == 0) { + return commands[i].fun(argc, argv); } } - tabby_link_close(fd); + usage(argc, argv, "Unknown command '%s'", argv[1]); return 0; - -error_link_open: - return 1; } diff --git a/bin/print.c b/bin/print.c new file mode 100644 index 0000000..78af7ae --- /dev/null +++ b/bin/print.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static void usage(int argc, char **argv, char *message, ...) { + if (message) { + va_list args; + + va_start(args, message); + vfprintf(stderr, message, args); + fprintf(stderr, "\n"); + va_end(args); + } + + fprintf(stderr, "usage: %s print device sheet.tile\n", argv[0]); + + exit(1); +} + +int tabby_command_print(int argc, char **argv) { + int fd; + + ssize_t readlen; + size_t offset = 0; + + tabby_printer *printer; + + uint8_t band[TABBY_PRINTER_BAND_SIZE]; + + if (argc != 3) { + usage(argc, argv, "Must specify device and tile"); + } + + if ((fd = open(argv[2], O_RDONLY)) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "open()", argv[2], strerror(errno)); + + goto error_open_tile; + } + + if ((printer = tabby_printer_open(argv[1])) == NULL) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "tabby_printer_open()", argv[1], strerror(errno)); + + goto error_printer_open; + } + + do { + sleep(1); + + tabby_printer_init(printer); + } while (printer->device != TABBY_PRINTER_DEVICE_ID); + + while ((readlen = read(fd, band, sizeof(band))) >= 0) { + offset += readlen; + + tabby_printer_band_send(printer, band); + + if (offset % TABBY_PRINTER_SHEET_SIZE == 0) { + uint8_t feeds = 0x00; + + if (offset == TABBY_PRINTER_SHEET_SIZE) { + feeds |= 0x10; + } + + tabby_printer_band_finish(printer); + + tabby_printer_job_start(printer, 1, feeds, 0x00, 0x40); + + tabby_printer_job_wait(printer); + } + } + + tabby_printer_job_start(printer, 1, 0x03, 0x00, 0x40); + + tabby_printer_job_wait(printer); + + tabby_printer_close(printer); + + return 0; + +error_printer_open: + close(fd); + +error_open_tile: + return 1; +} diff --git a/include/tabby/printer.h b/include/tabby/printer.h index dfe319c..613b274 100644 --- a/include/tabby/printer.h +++ b/include/tabby/printer.h @@ -39,6 +39,24 @@ typedef enum { TABBY_PRINTER_COMPRESSION_RLE = 0x01 } tabby_printer_compression; +typedef struct _tabby_printer_response { + uint8_t device; + uint8_t status; +} tabby_printer_response; + +typedef struct _tabby_printer { + int fd; + + union { + tabby_printer_response response; + + struct { + uint8_t device, + status; + }; + }; +} tabby_printer; + /* * Data definitions for packets sent from Game Boy to printer */ @@ -75,42 +93,42 @@ typedef struct _tabby_printer_buffer { uint16_t sum; } tabby_printer_buffer; -typedef struct _tabby_printer_response { - uint8_t device; - uint8_t status; -} tabby_printer_response; +tabby_printer *tabby_printer_open(const char *device); + +void tabby_printer_close(tabby_printer *printer); /* * For receiving printer data packets from a Game Boy Camera */ -int tabby_printer_packet_recv(int fd, +int tabby_printer_packet_recv(tabby_printer *printer, tabby_printer_packet *header, void *body); /* * For sending printer data packets to a Game Boy Printer */ -int tabby_printer_packet_send(int fd, +int tabby_printer_packet_send(tabby_printer *printer, tabby_printer_packet *header, - void *body, - tabby_printer_response *response); + void *body); -int tabby_printer_init(int fd, - tabby_printer_response *response); +int tabby_printer_init(tabby_printer *printer); -int tabby_printer_send_inquiry(int fd, - tabby_printer_response *response); +int tabby_printer_inquiry_send(tabby_printer *printer); -int tabby_printer_job_start(int fd, uint8_t sheets, - uint8_t linefeeds, - uint8_t palette, - uint8_t density, - tabby_printer_response *response); +int tabby_printer_job_start(tabby_printer *printer, uint8_t sheets, + uint8_t linefeeds, + uint8_t palette, + uint8_t density); -int tabby_printer_job_cancel(int fd, - tabby_printer_response *response); +int tabby_printer_job_cancel(tabby_printer *printer); -int tabby_printer_send_sheet(int fd, void *data, - tabby_printer_response *response); +int tabby_printer_job_wait(tabby_printer *printer); + +int tabby_printer_band_send(tabby_printer *printer, uint8_t *band); + +int tabby_printer_band_finish(tabby_printer *printer); + +int tabby_printer_sheet_send(tabby_printer *printer, void *data, + uint16_t size); #endif /* _TABBY_PRINTER_H */ diff --git a/src/link.c b/src/link.c index c5e7495..359f097 100644 --- a/src/link.c +++ b/src/link.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -18,6 +17,8 @@ int tabby_link_open(const char *dev) { cfmakeraw(&attr); cfsetspeed(&attr, TABBY_LINK_BAUD); + sleep(1); + if (tcsetattr(fd, TCSAFLUSH, &attr) < 0) { goto error_io; } diff --git a/src/printer.c b/src/printer.c index 29f612f..ffce444 100644 --- a/src/printer.c +++ b/src/printer.c @@ -1,5 +1,6 @@ -#include +#include #include +#include #include #include #include @@ -9,6 +10,34 @@ #define PACKET_RECV_ERROR_THRESHOLD 30 +tabby_printer *tabby_printer_open(const char *device) { + tabby_printer *printer; + + if ((printer = malloc(sizeof(*printer))) == NULL) { + goto error_malloc_printer; + } + + if ((printer->fd = tabby_link_open(device)) < 0) { + goto error_link_open; + } + + printer->device = TABBY_PRINTER_DEVICE_ID; + printer->status = TABBY_PRINTER_OK; + + return printer; + +error_link_open: + free(printer); + +error_malloc_printer: + return NULL; +} + +void tabby_printer_close(tabby_printer *printer) { + tabby_link_close(printer->fd); + free(printer); +} + static uint16_t checksum(tabby_printer_packet *header, void *body) { uint16_t checksum = header->data[2] + header->data[3] @@ -24,7 +53,7 @@ static uint16_t checksum(tabby_printer_packet *header, void *body) { return checksum; } -int tabby_printer_packet_recv(int fd, +int tabby_printer_packet_recv(tabby_printer *printer, tabby_printer_packet *header, void *body) { ssize_t len; @@ -38,7 +67,7 @@ int tabby_printer_packet_recv(int fd, memset(header, '\0', sizeof(*header)); - while ((len = read(fd, &value, 1)) >= 0) { + while ((len = read(printer->fd, &value, 1)) >= 0) { if (i == 0) { if (value == TABBY_PRINTER_SYNC_1) { header->preamble[0] = value; @@ -90,39 +119,26 @@ error_io: return -errno; } -static inline int resend(tabby_printer_response *response) { - if (response->device != TABBY_PRINTER_DEVICE_ID) { - return 1; - } - - if (response->status & (TABBY_PRINTER_ER0 | TABBY_PRINTER_SUM)) { - return 1; - } - - return 0; -} - -int tabby_printer_packet_send(int fd, +int tabby_printer_packet_send(tabby_printer *printer, tabby_printer_packet *header, - void *body, - tabby_printer_response *response) { + void *body) { uint16_t sum = checksum(header, body); - if (write(fd, header, sizeof(*header)) < 0) { + if (write(printer->fd, header, sizeof(*header)) < 0) { goto error_io; } if (header->size) { - if (write(fd, body, header->size) < 0) { + if (write(printer->fd, body, header->size) < 0) { goto error_io; } } - if (write(fd, &sum, sizeof(sum)) < 0) { + if (write(printer->fd, &sum, sizeof(sum)) < 0) { goto error_io; } - if (read(fd, response, sizeof(*response)) < 0) { + if (read(printer->fd, &printer->response, sizeof(printer->response)) < 0) { goto error_io; } @@ -141,29 +157,26 @@ static void init_header(tabby_printer_packet *header, header->size = (uint16_t)size; } -int tabby_printer_init(int fd, - tabby_printer_response *response) { +int tabby_printer_init(tabby_printer *printer) { tabby_printer_packet header; init_header(&header, TABBY_PRINTER_PACKET_INIT, 0); - return tabby_printer_packet_send(fd, &header, NULL, response); + return tabby_printer_packet_send(printer, &header, NULL); } -int tabby_printer_send_inquiry(int fd, - tabby_printer_response *response) { +int tabby_printer_inquiry_send(tabby_printer *printer) { tabby_printer_packet header; init_header(&header, TABBY_PRINTER_PACKET_INQUIRY, 0); - return tabby_printer_packet_send(fd, &header, NULL, response); + return tabby_printer_packet_send(printer, &header, NULL); } -int tabby_printer_job_start(int fd, uint8_t sheets, - uint8_t linefeeds, - uint8_t palette, - uint8_t density, - tabby_printer_response *response) { +int tabby_printer_job_start(tabby_printer *printer, uint8_t sheets, + uint8_t linefeeds, + uint8_t palette, + uint8_t density) { tabby_printer_packet header; uint8_t body[4] = { @@ -172,41 +185,69 @@ int tabby_printer_job_start(int fd, uint8_t sheets, init_header(&header, TABBY_PRINTER_PACKET_JOB, sizeof(body)); - return tabby_printer_packet_send(fd, &header, &body, response); + return tabby_printer_packet_send(printer, &header, &body); } -int tabby_printer_job_cancel(int fd, - tabby_printer_response *response) { +int tabby_printer_job_cancel(tabby_printer *printer) { tabby_printer_packet header; init_header(&header, TABBY_PRINTER_PACKET_CANCEL, 0); - return tabby_printer_packet_send(fd, &header, NULL, response); + return tabby_printer_packet_send(printer, &header, NULL); } -int tabby_printer_send_sheet(int fd, void *data, - tabby_printer_response *response) { - int i; - size_t offset = 0; +int tabby_printer_job_wait(tabby_printer *printer) { + do { + sleep(1); + + if (tabby_printer_inquiry_send(printer) < 0) { + goto error_inquiry_send; + } + } while (printer->status & TABBY_PRINTER_UNTRAN); + + return 0; + +error_inquiry_send: + return -1; +} + +int tabby_printer_band_send(tabby_printer *printer, uint8_t *band) { + tabby_printer_packet header; + + init_header(&header, TABBY_PRINTER_PACKET_DATA, TABBY_PRINTER_BAND_SIZE); + + return tabby_printer_packet_send(printer, &header, band); +} + +int tabby_printer_band_finish(tabby_printer *printer) { + tabby_printer_packet header; + + init_header(&header, TABBY_PRINTER_PACKET_DATA, 0); + + return tabby_printer_packet_send(printer, &header, NULL); +} + +int tabby_printer_sheet_send(tabby_printer *printer, void *data, + uint16_t size) { + uint16_t offset = 0; tabby_printer_packet header; - for (i=0; istatus & TABBY_PRINTER_SUM) { + tabby_printer_init(printer); + + offset = 0; continue; } @@ -216,7 +257,7 @@ int tabby_printer_send_sheet(int fd, void *data, init_header(&header, TABBY_PRINTER_PACKET_DATA, 0); - return tabby_printer_packet_send(fd, &header, NULL, response); + return tabby_printer_packet_send(printer, &header, NULL); error_packet_send: return -1; From 7445683997dde6e39a78cde8303102b5ed4fafd7 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Fri, 10 Jun 2016 03:25:22 +0000 Subject: [PATCH 19/25] I fookin' forgot! Fookin' prawns --- bin/grab.c | 4 ++-- bin/print.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bin/grab.c b/bin/grab.c index 46a96fa..fd6149f 100644 --- a/bin/grab.c +++ b/bin/grab.c @@ -30,13 +30,13 @@ int tabby_command_grab(int argc, char **argv) { uint8_t body[TABBY_PRINTER_PACKET_MAX_SIZE]; - if (argc != 2) { + if (argc != 3) { usage(argc, argv, "No device specified"); } if ((printer = tabby_printer_open(argv[1])) == NULL) { fprintf(stderr, "%s: %s: %s: %s\n", argv[0], "tabby_printer_open()", - argv[1], strerror(errno)); + argv[2], strerror(errno)); goto error_printer_open; } diff --git a/bin/print.c b/bin/print.c index 78af7ae..8cc6207 100644 --- a/bin/print.c +++ b/bin/print.c @@ -35,20 +35,20 @@ int tabby_command_print(int argc, char **argv) { uint8_t band[TABBY_PRINTER_BAND_SIZE]; - if (argc != 3) { + if (argc != 4) { usage(argc, argv, "Must specify device and tile"); } - if ((fd = open(argv[2], O_RDONLY)) < 0) { + if ((fd = open(argv[3], O_RDONLY)) < 0) { fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "open()", argv[2], strerror(errno)); + argv[0], "open()", argv[3], strerror(errno)); goto error_open_tile; } - if ((printer = tabby_printer_open(argv[1])) == NULL) { + if ((printer = tabby_printer_open(argv[2])) == NULL) { fprintf(stderr, "%s: %s: %s: %s\n", - argv[0], "tabby_printer_open()", argv[1], strerror(errno)); + argv[0], "tabby_printer_open()", argv[2], strerror(errno)); goto error_printer_open; } From ac3377bed199d538fb01a74572a795cb163b06c0 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Fri, 10 Jun 2016 03:30:58 +0000 Subject: [PATCH 20/25] Eventually I'll make feeds something you specify at the stop and start of a command invocation or whatever. Man I'm drunk --- bin/print.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/bin/print.c b/bin/print.c index 8cc6207..f575929 100644 --- a/bin/print.c +++ b/bin/print.c @@ -65,23 +65,21 @@ int tabby_command_print(int argc, char **argv) { tabby_printer_band_send(printer, band); if (offset % TABBY_PRINTER_SHEET_SIZE == 0) { - uint8_t feeds = 0x00; - - if (offset == TABBY_PRINTER_SHEET_SIZE) { - feeds |= 0x10; - } - tabby_printer_band_finish(printer); - tabby_printer_job_start(printer, 1, feeds, 0x00, 0x40); + tabby_printer_job_start(printer, 1, 0x00, 0x00, 0x40); tabby_printer_job_wait(printer); } } - tabby_printer_job_start(printer, 1, 0x03, 0x00, 0x40); + if (offset % TABBY_PRINTER_SHEET_SIZE) { + tabby_printer_band_finish(printer); - tabby_printer_job_wait(printer); + tabby_printer_job_start(printer, 1, 0x00, 0x00, 0x40); + + tabby_printer_job_wait(printer); + } tabby_printer_close(printer); From a766ac528cab8a39fe3b00942d0424511ccafa1c Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Thu, 9 Jun 2016 23:04:42 -0500 Subject: [PATCH 21/25] Whoops --- bin/print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/print.c b/bin/print.c index f575929..8ffe261 100644 --- a/bin/print.c +++ b/bin/print.c @@ -59,7 +59,7 @@ int tabby_command_print(int argc, char **argv) { tabby_printer_init(printer); } while (printer->device != TABBY_PRINTER_DEVICE_ID); - while ((readlen = read(fd, band, sizeof(band))) >= 0) { + while ((readlen = read(fd, band, sizeof(band))) > 0) { offset += readlen; tabby_printer_band_send(printer, band); From 750985745ddea17ff253254ec3dd3a7da33d7a85 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Thu, 9 Jun 2016 23:23:45 -0500 Subject: [PATCH 22/25] Well this seems to kinda work --- src/printer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printer.c b/src/printer.c index ffce444..21ceec3 100644 --- a/src/printer.c +++ b/src/printer.c @@ -203,7 +203,7 @@ int tabby_printer_job_wait(tabby_printer *printer) { if (tabby_printer_inquiry_send(printer) < 0) { goto error_inquiry_send; } - } while (printer->status & TABBY_PRINTER_UNTRAN); + } while (printer->status); return 0; From a804012291779a415acf9ebc2d4bec1bb777c7eb Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Thu, 9 Jun 2016 23:33:31 -0500 Subject: [PATCH 23/25] This aids in reliability! --- bin/print.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/print.c b/bin/print.c index 8ffe261..f3769ae 100644 --- a/bin/print.c +++ b/bin/print.c @@ -67,6 +67,8 @@ int tabby_command_print(int argc, char **argv) { if (offset % TABBY_PRINTER_SHEET_SIZE == 0) { tabby_printer_band_finish(printer); + tabby_printer_job_wait(printer); + tabby_printer_job_start(printer, 1, 0x00, 0x00, 0x40); tabby_printer_job_wait(printer); @@ -76,6 +78,8 @@ int tabby_command_print(int argc, char **argv) { if (offset % TABBY_PRINTER_SHEET_SIZE) { tabby_printer_band_finish(printer); + tabby_printer_job_wait(printer); + tabby_printer_job_start(printer, 1, 0x00, 0x00, 0x40); tabby_printer_job_wait(printer); From 81ca7b7ac986e7d7665c898dee14ae90c0b0a073 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Thu, 9 Jun 2016 23:34:19 -0500 Subject: [PATCH 24/25] This is more aptly named --- bin/print.c | 8 ++++---- include/tabby/printer.h | 2 +- src/printer.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/print.c b/bin/print.c index f3769ae..529c709 100644 --- a/bin/print.c +++ b/bin/print.c @@ -67,22 +67,22 @@ int tabby_command_print(int argc, char **argv) { if (offset % TABBY_PRINTER_SHEET_SIZE == 0) { tabby_printer_band_finish(printer); - tabby_printer_job_wait(printer); + tabby_printer_wait(printer); tabby_printer_job_start(printer, 1, 0x00, 0x00, 0x40); - tabby_printer_job_wait(printer); + tabby_printer_wait(printer); } } if (offset % TABBY_PRINTER_SHEET_SIZE) { tabby_printer_band_finish(printer); - tabby_printer_job_wait(printer); + tabby_printer_wait(printer); tabby_printer_job_start(printer, 1, 0x00, 0x00, 0x40); - tabby_printer_job_wait(printer); + tabby_printer_wait(printer); } tabby_printer_close(printer); diff --git a/include/tabby/printer.h b/include/tabby/printer.h index 613b274..4a75f56 100644 --- a/include/tabby/printer.h +++ b/include/tabby/printer.h @@ -122,7 +122,7 @@ int tabby_printer_job_start(tabby_printer *printer, uint8_t sheets, int tabby_printer_job_cancel(tabby_printer *printer); -int tabby_printer_job_wait(tabby_printer *printer); +int tabby_printer_wait(tabby_printer *printer); int tabby_printer_band_send(tabby_printer *printer, uint8_t *band); diff --git a/src/printer.c b/src/printer.c index 21ceec3..47a87f3 100644 --- a/src/printer.c +++ b/src/printer.c @@ -196,7 +196,7 @@ int tabby_printer_job_cancel(tabby_printer *printer) { return tabby_printer_packet_send(printer, &header, NULL); } -int tabby_printer_job_wait(tabby_printer *printer) { +int tabby_printer_wait(tabby_printer *printer) { do { sleep(1); From dcaf33ce01fc7ef5b297909827fddc28e326543c Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Fri, 10 Jun 2016 22:12:22 +0000 Subject: [PATCH 25/25] I *really* care about reliability and error detection! --- include/tabby/printer.h | 3 +++ src/printer.c | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/tabby/printer.h b/include/tabby/printer.h index 4a75f56..6400b75 100644 --- a/include/tabby/printer.h +++ b/include/tabby/printer.h @@ -26,6 +26,9 @@ typedef enum { TABBY_PRINTER_OK = 0 } tabby_printer_status; +#define TABBY_PRINTER_WAIT 0x0e +#define TABBY_PRINTER_ERROR 0xf0 + typedef enum { TABBY_PRINTER_PACKET_INIT = 0x01, TABBY_PRINTER_PACKET_JOB = 0x02, diff --git a/src/printer.c b/src/printer.c index 47a87f3..3c85a59 100644 --- a/src/printer.c +++ b/src/printer.c @@ -197,16 +197,25 @@ int tabby_printer_job_cancel(tabby_printer *printer) { } int tabby_printer_wait(tabby_printer *printer) { - do { + while (1) { sleep(1); if (tabby_printer_inquiry_send(printer) < 0) { goto error_inquiry_send; } - } while (printer->status); + + if (printer->status & (TABBY_PRINTER_WAIT | TABBY_PRINTER_SUM)) { + continue; + } else if (printer->status & TABBY_PRINTER_ERROR) { + goto error_printer; + } else { + break; + } + } return 0; +error_printer: error_inquiry_send: return -1; }