/* * DDdefs.cpp * * Created on: Dec 19, 2025 * Author: Arpita Srivastava */ #include #include #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif static bool auto_publish_flag = false; // If set to true, start auto publishing adc.temp and raw_cond static uint8_t error_flag = 0; // If set to 1, it means some error occurred. static void tx_cal_bin(void); // Helper function to transmit calibration data in binary format static void tx_version_bin(void); // Helper function to transmit version info in binary format /** * @brief Retrieves the current error flag value. * * @return uint8_t Current value of the error flag. */ uint8_t get_error_flag(void) { return error_flag; } /** * @brief Sets the error flag to indicate an error condition. */ void set_error_flag(void) { error_flag = 1; } /** * @brief Clears the error flag to indicate no error condition. */ void clear_error_flag(void) { error_flag = 0; } /** * @brief Checks whether automatic publishing is enabled. * * @return true Automatic publishing is enabled. * @return false Automatic publishing is disabled. */ bool is_auto_publish_enbld(void) { return auto_publish_flag; } /** * @brief Enables automatic publishing. * * Sets the internal flag to start automatic publishing. */ void start_auto_publishing(void) { auto_publish_flag = true; } /** * @brief Disables automatic publishing. * * Clears the internal flag to stop automatic publishing. */ void stop_auto_publishing(void) { auto_publish_flag = false; } /** * @brief Publishes ADC data when auto-publish is enabled. * * @param[in] argc Argument count (unused). * @param[in] argv Argument vector (unused). * * @return Always returns 0. */ int auto_publish(int argc, char *argv[]) { if(true == auto_publish_flag) { AutoPollStruct auto_poll_data; float raw_cond = 0; adc_file adc; rewind(p_adc); fread(&adc, sizeof(adc_file), 1, p_adc); raw_cond = ((adc.p_curt - adc.n_curt) / (adc.p_volt - adc.n_volt)); auto_poll_data.cond_data.raw_cond = raw_cond; auto_poll_data.cond_data.read_count = (uint8_t)(adc.adc0_hit & 0xFF); auto_poll_data.cond_data.error = get_error_flag(); auto_poll_data.temp_data.raw_temp = adc.temp; auto_poll_data.temp_data.read_count = (uint8_t)(adc.adc1_hit & 0xFF); auto_poll_data.temp_data.error = get_error_flag(); // Send data write(STDOUT_FILENO, &auto_poll_data, sizeof(auto_poll_data)); } return 0; } /** * @brief UART command "b": start binary auto-polling. * * Enables automatic publishing and writes operation status to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_start_poll_bin(int argc, char *argv[]) { setStatus status = SET_STATUS_ERROR; if (argc != 1) { // Send error message fwrite(&status, sizeof(status), 1, stdout); } else { start_auto_publishing(); } fflush(stdout); return 0; } /** * @brief UART command "e": stop binary auto-polling. * * Disables automatic publishing and writes operation status to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_stop_poll_bin(int argc, char *argv[]) { setStatus status = SET_STATUS_ERROR; if (argc != 1) { // Send error message fwrite(&status, sizeof(status), 1, stdout); } else { stop_auto_publishing(); } fflush(stdout); return 0; } /** * @brief UART command "getraw": transmit raw ADC readings (text). * * Prints p/n current, p/n voltage, temperature, and computed raw conductivity. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_tx_raw_poll(int argc, char *argv[]) { if (argc != 1) { printf("%s: syntax error, please use the following syntax: %s\n\n", argv[0], argv[0]); } else { adc_file adc; rewind(p_adc); fread(&adc, sizeof(adc_file), 1, p_adc); printf("+Ip-p: %eA\n", adc.p_curt); printf("-Ip-p: %eA\n", adc.n_curt); printf("+Vp-p: %eV\n", adc.p_volt); printf("-Vp-p: %eV\n", adc.n_volt); printf("TEMP: %f'C\n", adc.temp); float raw_conductivity = ((adc.p_curt - adc.n_curt) / (adc.p_volt - adc.n_volt)); printf("Raw conductivity: %eS/cm\n\n", raw_conductivity); } fflush(stdout); return 0; } /** * @brief UART command "setcal1": receive and store calibration coefficient 1 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 1 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal1(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff1) coeff1 = constant; fseek(p_cal, (int) (&p_cal_file->coeff1) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff1, sizeof(cal_file::coeff1), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 1 is set to: %fV\n\n", argv[0], cal_var.coeff1); } else { // Value out of range printf("%s: Error, coefficient 1 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "setcal2": receive and store calibration coefficient 2 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 2 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal2(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff2) coeff2 = constant; fseek(p_cal, (int) (&p_cal_file->coeff2) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff2, sizeof(cal_file::coeff2), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 2 is set to: %fV\n\n", argv[0], cal_var.coeff2); } else { // Value out of range printf("%s: Error, coefficient 2 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "setcal3": receive and store calibration coefficient 3 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 3 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal3(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff3) coeff3 = constant; fseek(p_cal, (int) (&p_cal_file->coeff3) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff3, sizeof(cal_file::coeff3), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 3 is set to: %fV\n\n", argv[0], cal_var.coeff3); } else { // Value out of range printf("%s: Error, coefficient 3 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "setcal4": receive and store calibration coefficient 4 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 4 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal4(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff4) coeff4 = constant; fseek(p_cal, (int) (&p_cal_file->coeff4) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff4, sizeof(cal_file::coeff4), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 4 is set to: %fV\n\n", argv[0], cal_var.coeff4); } else { // Value out of range printf("%s: Error, coefficient 4 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "setcal5": receive and store calibration coefficient 5 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 5 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal5(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff5) coeff5 = constant; fseek(p_cal, (int) (&p_cal_file->coeff5) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff5, sizeof(cal_file::coeff5), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 5 is set to: %fV\n\n", argv[0], cal_var.coeff5); } else { // Value out of range printf("%s: Error, coefficient 5 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "setcal6": receive and store calibration coefficient 6 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 6 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal6(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff6) coeff6 = constant; fseek(p_cal, (int) (&p_cal_file->coeff6) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff6, sizeof(cal_file::coeff6), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 6 is set to: %fV\n\n", argv[0], cal_var.coeff6); } else { // Value out of range printf("%s: Error, coefficient 6 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "setcal7": receive and store calibration coefficient 7 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 7 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal7(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff7) coeff7 = constant; fseek(p_cal, (int) (&p_cal_file->coeff7) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff7, sizeof(cal_file::coeff7), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 7 is set to: %fV\n\n", argv[0], cal_var.coeff7); } else { // Value out of range printf("%s: Error, coefficient 7 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "setcal8": receive and store calibration coefficient 8 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 8 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal8(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff8) coeff8 = constant; fseek(p_cal, (int) (&p_cal_file->coeff8) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff8, sizeof(cal_file::coeff8), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 8 is set to: %fV\n\n", argv[0], cal_var.coeff8); } else { // Value out of range printf("%s: Error, coefficient 8 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "setcal9": receive and store calibration coefficient 9 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 9 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal9(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff9) coeff9 = constant; fseek(p_cal, (int) (&p_cal_file->coeff9) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff9, sizeof(cal_file::coeff9), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 9 is set to: %fV\n\n", argv[0], cal_var.coeff9); } else { // Value out of range printf("%s: Error, coefficient 9 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "setcal10": receive and store calibration coefficient 10 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 10 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal10(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff10) coeff10 = constant; fseek(p_cal, (int) (&p_cal_file->coeff10) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff10, sizeof(cal_file::coeff10), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 10 is set to: %fV\n\n", argv[0], cal_var.coeff10); } else { // Value out of range printf("%s: Error, coefficient 10 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "setcal11": receive and store calibration coefficient 11 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 11 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal11(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff11) coeff11 = constant; fseek(p_cal, (int) (&p_cal_file->coeff11) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff11, sizeof(cal_file::coeff11), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 11 is set to: %fV\n\n", argv[0], cal_var.coeff11); } else { // Value out of range printf("%s: Error, coefficient 11 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "setcal12": receive and store calibration coefficient 12 (text mode). * * Parses the coefficient value from the UART command, validates its range, * stores coefficient 12 in the calibration file, and prints the result or * an error message to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_cal12(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { float constant = -1; sscanf(argv[1], "%f", &constant); if (constant <= MAX_COEFF && constant >= MIN_COEFF) { cal_file cal_var; cal_file * p_cal_file = &cal_var; decltype(p_cal_file->coeff12) coeff12 = constant; fseek(p_cal, (int) (&p_cal_file->coeff12) - (int) (p_cal_file), SEEK_SET); fwrite(&coeff12, sizeof(cal_file::coeff12), 1, p_cal); fflush(p_cal); // Coefficient set successfully printf("%s: Coefficient 12 is set to: %fV\n\n", argv[0], cal_var.coeff12); } else { // Value out of range printf("%s: Error, coefficient 12 input: %s is not in range: %f~%f\n\n", argv[0], argv[1], MIN_COEFF, MAX_COEFF); } } fflush(stdout); return 0; } /** * @brief UART command "getcal": transmit calibration data in text format. * * Reads all calibration coefficients from persistent storage and prints them * to STDOUT in human-readable form. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_tx_cal_data(int argc, char *argv[]) { if (argc != 1) { printf("%s: syntax error, please use the following syntax: %s\n\n", argv[0], argv[0]); } else { cal_file cal; rewind(p_cal); fread(&cal, sizeof(cal_file), 1, p_cal); printf("Coeff_1: %f\n", cal.coeff1); printf("Coeff_2: %f\n", cal.coeff2); printf("Coeff_3: %f\n", cal.coeff3); printf("Coeff_4: %f\n", cal.coeff4); printf("Coeff_5: %f\n", cal.coeff5); printf("Coeff_6: %f\n", cal.coeff6); printf("Coeff_7: %f\n", cal.coeff7); printf("Coeff_8: %f\n", cal.coeff8); printf("Coeff_9: %f\n", cal.coeff9); printf("Coeff_10: %f\n", cal.coeff10); printf("Coeff_11: %f\n", cal.coeff11); printf("Coeff_12: %f\n\n", cal.coeff12); } fflush(stdout); return 0; } /** * @brief UART command "sethw": receive and store hardware version. * * Parses the hardware version string from the command, validates its length, * stores it in persistent storage, and prints the result or an error message. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_hardware_ver(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { const char *input = argv[1]; size_t len = strnlen(input, MAX_VERSION_LENGTH); if ((len == 0) || (len >= MAX_VERSION_LENGTH)) { printf("%s: error, length of input hardware version number: " "%s is not in range: %d~%d\n\n", argv[0], argv[1], MIN_VERSION_LENGTH, (MAX_VERSION_LENGTH-1)); } else { ser_file ser_var; ser_file * p_ser_file = &ser_var; char version[MAX_VERSION_LENGTH] = {}; memcpy(version, input, len); version[len] = '\0'; decltype(((ser_file*)0)->hw_ver) version_number{}; memcpy(version_number, version, len + 1); fseek(p_ser, (int) (&p_ser_file->hw_ver) - (int) (p_ser_file), SEEK_SET); fwrite(&version_number, sizeof(ser_file::hw_ver), 1, p_ser); fflush(p_ser); // Hardware Version Number set successfully printf("%s: Hardware Version Number is set to: %sV\n\n", argv[0], ser_var.hw_ver); } } fflush(stdout); return 0; } /** * @brief UART command "setsn": receive and store serial number. * * Parses the serial number string from the command, validates its length, * stores it in persistent storage, and prints the result or an error message. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_rx_serial_num(int argc, char *argv[]) { if (argc != 2) { // Incorrect number of arguments printf("%s: Syntax error, please use the following syntax: %s COEFF_VALUE\n\n", argv[0], argv[0]); } else { const char *input = argv[1]; size_t len = strnlen(input, MAX_VERSION_LENGTH); if ((len == 0) || (len >= MAX_VERSION_LENGTH)) { printf("%s: error, length of input serial number: " "%s is not in range: %d~%d\n\n", argv[0], argv[1], MIN_VERSION_LENGTH, (MAX_VERSION_LENGTH-1)); } else { ser_file ser_var; ser_file * p_ser_file = &ser_var; char serial[MAX_VERSION_LENGTH] = {}; memcpy(serial, input, len); serial[len] = '\0'; decltype(((ser_file*)0)->ser_num) serial_number{}; memcpy(serial_number, serial, len + 1); fseek(p_ser, (int) (&p_ser_file->ser_num) - (int) (p_ser_file), SEEK_SET); fwrite(&serial_number, sizeof(ser_file::ser_num), 1, p_ser); fflush(p_ser); // Serial Number set successfully printf("%s: Serial Number is set to: %sV\n\n", argv[0], ser_var.ser_num); } } fflush(stdout); return 0; } /** * @brief UART command "getver": transmit firmware, hardware, and serial version information in text format. * * Reads device identification fields from persistent storage and prints the * firmware version, hardware version, and serial number to STDOUT. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_tx_version_data(int argc, char *argv[]) { if (argc != 1) { printf("%s: syntax error, please use the following syntax: %s\n\n", argv[0], argv[0]); } else { ser_file ser; rewind(p_ser); fread(&ser, sizeof(ser_file), 1, p_ser); char fw_ver[MAX_VERSION_LENGTH] = FIRMWARE_VERSION; printf("Firmware version: %s\n", fw_ver); printf("Hardware version: %s\n", ser.hw_ver); printf("Serial Number: %s\n\n", ser.ser_num); } fflush(stdout); return 0; } /** * @brief UART command "U": transmit calibration data and firmware version in binary format. * * On valid invocation, transmits calibration data followed by firmware version * information to STDOUT in binary form. If the argument count is incorrect, * transmits an error status value instead. * * @param[in] argc Argument count. * @param[in] argv Argument vector. * * @return Always returns 0. */ int cmd_tx_cal_ver_bin(int argc, char *argv[]) { setStatus status = SET_STATUS_ERROR; if (argc != 1) { // Incorrect number of arguments fwrite(&status, sizeof(status), 1, stdout); } else { tx_cal_bin(); tx_version_bin(); } fflush(stdout); return 0; } /** * @brief Helper function to transmit calibration coefficients in binary format to STDOUT. * * Reads calibration coefficients from persistent storage, packs them into a * @c coeffStruct, and writes the binary structure to STDOUT. */ static void tx_cal_bin(void) { coeffStruct cal_data; cal_file cal; rewind(p_cal); fread(&cal, sizeof(cal_file), 1, p_cal); cal_data.coeff1 = cal.coeff1; cal_data.coeff2 = cal.coeff2; cal_data.coeff3 = cal.coeff3; cal_data.coeff4 = cal.coeff4; cal_data.coeff5 = cal.coeff5; cal_data.coeff6 = cal.coeff6; cal_data.coeff7 = cal.coeff7; cal_data.coeff8 = cal.coeff8; cal_data.coeff9 = cal.coeff9; cal_data.coeff10 = cal.coeff10; cal_data.coeff11 = cal.coeff11; cal_data.coeff12 = cal.coeff12; fwrite(&cal_data, sizeof(cal_data), 1, stdout); fflush(stdout); } /** * @brief Helper function to transmit ransmits firmware, hardware, and serial version * information in binary format to STDOUT. * * Reads hardware version and serial number from persistent storage, combines them * with the firmware version, packs the fields into a @c versionStruct, and writes * the binary structure to STDOUT. */ static void tx_version_bin(void) { versionStruct ver_data; ser_file ser; rewind(p_ser); fread(&ser, sizeof(ser_file), 1, p_ser); strcpy(ver_data.fw_ver, FIRMWARE_VERSION); strcpy(ver_data.hw_ver, ser.hw_ver); strcpy(ver_data.ser_num, ser.ser_num); fwrite(&ver_data, sizeof(ver_data), 1, stdout); fflush(stdout); } #ifdef __cplusplus } // extern "C" #endif