forked from 400plus/400plus
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmsm.c
110 lines (79 loc) · 2.39 KB
/
msm.c
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <vxworks.h>
#include "firmware/camera.h"
#include "main.h"
#include "macros.h"
#include "button.h"
#include "utils.h"
#include "shutter.h"
#include "intercom.h"
#include "msm.h"
int msm_ae_return; // Multi-spot metering: AE mode to return after first shot
tv_t msm_tv_return; // Multi-spot metering: Tv value in M mode to return
av_t msm_av_return; // Multi-spot metering: Av value in M mode to return
void msm_reset(void);
void msm_reset(void) {
status.msm_count = 0;
status.msm_tv = EV_ZERO;
status.msm_av = EV_ZERO;
status.msm_active = FALSE;
}
void msm_register(void) {
static int last_flag; // Last value registered can be deleted
static tv_t last_tv; // Last Tv value registered
static av_t last_av; // Last Av value registered
int ts_start = timestamp();
if (status.measuring) {
if (status.msm_count < 8) {
status.vf_status = VF_STATUS_MSM;
send_to_intercom(IC_SET_BURST_COUNTER, status.msm_count + 1);
}
beep();
}
while (status.button_down == BUTTON_DOWN) {
if (timestamp() - ts_start > MSM_TIMEOUT) {
if (last_flag) {
status.msm_count--;
status.msm_tv -= last_tv;
status.msm_av -= last_av;
last_flag = FALSE;
send_to_intercom(IC_SET_BURST_COUNTER, status.msm_count);
beep();
}
return;
}
SleepTask(MSM_RETRY);
}
status.msm_count++;
status.msm_tv += status.measured_tv;
status.msm_av += status.measured_av;
last_flag = TRUE;
last_tv = status.measured_tv;
last_av = status.measured_av;
}
void msm_release(void) {
send_to_intercom(IC_SET_BURST_COUNTER, 9);
}
void msm_start(void) {
if (status.msm_count > 0) {
status.msm_active = TRUE;
tv_t tv = ev_normalize(status.msm_tv / status.msm_count);
av_t av = ev_normalize(status.msm_av / status.msm_count);
av_t av_max = DPData.ef_lens_exist ? DPData.avmax : AV_MAX;
av_t av_min = DPData.ef_lens_exist ? DPData.avo : AV_MIN;
msm_ae_return = DPData.ae;
send_to_intercom(IC_SET_AE, AE_MODE_M);
msm_tv_return = DPData.tv_val;
msm_av_return = DPData.av_val;
send_to_intercom(IC_SET_TV_VAL, CLAMP(tv, TV_MIN, TV_MAX));
send_to_intercom(IC_SET_AV_VAL, CLAMP(av, av_min, av_max));
enqueue_action(beep);
}
}
void msm_stop(void) {
wait_for_camera();
SleepTask(RELEASE_WAIT);
send_to_intercom(IC_SET_TV_VAL, msm_tv_return);
send_to_intercom(IC_SET_AV_VAL, msm_av_return);
send_to_intercom(IC_SET_AE, msm_ae_return);
enqueue_action(msm_reset);
}