X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=tv_i2c_hack;a=blobdiff_plain;f=src%2Fmain.c;fp=src%2Fmain.c;h=2584292e49d52d5998f3e5aff06d5897c42c2882;hp=0000000000000000000000000000000000000000;hb=3b128b470c001555ba1c69ba8b0c96994182f8a1;hpb=efb5b9c4333f6034595b30d7d549fab2b120d9c9 diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..2584292 --- /dev/null +++ b/src/main.c @@ -0,0 +1,215 @@ +#include +#include +#include +#include +#include +#include +#include "serial.h" +#include "i2c.h" + +/* TODO + * IR decoding, connected to PCINT0 + * enable/disable with switch on PCINT1 + * some of the buttons multiplexed on ADC0 + */ + +#define EVQ_SIZE 64 +uint16_t evq[EVQ_SIZE]; +volatile int evq_wr, evq_rd; + +#define LOGNUM(x) EVLOG(EV_DEBUG, (x)) + +#define EVLOG(ev, data) \ + do { \ + if(ev != EV_DEBUG || dbgmode) { \ + evq[evq_wr] = ((uint16_t)(ev) << 8) | (data); \ + evq_wr = (evq_wr + 1) & (EVQ_SIZE - 1); \ + if(evq_wr == evq_rd) { \ + evq_rd = (evq_rd + 1) & (EVQ_SIZE - 1); \ + } \ + } \ + } while(0) + +/* serial input buffer */ +static char input[64]; +static unsigned char inp_cidx; + +static unsigned char data[16]; + +static uint16_t dump_addr; +static int dump_count; +static int dbgmode; + +static void proc_cmd(char *input); +static void printstat(void); +static void printdump(void); + + +int main(void) +{ + uint16_t val; + + /* tri-state everything and disable pullups */ + DDRB = 1; /* B0: activity LED */ + DDRC = 0; /* I2C pins as inputs */ + DDRD = 0; + PORTB = 0; + PORTC = 0; + PORTD = 0; + + i2c_init(); + + init_serial(38400); + sei(); + + printf("TV i2c hack\n"); + + for(;;) { + i2c_check_async(); + + if(have_input()) { + int c = getchar(); + putchar(c); + + if(c == '\r' || c == '\n') { + putchar('\n'); + input[inp_cidx] = 0; + proc_cmd(input); + inp_cidx = 0; + } else if(inp_cidx < sizeof input - 1) { + input[inp_cidx++] = c; + } + } + + /* read from queue and send over the serial port */ + val = 0xffff; + cli(); + if(evq_wr != evq_rd) { + val = evq[evq_rd]; + evq_rd = (evq_rd + 1) & (EVQ_SIZE - 1); + } + sei(); + + if(val != 0xffff) { + unsigned char ev = val >> 8; + printf("%02x: %02x\n", ev, val & 0xff); + } + } + return 0; +} + +static void proc_cmd(char *input) +{ + char *endp; + + if(strcmp(input, "dbg") == 0) { + printf("OK dbg\n"); + dbgmode = 1; + + } else if(strcmp(input, "nodbg") == 0) { + printf("OK nodbg\n"); + dbgmode = 0; + + } else if(strcmp(input, "av") == 0) { + printf("OK AV\n"); + + /* AV switch (22): 0 0 SVO CMB1 CMB0 INA INB 0 */ + data[0] = 0x22; + i2c_write(0x8a, 0x22, data, 1); + i2c_async(i2c_hold); + + } else if(strcmp(input, "rgb") == 0) { + printf("OK RGB\n"); + + /* Control 0 (2a): 0 IE2 RBL AKB CL3 CL2 CL1 CL0 + * Control 1 (2b): 0 0 0 0 0 0 YUV HBL + */ + data[0] = 0x70; + data[1] = 0; + i2c_write(0x8a, 0x2a, data, 1); + i2c_wait(); + i2c_write(0x8a, 0x2b, data + 1, 1); + + } else if(memcmp(input, "vol ", 4) == 0) { + int vol = atoi(input + 4); + if(vol < 1 || vol > 63) { + printf("ERR vol (%s)\n", input + 4); + } else { + data[0] = vol; + i2c_write(0x8a, 0x1f, data, 1); + printf("OK volume: %d\n", vol); + } + + } else if(memcmp(input, "sat", 3) == 0) { + printf("OK sat\n"); + data[0] = atoi(input + 3); + if(data[0] <= 0 || data[0] > 0x3f) { + data[0] = 0x1f; + } + i2c_write(0x8a, 0x1c, data, 1); + i2c_async(i2c_hold); /* hold I2C when done */ + + } else if(strcmp(input, "rel") == 0) { + printf("OK release\n"); + i2c_release(); + + } else if(strcmp(input, "status") == 0) { + i2c_read(0x8a, 0, data, 3); + i2c_async(printstat); + + } else if(memcmp(input, "rd ", 3) == 0) { + dump_addr = strtol(input + 3, &endp, 16); + + if(endp > input + 3 && dump_addr >= 0 && dump_addr < 2048) { + dump_count = 1; + i2c_read(0xa0 | ((dump_addr >> 7) & 0xe), dump_addr & 0xff, data, 1); + i2c_async(printdump); + } else { + printf("ERR address: %s\n", input + 3); + } + + } else if(memcmp(input, "dump ", 5) == 0) { + dump_addr = strtol(input + 5, &endp, 16); + + if(endp > input + 5 && dump_addr >= 0 && dump_addr < 2048) { + dump_count = 1; + dump_addr &= 0xff0; + i2c_read(0xa0 | ((dump_addr >> 7) & 0xe), dump_addr & 0xff, data, 16); + i2c_async(printdump); + } else { + printf("ERR address: %s\n", input + 5); + } + + } else if(strcmp(input, "abort") == 0) { + i2c_abort(); + printf("OK\n"); + + } else { + printf("ERR command (%s)\n", input); + } +} + +static void printstat(void) +{ + printf("OK status: %02x %02x %02x\n", (unsigned int)data[0], + (unsigned int)data[1], (unsigned int)data[2]); +} + +static void printdump(void) +{ + int i; + while(dump_count > 0) { + printf("OK %03x:", dump_addr); + for(i=0; i<16; i++) { + if(i == 8) putchar(' '); + + if(--dump_count >= 0) { + printf(" %02x", data[i]); + } else { + printf(" "); + } + dump_addr += 16; + } + putchar('\n'); + } +}