tabby/avr/send.c
2016-06-06 02:04:18 -05:00

273 lines
6 KiB
C

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <tabby/printer.h>
#include <tabby/avr/uart.h>
#include <tabby/avr.h>
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; 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_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<sizeof(header); i++) {
(void)spi_send_byte(header.data[i]);
}
for (i=0; i<size; i++) {
(void)spi_send_byte(body[i]);
}
(void)spi_send_byte( sum & 0x00ff);
(void)spi_send_byte((sum & 0xff00) >> 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<size; i+=TABBY_PRINTER_BAND_SIZE) {
spi_send_data(sheet + i, TABBY_PRINTER_BAND_SIZE, response);
}
spi_send_data(NULL, 0, response);
}
int main() {
uint16_t i = 0,
b = 0,
sheet_offset = 0;
uint8_t c;
tabby_printer_packet header = {
.size = 0
};
tabby_printer_response response = {
.device = TABBY_PRINTER_DEVICE_ID,
.status = TABBY_PRINTER_OK
};
tabby_printer_job job;
uint8_t sheet[TABBY_PRINTER_SHEET_SIZE];
uart_init();
spi_init();
sei();
while (1) {
uart_putchar('O', NULL);
c = uart_getchar(NULL);
if (c == 'K') {
break;
}
}
while (1) {
c = uart_getchar(NULL);
switch (i) {
case 0: {
if (c == TABBY_PRINTER_SYNC_1) {
header.data[0] = c;
i++;
b = 0;
}
break;
}
case 1: {
if (c == TABBY_PRINTER_SYNC_2) {
header.data[1] = c;
i++;
} else {
i = 0;
}
break;
}
case 2: {
switch (c) {
case TABBY_PRINTER_PACKET_INIT:
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;
i++;
break;
}
default: {
i = 0;
break;
}
}
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) {
if (header.type == TABBY_PRINTER_PACKET_JOB) {
job.data[b] = c;
} else if (header.type == TABBY_PRINTER_PACKET_DATA) {
sheet[sheet_offset++] = c;
}
b++;
} else if (b == header.size) {
b++;
} else if (b == header.size + 1) {
i = 0;
b = 0;
if (header.type == TABBY_PRINTER_PACKET_JOB) {
spi_send_sheet(sheet, sheet_offset, &response);
spi_send_job(&job, &response);
sheet_offset = 0;
} else if (header.type == TABBY_PRINTER_PACKET_INQUIRY) {
spi_send_inquiry(&response);
}
uart_putchar(response.device, NULL);
uart_putchar(response.status, NULL);
}
}
}
}
return 0;
}