12 static uint32_t station_id = 0x12345678;
13 static uint8_t feedback_threshold = 30;
15 void mfx_set_station_id(uint32_t id)
20 static OutputPacket *mfx_create_packet(MfxEncodingState *state)
22 OutputPacket *packet = output_create_packet();
23 packet->bit_duration = 4;
24 packet->repeat_count = 1;
25 packet->final_delay = 0;
27 packet->data[0] = 0x9B;
29 state->ones_count = 0;
34 static inline void mfx_update_crc8(MfxEncodingState *state, uint8_t bits, uint8_t length)
36 for(uint8_t i=length; i--; )
38 uint8_t bit = (bits>>i)&1;
39 if(bit^(state->crc8>>7))
40 state->crc8 = (state->crc8<<1)^7;
46 static inline uint8_t mfx_get_output_level(const OutputPacket *packet)
48 uint8_t b = packet->length-1;
49 return (packet->data[b>>3]>>(b&7))&1;
52 static inline void mfx_ensure_low_level(OutputPacket *packet)
54 if(mfx_get_output_level(packet))
56 // Motorola decoders require a low logic level when idle.
57 uint8_t out_bit = packet->length;
59 packet->data[out_bit>>3] = 0;
64 static inline void mfx_encode_flag_pairs(OutputPacket *packet, uint8_t count)
66 static const uint8_t flag_bits[5] = { 0x9B, 0x6C, 0xB2, 0xC9, 0x26 };
68 uint8_t invert = mfx_get_output_level(packet)*0xFF;
69 uint8_t shift = packet->length&7;
70 uint8_t total_bits = count*10;
71 uint8_t tail_bits = (total_bits+shift)&7;
72 uint8_t out_byte = packet->length>>3;
75 uint8_t head_bits = 8-shift;
76 packet->data[out_byte++] |= (flag_bits[0]^invert)<<shift;
79 uint8_t bytes = (total_bits-head_bits)>>3;
80 uint8_t carry = flag_bits[0]>>head_bits;
83 packet->data[out_byte++] = (carry|(flag_bits[i]<<shift))^invert;
84 carry = flag_bits[i]>>head_bits;
86 if(++i>=sizeof(flag_bits))
87 i -= sizeof(flag_bits);
91 packet->data[out_byte] = ((carry|(flag_bits[i]<<shift))^invert)&((1<<tail_bits)-1);
96 uint8_t bytes = total_bits>>3;
99 packet->data[out_byte++] = flag_bits[i]^invert;
101 if(++i>=sizeof(flag_bits))
102 i -= sizeof(flag_bits);
105 uint8_t tail_bits = (total_bits+shift)&7;
107 packet->data[out_byte] = (flag_bits[i]^invert)&((1<<tail_bits)-1);
110 packet->length += total_bits;
113 static inline void mfx_encode_bits8_raw(OutputPacket *packet, MfxEncodingState *state, uint8_t bits, uint8_t length)
115 uint8_t out_bit = packet->length;
116 uint8_t out_level = mfx_get_output_level(packet);
117 uint8_t ones_count = state->ones_count;
119 for(uint8_t i=length; i--; )
121 uint8_t bit = (bits>>i)&1;
131 // out_bit is always even at this point
133 packet->data[out_bit>>3] = bit;
135 packet->data[out_bit>>3] |= bit<<(out_bit&7);
146 state->ones_count = ones_count;
147 packet->length = out_bit;
150 static inline void mfx_encode_bits8(OutputPacket *packet, MfxEncodingState *state, uint8_t bits, uint8_t length)
152 mfx_encode_bits8_raw(packet, state, bits, length);
153 mfx_update_crc8(state, bits, length);
156 static inline void mfx_encode_bits16(OutputPacket *packet, MfxEncodingState *state, uint16_t bits, uint8_t length)
158 mfx_encode_bits8(packet, state, bits>>8, length-8);
159 mfx_encode_bits8(packet, state, bits, 8);
162 static inline void mfx_encode_bits32(OutputPacket *packet, MfxEncodingState *state, uint32_t bits, uint8_t length)
166 mfx_encode_bits8(packet, state, bits>>24, length-24);
167 mfx_encode_bits8(packet, state, bits>>16, 8);
170 mfx_encode_bits8(packet, state, bits>>16, length-16);
171 mfx_encode_bits8(packet, state, bits>>8, 8);
172 mfx_encode_bits8(packet, state, bits, 8);
175 static inline void mfx_address_field(OutputPacket *packet, MfxEncodingState *state, uint16_t address)
178 mfx_encode_bits16(packet, state, 0x100|address, 9);
179 else if(address<0x200)
180 mfx_encode_bits16(packet, state, 0xC00|address, 12);
181 else if(address<0x800)
182 mfx_encode_bits16(packet, state, 0x7000|address, 15);
185 mfx_encode_bits8(packet, state, 0xF, 4);
186 mfx_encode_bits16(packet, state, address, 14);
190 void mfx_speed_field(OutputPacket *packet, MfxEncodingState *state, uint8_t speed_dir)
195 mfx_encode_bits8(packet, state, 0x1, 3);
196 mfx_encode_bits8(packet, state, speed_dir, 8);
200 mfx_encode_bits8(packet, state, speed_dir>>4, 7);
203 static void mfx_finish_packet(OutputPacket *packet, MfxEncodingState *state)
205 mfx_encode_bits8_raw(packet, state, state->crc8, 8);
206 mfx_encode_flag_pairs(packet, 2);
207 mfx_ensure_low_level(packet);
210 static void mfx_finish_packet_feedback(OutputPacket *packet, MfxEncodingState *state)
212 mfx_encode_bits8_raw(packet, state, state->crc8, 8);
213 mfx_encode_flag_pairs(packet, 11);
214 mfx_encode_bits8_raw(packet, state, 0x3, 4);
215 uint8_t fill = (1-mfx_get_output_level(packet))*0xFF;
217 for(uint8_t i=0; i<2; ++i)
219 packet = output_create_chained_packet();
220 packet->bit_duration = 4;
221 packet->repeat_count = 1;
222 packet->final_delay = 0;
223 packet->trigger_position = 112;
224 packet->trigger_value = i+1;
226 for(uint8_t j=0; j<16; ++j)
227 packet->data[j] = fill;
228 packet->length = 128;
229 mfx_encode_flag_pairs(packet, 1+i);
233 mfx_ensure_low_level(packet);
236 static void mfx_receive_feedback()
238 /* The decoder should activate a 52.6 kHz carrier to indicate positive
239 acknowledgement, but so far I've been unable to build a circuit that detects
240 it. The increased current draw can nevertheless be measured. */
243 current[0] = monitor_track_current();
246 uint8_t trig = output_get_trigger();
249 current[trig] = monitor_track_current();
256 reply[0] = MFX_FEEDBACK;
257 if(current[1]>feedback_threshold)
259 current[1] -= feedback_threshold;
260 reply[1] = (current[1]>current[0] && current[1]>current[2]);
264 interface_send(reply, 2);
267 void mfx_announce_packet(uint16_t serial)
269 MfxEncodingState state;
270 OutputPacket *packet = mfx_create_packet(&state);
271 mfx_address_field(packet, &state, 0);
272 // Packet type: 111101
273 mfx_encode_bits8(packet, &state, 0x3D, 6);
274 mfx_encode_bits32(packet, &state, station_id, 32);
275 mfx_encode_bits16(packet, &state, serial, 16);
276 mfx_finish_packet(packet, &state);
277 output_send_packet();
280 void mfx_search_packet(uint32_t mask_bits, uint8_t mask_size)
282 MfxEncodingState state;
283 OutputPacket *packet = mfx_create_packet(&state);
284 mfx_address_field(packet, &state, 0);
285 // Packet type: 111010
286 mfx_encode_bits8(packet, &state, 0x3A, 6);
287 mfx_encode_bits8(packet, &state, mask_size, 6);
288 mfx_encode_bits32(packet, &state, mask_bits, 32);
289 mfx_finish_packet_feedback(packet, &state);
290 output_send_packet();
293 void mfx_assign_address_packet(uint16_t addr, uint32_t id)
295 MfxEncodingState state;
296 OutputPacket *packet = mfx_create_packet(&state);
297 mfx_address_field(packet, &state, 0);
298 // Packet type: 111011
299 mfx_encode_bits8(packet, &state, 0x3B, 6);
300 mfx_encode_bits16(packet, &state, addr, 14);
301 mfx_encode_bits32(packet, &state, id, 32);
302 mfx_finish_packet(packet, &state);
303 output_send_packet();
306 void mfx_ping_packet(uint16_t addr, uint32_t id)
308 MfxEncodingState state;
309 OutputPacket *packet = mfx_create_packet(&state);
310 mfx_address_field(packet, &state, addr);
311 // Packet type: 111100
312 mfx_encode_bits8(packet, &state, 0x3C, 6);
313 mfx_encode_bits32(packet, &state, id, 32);
314 mfx_finish_packet_feedback(packet, &state);
315 output_send_packet();
318 void mfx_speed_packet(uint16_t addr, uint8_t speed_dir)
320 MfxEncodingState state;
321 OutputPacket *packet = mfx_create_packet(&state);
322 mfx_address_field(packet, &state, addr);
323 mfx_speed_field(packet, &state, speed_dir);
324 mfx_finish_packet(packet, &state);
325 output_send_packet();
328 void mfx_speed_funcs8_packet(uint16_t addr, uint8_t speed_dir, uint8_t funcs)
330 MfxEncodingState state;
331 OutputPacket *packet = mfx_create_packet(&state);
332 mfx_address_field(packet, &state, addr);
333 mfx_speed_field(packet, &state, speed_dir);
337 mfx_encode_bits8(packet, &state, 0x6, 4);
338 mfx_encode_bits8(packet, &state, funcs, 8);
342 mfx_encode_bits8(packet, &state, 0x20|funcs, 7);
343 mfx_finish_packet(packet, &state);
344 output_send_packet();
347 void mfx_speed_funcs16_packet(uint16_t addr, uint8_t speed_dir, uint16_t funcs)
349 MfxEncodingState state;
350 OutputPacket *packet = mfx_create_packet(&state);
351 mfx_address_field(packet, &state, addr);
352 mfx_speed_field(packet, &state, speed_dir);
354 mfx_encode_bits8(packet, &state, 0x7, 4);
355 mfx_encode_bits16(packet, &state, funcs, 16);
356 mfx_finish_packet(packet, &state);
357 output_send_packet();
360 uint8_t mfx_command(const uint8_t *cmd, uint8_t length)
362 if(cmd[0]==MFX_SET_STATION_ID)
367 uint32_t id = (cmd[1]<<8)|cmd[2];
369 id |= (uint16_t)(cmd[3]<<8)|cmd[4];
370 mfx_set_station_id(id);
372 else if(cmd[0]==MFX_ANNOUNCE)
377 mfx_announce_packet((cmd[1]<<8)|cmd[2]);
379 else if(cmd[0]==MFX_SEARCH)
384 uint8_t mask_size = cmd[5];
386 return INVALID_VALUE;
388 uint32_t mask_bits = (cmd[1]<<8)|cmd[2];
390 mask_bits |= (uint16_t)(cmd[3]<<8)|cmd[4];
391 mfx_search_packet(mask_bits, mask_size);
392 mfx_receive_feedback();
394 else if(cmd[0]==MFX_ASSIGN_ADDRESS || cmd[0]==MFX_PING)
399 uint16_t addr = (cmd[1]<<8)|cmd[2];
400 if(addr==0 || addr>0x3FFF)
401 return INVALID_VALUE;
403 uint32_t id = (cmd[3]<<8)|cmd[4];
405 id |= (uint16_t)(cmd[5]<<8)|cmd[6];
406 if(cmd[0]==MFX_ASSIGN_ADDRESS)
407 mfx_assign_address_packet(addr, id);
410 mfx_ping_packet(addr, id);
411 mfx_receive_feedback();
414 else if(cmd[0]==MFX_SPEED || cmd[0]==MFX_SPEED_FUNCS8 || cmd[0]==MFX_SPEED_FUNCS16)
416 if(cmd[0]==MFX_SPEED && length!=4)
418 else if(cmd[0]==MFX_SPEED_FUNCS8 && length!=5)
420 else if(cmd[0]==MFX_SPEED_FUNCS16 && length!=6)
423 uint16_t addr = (cmd[1]<<8)|cmd[2];
424 if(addr==0 || addr>0x3FFF)
425 return INVALID_VALUE;
427 uint8_t speed_dir = cmd[3];
428 if((speed_dir&0x7F)==0x7F)
429 return INVALID_VALUE;
432 if(cmd[0]==MFX_SPEED)
433 mfx_speed_packet(addr, speed_dir);
434 else if(cmd[0]==MFX_SPEED_FUNCS8)
435 mfx_speed_funcs8_packet(addr, speed_dir, cmd[4]);
436 else if(cmd[0]==MFX_SPEED_FUNCS16)
437 mfx_speed_funcs8_packet(addr, speed_dir, (cmd[4]<<8)|cmd[5]);
440 return INVALID_COMMAND;