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);
118 for(uint8_t i=length; i--; )
120 uint8_t bit = (bits>>i)&1;
122 if(state->ones_count>=8)
126 state->ones_count = 0;
131 state->ones_count = 0;
136 // out_bit is always even at this point
138 packet->data[out_bit>>3] = bit;
140 packet->data[out_bit>>3] |= bit<<(out_bit&7);
145 packet->length = out_bit;
148 static inline void mfx_encode_bits8(OutputPacket *packet, MfxEncodingState *state, uint8_t bits, uint8_t length)
150 mfx_encode_bits8_raw(packet, state, bits, length);
151 mfx_update_crc8(state, bits, length);
154 static inline void mfx_encode_bits16(OutputPacket *packet, MfxEncodingState *state, uint16_t bits, uint8_t length)
156 mfx_encode_bits8(packet, state, bits>>8, length-8);
157 mfx_encode_bits8(packet, state, bits, 8);
160 static inline void mfx_encode_bits32(OutputPacket *packet, MfxEncodingState *state, uint32_t bits, uint8_t length)
164 mfx_encode_bits8(packet, state, bits>>24, length-24);
165 mfx_encode_bits8(packet, state, bits>>16, 8);
168 mfx_encode_bits8(packet, state, bits>>16, length-16);
169 mfx_encode_bits8(packet, state, bits>>8, 8);
170 mfx_encode_bits8(packet, state, bits, 8);
173 static inline void mfx_address_field(OutputPacket *packet, MfxEncodingState *state, uint16_t address)
176 mfx_encode_bits16(packet, state, 0x100|address, 9);
177 else if(address<0x200)
178 mfx_encode_bits16(packet, state, 0xC00|address, 12);
179 else if(address<0x800)
180 mfx_encode_bits16(packet, state, 0x7000|address, 15);
183 mfx_encode_bits8(packet, state, 0xF, 4);
184 mfx_encode_bits16(packet, state, address, 14);
188 void mfx_speed_field(OutputPacket *packet, MfxEncodingState *state, uint8_t speed_dir)
193 mfx_encode_bits8(packet, state, 0x1, 3);
194 mfx_encode_bits8(packet, state, speed_dir, 8);
198 mfx_encode_bits8(packet, state, speed_dir>>4, 7);
201 static void mfx_finish_packet(OutputPacket *packet, MfxEncodingState *state)
203 mfx_encode_bits8_raw(packet, state, state->crc8, 8);
204 mfx_encode_flag_pairs(packet, 2);
205 mfx_ensure_low_level(packet);
208 static void mfx_finish_packet_feedback(OutputPacket *packet, MfxEncodingState *state)
210 mfx_encode_bits8_raw(packet, state, state->crc8, 8);
211 mfx_encode_flag_pairs(packet, 11);
212 mfx_encode_bits8_raw(packet, state, 0x3, 4);
213 uint8_t fill = (1-mfx_get_output_level(packet))*0xFF;
215 for(uint8_t i=0; i<2; ++i)
217 packet = output_create_chained_packet();
218 packet->bit_duration = 4;
219 packet->repeat_count = 1;
220 packet->final_delay = 0;
221 packet->trigger_position = 112;
222 packet->trigger_value = i+1;
224 for(uint8_t j=0; j<16; ++j)
225 packet->data[j] = fill;
226 packet->length = 128;
227 mfx_encode_flag_pairs(packet, 1+i);
231 mfx_ensure_low_level(packet);
234 static void mfx_receive_feedback()
236 /* The decoder should activate a 52.6 kHz carrier to indicate positive
237 acknowledgement, but so far I've been unable to build a circuit that detects
238 it. The increased current draw can nevertheless be measured. */
241 current[0] = monitor_track_current();
244 uint8_t trig = output_get_trigger();
247 current[trig] = monitor_track_current();
254 reply[0] = MFX_FEEDBACK;
255 if(current[1]>feedback_threshold)
257 current[1] -= feedback_threshold;
258 reply[1] = (current[1]>current[0] && current[1]>current[2]);
262 interface_send(reply, 2);
265 void mfx_announce_packet(uint16_t serial)
267 MfxEncodingState state;
268 OutputPacket *packet = mfx_create_packet(&state);
269 mfx_address_field(packet, &state, 0);
270 // Packet type: 111101
271 mfx_encode_bits8(packet, &state, 0x3D, 6);
272 mfx_encode_bits32(packet, &state, station_id, 32);
273 mfx_encode_bits16(packet, &state, serial, 16);
274 mfx_finish_packet(packet, &state);
275 output_send_packet();
278 void mfx_search_packet(uint32_t mask_bits, uint8_t mask_size)
280 MfxEncodingState state;
281 OutputPacket *packet = mfx_create_packet(&state);
282 mfx_address_field(packet, &state, 0);
283 // Packet type: 111010
284 mfx_encode_bits8(packet, &state, 0x3A, 6);
285 mfx_encode_bits8(packet, &state, mask_size, 6);
286 mfx_encode_bits32(packet, &state, mask_bits, 32);
287 mfx_finish_packet_feedback(packet, &state);
288 output_send_packet();
291 void mfx_assign_address_packet(uint16_t addr, uint32_t id)
293 MfxEncodingState state;
294 OutputPacket *packet = mfx_create_packet(&state);
295 mfx_address_field(packet, &state, 0);
296 // Packet type: 111011
297 mfx_encode_bits8(packet, &state, 0x3B, 6);
298 mfx_encode_bits16(packet, &state, addr, 14);
299 mfx_encode_bits32(packet, &state, id, 32);
300 mfx_finish_packet(packet, &state);
301 output_send_packet();
304 void mfx_ping_packet(uint16_t addr, uint32_t id)
306 MfxEncodingState state;
307 OutputPacket *packet = mfx_create_packet(&state);
308 mfx_address_field(packet, &state, addr);
309 // Packet type: 111100
310 mfx_encode_bits8(packet, &state, 0x3C, 6);
311 mfx_encode_bits32(packet, &state, id, 32);
312 mfx_finish_packet_feedback(packet, &state);
313 output_send_packet();
316 void mfx_speed_packet(uint16_t addr, uint8_t speed_dir)
318 MfxEncodingState state;
319 OutputPacket *packet = mfx_create_packet(&state);
320 mfx_address_field(packet, &state, addr);
321 mfx_speed_field(packet, &state, speed_dir);
322 mfx_finish_packet(packet, &state);
323 output_send_packet();
326 void mfx_speed_funcs8_packet(uint16_t addr, uint8_t speed_dir, uint8_t funcs)
328 MfxEncodingState state;
329 OutputPacket *packet = mfx_create_packet(&state);
330 mfx_address_field(packet, &state, addr);
331 mfx_speed_field(packet, &state, speed_dir);
335 mfx_encode_bits8(packet, &state, 0x6, 4);
336 mfx_encode_bits8(packet, &state, funcs, 8);
340 mfx_encode_bits8(packet, &state, 0x20|funcs, 7);
341 mfx_finish_packet(packet, &state);
342 output_send_packet();
345 void mfx_speed_funcs16_packet(uint16_t addr, uint8_t speed_dir, uint16_t funcs)
347 MfxEncodingState state;
348 OutputPacket *packet = mfx_create_packet(&state);
349 mfx_address_field(packet, &state, addr);
350 mfx_speed_field(packet, &state, speed_dir);
352 mfx_encode_bits8(packet, &state, 0x7, 4);
353 mfx_encode_bits16(packet, &state, funcs, 16);
354 mfx_finish_packet(packet, &state);
355 output_send_packet();
358 uint8_t mfx_command(const uint8_t *cmd, uint8_t length)
360 if(cmd[0]==MFX_SET_STATION_ID)
365 uint32_t id = (cmd[1]<<8)|cmd[2];
367 id |= (uint16_t)(cmd[3]<<8)|cmd[4];
368 mfx_set_station_id(id);
370 else if(cmd[0]==MFX_ANNOUNCE)
375 mfx_announce_packet((cmd[1]<<8)|cmd[2]);
377 else if(cmd[0]==MFX_SEARCH)
382 uint8_t mask_size = cmd[5];
384 return INVALID_VALUE;
386 uint32_t mask_bits = (cmd[1]<<8)|cmd[2];
388 mask_bits |= (uint16_t)(cmd[3]<<8)|cmd[4];
389 mfx_search_packet(mask_bits, mask_size);
390 mfx_receive_feedback();
392 else if(cmd[0]==MFX_ASSIGN_ADDRESS || cmd[0]==MFX_PING)
397 uint16_t addr = (cmd[1]<<8)|cmd[2];
398 if(addr==0 || addr>0x3FFF)
399 return INVALID_VALUE;
401 uint32_t id = (cmd[3]<<8)|cmd[4];
403 id |= (uint16_t)(cmd[5]<<8)|cmd[6];
404 if(cmd[0]==MFX_ASSIGN_ADDRESS)
405 mfx_assign_address_packet(addr, id);
408 mfx_ping_packet(addr, id);
409 mfx_receive_feedback();
412 else if(cmd[0]==MFX_SPEED || cmd[0]==MFX_SPEED_FUNCS8 || cmd[0]==MFX_SPEED_FUNCS16)
414 if(cmd[0]==MFX_SPEED && length!=4)
416 else if(cmd[0]==MFX_SPEED_FUNCS8 && length!=5)
418 else if(cmd[0]==MFX_SPEED_FUNCS16 && length!=6)
421 uint16_t addr = (cmd[1]<<8)|cmd[2];
422 if(addr==0 || addr>0x3FFF)
423 return INVALID_VALUE;
425 uint8_t speed_dir = cmd[3];
426 if((speed_dir&0x7F)==0x7F)
427 return INVALID_VALUE;
430 if(cmd[0]==MFX_SPEED)
431 mfx_speed_packet(addr, speed_dir);
432 else if(cmd[0]==MFX_SPEED_FUNCS8)
433 mfx_speed_funcs8_packet(addr, speed_dir, cmd[4]);
434 else if(cmd[0]==MFX_SPEED_FUNCS16)
435 mfx_speed_funcs8_packet(addr, speed_dir, (cmd[4]<<8)|cmd[5]);
438 return INVALID_COMMAND;