Skip to content

Commit dce32fd

Browse files
committed
calibration via usb cdc
1 parent 786dc07 commit dce32fd

5 files changed

Lines changed: 444 additions & 20 deletions

File tree

Core/Src/board.cpp

Lines changed: 282 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,24 @@
44
* Created on: Dec 25, 2020
55
* Author: andrey
66
*/
7+
#include <ctype.h>
78
#include <stdarg.h>
89
#include "board.h"
910
#include "usbd_cdc_if.h"
1011
#include "spi1106.h"
12+
#include "settings.h"
1113

1214
extern I2C_HandleTypeDef hi2c1;
15+
extern USBD_HandleTypeDef hUsbDeviceFS;
1316

1417
static volatile bool i2c_tx_completed = false;
1518
static volatile bool i2c_rx_completed = false;
1619

20+
const uint32_t flash_settings_page = 0x0800F7C2;
21+
static settings current_settings;
22+
23+
const auto app_title = "TCS34725 PAR meter 1.1";
24+
1725
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
1826
{
1927
i2c_tx_completed = true;
@@ -81,14 +89,26 @@ uint32_t i2c_read_word(uint8_t reg)
8189
return (uint32_t)(res[1] << 8) + (uint32_t)res[0];
8290
}
8391

84-
char log_buf[256];
92+
const uint32_t log_buf_size = 512;
93+
char log_buf[log_buf_size];
8594

8695
void log(const char* format, ...)
8796
{
97+
auto hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
98+
if (hcdc == nullptr)
99+
{
100+
return;
101+
}
102+
88103
va_list args;
89104
va_start(args, format);
90-
int nn = vsnprintf(log_buf, 256, format, args);
105+
int nn = vsnprintf(log_buf, log_buf_size, format, args);
91106
va_end(args);
107+
108+
while (hcdc->TxState != 0)
109+
{
110+
HAL_Delay(1);
111+
}
92112
CDC_Transmit_FS((uint8_t*)log_buf, nn);
93113
}
94114

@@ -99,7 +119,7 @@ void read_par()
99119
auto green = i2c_read_word(0x18);
100120
auto blue = i2c_read_word(0x1a);
101121

102-
log("w:%d r:%d g:%d b:%d\n\r", white, red, green, blue);
122+
//log("w:%d r:%d g:%d b:%d\n\r", white, red, green, blue);
103123

104124
const uint32_t buf_size = 64;
105125
uint8_t y = 2;
@@ -117,40 +137,282 @@ void read_par()
117137
snprintf(buf, buf_size, "B %d ", (int)blue);
118138
sh1106SmallPrint(0, y++, (uint8_t *)buf);
119139

120-
double par = (double)white * (double)0.045067;
140+
double par = current_settings.m_total_factor * current_settings.calc_normalized_from_raw(white, red, green, blue);
141+
//double par = (double)white * (double)0.045067;
121142
int ipar = par;
122143
snprintf(buf, buf_size, "%d ", ipar);
123144
sh1106MediumPrint(0, y++, (uint8_t *)buf);
124145
}
125146

126-
void main_loop(void)
147+
void send_status()
127148
{
128-
sh1106Init (40,0x22,1);
129-
sh1106Clear(0,7);
130-
sh1106SmallPrint(0, 0, (uint8_t *) "TCS34725 PAR meter 1.0");
149+
log("\n\r\n\r%s build %s %s\n\r", app_title, __DATE__, __TIME__);
150+
151+
auto chip_id = i2c_read_register(0x12);
152+
log("chip id:%X\n\r", chip_id);
131153

132-
//sh1106MediumPrint(0,1,(uint8_t *) "Hi SH1106");
133-
//sh1106MediumPrint(0,3,(uint8_t *) "Hello SH1106");
154+
log("Integration time %x %lfms\n\r", current_settings.m_integration_time, current_settings.get_integration_time());
155+
log("Wait time %x %lfms\n\r", current_settings.m_wait_time, current_settings.get_wait_time());
156+
log("Gain %x x%lf\n\r", current_settings.m_gain, current_settings.get_gain());
157+
log("PAR = K[%lf] * W[%lf] * R[%lf] * G[%lf] * B[%lf]\n\r",
158+
current_settings.m_total_factor,
159+
current_settings.m_white,
160+
current_settings.m_red,
161+
current_settings.m_green,
162+
current_settings.m_blue);
163+
log("Usage:\n\r");
164+
log("k <value> - set K factor\n\r");
165+
log("w <value> - set W factor, 0..1\n\r");
166+
log("r <value> - set R factor, 0..1\n\r");
167+
log("g <value> - set G factor, 0..1\n\r");
168+
log("b <value> - set B factor, 0..1\n\r");
169+
log("int <value> - set integration time, 0..255\n\r");
170+
log("wait <value> - set wait time, 0..255\n\r");
171+
log("gain <value> - set gain, 0..3\n\r");
172+
log("def - reset to defaults\n\r");
173+
log("flash - write changes to flash\n\r");
174+
log("par <par value> <raw w> <raw r> <raw g> <raw b>\n\r");
175+
log(" - calculate K factor from measured PAR\n\r");
176+
}
134177

