-
-
Notifications
You must be signed in to change notification settings - Fork 61
Expand file tree
/
Copy pathsnstool.c
More file actions
165 lines (139 loc) · 4 KB
/
snstool.c
File metadata and controls
165 lines (139 loc) · 4 KB
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <getopt.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "chipid.h"
#include "hal/common.h"
#include "snstool.h"
#include "tools.h"
extern void print_usage();
typedef struct {
const char *name;
uint16_t base_addr;
uint8_t len;
} Reg;
/* Mirrors the runtime hot set ipctool trace's _ae_step skeleton picks up
* for SC2315E. Values readable while the streamer is paused; HOLD toggles
* 0x00 -> 0x30 around grouped writes by cmos_gains_update. */
const Reg sc2315e_regs[] = {
{"EXP", 0x3e00, 3},
{"AGAIN", 0x3e08, 2},
{"DGAIN", 0x3e06, 2},
{"VMAX", 0x320e, 2},
{"R3301", 0x3301, 1},
{"R3314", 0x3314, 1},
{"R3632", 0x3632, 1},
{"HOLD", 0x3812, 1},
{"R5781", 0x5781, 1},
{"R5785", 0x5785, 1},
{NULL},
};
const Reg imx385_regs[] = {
{"SHS1", 0x3020, 3}, {"GAIN", 0x3014, 2},
{"HCG", 0x3009, 1}, {"SHS2", 0x3018, 3},
{"VMAX", 0x3018, 3}, {"RHS1", 0x302C, 3},
{"YOUT", 0x3357, 2}, {NULL},
};
/* Sony IMX291: 16-bit reg addr, 8-bit data, little-endian wide values.
* 0x3009 packs HCG (bit 4) and FRSEL (bits 3:0) -- watch this register
* to catch AE flipping HCG and clobbering DOL FRSEL on multi-byte writes.
* SHS1 is the only functional integration-time control on IMX291; SHS2
* (0x3024) and RHS1 (0x3030) are inherited from IMX290 silicon but
* non-functional, so they're not in this set. */
const Reg imx291_regs[] = {
{"HCG_FRSEL", 0x3009, 1},
{"GAIN", 0x3014, 1},
{"VMAX", 0x3018, 3},
{"HMAX", 0x301C, 2},
{"SHS1", 0x3020, 3},
{"OPORTSEL", 0x3046, 1},
{NULL},
};
struct {
const char *sns_name;
const Reg *reg;
uint8_t be;
} sns_regs[] = {
{"SC2315E", sc2315e_regs, .be = 1},
{"IMX291", imx291_regs, .be = 0},
{"IMX385", imx385_regs, .be = 0},
};
static int prepare_i2c_sensor(unsigned char i2c_addr) {
int fd = open_i2c_sensor_fd();
if (fd == -1) {
puts("Device not found");
exit(EXIT_FAILURE);
}
i2c_change_addr(fd, i2c_addr);
return fd;
}
static int prepare_spi_sensor() {
if (!open_spi_sensor_fd) {
puts("There is no platform specific SPI access layer");
exit(EXIT_FAILURE);
}
int fd = open_spi_sensor_fd();
if (fd == -1) {
puts("Device not found");
exit(EXIT_FAILURE);
}
return fd;
}
static read_register_t read_register;
static uint64_t readout_i2c_reg(int fd, sensor_ctx_t *ctx, const Reg *reg,
bool be) {
uint64_t value = 0;
for (int i = 0; i < reg->len; i++) {
value <<= 8;
unsigned int reg_addr = reg->base_addr;
if (be)
reg_addr += i;
else
reg_addr += reg->len - i - 1;
value |= read_register(fd, ctx->addr, reg_addr, ctx->reg_width,
ctx->data_width);
}
return value;
}
static int monitor_sensor(sensor_ctx_t *ctx, const Reg *reg, bool be) {
int fd = -1;
if (!strcmp(ctx->control, "i2c")) {
read_register = i2c_read_register;
fd = prepare_i2c_sensor(ctx->addr);
} else {
read_register = spi_read_register;
fd = prepare_spi_sensor();
}
while (1) {
const Reg *ptr = reg;
while (ptr->name) {
printf("%s\t%llx\t", ptr->name, readout_i2c_reg(fd, ctx, ptr, be));
ptr++;
}
printf("\n");
sleep(2);
}
return EXIT_SUCCESS;
}
static int monitor() {
sensor_ctx_t ctx;
if (!getsensorid(&ctx)) {
fprintf(stderr, "No sensor detected\n");
return EXIT_FAILURE;
}
for (size_t i = 0; i < ARRCNT(sns_regs); i++) {
if (!strcmp(sns_regs[i].sns_name, ctx.sensor_id))
return monitor_sensor(&ctx, sns_regs[i].reg, sns_regs[i].be);
}
fprintf(stderr, "Sensor %s is not supported\n", ctx.sensor_id);
return EXIT_FAILURE;
}
int snstool_cmd(int argc, char **argv) {
if (argc != 2) {
print_usage();
return EXIT_FAILURE;
}
return monitor();
}