-
Notifications
You must be signed in to change notification settings - Fork 0
/
ulp_prog.h
81 lines (64 loc) · 1.76 KB
/
ulp_prog.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#ifndef GATE_SENSOR_ULP_PROG_H
#define GATE_SENSOR_ULP_PROG_H
#include "ulp_inst.h"
namespace gate_ulp {
enum labels {
L_HALT = 1,
L_WAKE = 2,
L_SENSOR_HIGH = 3,
L_SENSOR_LOW = 4,
};
const ulp_insn_t program[]{
// R3 serves as the zero register for HULP macros
I_MOVI(R3, 0),
// Increment the ULP wake accumulator
I_GET(R0, R3, rtcd::ulp_check_acc),
I_ADDI(R0, R0, 1),
I_PUT(R0, R3, rtcd::ulp_check_acc),
// Load previous ADC value into R2
I_GET(R2, R3, rtcd::ulp_a1c5_value),
I_ADC_POWER_ON(),
// Measure ADC1 channel 5 into R1
I_ADC(R1, 0, ADC1_CHANNEL_5),
I_ADC_POWER_OFF(),
// Store measured value
I_PUT(R1, R3, rtcd::ulp_a1c5_value),
// Copy measurement to R0 for branch instructions
I_MOVR(R0, R1),
// if val > high threshold
M_BGE(L_SENSOR_HIGH, Gate::THRESHOLD_HIGH),
// if val < low threshold
M_BL(L_SENSOR_LOW, Gate::THRESHOLD_LOW),
// else increment the ULP out-of-range accumulator
I_GET(R0, R3, rtcd::ulp_oor_acc),
I_ADDI(R0, R0, 1),
I_PUT(R0, R3, rtcd::ulp_oor_acc),
// and halt
M_BX(L_HALT),
M_LABEL(L_SENSOR_HIGH),
I_MOVI(R1, GateState::OPEN),
I_GET(R0, R3, rtcd::last_state),
I_ANDR(R0, R0, R1),
// if (cur & prev != 0) then no change
M_BGE(L_HALT, 1),
// state *has* changed
M_BX(L_WAKE),
M_LABEL(L_SENSOR_LOW),
I_MOVI(R1, GateState::CLOSED),
I_GET(R0, R3, rtcd::last_state),
I_ANDR(R0, R0, R1),
// if (cur & prev != 0) then no change
M_BGE(L_HALT, 1),
// state *has* changed
M_BX(L_WAKE),
M_LABEL(L_WAKE),
// Cancel the ULP wake timer
I_END(),
// And wake CPU
M_WAKE_WHEN_READY(),
// Halt the ULP
M_LABEL(L_HALT),
I_HALT()
};
}
#endif //GATE_SENSOR_ULP_PROG_H