/* * Description in header */ void analyze_hms(bucket_t *b, uint8_t *datatype, uint8_t *obuf, uint8_t *oby) { if (IS868MHZ && *datatype == 0 && b->state == STATE_HMS) { input_t in; in.byte = 0; in.bit = 7; in.data = b->data; if(b->byteidx*8 + (7-b->bitidx) < 69) return; // failed uint8_t crc = 0, i = 0; for(i = 0; i < 6; i++) { obuf[i] = getbits(&in, 8, 0); if(parity_even_bit(obuf[i]) != getbit( &in )) return; // failed if(getbit(&in)) return; // failed crc = crc ^ obuf[i]; } *oby = i; // Read crc uint8_t CRC = getbits(&in, 8, 0); if(parity_even_bit(CRC) != getbit(&in)) return; // failed if(crc!=CRC) return; // failes *datatype = TYPE_HMS; return; // OK } }
uint8_t random8(void) { uint8_t i, t[4]; for (i = 0; i < 8; ++i) { *((uint32_t *)t) = state & POLYNOM; state = state << 1 | (parity_even_bit(t[0]) ^ parity_even_bit(t[1]) ^ parity_even_bit(t[2]) ^ parity_even_bit(t[3])); } return (uint8_t)state; }
uint8_t analyze_hms(bucket_t *b) { printf("======== Checking: HMS\n"); input_t in; in.byte = 0; in.bit = 7; in.data = b->data; oby = 0; if(b->byteidx*8 + (7-b->bitidx) < 69) { printf("Not enough bits\n"); return 0; } uint8_t crc = 0; for(oby = 0; oby < 6; oby++) { obuf[oby] = getbits(&in, 8, 0); printf("got byte %d at %d/%d\n", obuf[oby], in.byte, in.bit); if(parity_even_bit(obuf[oby]) != getbit( &in )) { printf("Wrong parity at %d/%d\n", in.byte, in.bit); return 0; } if(getbit(&in)) { printf("Wrong top bit at %d/%d\n", in.byte, in.bit); return 0; } crc = crc ^ obuf[oby]; } // Read crc uint8_t CRC = getbits(&in, 8, 0); if(parity_even_bit(CRC) != getbit(&in)) { printf("Wrong parity at %d/%d\n", in.byte, in.bit); return 0; } if(crc!=CRC) { printf("BAD CRC: %d vs. %d\n", crc, CRC); return 0; } return 1; }
void fs20_send_byte(uint8_t byte) { uint8_t i = 7; do { fs20_send_bit(byte & _BV(i)); } while (i-- > 0); fs20_send_bit(parity_even_bit(byte)); }
static void fs20sendBits(uint16_t data, uint8_t bits) { if (bits == 8) { ++bits; data = (data << 1) | parity_even_bit(data); } for (uint16_t mask = 1 << (bits - 1); mask != 0; mask >>= 1) { if (PACKET) { uint8_t n = (data & mask ? 3 : 2); for (uint8_t on = n; on > 0; on--) addOutBit(1); for (uint8_t off = n; off > 0; off--) addOutBit(0); } else { int width = data & mask ? 600 : 400; ookPulse(width, width); } } }
// 4.2 - this function writes a character out on the data line void SDI12::writeChar(uint8_t out) { out |= (parity_even_bit(out)<<7); // 4.2.1 - parity bit digitalWrite(_dataPin, HIGH); // 4.2.2 - start bit delayMicroseconds(SPACING); for (byte mask = 0x01; mask; mask<<=1){ // 4.2.3 - send payload if(out & mask){ digitalWrite(_dataPin, LOW); } else{ digitalWrite(_dataPin, HIGH); } delayMicroseconds(SPACING); } digitalWrite(_dataPin, LOW); // 4.2.4 - stop bit delayMicroseconds(SPACING); }
static uint8_t analyze(bucket_t *b, uint8_t t) { uint8_t cnt=0, iserr = 0, max, iby = 0; int8_t ibi=7, obi=7; printf("======== Checking: %c\n", t); nibble = 0; oby = 0; max = b->byteidx*8+(7-b->bitidx); obuf[0] = 0; while(cnt++ < max) { uint8_t bit = (b->data[iby] & _BV(ibi)) ? 1 : 0; // Input bit if(ibi-- == 0) { iby++; ibi=7; } if(t == TYPE_KS300 && obi == 3) { // nibble check if(!nibble) { if(!bit) { iserr = 1; break; } nibble = !nibble; continue; } nibble = !nibble; } if(obi == -1) { // next byte if(t == TYPE_FS20) { printf(" P%d (%d/%d)\n", bit, cnt, max); if(parity_even_bit(obuf[oby]) != bit) { iserr = 2; break; } } if(t == TYPE_EM || t == TYPE_KS300) { if(!bit) { iserr = 3; break; } } obuf[++oby] = 0; obi = 7; } else { // Normal bits printf("%d", bit); if(bit) { if(t == TYPE_FS20) obuf[oby] |= _BV(obi); if(t == TYPE_EM || t == TYPE_KS300) // LSB obuf[oby] |= _BV(7-obi); } obi--; } } if(cnt <= max && !iserr) iserr = 4; else if(iserr && t == TYPE_EM && obi == -1) // missing last stopbit oby++; else if(nibble) { // half byte msg oby++; } if(oby == 0 && !iserr) iserr = 5; printf("\nCNT: %d, ISERR: %d\n", cnt, iserr); return !iserr; }
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 }
/* Calaculate even parity bit */ void systemCalculateEvenParity(ui8 data, ui8 *result) { *result = parity_even_bit(data); }
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 }
static uint8_t analyze(bucket_t *b, uint8_t t, uint8_t *oby) { uint8_t i=0, cnt=0, max, iby = 0; int8_t ibi=7, obi=7; nibble = 0; max = b->byteidx*8+(7-b->bitidx); obuf[0] = 0; while(cnt++ < max) { uint8_t bit = (b->data[iby] & _BV(ibi)) ? 1 : 0; // Input bit if(ibi-- == 0) { iby++; ibi=7; } if(t == TYPE_KS300 && obi == 3) { // nibble check if(!nibble) { if(!bit) return 0; nibble = !nibble; continue; } nibble = !nibble; } if(obi == -1) { // next byte if(t == TYPE_FS20) { if(parity_even_bit(obuf[i]) != bit) return 0; } if(t == TYPE_EM || t == TYPE_KS300) { if(!bit) return 0; } obuf[++i] = 0; obi = 7; } else { // Normal bits if(bit) { if(t == TYPE_FS20) obuf[i] |= _BV(obi); if(t == TYPE_EM || t == TYPE_KS300) // LSB obuf[i] |= _BV(7-obi); } obi--; } } if(cnt <= max) return 0; else if(t == TYPE_EM && obi == -1) // missing last stopbit i++; else if(nibble) // half byte msg i++; *oby = i; if(i == 0) return 0; return 1; }