+/* get the frame from laser time difference, return 0 on error (this
+ * frame cannot be sent). */
+static uint32_t get_frame(uint16_t laserdiff)
+{
+ uint32_t frame = 0;
+ uint16_t val, mid, min, max;
+
+ /* for calibration, return the time */
+#ifdef INC_FRAME
+ static uint16_t fr = 1;
+ fr += 2;
+ return fr;
+#endif
+#ifdef SEND_RAWTIME
+ return laserdiff | 1; /* frame must be odd */
+#endif
+
+ min = 0;
+ max = 511;
+ while (min != max) {
+ mid = (max + min + 1) / 2;
+ val = pgm_read_word(&framedist_table[mid]);
+
+ if (laserdiff > val)
+ max = mid - 1;
+ else
+ min = mid;
+ }
+
+ frame |= ((uint32_t)((min << FRAME_DATA_SHIFT)
+ & FRAME_DATA_MASK));
+ frame |= BEACON_ID;
+
+ /* process cksum and return */
+ return do_cksum(frame);
+}