#define DEBUG 0 #include "k_talker.h" #include #include #include #include #if DEBUG #include #endif static uchar talker_bcount __attribute__((section (".data"))); static uchar talker_status __attribute__((section (".data"))); #define WAIT_FOR_S 0 #define WAIT_FOR_SNUM 1 #define WAIT_FOR_LEN 2 #define WAIT_FOR_ADDRESS 3 #define WAIT_FOR_CSUM 4 #define WAIT_FOR_END 5 #define WAIT_FOR_R 0 #define WAIT_FOR_RNUM 16 static struct { uchar snum; uchar len; uint address; uchar data[18]; uchar csum; uchar dataindex; } talker_data __attribute__((section (".data"))); void k_talker_init() { talker_bcount = talker_status = 0; k_putc('t'); } void k_talker_receive() { if (ringbuffer_canread(k_serial_readbuf) == 0) return; if (talker_status == 0) { uchar c = ringbuffer_read(k_serial_readbuf); if ((c == 'S') || (c == 'R')) { #if DEBUG k_debug_counter = 0; #endif talker_status = WAIT_FOR_SNUM; if (c == 'R') talker_status |= WAIT_FOR_RNUM; //k_cls(); //k_print("Talker: "); //k_print((c == 'S')?"receive":"send"); k_lcd_goto(40); k_putc('S'); return; } } if (talker_status != 0) { if (is_hex_c(ringbuffer_peek(k_serial_readbuf,0))) { uchar peekval = ringbuffer_read(k_serial_readbuf); //k_putc(peekval); switch (talker_status & 15) { case WAIT_FOR_SNUM: if ((peekval == '0') || (peekval == '1') || (peekval == '9')) { talker_data.snum = peekval; // talker_status = WAIT_FOR_LEN; talker_status++; talker_bcount = 0; talker_data.len = 0; k_putc('n'); return; } break; case WAIT_FOR_LEN: talker_data.len = (talker_data.len << 4) | hex2dec_c(peekval); talker_bcount++; if (talker_bcount >= 2) { if ((talker_data.len >= 3) && (talker_data.len <= 19)) { //talker_status = WAIT_FOR_ADDRESS; talker_status++; talker_bcount = 0; talker_data.address = 0; k_putc('l'); return; } talker_status = 0; } return; case WAIT_FOR_ADDRESS: talker_data.address = (talker_data.address << 4) | hex2dec_c(peekval); talker_bcount++; if (talker_bcount >= 4) { talker_bcount = 0; k_putc('a'); if (talker_data.len <= 3) { talker_status += (WAIT_FOR_END - WAIT_FOR_ADDRESS); return; } //talker_status = WAIT_FOR_CSUM; if (talker_status & WAIT_FOR_RNUM) talker_status = WAIT_FOR_RNUM + WAIT_FOR_END; else talker_status = WAIT_FOR_CSUM; talker_data.dataindex = 0; talker_data.data[talker_data.dataindex] = 0; return; } return; case WAIT_FOR_CSUM: talker_data.data[talker_data.dataindex] = (talker_data.data[talker_data.dataindex] << 4) | hex2dec_c(peekval); talker_bcount++; if (talker_bcount >= 2) { talker_data.dataindex++; talker_data.data[talker_data.dataindex] = 0; talker_bcount = 0; } if (talker_data.dataindex >= (talker_data.len - 3)) { // no need to check for RNUM since we never get here when reading talker_status = WAIT_FOR_END; talker_data.csum = 0; talker_bcount = 0; k_putc('d'); return; } return; case WAIT_FOR_END: talker_data.csum = (talker_data.csum << 4) | hex2dec_c(peekval); talker_bcount++; if (talker_bcount >= 2) { uchar calcsum, i, j; calcsum = csum(&talker_data.len, (talker_status & WAIT_FOR_RNUM)?3:(talker_data.len)); k_putc('c'); if (talker_status & WAIT_FOR_RNUM) { uchar i,*mem; k_putc('S'); k_serial_tx_c(calcsum); k_serial_tx_c(13); for (mem = (uchar*) talker_data.address,i=0,calcsum=0;i= 127) k_debug_counter = 129; } #endif } asm (".pushsection .k_stacks.kthread"); asm (" JSR k_talker_receive"); asm (".popsection"); asm (".pushsection .k_stacks.init"); asm (" JSR k_talker_init"); asm (".popsection"); /* This seems to be annoyingly unmacroable */ // asm (".pushsection .k_stacks.serialRX"); // asm (" JSR k_talker_receive"); // asm (".popsection"); // asm (".pushsection .k_stacks.tovr"); // asm (" JSR k_talker_receive"); // asm (".popsection");