.MODULE $M.rotary_enc.service_routine;
.CODESEGMENT ROTARY_ENC_SERVICE_ROUTINE_PM;
.DATASEGMENT DM;
$rotary_enc.service_routine:
// push rLink onto stack
$push_rLink_macro;
r0 = M[$PIO_IN];
r1 = 0x800;
r2 = 0x80;
// read PIO 11
r3 = 1;
null = r0 AND r1;
if Z r3 = 0;
// read PIO 7
r4 = 1;
null = r0 AND r2;
if Z r4 = 0;
// get last sample pio value
r1 = M[$pio_a_last_value];
r2 = M[$pio_b_last_value];
// save current pio value
M[$pio_a_last_value] = r3;
M[$pio_b_last_value] = r4;
// check if pre and cur value is match,
// otherwise register timer event
// pre pio A != pio B
null = r1 - r2;
if Z jump register_event;
// cur pio A = pio B
null = r3 - r4;
if NZ jump register_event;
// check rotate direction
// 1: rotation, -1; anti-rotation
// cur = pre pio A
r0 = 1;
null = r3 - r1;
if Z r0 = -1;
// send rotation number
r2 = $KALIMBA_MSG_ROTARY_ENCODER_RETURN_ID_1;
r3 = r0;
r4 = 1;
call $message.send;
register_event:
// fire a timer in 'MAX_BOUNCE_US' time
r1 = &$timer_struc;
r2 = 1000;
r3 = &$rotary_enc.service_routine;
call $timer.schedule_event_in;
// pop rLink from stack
jump $pop_rLink_and_rts;
.ENDMODULE;