135-
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
136-
HAL_Delay(1000);
178+
const uint32_t cmd_buf_size = 512;
179+
char cmd_buf[cmd_buf_size];
180+
char current_cmd_buf[cmd_buf_size];
181+
uint32_t cmd_input_size = 0;
182+
char* current_cmd = nullptr;
137183

138-
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
139-
HAL_Delay(1000);
184+
void process_cdc_input(char c)
185+
{
186+
c = tolower(c);
140187

141-
CDC_Transmit_FS((uint8_t*)"TCS34725 PAR meter 1.0\n\r", 39);
188+
if (c == '\r')
189+
{
190+
cmd_buf[cmd_input_size] = 0;
142191

143-
auto chip_id = i2c_read_register(0x12);
144-
log("chip id:%X\n\r", chip_id);
192+
memcpy(current_cmd_buf, cmd_buf, cmd_input_size + 1);
193+
current_cmd = current_cmd_buf;
194+
195+
cmd_input_size = 0;
196+
}
197+
else if (c == '\b')
198+
{
199+
if (cmd_input_size > 0) cmd_input_size--;
200+
}
201+
else
202+
{
203+
cmd_buf[cmd_input_size] = c;
204+
cmd_input_size++;
205+
}
145206

207+
if (cmd_input_size >= cmd_buf_size)
208+
{
209+
cmd_input_size = 0;
210+
}
211+
}
212+
213+
void CDC_OnDataReceived(uint8_t* pbuf, uint32_t *Len)
214+
{
215+
CDC_Transmit_FS(pbuf, *Len);
216+
217+
for (uint32_t i = 0; i < *Len; i++)
218+
{
219+
process_cdc_input((char)pbuf[i]);
220+
}
221+
}
222+
223+
bool starts(const char* buf, const char* probe)
224+
{
225+
auto probe_len = strlen(probe);
226+
return strncmp(buf, probe, probe_len) == 0;
227+
}
228+
229+
bool factor_cmd(const char* buf, const char* probe, double* factor)
230+
{
231+
auto probe_len = strlen(probe);
232+
233+
if (strncmp(buf, probe, probe_len) != 0)
234+
{
235+
return false;
236+
}
237+
238+
double k = 0;
239+
if (sscanf(buf + probe_len, "%lf", &k) < 1)
240+
{
241+
log("\n\rerror\n\r");
242+
send_status();
243+
return true;
244+
}
245+
*factor = k;
246+
log("\n\rok\n\r");
247+
return true;
248+
}
249+
250+
void init_tcs()
251+
{
146252
i2c_write_register(0x00, 0x03);
147-
i2c_write_register(0x01, 0xf6);
148-
i2c_write_register(0x03, 0xf6);
149-
i2c_write_register(0x0f, 0x00);
253+
i2c_write_register(0x01, current_settings.m_integration_time);
254+
i2c_write_register(0x03, current_settings.m_wait_time);
255+
i2c_write_register(0x0f, current_settings.m_gain);
256+
}
150257

