1
+ #include < cstdlib>
2
+ #include < math.h>
3
+ #include < map>
4
+ #include < vector>
5
+ #include < cstring>
6
+
7
+ #include " as7343.hpp"
8
+
9
+ namespace pimoroni {
10
+
11
+ bool AS7343::init () {
12
+ if (interrupt != PIN_UNUSED) {
13
+ gpio_set_function (interrupt, GPIO_FUNC_SIO);
14
+ gpio_set_dir (interrupt, GPIO_IN);
15
+ gpio_pull_up (interrupt);
16
+ }
17
+
18
+ uint8_t aux_id, revision_id, hardware_id;
19
+ get_version (aux_id, revision_id, hardware_id);
20
+
21
+ if (hardware_id != HARDWARE_ID) {
22
+ return false ;
23
+ }
24
+
25
+ reset ();
26
+
27
+ bank_select (0 );
28
+
29
+ // Enable all 7 channels in output FIFO
30
+ i2c->set_bits (address, reg::FIFO_MAP, 0 , FIFO_MAP_CH5 | FIFO_MAP_CH4 | FIFO_MAP_CH3 | FIFO_MAP_CH2 | FIFO_MAP_CH1 | FIFO_MAP_CH0 | FIFO_MAP_ASTATUS);
31
+
32
+ // Set the PON bit
33
+ i2c->reg_write_uint8 (address, reg::ENABLE, ENABLE_WEN | ENABLE_SMUXEN | ENABLE_SP_EN | ENABLE_PON);
34
+
35
+ return true ;
36
+ }
37
+
38
+ void AS7343::reset () {
39
+ i2c->reg_write_uint8 (address, reg::CONTROL, CONTROL_SW_RESET);
40
+ sleep_ms (1000 );
41
+ }
42
+
43
+ i2c_inst_t * AS7343::get_i2c () const {
44
+ return i2c->get_i2c ();
45
+ }
46
+
47
+ int AS7343::get_sda () const {
48
+ return i2c->get_sda ();
49
+ }
50
+
51
+ int AS7343::get_scl () const {
52
+ return i2c->get_scl ();
53
+ }
54
+
55
+ int AS7343::get_int () const {
56
+ return interrupt;
57
+ }
58
+
59
+ void AS7343::bank_select (uint8_t bank) {
60
+ if (bank == 1 ) {
61
+ i2c->set_bits (address, reg::CFG0, 0 , CFG0_BANK);
62
+ } else {
63
+ i2c->clear_bits (address, reg::CFG0, 0 , CFG0_BANK);
64
+ }
65
+ }
66
+
67
+ void AS7343::get_version (uint8_t &auxid, uint8_t &revid, uint8_t &hwid) {
68
+ bank_select (1 );
69
+ auxid = i2c->reg_read_uint8 (address, reg::AUXID) & 0b00001111 ;
70
+ revid = i2c->reg_read_uint8 (address, reg::REVID) & 0b00000111 ;
71
+ hwid = i2c->reg_read_uint8 (address, reg::ID);
72
+ bank_select (0 );
73
+ }
74
+
75
+ void AS7343::set_gain (float gain) {
76
+ if (gain == 0 .5f ) {
77
+ i2c->reg_write_uint8 (address, reg::CFG1, 0 );
78
+ } else {
79
+ uint16_t ugain = (uint16_t )gain;
80
+ uint16_t bitlength = 0 ;
81
+ while (ugain > 0 ) {
82
+ bitlength++;
83
+ ugain >>= 1 ;
84
+ }
85
+ i2c->reg_write_uint8 (address, reg::CFG1, bitlength & 0x1f );
86
+ }
87
+ }
88
+
89
+ void AS7343::set_channels (channel_count channel_count) {
90
+ this ->read_cycles = uint8_t (channel_count) / 6 ;
91
+ this ->ch_count = (uint8_t )channel_count;
92
+ uint8_t temp = i2c->reg_read_uint8 (address, reg::CFG20) & ~CFG20_18_CH;
93
+ switch (channel_count) {
94
+ case channel_count::SIX_CHANNEL:
95
+ temp |= CFG20_6_CH;
96
+ break ;
97
+ case channel_count::TWELVE_CHANNEL:
98
+ temp |= CFG20_12_CH;
99
+ break ;
100
+ case channel_count::EIGHTEEN_CHANNEL:
101
+ temp |= CFG20_18_CH;
102
+ break ;
103
+ }
104
+ i2c->reg_write_uint8 (address, reg::CFG20, temp);
105
+ }
106
+
107
+ void AS7343::set_illumination_current (float current) {
108
+ current -= 4 ;
109
+ current /= 2 .0f ;
110
+ uint8_t temp = i2c->reg_read_uint8 (address, reg::LED) & 0b10000000 ;
111
+ temp |= (uint8_t )current;
112
+ i2c->reg_write_uint8 (address, reg::LED, temp);
113
+ }
114
+
115
+ void AS7343::set_illumination_led (bool state) {
116
+ uint8_t temp = i2c->reg_read_uint8 (address, reg::LED) & 0b01111111 ;
117
+ temp |= state ? 0x80 : 0x00 ;
118
+ i2c->reg_write_uint8 (address, reg::LED, temp);
119
+ }
120
+
121
+ void AS7343::set_measurement_time (float measurement_time_ms) {
122
+ constexpr float resolution = 2 .78f ;
123
+ i2c->reg_write_uint8 (address, reg::WTIME, (uint8_t )((measurement_time_ms - resolution) / resolution));
124
+ }
125
+
126
+ void AS7343::set_integration_time (float integration_time_us, uint8_t repeat) {
127
+ constexpr float resolution = 2 .78f ;
128
+ constexpr float max_astep = (65534 + 1 ) * resolution;
129
+
130
+ if (integration_time_us <= max_astep) {
131
+ i2c->reg_write_uint8 (address, reg::ATIME, repeat - 1 );
132
+ i2c->reg_write_uint16 (address, reg::ASTEP, (uint16_t )((integration_time_us - resolution) / resolution) & 0xfffe );
133
+ } else {
134
+ // Time out of range...
135
+ }
136
+ }
137
+
138
+ void AS7343::read_fifo (uint16_t *buf) {
139
+ uint16_t expected_results = read_cycles * 7 ;
140
+ uint16_t result_slot = 0 ;
141
+
142
+ while (i2c->reg_read_uint8 (address, reg::FIFO_LVL) < expected_results) {
143
+ sleep_ms (1 );
144
+ }
145
+
146
+ while (i2c->reg_read_uint8 (address, reg::FIFO_LVL) > 0 && expected_results > 0 ) {
147
+ buf[result_slot] = i2c->reg_read_uint16 (address, reg::FDATA);
148
+ expected_results--;
149
+ result_slot++;
150
+ }
151
+ }
152
+
153
+ AS7343::reading AS7343::read () {
154
+ reading result;
155
+ read_fifo ((uint16_t *)&result);
156
+ return result;
157
+ }
158
+
159
+
160
+ }
0 commit comments