void fs20_process(void) { /* check if something has been received */ if (fs20_global.fs20.rec == 58) { #ifdef DEBUG_FS20_REC debug_printf("received new fs20 datagram:%02x%02x %02x %02x\n", fs20_global.fs20.datagram.hc1, fs20_global.fs20.datagram.hc2, fs20_global.fs20.datagram.addr, fs20_global.fs20.datagram.cmd); #ifdef DEBUG_FS20_REC_QUEUE debug_printf("queue fill is %u:\n", fs20_global.fs20.len); for (uint8_t l = 0; l < fs20_global.fs20.len; l++) { struct fs20_datagram_t *dg = &fs20_global.fs20.queue[l]; debug_printf("%u: %02x%02x addr %02x cmd %02x\n", l, dg->hc1, dg->hc2, dg->addr, dg->cmd); } #endif #endif if (fs20_global.fs20.datagram.sync == 0x0001) { #ifdef DEBUG_FS20_REC_VERBOSE debug_printf("valid sync\n"); #endif /* create shortcut to fs20_global.datagram */ volatile struct fs20_datagram_t *dg = &fs20_global.fs20.datagram; /* check parity */ uint8_t p1, p2, p3, p4, p5; uint8_t parity = 6; /* magic constant from fs20 protocol definition */ p1 = parity_even_bit(dg->hc1) ^ dg->p1; p2 = parity_even_bit(dg->hc2) ^ dg->p2; p3 = parity_even_bit(dg->addr) ^ dg->p3; p4 = parity_even_bit(dg->cmd) ^ dg->p4; p5 = parity_even_bit(dg->parity) ^ dg->p5; parity += dg->hc1 + dg->hc2 + dg->addr + dg->cmd; /* check parity */ if (!p1 && !p2 && !p3 && !p4 && !p5 && parity == dg->parity) { #ifdef DEBUG_FS20_REC debug_printf("valid datagram\n"); #endif /* shift queue backwards */ memmove(&fs20_global.fs20.queue[1], &fs20_global.fs20.queue[0], (FS20_QUEUE_LENGTH-1) * sizeof(struct fs20_datagram_t)); /* copy datagram to queue */ memcpy(&fs20_global.fs20.queue[0], (const void *)&fs20_global.fs20.datagram, sizeof(struct fs20_datagram_t)); if (fs20_global.fs20.len < FS20_QUEUE_LENGTH) fs20_global.fs20.len++; /* set timeout (for 120ms = 6 * 20ms), if received a complete packet */ fs20_global.fs20.timeout = 6; } else { #ifdef DEBUG_FS20_REC debug_printf("invalid datagram\n"); #endif } } else { #ifdef DEBUG_FS20_REC debug_printf("sync invalid!\n"); #endif } fs20_global.fs20.raw = 0; fs20_global.fs20.rec = 0; } #ifdef FS20_RECEIVE_WS300_SUPPORT if (fs20_global.ws300.rec == FS20_WS300_DATAGRAM_LENGTH) { #ifdef DEBUG_FS20_WS300 debug_printf("received ws300 datagram\n"); #endif #ifdef DEBUG_FS20_WS300_VERBOSE for (uint8_t i = 0; i < 10; i++) for (uint8_t j = 0; j < 8; j++) { if ( (i*8+j) % 5 == 4 ) printf(" "); printf("%u", (fs20_global.ws300.bytes[i] & _BV(j)) > 0); if ( (i*8+j) % 5 == 4 ) printf(" "); } printf("\n"); #endif ws300_parse_datagram(); /* clear global data structure */ memset((void *)&fs20_global.ws300.datagram, 0, sizeof(struct ws300_datagram_t)); fs20_global.ws300.sync = 0; fs20_global.ws300.rec = 0; } #endif }
void fs20_process(void) { /* check if something has been received */ if (((fs20_global.fs20.rec == FS20_DATAGRAM_LENGTH) && !(fs20_global.fs20.datagram.data.dg.cmd & (1 << 5))) || (fs20_global.fs20.rec == FS20_DATAGRAM_LENGTH_EXT)) { fs20_global.fs20.datagram.ext = (fs20_global.fs20.datagram.data.dg.cmd & (1 << 5)) ? 1 : 0; #ifdef DEBUG_FS20_REC if (fs20_global.fs20.rec == FS20_DATAGRAM_LENGTH) { #ifdef DEBUG_FS20_REC_VERBOSE printf("1cmd: "); for (uint8_t i = 0; i < 9; i++) { for (int8_t b = 7; b >= 0; b--) { printf("%u", (fs20_global.fs20.datagram.data.bytes[i] & (1<<b)) > 0); } printf(" "); } printf("\n"); debug_printf("1cmd: sync %02x hc1 %02x p1 %u hc2 %02x p2 %u addr %02x p3 %u cmd %02x p4 %u parity %02x p5 %u\n", fs20_global.fs20.datagram.data.dg.sync, fs20_global.fs20.datagram.data.dg.hc1, fs20_global.fs20.datagram.data.dg.p1, fs20_global.fs20.datagram.data.dg.hc2, fs20_global.fs20.datagram.data.dg.p2, fs20_global.fs20.datagram.data.dg.addr, fs20_global.fs20.datagram.data.dg.p3, fs20_global.fs20.datagram.data.dg.cmd, fs20_global.fs20.datagram.data.dg.p4, fs20_global.fs20.datagram.data.dg.parity, fs20_global.fs20.datagram.data.dg.p5); #else debug_printf("received new fs20 datagram: %02x%02x %02x %02x (valid: %u)\n", fs20_global.fs20.datagram.data.dg.hc1, fs20_global.fs20.datagram.data.dg.hc2, fs20_global.fs20.datagram.data.dg.addr, fs20_global.fs20.datagram.data.dg.cmd, (fs20_global.fs20.datagram.data.dg.sync == 0x01)); #endif } else if (fs20_global.fs20.rec == FS20_DATAGRAM_LENGTH_EXT) { #ifdef DEBUG_FS20_REC_VERBOSE printf("2cmd: "); for (uint8_t i = 0; i < 9; i++) { for (int8_t b = 7; b >= 0; b--) { printf("%u", (fs20_global.fs20.datagram.data.bytes[i] & (1<<b)) > 0); } printf(" "); } printf("\n"); debug_printf("2cmd: sync %02x hc1 %02x p1 %u hc2 %02x p2 %u addr %02x p3 %u cmd %02x p4 %u cmd2 %02x p5 %u parity %02x p6 %u\n", fs20_global.fs20.datagram.data.edg.sync, fs20_global.fs20.datagram.data.edg.hc1, fs20_global.fs20.datagram.data.edg.p1, fs20_global.fs20.datagram.data.edg.hc2, fs20_global.fs20.datagram.data.edg.p2, fs20_global.fs20.datagram.data.edg.addr, fs20_global.fs20.datagram.data.edg.p3, fs20_global.fs20.datagram.data.edg.cmd, fs20_global.fs20.datagram.data.edg.p4, fs20_global.fs20.datagram.data.edg.cmd2, fs20_global.fs20.datagram.data.edg.p5, fs20_global.fs20.datagram.data.edg.parity, fs20_global.fs20.datagram.data.edg.p6); #else debug_printf("received new ext fs20 datagram: %02x%02x %02x %02x %02x (valid: %u)\n", fs20_global.fs20.datagram.data.edg.hc1, fs20_global.fs20.datagram.data.edg.hc2, fs20_global.fs20.datagram.data.edg.addr, fs20_global.fs20.datagram.data.edg.cmd, fs20_global.fs20.datagram.data.edg.cmd2, (fs20_global.fs20.datagram.data.edg.sync == 0x01)); #endif } #ifdef DEBUG_FS20_REC_QUEUE debug_printf("queue fill is %u:\n", fs20_global.fs20.len); for (uint8_t l = 0; l < fs20_global.fs20.len; l++) { struct fs20_datagram_t *dg = &fs20_global.fs20.queue[l]; if (dg->ext) { debug_printf("%u: %02x%02x %02x %02x %02x\n", l, dg->data.edg.hc1, dg->data.edg.hc2, dg->data.edg.addr, dg->data.edg.cmd, dg->data.edg.cmd2); } else { debug_printf("%u: %02x%02x %02x %02x\n", l, dg->data.dg.hc1, dg->data.dg.hc2, dg->data.dg.addr, dg->data.dg.cmd); } } #endif #endif if (fs20_global.fs20.datagram.data.dg.sync == 0x0001) { #ifdef DEBUG_FS20_REC_VERBOSE debug_printf("valid sync\n"); #endif /* create shortcut to fs20_global.datagram */ volatile struct fs20_datagram_t *dg = &fs20_global.fs20.datagram; /* check parity */ uint8_t p1, p2, p3, p4, p5, p6; uint8_t fs20parity = 0; uint8_t fhtparity = 0; uint8_t dgparity = 0; p1 = parity_even_bit(dg->data.dg.hc1) ^ dg->data.dg.p1; p2 = parity_even_bit(dg->data.dg.hc2) ^ dg->data.dg.p2; p3 = parity_even_bit(dg->data.dg.addr) ^ dg->data.dg.p3; p4 = parity_even_bit(dg->data.dg.cmd) ^ dg->data.dg.p4; fs20parity = dg->data.dg.hc1 + dg->data.dg.hc2 + dg->data.dg.addr + dg->data.dg.cmd; fhtparity = fs20parity; fs20parity += 0x06; /* magic constant from fs20 protocol definition */ fhtparity += 0x0C; /* magic constant from fht protocol definition */ if ( dg->ext ) { fs20parity += dg->data.edg.cmd2; fhtparity += dg->data.edg.cmd2; p5 = parity_even_bit(dg->data.edg.cmd2) ^ dg->data.edg.p5; p6 = parity_even_bit(dg->data.edg.parity) ^ dg->data.edg.p6; dgparity = dg->data.edg.parity; } else { p5 = parity_even_bit(dg->data.dg.parity) ^ dg->data.dg.p5; p6 = 0; dgparity = dg->data.dg.parity; } /* check parity */ if (!p1 && !p2 && !p3 && !p4 && !p5 && !p6 && (fs20parity == dgparity || fhtparity == dgparity)) { #ifdef DEBUG_FS20_REC debug_printf("valid datagram\n"); #endif /* shift queue backwards */ memmove(&fs20_global.fs20.queue[1], &fs20_global.fs20.queue[0], (FS20_QUEUE_LENGTH-1) * sizeof(struct fs20_datagram_t)); dg->send = 1; /* copy datagram to queue */ memcpy(&fs20_global.fs20.queue[0], (const void *)&fs20_global.fs20.datagram, sizeof(struct fs20_datagram_t)); if (fs20_global.fs20.len < FS20_QUEUE_LENGTH) fs20_global.fs20.len++; /* set timeout (for 120ms = 6 * 20ms), if received a complete packet */ fs20_global.fs20.timeout = 6; } else { #ifdef DEBUG_FS20_REC debug_printf("invalid datagram\n"); #endif } } else { #ifdef DEBUG_FS20_REC debug_printf("sync invalid: %04x\n", fs20_global.fs20.datagram.data.dg.sync); #endif } fs20_global.fs20.rec = 0; //fs20_global.fs20.raw = 0; memset((void *)&fs20_global.fs20.datagram, 0, sizeof(struct fs20_datagram_t)); } #ifdef FS20_RECEIVE_WS300_SUPPORT if (fs20_global.ws300.rec == FS20_WS300_DATAGRAM_LENGTH) { #ifdef DEBUG_FS20_WS300 debug_printf("received ws300 datagram\n"); #endif #ifdef DEBUG_FS20_WS300_VERBOSE for (uint8_t i = 0; i < 10; i++) for (uint8_t j = 0; j < 8; j++) { if ( (i*8+j) % 5 == 4 ) printf(" "); printf("%u", (fs20_global.ws300.bytes[i] & _BV(j)) > 0); if ( (i*8+j) % 5 == 4 ) printf(" "); } printf("\n"); #endif ws300_parse_datagram(); /* clear global data structure */ memset((void *)&fs20_global.ws300.datagram, 0, sizeof(struct ws300_datagram_t)); fs20_global.ws300.sync = 0; fs20_global.ws300.rec = 0; } #endif }