// Returns a demedulated frame or -1 on code violation // // Since TX to RX delay is arbitrary rx_frame has to: // - detect start of frame (first pause) // - forward prng based on ts/TAG_BIT_PERIOD // - receive the frame // - detect end of frame (last pause) static int32_t rx_frame(uint8_t *len) { int32_t frame = 0; // add 2 SSP clock cycles (1 for tx and 1 for rx pipeline delay) // those will be substracted at the end of the rx phase last_frame_end -= 2; // wait for first pause (start of frame) for(uint8_t i = 0; true; ++i) { // increment prng every TAG_BIT_PERIOD last_frame_end += TAG_BIT_PERIOD; legic_prng_forward(1); // if start of frame was received exit delay loop if(wait_for(RWD_PAUSE, last_frame_end)) { last_frame_end = GetCountSspClk(); break; } // check for code violation if(i > RWD_CMD_TIMEOUT) { return -1; } } // receive frame for(*len = 0; true; ++(*len)) { // receive next bit LED_D_ON(); int8_t bit = rx_bit(); LED_D_OFF(); // check for code violation and to short / long frame if((bit < 0) && ((*len < RWD_MIN_FRAME_LEN) || (*len > RWD_MAX_FRAME_LEN))) { return -1; } // check for code violation caused by end of frame if(bit < 0) { break; } // append bit frame |= (bit ^ legic_prng_get_bit()) << (*len); legic_prng_forward(1); } // rx_bit sets coordination timestamp to start of pause, append pause duration // and substract 2 SSP clock cycles (1 for rx and 1 for tx pipeline delay) to // obtain exact end of frame. last_frame_end += RWD_TIME_PAUSE - 2; return frame; }
unsigned char spi_slow_wr(register unsigned char data) { register int cnt; for (cnt = 0; cnt < 8; cnt++) { tx_bit(data & MSB); delay1u5(); cts_bit(1); /* SPI clock ON */ data = (data << 1) | rx_bit(); /* SPI data input */ delay1u5(); cts_bit(0); /* SPI clock OFF */ } return(data); }