Set the POS interval to 240 seconds (255 would be the maximum.
[ruwai.git] / software / c++ / ruwaicom / src / root.cpp
blob94356e0953f5179f678acddd3455c5ca51f3864f
1 /*--------------------------------------------------------------------------*/
2 // LICENSE
3 //
4 // This file is part of ruwai.
5 //
6 // If you use ruwai_parser in any program or publication, please inform and
7 // acknowledge its author Stefan Mertl (stefan@mertl-research.at).
8 //
9 // ruwai is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 3 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 /*--------------------------------------------------------------------------*/
23 #include "root.h"
24 #include "log_temperature.h"
26 Root::Root(std::string config_file)
28 boost::property_tree::ptree pt;
29 double c1_gain, c2_gain, c3_gain, c4_gain;
30 int sps_raw;
32 display = new LCDDisplay(66, 67, 45, 23, 47, 27);
33 display->init();
34 display->clear();
35 display->home();
36 display->print("Hello, Ruwai", "is speaking.");
38 try {
39 boost::property_tree::ini_parser::read_ini(config_file, pt);
41 // ---------------------------------------------------------
42 // Parse the arduino stack section.
43 dev_name = pt.get<std::string>("arduino_stack.serial_port");
44 n_channels = pt.get<unsigned int>("arduino_stack.n_channels");
46 channel1_active = pt.get<bool>("arduino_stack.channel1_active");
47 channel2_active = pt.get<bool>("arduino_stack.channel2_active");
48 channel3_active = pt.get<bool>("arduino_stack.channel3_active");
49 channel4_active = pt.get<bool>("arduino_stack.channel4_active");
51 if (channel1_active)
53 record_channels.push_back(1);
56 if (channel2_active)
58 record_channels.push_back(2);
61 if (channel3_active)
63 record_channels.push_back(3);
66 if (channel4_active)
68 record_channels.push_back(4);
71 c1_gain = pt.get<double>("arduino_stack.channel1_pga");
72 channel1_gain = translate_pga_gain(c1_gain);
73 if (channel1_gain == PGA_GAIN_UNKNOWN)
75 syslog(LOG_ERR, "[ERROR][root] Unknown gain setting for channel 1: %f.", c1_gain);
76 std::exit(EXIT_FAILURE);
79 c2_gain = pt.get<double>("arduino_stack.channel2_pga");
80 channel2_gain = translate_pga_gain(c2_gain);
81 if (channel2_gain == PGA_GAIN_UNKNOWN)
83 syslog(LOG_ERR, "[ERROR][root] Unknown gain setting for channel 4: %f.", c2_gain);
84 std::exit(EXIT_FAILURE);
87 c3_gain = pt.get<double>("arduino_stack.channel3_pga");
88 channel3_gain = translate_pga_gain(c3_gain);
89 if (channel3_gain == PGA_GAIN_UNKNOWN)
91 syslog(LOG_ERR, "[ERROR][root] Unknown gain setting for channel 4: %f.", c3_gain);
92 std::exit(EXIT_FAILURE);
95 c4_gain = pt.get<double>("arduino_stack.channel4_pga");
96 channel4_gain = translate_pga_gain(c4_gain);
97 if (channel4_gain == PGA_GAIN_UNKNOWN)
99 syslog(LOG_ERR, "[ERROR][root] Unknown gain setting for channel 4: %f.", c4_gain);
100 std::exit(EXIT_FAILURE);
103 sps_raw = pt.get<uint16_t>("arduino_stack.sps");
104 sps = translate_adc_sps(sps_raw);
105 if (sps == ADC_SPS_UNKNOWN)
107 syslog(LOG_ERR, "[ERROR][root] Not supported sps setting: %d.", sps_raw);
108 std::exit(EXIT_FAILURE);
112 // ------------------------------------------------------------------------
113 // Parse the record section.
114 storage_mode = pt.get<std::string>("record.storage_mode");
115 tmp_dir = pt.get<std::string>("record.tmp_dir");
116 ruwai_serial_file = pt.get<std::string>("record.ruwai_serial_file");
117 file_length = pt.get<unsigned int>("record.file_length");
118 //record_channels = to_array<unsigned int>(pt.get<std::string>("record.record_channels"));
121 // ------------------------------------------------------------------------
122 // Parse the gps section.
123 gps_usb_active = pt.get<bool>("gps.usb_active");
126 // ------------------------------------------------------------------------
127 // Depending on the selected storage mode, parse the sd or hdd section.
128 if (storage_mode == "sd")
130 sd_dev_label = pt.get<std::string>("sd.dev_label");
131 sd_dev_1 = pt.get<std::string>("sd.dev_1");
132 sd_dev_2 = pt.get<std::string>("sd.dev_2");
133 sd_mnt_point = pt.get<std::string>("sd.mnt_point");
134 } else if (storage_mode == "hdd")
136 hdd_mseed_dir = pt.get<std::string>("hdd.mseed_dir");
139 // ------------------------------------------------------------------------
140 rts_start_server = pt.get<bool>("rt_server.start_server");
141 rts_port = pt.get<unsigned int>("rt_server.port");
142 rts_max_clients = pt.get<unsigned int>("rt_server.max_clients");
144 catch (const boost::property_tree::ptree_bad_path& e) {
145 syslog(LOG_ERR, "[ERROR][root] Couldn't read the config file %s. Error message: %s.", config_file.c_str(), e.what());
146 throw;
150 try {
151 //const std::string serial_filename = "/etc/ruwai_serial";
152 std::string line;
153 std::ifstream myfile(ruwai_serial_file);
154 if (myfile.is_open())
156 std::getline(myfile, line);
157 boost::trim_left(line);
158 boost::trim_right(line);
159 serial_number = line;
160 syslog(LOG_NOTICE, "[root] Ruwai serial number: %s.", serial_number.c_str());
161 myfile.close();
163 else
165 syslog(LOG_ERR, "[ERROR][root] Unable to open the file %s to read the serial number.", ruwai_serial_file.c_str());
166 std::exit(EXIT_FAILURE);
169 catch (...) {
170 syslog(LOG_ERR, "[ERROR][root] Couldn't read the serial number from %s. Unknown error.", ruwai_serial_file.c_str());
171 throw;
175 std::string rec_channels_string = "";
176 for (unsigned int k = 0; k < record_channels.size(); k++)
178 rec_channels_string += std::to_string(record_channels[k]);
180 if (k < record_channels.size() - 1)
182 rec_channels_string += ",";
186 syslog(LOG_NOTICE, "------- read configuration --------");
187 syslog(LOG_NOTICE, "arduino_stack");
188 syslog(LOG_NOTICE, "serial_port: %s", dev_name.c_str());
189 syslog(LOG_NOTICE, "n_channels: %d", n_channels);
190 syslog(LOG_NOTICE, "channel1_active: %d", channel1_active);
191 syslog(LOG_NOTICE, "channel2_active: %d", channel2_active);
192 syslog(LOG_NOTICE, "channel3_active: %d", channel3_active);
193 syslog(LOG_NOTICE, "channel4_active: %d", channel4_active);
194 syslog(LOG_NOTICE, "channel1_gain: %.3f (%d)", c1_gain, channel1_gain);
195 syslog(LOG_NOTICE, "channel2_gain: %.3f (%d)", c2_gain, channel2_gain);
196 syslog(LOG_NOTICE, "channel3_gain: %.3f (%d)", c3_gain, channel3_gain);
197 syslog(LOG_NOTICE, "channel4_gain: %.3f (%d)", c4_gain, channel4_gain);
198 syslog(LOG_NOTICE, "sps: %d (%d)", sps_raw, sps);
199 syslog(LOG_NOTICE, "record");
200 syslog(LOG_NOTICE, "storage_mode: %s", storage_mode.c_str());
201 syslog(LOG_NOTICE, "tmp_dir: %s", tmp_dir.c_str());
202 syslog(LOG_NOTICE, "record_channels: %s", rec_channels_string.c_str());
203 syslog(LOG_NOTICE, "file_length: %d", file_length);
204 if (storage_mode == "sd")
206 syslog(LOG_NOTICE, "sd");
207 syslog(LOG_NOTICE, "dev_label: %s", sd_dev_label.c_str());
208 syslog(LOG_NOTICE, "dev_1: %s", sd_dev_1.c_str());
209 syslog(LOG_NOTICE, "dev_2: %s", sd_dev_2.c_str());
210 syslog(LOG_NOTICE, "mnt_point: %s", sd_mnt_point.c_str());
211 } else if (storage_mode == "hdd")
213 syslog(LOG_NOTICE, "hdd");
214 syslog(LOG_NOTICE, "mseed_dir: %s", hdd_mseed_dir.c_str());
216 syslog(LOG_NOTICE, "gps");
217 syslog(LOG_NOTICE, "usb_active: %d", gps_usb_active);
218 syslog(LOG_NOTICE, "rt_server");
219 syslog(LOG_NOTICE, "start_server: %d", rts_start_server);
220 syslog(LOG_NOTICE, "port: %d", rts_port);
221 syslog(LOG_NOTICE, "max_clients: %d", rts_max_clients);
222 syslog(LOG_NOTICE, "-----------------------------------");
224 // Create the temporary data directory.
225 if (!boost::filesystem::exists(tmp_dir))
227 if (!boost::filesystem::create_directory(tmp_dir))
229 syslog(LOG_ERR, "[ERROR][root] Can't create the tmp_dir: %s. This is mandatory. Exiting.", tmp_dir.c_str());
230 std::exit(EXIT_FAILURE);
234 std::string mseed_dir;
235 if (storage_mode == "sd")
236 mseed_dir = sd_mnt_point;
237 else if (storage_mode == "hdd")
238 mseed_dir = hdd_mseed_dir;
239 recorder = new Recorder(serial_number, n_channels, record_channels, sps, mseed_dir, tmp_dir, file_length);
240 rt_server = new RealTimeServer(rts_port, rts_max_clients);
244 bool
245 Root::ready(void)
247 bool is_ready = true;
249 // Check the output directory structure. If it doesn't exist, it's created.
250 if(!recorder->check_output_dir_structure())
252 syslog(LOG_ERR, "[ERROR][root] The output directory structure couldn't be created. Can't start the recorder.");
253 is_ready = false;
256 if (storage_mode == "sd" && !is_sd_mounted())
258 is_ready = false;
261 return is_ready;
264 bool
265 Root::is_sd_dev_available(void)
267 bool dev_available = false;
268 struct stat sb;
270 if (stat(sd_dev_label.c_str(), &sb) != -1)
272 switch (sb.st_mode & S_IFMT) {
273 case S_IFBLK:
274 syslog(LOG_NOTICE, "[root] SD card block device found at %s.", sd_dev_label.c_str());
275 dev_available = true;
276 break;
277 default:
278 syslog(LOG_ERR, "[ERROR][root] SD card device file %s is not a block device.", sd_dev_label.c_str());
279 break;
282 else
284 syslog(LOG_WARNING, "[WARNING][root] SD card block device file %s not found.", sd_dev_label.c_str());
287 return dev_available;
290 bool
291 Root::is_sd_mounted(void)
293 FILE *mtab = NULL;
294 struct mntent *part = NULL;
295 bool is_mounted = false;
297 if ((mtab = setmntent("/etc/mtab", "r")) != NULL)
299 while ((part = getmntent(mtab)) != NULL)
301 if((part->mnt_fsname != NULL) && ((strcmp(part->mnt_fsname, sd_dev_1.c_str())) == 0 || (strcmp(part->mnt_fsname, sd_dev_2.c_str())) == 0) && (strcmp(part->mnt_dir, sd_mnt_point.c_str()) == 0) )
303 is_mounted = true;
307 endmntent(mtab);
308 if (is_mounted)
310 syslog(LOG_NOTICE, "[root] The SD card is correctly mounted at %s.", sd_mnt_point.c_str());
312 else
314 syslog(LOG_WARNING, "[WARNING][root] The SD card is NOT mounted. Couldn't find an entry for %s or %s mounted at %s in /etc/mtab.", sd_dev_1.c_str(), sd_dev_2.c_str(), sd_mnt_point.c_str());
316 return is_mounted;
320 bool
321 Root::mount_sd(void)
323 bool mount_success = false;
324 int ret_val = -1;
326 // TODO: Use the mount function instead of calling mount using the system
327 // command. Using the mount function didn't work because of missing
328 // permissions when running as a normal user. Also the mtab entry is not
329 // written automatically. I think I would have to add an entry to mtab.
330 //ret_val = mount(sd_dev_label.c_str(), sd_mnt_point.c_str(), "ext4", MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL);
332 std::string cmd = "mount " + sd_mnt_point;
333 ret_val = system(cmd.c_str());
335 if (ret_val == 0)
337 syslog(LOG_NOTICE, "[root] Successfully mounted the sd card on %s.", sd_mnt_point.c_str());
338 mount_success = true;
340 else
342 syslog(LOG_ERR, "[ERROR][root] Troubles when mounting the SD card: %s.", strerror(errno));
344 return mount_success;
348 void
349 Root::run(void)
351 bool port_open = false;
352 bool config_confirmed = false;
353 int max_try = 10;
355 display->print("Starting...", "");
357 // Start the temperature logging thread.
358 syslog(LOG_NOTICE, "[root] Starting the temperature logging thread.");
359 std::thread t_temp_log(log_temperature);
360 t_temp_log.detach();
362 // Check the output directory structure. If it doesn't exist, it's created.
363 if(!recorder->check_output_dir_structure())
365 syslog(LOG_ERR, "[ERROR][root] The output directory structure couldn't be created. Can't start the recorder.");
367 else
369 port_open = open_port();
371 if (port_open)
373 bool success;
374 // Test the chrono measurement.
376 syslog(LOG_DEBUG, "Testing the chrono measurement with usleep(1000).");
377 auto start = std::chrono::high_resolution_clock::now();
378 usleep(1000);
379 auto end = std::chrono::high_resolution_clock::now();
380 auto diff = end - start;
381 syslog(LOG_DEBUG, "Measured time: %d nanoseconds", (int)std::chrono::duration_cast<std::chrono::nanoseconds>(diff).count());
384 // Start the real time server if activated.
385 if (rts_start_server)
387 syslog(LOG_NOTICE, "[root] Starting the realtime server thread.");
388 std::thread t_rts([&] (RealTimeServer* rt_server) {rt_server->start_listen();}, rt_server);
389 t_rts.detach();
392 configure_port();
393 parser = new SerialParser(serial_port, recorder);
394 std::thread t_read_and_parse([&] (SerialParser* parser) {parser->read_and_parse();}, parser);
396 // Wait for handshaking.
397 display->print("Handshaking...", "");
398 syslog(LOG_NOTICE, "[root] Handshaking with Arduino stack....");
399 max_try = 10;
400 for (int k = 0; k < max_try; k++)
402 syslog(LOG_NOTICE, "[root] Waiting for handshake with Arduino stack...");
403 parser->start_handshake();
404 usleep(1000000);
405 if (parser->is_synced())
407 break;
410 if (!parser->is_synced())
412 syslog(LOG_ERR, "[ERROR][root] ...tried handshake for %d times. Got no answer. Giving up.", max_try);
413 std::exit(EXIT_FAILURE);
415 else
417 syslog(LOG_NOTICE, "[root] ...handshake was successful.");
421 display->print("Configuring...", "");
422 syslog(LOG_NOTICE, "[root] Setting the Arduino stack to control mode.");
423 success = parser->set_control_mode();
424 if (success)
426 syslog(LOG_NOTICE, "[root] Confirmed control mode configuration by the Arduino stack.");
428 else
430 syslog(LOG_ERR, "[ERROR][root] No confirmation of the control mode configuration.");
433 // Configure the Arduino stack.
434 // TODO: Restart the configuration if no confirmation was received.
435 syslog(LOG_NOTICE, "[root] Configuring the Arduino stack....");
436 max_try = 10;
437 for (int k = 0; k < max_try; k++)
439 config_confirmed = true;
440 syslog(LOG_NOTICE, "[root] Setting the sps to %d.", sps);
441 success = parser->set_sps((uint16_t)sps);
442 if (success)
444 syslog(LOG_NOTICE, "[root] Confirmed sps configuration by the Arduino stack.");
446 else
448 syslog(LOG_ERR, "[ERROR][root] No confirmation of the sps configuration. Start again.");
449 config_confirmed = false;
450 continue;
453 syslog(LOG_NOTICE, "[root] Activating the channels.");
454 success = parser->set_channels(channel1_active, channel2_active, channel3_active, channel4_active, channel1_gain, channel2_gain, channel3_gain, channel4_gain);
455 if (success)
457 syslog(LOG_NOTICE, "[root] Confirmed channel configuration by the Arduino stack.");
459 else
461 syslog(LOG_ERR, "[ERROR][root] No confirmation of the channel configuration. Start again.");
462 config_confirmed = false;
463 continue;
466 syslog(LOG_NOTICE, "[root] Sending the GPS configuration.");
467 success = parser->set_gps(gps_usb_active);
468 if (success)
470 syslog(LOG_NOTICE, "[root] Confirmed gps configuration by the Arduino stack.");
472 else
474 syslog(LOG_ERR, "[ERROR][root] No confirmation of the gps configuration. Start again.");
475 config_confirmed = false;
476 continue;
480 if (config_confirmed)
482 break;
486 if (!config_confirmed)
488 syslog(LOG_ERR, "[ERROR][root] Couldn't configure the Arduino Stack. Tried it %d times.", max_try);
489 std::exit(EXIT_FAILURE);
492 syslog(LOG_NOTICE, "[root] Stack configured successfully.");
494 syslog(LOG_NOTICE, "[root] Set to record mode.");
495 success = parser->set_record_mode();
496 if (success)
498 syslog(LOG_NOTICE, "[root] Confirmed record mode configuration by the Arduino stack.");
499 display->print("Recording...", "");
501 else
503 syslog(LOG_ERR, "[ERROR][root] No confirmation of the record mode configuration.");
506 //std::thread t_lcd_status([&] (Root* this) {this->lcd_status();}, this);
507 std::thread t_lcd_status(&Root::lcd_status, this);
509 t_read_and_parse.join();
511 // Close the serial port.
512 close_port();
518 bool
519 Root::open_port(void)
521 serial_port = open(dev_name.c_str(), O_RDWR | O_NOCTTY );
522 if(serial_port == -1)
524 // Couldn't open the serial port.
525 syslog(LOG_ERR, "[ERROR][root] Unable to open the Arduino stack serial port %s", dev_name.c_str());
526 return false;
528 else
530 //fcntl(serial_port, F_SETFL, 0);
531 syslog(LOG_NOTICE, "[root] Serial port %s to Arduino stack opened.", dev_name.c_str());
532 return true;
536 void
537 Root::close_port(void)
539 close(serial_port);
543 void
544 Root::configure_port(void)
546 struct termios port_options; // struct to hold the port settings
548 // Fetch the current port settings
549 tcgetattr(serial_port, &port_options);
551 // Flush the port's buffers (in and out) before we start using it
552 tcflush(serial_port, TCIOFLUSH);
554 // Input flags - Turn off input processing
556 // convert break to null byte, no CR to NL translation,
557 // no NL to CR translation, don't mark parity errors or breaks
558 // no input parity check, don't strip high bit off,
559 // no XON/XOFF software flow control
561 // port_options.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
562 // INLCR | PARMRK | INPCK | ISTRIP | IXON);
563 port_options.c_iflag = 0;
565 // Output flags - Turn off output processing
567 // no CR to NL translation, no NL to CR-NL translation,
568 // no NL to CR translation, no column 0 CR suppression,
569 // no Ctrl-D suppression, no fill characters, no case mapping,
570 // no local output processing
572 // port_options.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
573 // ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
574 port_options.c_oflag = 0;
576 // Turn off line processing
578 // echo off, echo newline off, canonical mode on,
579 // extended input processing off, signal chars off
580 // port_options.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
582 // In non-blocking mode, the infinite loop in the serial parser causes a
583 // large CPU load which significantly increases the power consumption of
584 // the BBB.
585 port_options.c_lflag = 0;
586 port_options.c_lflag &= ~ICANON; // Set to non-canonical (blocking) mode.
587 port_options.c_cc[VMIN] = 0; // Minimum number of bytes read.
588 port_options.c_cc[VTIME] = 10; // timeout in deci-seconds
590 // Set the input and output baud rates
591 cfsetispeed(&port_options, B1000000);
592 cfsetospeed(&port_options, B1000000);
593 //cfsetispeed(&port_options, B500000);
594 //cfsetospeed(&port_options, B500000);
595 //cfsetispeed(&port_options, B1152000);
596 //cfsetospeed(&port_options, B1152000);
598 // c_cflag contains a few important things- CLOCAL and CREAD, to prevent
599 // this program from "owning" the port and to enable receipt of data.
600 // Also, it holds the settings for number of data bits, parity, stop bits,
601 // and hardware flow control.
602 port_options.c_cflag |= CLOCAL;
603 port_options.c_cflag |= CREAD;
604 // Set up the frame information.
605 port_options.c_cflag &= ~CSIZE; // clear frame size info
606 port_options.c_cflag |= CS8; // 8 bit frames
607 port_options.c_cflag &= ~PARENB;// no parity
608 port_options.c_cflag &= ~CSTOPB;// one stop bit
610 // Now that we've populated our options structure, let's push it back to the
611 // system.
612 tcsetattr(serial_port, TCSANOW, &port_options);
614 syslog(LOG_DEBUG, "Configured the serial port:");
615 syslog(LOG_DEBUG, "port_options.c_cflag: %d - %s", port_options.c_cflag, std::bitset<16>(port_options.c_cflag).to_string().c_str());
616 syslog(LOG_DEBUG, "port_options.c_iflag: %d - %s", port_options.c_iflag, std::bitset<16>(port_options.c_iflag).to_string().c_str());
617 syslog(LOG_DEBUG, "port_options.c_oflag: %d - %s", port_options.c_oflag, std::bitset<16>(port_options.c_oflag).to_string().c_str());
618 syslog(LOG_DEBUG, "port_options.c_lflag: %d - %s", port_options.c_lflag, std::bitset<16>(port_options.c_lflag).to_string().c_str());
620 // Flush the buffer one more time.
621 tcflush(serial_port, TCIOFLUSH);
623 //fcntl(serial_port, F_SETFL, 0);
627 void
628 Root::clear_tmp_dir(void)
630 // Check for forgotten files in the tmp directory.
631 syslog(LOG_NOTICE, "[root] Cleaning the tmp directory.");
633 std::vector<std::string> file_list;
634 boost::filesystem::path search_dir(tmp_dir);
635 boost::filesystem::directory_iterator end_itr;
637 if (boost::filesystem::exists(search_dir) && boost::filesystem::is_directory(search_dir))
639 for (boost::filesystem::directory_iterator dir_itr(search_dir); dir_itr != end_itr; dir_itr++)
641 //syslog(LOG_NOTICE, "Moving file %s from tmp directory to mseed_dir.", dir_itr->path().filename().string().c_str());
642 file_list.push_back(dir_itr->path().filename().string());
646 if (file_list.size() == 0)
648 syslog(LOG_NOTICE, "[root] No data files found in the tmp directory: %s.", search_dir.c_str());
650 else
652 recorder->copy_files(file_list);
658 pga_gain_t
659 Root::translate_pga_gain(double gain)
661 pga_gain_t ret = PGA_GAIN_UNKNOWN;
662 if (gain == 0.125 || gain == 0.172 || gain == 0.25 || gain == 0.344 || \
663 gain == 0.5 || gain == 0.688 || gain == 1 || gain == 1.375 || \
664 gain == 2 || gain == 2.75 || gain == 4 || gain == 5.5 || gain == 8 || \
665 gain == 11 || gain == 16 || gain == 22 || gain == 32 || gain == 44 || \
666 gain == 64 || gain == 88 || gain == 128 || gain == 176)
668 ret = (pga_gain_t) gain;
670 return ret;
675 pga_gain_t
676 Root::translate_pga_gain(double gain)
678 pga_gain_t ret = PGA_GAIN_UNKNOWN;
679 if (gain == 0.125)
680 ret = PGA_GAIN_0_125;
681 else if (gain == 0.172)
682 ret = PGA_GAIN_0_172;
683 else if (gain == 0.25)
684 ret = PGA_GAIN_0_25;
685 else if (gain == 0.344)
686 ret = PGA_GAIN_0_344;
687 else if (gain == 0.5)
688 ret = PGA_GAIN_0_5;
689 else if (gain == 0.688)
690 ret = PGA_GAIN_0_688;
691 else if (gain == 1)
692 ret = PGA_GAIN_1;
693 else if (gain == 1.375)
694 ret = PGA_GAIN_1_375;
695 else if (gain == 2)
696 ret = PGA_GAIN_2;
697 else if (gain == 2.75)
698 ret = PGA_GAIN_2_75;
699 else if (gain == 4)
700 ret = PGA_GAIN_4;
701 else if (gain == 5.5)
702 ret = PGA_GAIN_5_5;
703 else if (gain == 8)
704 ret = PGA_GAIN_8;
705 else if (gain == 11)
706 ret = PGA_GAIN_11;
707 else if (gain == 16)
708 ret = PGA_GAIN_16;
709 else if (gain == 22)
710 ret = PGA_GAIN_22;
711 else if (gain == 32)
712 ret = PGA_GAIN_32;
713 else if (gain == 44)
714 ret = PGA_GAIN_44;
715 else if (gain == 64)
716 ret = PGA_GAIN_64;
717 else if (gain == 88)
718 ret = PGA_GAIN_88;
719 else if (gain == 128)
720 ret = PGA_GAIN_128;
721 else if (gain == 176)
722 ret = PGA_GAIN_176;
724 return ret;
729 adc_sps_t
730 Root::translate_adc_sps(uint16_t sps)
732 adc_sps_t ret = ADC_SPS_UNKNOWN;
733 if (sps == 100 || sps == 200 || sps == 400 || sps == 500 || \
734 sps == 800 )
736 ret = (adc_sps_t) sps;
738 return ret;
742 void
743 Root::lcd_status(void)
745 char c_time_string[27];
746 std::string time_string;
747 timestamp_t last_timestamp;
749 while (true)
751 std::stringstream stream;
752 std::string msg1;
753 std::string msg2;
755 last_timestamp = recorder->get_last_timestamp();
756 ms_hptime2isotimestr(last_timestamp.time, c_time_string, true);
757 time_string = std::string(c_time_string);
758 display->print(time_string.substr(0, 10), time_string.substr(11));
759 std::this_thread::sleep_for(std::chrono::seconds(5));
762 stream << "GPS F:" << last_timestamp.gps_fix << " OK:" << last_timestamp.gps_fix_ok;
763 msg1 = stream.str();
764 stream.str("");
765 stream << "SLTS:" << last_timestamp.sec_slts;
766 msg2 = stream.str();
767 display->print(msg1, msg2);
768 std::this_thread::sleep_for(std::chrono::seconds(5));
771 std::vector<int> tmp_file_size(recorder->tmp_file_size);
772 stream.str("");
773 stream << "Recording";
774 msg1 = stream.str();
776 stream.str("");
777 stream << tmp_file_size.size() << " files";
778 msg2 = stream.str();
779 display->print(msg1, msg2);
780 std::this_thread::sleep_for(std::chrono::seconds(2));
783 for (unsigned int k = 0; k < tmp_file_size.size(); k++)
785 stream.str("");
786 stream << "Size file " << k + 1;
787 msg1 = stream.str();
789 stream.str("");
790 stream << recorder->tmp_file_size[k] << " kB";
791 msg2 = stream.str();
792 display->print(msg1, msg2);
793 std::this_thread::sleep_for(std::chrono::seconds(2));
796 /* TODO: Getting the file size is blocking the program somehow.
797 std::string tmp_dir = recorder->get_tmp_dir();
798 std::vector<std::string> rec_files = get_file_list(tmp_dir);
799 std::sort(rec_files.begin(), rec_files.end());
800 stream.str("");
801 stream << rec_files.size() << " files";
802 msg1 = stream.str();
804 stream.str("");
805 for (std::vector<std::string>::iterator it = rec_files.begin(); it != rec_files.end(); it++)
807 std::string file_path = tmp_dir + "/" + *it;
808 stream << boost::filesystem::file_size(file_path) / 1024 << "; ";
810 msg2 = stream.str();
811 stream.str("");
816 std::vector<std::string>
817 Root::get_file_list(const std::string path)
819 std::vector<std::string> m_file_list;
820 if (!path.empty())
822 boost::filesystem::path apk_path(path);
824 for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(apk_path), {}))
826 m_file_list.push_back(entry.path().string());
829 return m_file_list;