#include #include #include #include #include #include static tabby_printer_packet header = { .type = 0, .compression = 0, .size = 0 }; static tabby_printer_response response; static uint8_t body[TABBY_PRINTER_MAX_PACKET_SIZE]; static uint16_t sum = 0x0000; /* * So like, we're abusing pins here. So badly, it's beyond. So here's what's * going down: We want to retain the same physical I/O connections between * both the sending and receiving flavors of the whole Game Boy Printer * endeavor, and that mean/s that we must absolutely bit bang MOSI and MISO * opposite from their ordinary roles. The reason being: There is no notion * of MISO or MOSI from the Game Boy's (nor its peripherals') point of view. * The SI and SO pins over a link cable are crossed over, so SI on one end * always connects to SO on the other, and vice-versa. */ static void spi_init() { /* * Set SC to output */ DDRB |= (1 << DDB5); /* * Configure SO as output */ DDRB |= (1 << DDB4); /* * Configure SI as input with pullup */ DDRB &= ~(1 << DDB3); PORTB |= (1 << DDB3); /* * Set SO clear */ PORTB &= ~(1 << PORTB4); /* * Set SC high */ PORTB |= (1 << PORTB5); } static uint8_t spi_send_byte(uint8_t value) { uint8_t i, ret = 0; for (i=0; i<8; i++) { PORTB &= ~(1 << PORTB5); if (value & 0x80) { PORTB |= (1 << PORTB4); } else { PORTB &= ~(1 << PORTB4); } value <<= 1; ret <<= 1; _delay_us(60); if (PINB & (1 << PINB3)) { ret |= 1; } PORTB |= (1 << PORTB5); _delay_us(60); } _delay_us(150); return ret; } static void spi_send_packet() { int i; for (i=0; i> 8); response.device = spi_send_byte(0); response.status = spi_send_byte(0); _delay_us(270); } static uint16_t checksum() { uint16_t sum = 0; size_t i; for (i=2; i<6; i++) { sum += header.data[i]; } for (i=0; i