258+
bool reg_cmd(const char* buf, const char* probe, uint8_t* reg)
259+
{
260+
auto probe_len = strlen(probe);
261+
262+
if (strncmp(buf, probe, probe_len) != 0)
263+
{
264+
return false;
265+
}
266+
267+
unsigned int x = 0;
268+
if (sscanf(buf + probe_len, "%x", &x) < 1)
269+
{
270+
log("\n\rerror\n\r");
271+
send_status();
272+
return true;
273+
}
274+
*reg = (uint8_t)x;
275+
init_tcs();
276+
log("\n\rok\n\r");
277+
return true;
278+
}
279+
280+
bool flash_current_settings()
281+
{
282+
current_settings.make_valid();
283+
284+
HAL_FLASH_Unlock();
285+
286+
FLASH_EraseInitTypeDef erase_init;
287+
erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
288+
erase_init.Banks = 0;
289+
erase_init.PageAddress = flash_settings_page;
290+
erase_init.NbPages = 1;
291+
uint32_t error = 0;
292+
if (HAL_FLASHEx_Erase(&erase_init, &error) != HAL_OK)
293+
{
294+
while (HAL_FLASH_Lock() != HAL_OK) ;
295+
return false;
296+
}
297+
298+
FLASH_WaitForLastOperation(500);
299+
300+
auto data = reinterpret_cast<uint32_t*>(&current_settings);
301+
uint32_t flash_addr = flash_settings_page;
302+
uint32_t i = 0;
303+
while (i < sizeof(settings))
304+
{
305+
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, flash_addr, *data) != HAL_OK)
306+
{
307+
while (HAL_FLASH_Lock() != HAL_OK) ;
308+
return false;
309+
}
310+
data++;
311+
flash_addr += 4;
312+
i += 4;
313+
}
314+
HAL_FLASH_Lock();
315+
return true;
316+
}
317+
318+
void try_exec_received_command()
319+
{
320+
if (current_cmd == nullptr)
321+
{
322+
return;
323+
}
324+
325+
auto cmd = current_cmd;
326+
current_cmd = nullptr;
327+
328+
if (factor_cmd(cmd, "k ", &current_settings.m_total_factor)) return;
329+
if (factor_cmd(cmd, "w ", &current_settings.m_white)) return;
330+
if (factor_cmd(cmd, "r ", &current_settings.m_red)) return;
331+
if (factor_cmd(cmd, "g ", &current_settings.m_green)) return;
332+
if (factor_cmd(cmd, "b ", &current_settings.m_blue)) return;
333+
if (reg_cmd(cmd, "int ", &current_settings.m_integration_time)) return;
334+
if (reg_cmd(cmd, "wait ", &current_settings.m_wait_time)) return;
335+
if (reg_cmd(cmd, "gain ", &current_settings.m_gain)) return;
336+
337+
if (starts(cmd, "def"))
338+
{
339+
current_settings.set_default();
340+
init_tcs();
341+
log("\n\rok\n\r");
342+
return;
343+
}
344+
345+
if (starts(cmd, "flash"))
346+
{
347+
if (!flash_current_settings())
348+
{
349+
log("\n\rerror\n\r");
350+
}
351+
else
352+
{
353+
auto fl_settings = reinterpret_cast<settings*>(flash_settings_page);
354+
if (fl_settings->is_valid())
355+
{
356+
log("\n\rok\n\r");
357+
}
358+
else
359+
{
360+
log("\n\rerror\n\r");
361+
}
362+
}
363+
return;
364+
}
365+
366+
if (starts(cmd, "par "))
367+
{
368+
double par = 0;
369+
double w = 0;
370+
double r = 0;
371+
double g = 0;
372+
double b = 0;
373+
if (sscanf(cmd + 4, "%lf %lf %lf %lf %lf", &par, &w, &r, &g, &b) < 5)
374+
{
375+
log("\n\rerror\n\r");
376+
send_status();
377+
return;
378+
}
379+
380+
auto raw = current_settings.calc_normalized_from_raw((uint32_t)w, (uint32_t)r, (uint32_t)g, (uint32_t)b);
381+
if (raw == 0)
382+
{
383+
log("\n\rerror: bad raw values\n\r");
384+
return;
385+
}
386+
387+
current_settings.m_total_factor = par / raw;
388+
389+
log("\n\rok\n\r");
390+
return;
391+
}
392+
393+
send_status();
394+
}
395+
396+
void main_loop(void)
397+
{
398+
current_settings.set_default();
399+
400+
auto fl_settings = reinterpret_cast<settings*>(flash_settings_page);
401+
if (fl_settings->is_valid())
402+
{
403+
memcpy(&current_settings, fl_settings, sizeof(settings));
404+
}
405+
406+
sh1106Init (40,0x22,1);
407+
sh1106Clear(0,7);
408+
sh1106SmallPrint(0, 0, (uint8_t*)app_title);
409+
410+
init_tcs();
151411

152412
while (true)
153413
{
414+
try_exec_received_command();
415+
154416
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
155417
read_par();
156418

Core/Src/board.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#endif
1515

1616
void main_loop(void);
17+
void CDC_OnDataReceived(uint8_t* pbuf, uint32_t *Len);
1718

1819
#ifdef __cplusplus
1920
}

0 commit comments

Comments
 (0)