2016-06-01 22:30:12 -05:00
|
|
|
#include <avr/io.h>
|
|
|
|
#include <avr/interrupt.h>
|
2016-06-01 23:40:40 -05:00
|
|
|
#include <avr/sleep.h>
|
2016-06-01 22:30:12 -05:00
|
|
|
#include <util/delay.h>
|
|
|
|
|
|
|
|
#include <tabby/printer.h>
|
|
|
|
#include <tabby/avr/uart.h>
|
2016-06-05 12:37:05 -05:00
|
|
|
#include <tabby/avr.h>
|
2016-06-01 22:30:12 -05:00
|
|
|
|
2016-06-03 23:01:49 -05:00
|
|
|
static void spi_init() {
|
2016-06-05 12:37:05 -05:00
|
|
|
SC_OUTPUT();
|
|
|
|
SO_OUTPUT();
|
|
|
|
|
|
|
|
SI_INPUT();
|
|
|
|
SI_PULLUP();
|
|
|
|
|
|
|
|
SC_HIGH();
|
|
|
|
SO_LOW();
|
2016-06-03 23:01:49 -05:00
|
|
|
}
|
2016-06-03 16:54:39 -05:00
|
|
|
|
2016-06-03 23:01:49 -05:00
|
|
|
static uint8_t spi_send_byte(uint8_t value) {
|
2016-06-04 19:11:06 -05:00
|
|
|
uint8_t i, ret = 0;
|
2016-06-02 00:01:50 -05:00
|
|
|
|
2016-06-03 23:01:49 -05:00
|
|
|
for (i=0; i<8; i++) {
|
2016-06-05 12:37:05 -05:00
|
|
|
SC_LOW();
|
2016-06-04 01:45:57 -05:00
|
|
|
|
2016-06-03 23:01:49 -05:00
|
|
|
if (value & 0x80) {
|
2016-06-05 12:37:05 -05:00
|
|
|
SO_HIGH();
|
2016-06-03 23:01:49 -05:00
|
|
|
} else {
|
2016-06-05 12:37:05 -05:00
|
|
|
SO_LOW();
|
2016-06-03 23:01:49 -05:00
|
|
|
}
|
2016-06-02 00:01:50 -05:00
|
|
|
|
2016-06-05 12:37:05 -05:00
|
|
|
_delay_us(SPI_PULSE_USEC);
|
2016-06-04 19:11:06 -05:00
|
|
|
|
2016-06-04 23:58:07 -05:00
|
|
|
value <<= 1;
|
2016-06-05 23:52:28 -05:00
|
|
|
ret <<= 1;
|
2016-06-01 23:40:40 -05:00
|
|
|
|
2016-06-05 12:37:05 -05:00
|
|
|
if (SI_IS_HIGH()) {
|
2016-06-03 23:01:49 -05:00
|
|
|
ret |= 1;
|
|
|
|
}
|
2016-06-01 22:30:12 -05:00
|
|
|
|
2016-06-05 12:37:05 -05:00
|
|
|
SC_HIGH();
|
2016-06-04 22:12:14 -05:00
|
|
|
|
2016-06-05 12:37:05 -05:00
|
|
|
_delay_us(SPI_PULSE_USEC);
|
2016-06-01 22:30:12 -05:00
|
|
|
}
|
|
|
|
|
2016-06-03 23:01:49 -05:00
|
|
|
return ret;
|
|
|
|
}
|
2016-06-01 23:40:40 -05:00
|
|
|
|
2016-06-05 22:51:28 -05:00
|
|
|
static uint16_t checksum(tabby_printer_packet *header, uint8_t *body) {
|
|
|
|
uint16_t sum = 0;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=2; i<sizeof(*header); i++) {
|
|
|
|
sum += header->data[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=0; i<header->size; 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);
|
|
|
|
|
2016-06-03 23:01:49 -05:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=0; i<sizeof(header); i++) {
|
|
|
|
(void)spi_send_byte(header.data[i]);
|
2016-06-01 22:30:12 -05:00
|
|
|
}
|
|
|
|
|
2016-06-05 22:51:28 -05:00
|
|
|
for (i=0; i<size; i++) {
|
2016-06-03 23:01:49 -05:00
|
|
|
(void)spi_send_byte(body[i]);
|
|
|
|
}
|
2016-06-01 22:30:12 -05:00
|
|
|
|
2016-06-03 23:01:49 -05:00
|
|
|
(void)spi_send_byte( sum & 0x00ff);
|
|
|
|
(void)spi_send_byte((sum & 0xff00) >> 8);
|
|
|
|
|
2016-06-05 22:51:28 -05:00
|
|
|
(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<size; i+=TABBY_PRINTER_BAND_SIZE) {
|
|
|
|
spi_send_data(sheet + i, TABBY_PRINTER_BAND_SIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
spi_send_data(NULL, 0);
|
|
|
|
|
|
|
|
spi_send_job(1, 0x13, 0x00, 0x40);
|
2016-06-01 23:40:40 -05:00
|
|
|
}
|
|
|
|
|
2016-06-01 22:30:12 -05:00
|
|
|
int main() {
|
2016-06-05 22:51:28 -05:00
|
|
|
uint16_t i = 0,
|
|
|
|
b = 0,
|
|
|
|
sheet_offset = 0;
|
2016-06-05 12:37:05 -05:00
|
|
|
|
|
|
|
uint8_t c;
|
2016-06-01 23:40:40 -05:00
|
|
|
|
2016-06-05 22:51:28 -05:00
|
|
|
tabby_printer_packet header = {
|
|
|
|
.size = 0
|
|
|
|
};
|
|
|
|
|
|
|
|
uint8_t sheet[TABBY_PRINTER_SHEET_SIZE];
|
|
|
|
|
2016-06-01 22:30:12 -05:00
|
|
|
uart_init();
|
2016-06-03 23:01:49 -05:00
|
|
|
spi_init();
|
2016-06-01 22:30:12 -05:00
|
|
|
|
|
|
|
sei();
|
|
|
|
|
2016-06-04 19:11:06 -05:00
|
|
|
while (1) {
|
|
|
|
uart_putchar('O', NULL);
|
|
|
|
|
|
|
|
c = uart_getchar(NULL);
|
|
|
|
|
|
|
|
if (c == 'K') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-01 22:30:12 -05:00
|
|
|
while (1) {
|
2016-06-01 23:40:40 -05:00
|
|
|
c = uart_getchar(NULL);
|
|
|
|
|
|
|
|
switch (i) {
|
|
|
|
case 0: {
|
2016-06-05 12:37:05 -05:00
|
|
|
if (c == TABBY_PRINTER_SYNC_1) {
|
2016-06-01 23:40:40 -05:00
|
|
|
header.data[0] = c;
|
|
|
|
i++;
|
|
|
|
|
|
|
|
b = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 1: {
|
2016-06-05 12:37:05 -05:00
|
|
|
if (c == TABBY_PRINTER_SYNC_2) {
|
2016-06-01 23:40:40 -05:00
|
|
|
header.data[1] = c;
|
|
|
|
i++;
|
|
|
|
} else {
|
|
|
|
i = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 2: {
|
2016-06-02 22:54:59 -05:00
|
|
|
switch (c) {
|
2016-06-05 12:37:05 -05:00
|
|
|
case TABBY_PRINTER_PACKET_INIT:
|
|
|
|
case TABBY_PRINTER_PACKET_JOB:
|
2016-06-05 22:51:28 -05:00
|
|
|
case TABBY_PRINTER_PACKET_CANCEL: {
|
|
|
|
sheet_offset = 0;
|
|
|
|
}
|
|
|
|
|
2016-06-05 12:37:05 -05:00
|
|
|
case TABBY_PRINTER_PACKET_DATA:
|
|
|
|
case TABBY_PRINTER_PACKET_INQUIRY: {
|
2016-06-02 22:54:59 -05:00
|
|
|
header.type = c;
|
|
|
|
i++;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default: {
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-06-01 23:40:40 -05:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 3: {
|
|
|
|
header.compression = c;
|
|
|
|
i++;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 4: {
|
|
|
|
header.size = c;
|
|
|
|
i++;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 5: {
|
|
|
|
header.size |= c << 8;
|
|
|
|
i++;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default: {
|
|
|
|
if (b < header.size) {
|
2016-06-05 22:51:28 -05:00
|
|
|
sheet[sheet_offset++] = c;
|
|
|
|
b++;
|
2016-06-01 23:40:40 -05:00
|
|
|
} else if (b == header.size) {
|
2016-06-02 22:55:13 -05:00
|
|
|
b++;
|
2016-06-01 23:40:40 -05:00
|
|
|
} else if (b == header.size + 1) {
|
2016-06-02 23:32:38 -05:00
|
|
|
i = 0;
|
|
|
|
b = 0;
|
|
|
|
|
2016-06-05 22:51:28 -05:00
|
|
|
switch (header.type) {
|
|
|
|
case TABBY_PRINTER_PACKET_DATA: {
|
|
|
|
if (header.size == 0) {
|
|
|
|
spi_send_sheet(sheet, sheet_offset);
|
|
|
|
|
|
|
|
sheet_offset = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-06-02 00:01:50 -05:00
|
|
|
|
2016-06-05 22:51:28 -05:00
|
|
|
uart_putchar(TABBY_PRINTER_DEVICE_ID, NULL);
|
|
|
|
uart_putchar(0x00, NULL);
|
2016-06-01 23:40:40 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-06-01 22:30:12 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|