Index: ADuCM360_demo_cn0359/.cproject =================================================================== diff -u -r93501a11686db33641c04a2678bf69dd8c67677a -re68895e85fe32aca137ce08ac5d6accd67fec591 --- ADuCM360_demo_cn0359/.cproject (.../.cproject) (revision 93501a11686db33641c04a2678bf69dd8c67677a) +++ ADuCM360_demo_cn0359/.cproject (.../.cproject) (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -22,7 +22,7 @@ - + @@ -183,8 +183,8 @@ + - @@ -361,8 +361,8 @@ + - Index: ADuCM360_demo_cn0359/include/applications/DDdefs.h =================================================================== diff -u --- ADuCM360_demo_cn0359/include/applications/DDdefs.h (revision 0) +++ ADuCM360_demo_cn0359/include/applications/DDdefs.h (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -0,0 +1,127 @@ +/* + * DDdefs.h + * + * Created on: Dec 19, 2025 + * Author: Arpita Srivastava + */ + +#ifndef _DD_DEFS_H_ +#define _DD_DEFS_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Set operation status +typedef enum +{ + SET_STATUS_ERROR = 0, + SET_STATUS_SUCCESS = 1 +}setStatus; + + +/** + * @brief Packed UART payload for conductivity data. + */ +struct __attribute__((packed)) condStruct +{ + const char id = 'r'; + float raw_cond = 0.0; + uint8_t read_count = 0; + uint8_t error = 0; +}; + + +/** + * @brief Packed UART payload for temperature data. + */ +struct __attribute__((packed)) tempStruct +{ + const char id = 't'; + float raw_temp = 0.0; + uint8_t read_count = 0; + uint8_t error = 0; +}; + + +/** + * @brief Packed UART payload for auto-poll conductivity and temperature data. + */ +struct __attribute__((packed)) AutoPollStruct +{ + condStruct cond_data; + tempStruct temp_data; +}; + +/** + * @brief Packed UART payload for calibration coefficients. + */ +struct __attribute__((packed)) coeffStruct +{ + const char id = 'c'; + float coeff1 = DEFAULT_COEFF; + float coeff2 = DEFAULT_COEFF; + float coeff3 = DEFAULT_COEFF; + float coeff4 = DEFAULT_COEFF; + float coeff5 = DEFAULT_COEFF; + float coeff6 = DEFAULT_COEFF; + float coeff7 = DEFAULT_COEFF; + float coeff8 = DEFAULT_COEFF; + float coeff9 = DEFAULT_COEFF; + float coeff10 = DEFAULT_COEFF; + float coeff11 = DEFAULT_COEFF; + float coeff12 = DEFAULT_COEFF; +}; + + +/** + * @brief Packed UART payload for firmware/hardware version and serial number. + */ +struct __attribute__((packed)) versionStruct +{ + const char id = 'v'; + char fw_ver[MAX_VERSION_LENGTH] = FIRMWARE_VERSION; + char hw_ver[MAX_VERSION_LENGTH] = ""; + char ser_num[MAX_VERSION_LENGTH] = ""; +}; + +uint8_t get_error_flag(void); +void set_error_flag(void); +void clear_error_flag(void); + +bool is_auto_publish_enbld(void); +void start_auto_publishing(void); +void stop_auto_publishing(void); +int auto_publish(int argc, char *argv[]); + +extern int cmd_start_poll_bin(int argc, char *argv[]); +extern int cmd_stop_poll_bin(int argc, char *argv[]); +extern int cmd_tx_raw_poll(int argc, char *argv[]); + +extern int cmd_rx_cal1(int argc, char *argv[]); +extern int cmd_rx_cal2(int argc, char *argv[]); +extern int cmd_rx_cal3(int argc, char *argv[]); +extern int cmd_rx_cal4(int argc, char *argv[]); +extern int cmd_rx_cal5(int argc, char *argv[]); +extern int cmd_rx_cal6(int argc, char *argv[]); +extern int cmd_rx_cal7(int argc, char *argv[]); +extern int cmd_rx_cal8(int argc, char *argv[]); +extern int cmd_rx_cal9(int argc, char *argv[]); +extern int cmd_rx_cal10(int argc, char *argv[]); +extern int cmd_rx_cal11(int argc, char *argv[]); +extern int cmd_rx_cal12(int argc, char *argv[]); +extern int cmd_tx_cal_data(int argc, char *argv[]); + +extern int cmd_rx_hardware_ver(int argc, char *argv[]); +extern int cmd_rx_serial_num(int argc, char *argv[]); +extern int cmd_tx_version_data(int argc, char *argv[]); +extern int cmd_tx_cal_ver_bin(int argc, char *argv[]); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* -_DD_DEFS_H_ */ Index: ADuCM360_demo_cn0359/include/hal/devices.h =================================================================== diff -u -r8d80f35bf88694bd50d769b9bab31db8364a9004 -re68895e85fe32aca137ce08ac5d6accd67fec591 --- ADuCM360_demo_cn0359/include/hal/devices.h (.../devices.h) (revision 8d80f35bf88694bd50d769b9bab31db8364a9004) +++ ADuCM360_demo_cn0359/include/hal/devices.h (.../devices.h) (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -42,7 +42,7 @@ #include -extern FILE *p_lcd, *p_uart, *p_flash, *p_dac, *p_adc, *p_pwm, *p_ad8253; +extern FILE *p_lcd, *p_uart, *p_flash, *p_dac, *p_adc, *p_pwm, *p_ad8253, *p_cal, *p_ser; extern void initial_devices(void); Index: ADuCM360_demo_cn0359/include/hal/drivers/calibration.h =================================================================== diff -u --- ADuCM360_demo_cn0359/include/hal/drivers/calibration.h (revision 0) +++ ADuCM360_demo_cn0359/include/hal/drivers/calibration.h (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -0,0 +1,79 @@ +/* + * calibration.h + * + * Created on: Dec 22, 2025 + * Author: Arpita Srivastava + */ + +#ifndef __CALIBRATION_H__ +#define __CALIBRATION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +#define FIRMWARE_VERSION "v0.1.0" // Major.Minor.Build + +#define MIN_VERSION_LENGTH 1 // Minimum version string length +#define MAX_VERSION_LENGTH 13 // Maximum version string length + +#define DEFAULT_COEFF 0.0F // Default calibration coefficient + +#define MIN_COEFF -1000.0F // Minimum valid calibration coefficient +#define MAX_COEFF 1000.0F // Maximum valid calibration coefficient + +/** + * @brief Flash structure for calibration coefficients. + */ +struct __attribute__((packed)) cal_file +{ + float coeff1 = DEFAULT_COEFF; + float coeff2 = DEFAULT_COEFF; + float coeff3 = DEFAULT_COEFF; + float coeff4 = DEFAULT_COEFF; + float coeff5 = DEFAULT_COEFF; + float coeff6 = DEFAULT_COEFF; + float coeff7 = DEFAULT_COEFF; + float coeff8 = DEFAULT_COEFF; + float coeff9 = DEFAULT_COEFF; + float coeff10 = DEFAULT_COEFF; + float coeff11 = DEFAULT_COEFF; + float coeff12 = DEFAULT_COEFF; + +}const default_cal_data; + + +/** + * @brief Flash structure for hardware version and serial number. + */ +struct __attribute__((packed)) ser_file +{ + char hw_ver[MAX_VERSION_LENGTH] = "0.0.0"; + char ser_num[MAX_VERSION_LENGTH] = "0.0.0"; + +}const default_ser_data; + +extern ssize_t cal_write(const void *buf, size_t count); + +extern ssize_t cal_read(void *buf, size_t count); + +extern off_t cal_lseek(off_t offset, int whence); + +extern void cal_open(void); + +extern ssize_t ser_write(const void *buf, size_t count); + +extern ssize_t ser_read(void *buf, size_t count); + +extern off_t ser_lseek(off_t offset, int whence); + +extern void ser_open(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* __CALIBRATION_H__ */ Index: ADuCM360_demo_cn0359/ld_script/gcc_arm.ld =================================================================== diff -u -r8d80f35bf88694bd50d769b9bab31db8364a9004 -re68895e85fe32aca137ce08ac5d6accd67fec591 --- ADuCM360_demo_cn0359/ld_script/gcc_arm.ld (.../gcc_arm.ld) (revision 8d80f35bf88694bd50d769b9bab31db8364a9004) +++ ADuCM360_demo_cn0359/ld_script/gcc_arm.ld (.../gcc_arm.ld) (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -114,6 +114,10 @@ . = ALIGN(512); *(.flash_disk) . = ALIGN(512); + *(.cal_disk) + . = ALIGN(512); + *(.ser_disk) + . = ALIGN(512); KEEP(*(.eh_frame*)) } > FLASH Index: ADuCM360_demo_cn0359/src/applications/DDdefs.cpp =================================================================== diff -u --- ADuCM360_demo_cn0359/src/applications/DDdefs.cpp (revision 0) +++ ADuCM360_demo_cn0359/src/applications/DDdefs.cpp (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -0,0 +1,1086 @@ +/* + * 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 + + Index: ADuCM360_demo_cn0359/src/applications/dialog/Dialog.cpp =================================================================== diff -u -r8d80f35bf88694bd50d769b9bab31db8364a9004 -re68895e85fe32aca137ce08ac5d6accd67fec591 --- ADuCM360_demo_cn0359/src/applications/dialog/Dialog.cpp (.../Dialog.cpp) (revision 8d80f35bf88694bd50d769b9bab31db8364a9004) +++ ADuCM360_demo_cn0359/src/applications/dialog/Dialog.cpp (.../Dialog.cpp) (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -44,31 +44,37 @@ int on_cw(int argc, char *argv[]) { p_dialog->OnEncoderCW(); + return 0; } int on_ccw(int argc, char *argv[]) { p_dialog->OnEncoderCCW(); + return 0; } int on_button_down(int argc, char *argv[]) { p_dialog->OnButtonDown(); + return 0; } int on_button_up(int argc, char *argv[]) { p_dialog->OnButtonUp(); + return 0; } int on_conductivity(int argc, char *argv[]) { p_dialog->OnConductivity(); + return 0; } int on_rtd(int argc, char *argv[]) { p_dialog->OnRTD(); + return 0; } void CDialog::OnEncoderCW(void) Index: ADuCM360_demo_cn0359/src/applications/dialog/SplashDialog.cpp =================================================================== diff -u -r8d80f35bf88694bd50d769b9bab31db8364a9004 -re68895e85fe32aca137ce08ac5d6accd67fec591 --- ADuCM360_demo_cn0359/src/applications/dialog/SplashDialog.cpp (.../SplashDialog.cpp) (revision 8d80f35bf88694bd50d769b9bab31db8364a9004) +++ ADuCM360_demo_cn0359/src/applications/dialog/SplashDialog.cpp (.../SplashDialog.cpp) (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -53,6 +53,7 @@ beep(200); p_dialog = &HomeDialog; p_dialog->OnCreat(); + return 0; } void CSplashDialog::OnButtonDown(void) Index: ADuCM360_demo_cn0359/src/applications/main.cpp =================================================================== diff -u -r8d80f35bf88694bd50d769b9bab31db8364a9004 -re68895e85fe32aca137ce08ac5d6accd67fec591 --- ADuCM360_demo_cn0359/src/applications/main.cpp (.../main.cpp) (revision 8d80f35bf88694bd50d769b9bab31db8364a9004) +++ ADuCM360_demo_cn0359/src/applications/main.cpp (.../main.cpp) (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -44,11 +44,15 @@ #include #include #include +#include int main(void) { SystemCoreClockUpdate(); // SystemCoreClock in bss, cleared by _start + // Clear the disk error flag + clear_error_flag(); + initial_devices(); SysTick_Config(SystemCoreClock / @@ -57,6 +61,9 @@ p_dialog = &SplashDialog; p_dialog->OnCreat(); + // Start automated polling / publishing + start_auto_publishing(); + while (true) { message_loop(); } Index: ADuCM360_demo_cn0359/src/applications/uart_exec.cpp =================================================================== diff -u -r509657069dd7ee800560a5c0b790077ce4cbd31a -re68895e85fe32aca137ce08ac5d6accd67fec591 --- ADuCM360_demo_cn0359/src/applications/uart_exec.cpp (.../uart_exec.cpp) (revision 509657069dd7ee800560a5c0b790077ce4cbd31a) +++ ADuCM360_demo_cn0359/src/applications/uart_exec.cpp (.../uart_exec.cpp) (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -50,6 +50,7 @@ #include #include #include +#include struct command { const char *cmd; @@ -58,13 +59,39 @@ #define SIZE(a) (sizeof(a)/sizeof(a[0])) -struct command command_table[] = {{"poll", cmd_poll}, +struct command command_table[] = { + + {"poll", cmd_poll}, {"setvolt", cmd_voltage}, {"setfreq", cmd_frequency}, {"setk", cmd_cellconstant}, {"setcof", cmd_coefficient}, {"setstm", cmd_setuptime}, - {"sethtm", cmd_holdtime} + {"sethtm", cmd_holdtime}, + + {"b" , cmd_start_poll_bin}, + {"e" , cmd_stop_poll_bin}, + {"getraw" , cmd_tx_raw_poll}, + + {"setcal1" , cmd_rx_cal1}, + {"setcal2" , cmd_rx_cal2}, + {"setcal3" , cmd_rx_cal3}, + {"setcal4" , cmd_rx_cal4}, + {"setcal5" , cmd_rx_cal5}, + {"setcal6" , cmd_rx_cal6}, + {"setcal7" , cmd_rx_cal7}, + {"setcal8" , cmd_rx_cal8}, + {"setcal9" , cmd_rx_cal9}, + {"setcal10", cmd_rx_cal10}, + {"setcal11", cmd_rx_cal11}, + {"setcal12", cmd_rx_cal12}, + {"getcal" , cmd_tx_cal_data}, + + {"sethw" , cmd_rx_hardware_ver}, + {"setsn" , cmd_rx_serial_num}, + {"getver" , cmd_tx_version_data}, + {"U" , cmd_tx_cal_ver_bin}, + }; int rx_line(int argc, char *argv[]) Index: ADuCM360_demo_cn0359/src/hal/devices.cpp =================================================================== diff -u -r8d80f35bf88694bd50d769b9bab31db8364a9004 -re68895e85fe32aca137ce08ac5d6accd67fec591 --- ADuCM360_demo_cn0359/src/hal/devices.cpp (.../devices.cpp) (revision 8d80f35bf88694bd50d769b9bab31db8364a9004) +++ ADuCM360_demo_cn0359/src/hal/devices.cpp (.../devices.cpp) (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -48,21 +48,53 @@ #include #include #include +#include +#include -FILE *p_lcd, *p_uart, *p_flash, *p_dac, *p_adc, *p_pwm, *p_ad8253; +#define SIZE_OF_FLASH_FILE sizeof(flash_file) +#define SIZE_OF_DAC_FILE sizeof(dac_file) +#define SIZE_OF_PWM_FILE sizeof(pwm_file) +#define SIZE_OF_AD8253_FILE sizeof(ad8253_file) +#define SIZE_OF_ADC_FILE sizeof(adc_file) +#define SIZE_OF_CAL_FILE sizeof(cal_file) +#define SIZE_OF_SER_FILE sizeof(ser_file) +FILE *p_lcd, *p_uart, *p_flash, *p_dac, *p_adc, *p_pwm, *p_ad8253, *p_cal, *p_ser; + +static char stdout_buf[64]; +static char stdin_buf[16]; +static char stderr_buf[0]; +static char p_flash_buf[SIZE_OF_FLASH_FILE]; +static char p_uart_buf[0]; +static char p_lcd_buf[16]; +static char p_dac_buf[SIZE_OF_DAC_FILE]; +static char p_pwm_buf[SIZE_OF_PWM_FILE]; +static char p_ad8253_buf[SIZE_OF_AD8253_FILE]; +static char p_adc_buf[SIZE_OF_ADC_FILE]; +static char p_cal_buf[SIZE_OF_CAL_FILE]; +static char p_ser_buf[SIZE_OF_SER_FILE]; + +static void verify_cal_disk(void); +static void verify_ser_disk(void); +static bool is_coeff_in_range(float coeff); + void initial_devices(void) { - setvbuf(stdout, nullptr, _IOLBF, 64); - setvbuf(stdin, nullptr, _IOFBF, 16); - setvbuf(stderr, nullptr, _IONBF, 0); +// setvbuf(stdout, nullptr, _IOLBF, 64); +// setvbuf(stdin, nullptr, _IOFBF, 16); +// setvbuf(stderr, nullptr, _IONBF, 0); + setvbuf(stdout, stdout_buf, _IOLBF, 64); + setvbuf(stdin, stdin_buf, _IOFBF, 16); + setvbuf(stderr, stderr_buf, _IONBF, 0); + NVIC_SetPriorityGrouping(6); //2 groups, each group have 4 subpriorities buzzer_open(); p_flash = fopen("flash", "rb+"); - setvbuf(p_flash, nullptr, _IOFBF, sizeof(flash_file)); +// setvbuf(p_flash, nullptr, _IOFBF, sizeof(flash_file)); + setvbuf(p_flash, p_flash_buf, _IOFBF, SIZE_OF_FLASH_FILE); flash_file setting; rewind(p_flash); @@ -93,23 +125,127 @@ beep(50, 50, 50, 50, 50, 50, 50, 50, 50); } + p_cal = fopen("cal", "rb+"); + setvbuf(p_cal, p_cal_buf, _IOFBF, SIZE_OF_CAL_FILE); + verify_cal_disk(); + + p_ser = fopen("ser", "rb+"); + setvbuf(p_ser, p_ser_buf, _IOFBF, SIZE_OF_SER_FILE); + verify_ser_disk(); + p_uart = fopen("uart", "r"); - setvbuf(p_uart, nullptr, _IONBF, 0); +// setvbuf(p_uart, nullptr, _IONBF, 0); + setvbuf(p_uart, p_uart_buf, _IONBF, 0); p_lcd = fopen("lcd", "rb+"); - setvbuf(p_lcd, nullptr, _IOFBF, 16); +// setvbuf(p_lcd, nullptr, _IOFBF, 16); + setvbuf(p_lcd, p_lcd_buf, _IOFBF, 16); p_dac = fopen("dac", "rb+"); - setvbuf(p_dac, nullptr, _IOFBF, sizeof(dac_file)); +// setvbuf(p_dac, nullptr, _IOFBF, sizeof(dac_file)); + setvbuf(p_dac, p_dac_buf, _IOFBF, SIZE_OF_DAC_FILE); p_pwm = fopen("pwm", "rb+"); - setvbuf(p_pwm, nullptr, _IOFBF, sizeof(pwm_file)); +// setvbuf(p_pwm, nullptr, _IOFBF, sizeof(pwm_file)); + setvbuf(p_pwm, p_pwm_buf, _IOFBF, SIZE_OF_PWM_FILE); p_ad8253 = fopen("ad8253", "rb+"); - setvbuf(p_ad8253, nullptr, _IOFBF, sizeof(ad8253_file)); +// setvbuf(p_ad8253, nullptr, _IOFBF, sizeof(ad8253_file)); + setvbuf(p_ad8253, p_ad8253_buf, _IOFBF, SIZE_OF_AD8253_FILE); p_adc = fopen("adc", "rb"); - setvbuf(p_adc, nullptr, _IOFBF, sizeof(adc_file)); +// setvbuf(p_adc, nullptr, _IOFBF, sizeof(adc_file)); + setvbuf(p_adc, p_adc_buf, _IOFBF, SIZE_OF_ADC_FILE); encoder_open(); } + + +/** + * @brief Verifies calibration coefficients stored on disk. + * + * Reads all calibration coefficients from persistent storage and checks each + * coefficient to ensure it lies within the valid numeric range. If any + * coefficient is out of range, the error flag is set. + */ +static void verify_cal_disk(void) +{ + cal_file cal_data; + rewind(p_cal); + fread(&cal_data, sizeof(cal_file), 1, p_cal); + + if ( ( true == is_coeff_in_range( cal_data.coeff1 ) ) && + ( true == is_coeff_in_range( cal_data.coeff2 ) ) && + ( true == is_coeff_in_range( cal_data.coeff3 ) ) && + ( true == is_coeff_in_range( cal_data.coeff4 ) ) && + ( true == is_coeff_in_range( cal_data.coeff5 ) ) && + ( true == is_coeff_in_range( cal_data.coeff6 ) ) && + ( true == is_coeff_in_range( cal_data.coeff7 ) ) && + ( true == is_coeff_in_range( cal_data.coeff8 ) ) && + ( true == is_coeff_in_range( cal_data.coeff9 ) ) && + ( true == is_coeff_in_range( cal_data.coeff10 ) ) && + ( true == is_coeff_in_range( cal_data.coeff11 ) ) && + ( true == is_coeff_in_range( cal_data.coeff12 ) ) ) + + { //check cal_disk + // disk ok + + } + else + { // disk error + set_error_flag(); + } +} + + +/** + * @brief Verifies version and serial fields read from persistent storage. + * + * Reads hardware version and serial number from persistent storage and checks + * that lengths fall within the configured minimum and maximum bounds. + * Sets the error flag if validation fails. + */ +static void verify_ser_disk(void) +{ + ser_file ser_data; + rewind(p_ser); + fread(&ser_data, sizeof(ser_file), 1, p_ser); + + char fw_ver[MAX_VERSION_LENGTH] = FIRMWARE_VERSION; + + int fw_len = strlen(fw_ver); + int hw_len = strlen(ser_data.hw_ver); + int sn_len = strlen(ser_data.ser_num); + + if (fw_len < MAX_VERSION_LENGTH + && fw_len >= MIN_VERSION_LENGTH + && hw_len < MAX_VERSION_LENGTH + && hw_len >= MIN_VERSION_LENGTH + && sn_len < MAX_VERSION_LENGTH + && sn_len >= MIN_VERSION_LENGTH) + { //check ser_disk + // disk ok + } + else + { // disk error + set_error_flag(); + } +} + + +/** + * @brief Checks whether a coefficient value lies within the valid range. + * + * @param[in] coeff Coefficient value to be validated. + * + * @return true if the coefficient is within the allowed range; false otherwise. + */ +static bool is_coeff_in_range(float coeff) +{ + bool result = false; + if ((coeff <= MAX_COEFF) && (coeff >= MIN_COEFF)) + { + result = true; + } + return result; +} Index: ADuCM360_demo_cn0359/src/hal/drivers/adc.cpp =================================================================== diff -u -r8d80f35bf88694bd50d769b9bab31db8364a9004 -re68895e85fe32aca137ce08ac5d6accd67fec591 --- ADuCM360_demo_cn0359/src/hal/drivers/adc.cpp (.../adc.cpp) (revision 8d80f35bf88694bd50d769b9bab31db8364a9004) +++ ADuCM360_demo_cn0359/src/hal/drivers/adc.cpp (.../adc.cpp) (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -50,9 +50,10 @@ #include #include #include +#include #define ADC0FLT_AF (15<<8) -#define ADC0FLT_SF 124 +#define ADC0FLT_SF 31 #define ADC1FLT_AF (15<<8) #define ADC1FLT_SF 124 @@ -394,6 +395,17 @@ t.timer_app.argv = new char*; new_timer(t); + + // If automated polling / publihsing flag is enabled + if(true == is_auto_publish_enbld()) + { + // Start publihsing raw conductivity measurements + app msg; + msg.argc = 0; + msg.fun = auto_publish; + msg.argv = new char*; + post_message(msg); + } break; } @@ -511,11 +523,11 @@ result.temp = 25; } - app msg; - msg.argc = 0; - msg.fun = on_rtd; - msg.argv = new char*; - post_message(msg); +// app msg; +// msg.argc = 0; +// msg.fun = on_rtd; +// msg.argv = new char*; +// post_message(msg); pADI_ADC1->CON = (pADI_ADC1->CON & ~ADC1CON_ADCREF_MSK & ~ADC1CON_ADCDIAG_MSK & ~ADC1CON_ADCCP_MSK & ~ADC1CON_ADCCN_MSK) Index: ADuCM360_demo_cn0359/src/hal/drivers/calibration.cpp =================================================================== diff -u --- ADuCM360_demo_cn0359/src/hal/drivers/calibration.cpp (revision 0) +++ ADuCM360_demo_cn0359/src/hal/drivers/calibration.cpp (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -0,0 +1,324 @@ +/* + * calibration.cpp + * + * Created on: Dec 22, 2025 + * Author: Arpita Srivastava + */ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static int pos_cal = 0; + +//cal_disk exclusive in his own flash sector +static const struct cal_file cal_disk __attribute__ ((aligned (512), + section (".cal_disk"))); + +static const char * const p_cal_disk = (const char *) (&cal_disk); + +static int pos_ser = 0; + +//ser_disk exclusive in its own flash sector +static const struct ser_file ser_disk __attribute__ ((aligned (512), + section (".ser_disk"))); + +static const char * const p_ser_disk = (const char *) (&ser_disk); + +/** + * @brief Writes calibration data to flash. + * + * @param[in] buf Pointer to data buffer. + * @param[in] count Number of bytes to write. + * + * @return Number of bytes written. + */ +ssize_t cal_write(const void *buf, size_t count) +{ + if (pos_cal >= sizeof(cal_file)) { + errno = ENOSPC; + return -1; + } + + int start_page = pos_cal >> 9; + + int end_page = ((pos_cal + count) < sizeof(cal_file) ? + (pos_cal + count - 1) : (sizeof(cal_file) - 1)) >> 9; + + int remain_bytes = count; + const char *remain_buf; + remain_buf = (const char *) buf; + + for (int i = start_page; i <= end_page; ++i) { + char buffer[512] __attribute__ ((aligned (sizeof(unsigned long)))); + + memcpy(buffer, &p_cal_disk[i << 9], 512); + + pADI_FEE->FEEADR0H = (((int) (&p_cal_disk[i << 9]) >> 16) & 0x1); + pADI_FEE->FEEADR0L = ((int) (&p_cal_disk[i << 9]) & 0xfe00); + + pADI_FEE->FEEKEY = FEEKEY_VALUE_USERKEY1; + pADI_FEE->FEEKEY = FEEKEY_VALUE_USERKEY2; + + pADI_FEE->FEECMD = FEECMD_CMD_ERASEPAGE; // erase + while (FEESTA_CMDBUSY_BBA) + ; + + int write_count = (pos_cal & 0x1ff) + remain_bytes > 512 ? 512 - + (pos_cal & 0x1ff) : remain_bytes; + + memcpy(&buffer[pos_cal & 0x1ff], remain_buf, write_count); + + FEECON0_WREN_BBA = true; + + unsigned long *p_src, *p_dst; + p_src = (unsigned long *) buffer; + p_dst = (unsigned long *) (&p_cal_disk[i << 9]); + + for (int i = 0; i < 128; ++i) { + while (FEESTA_WRBUSY_BBA) + ; + p_dst[i] = p_src[i]; + } + + FEECON0_WREN_BBA = false; + + pos_cal += write_count; + remain_bytes -= write_count; + remain_buf += write_count; + } + + return (count - remain_bytes); +} + + +/** + * @brief Reads calibration data from flash. + * + * @param[out] buf Pointer to destination buffer. + * @param[in] count Number of bytes to read. + * + * @return Number of bytes read. + */ +ssize_t cal_read(void *buf, size_t count) +{ + if ((pos_cal + count) > sizeof(cal_file)) { + count = sizeof(cal_file) - pos_cal; + } + + memcpy(buf, &p_cal_disk[pos_cal], count); + + pos_cal += count; + + return count; +} + + +/** + * @brief Moves the calibration flash file pointer. + * + * @param[in] offset Offset value. + * @param[in] whence Reference position. + * + * @return New offset location. + */ +off_t cal_lseek(off_t offset, int whence) +{ + switch (whence) { + case SEEK_SET: + if (offset > sizeof(cal_file) || offset < 0) { + errno = EINVAL; + return -1; + } else { + pos_cal = offset; + } + + break; + case SEEK_CUR: + if ((pos_cal + offset) > sizeof(cal_file) || (pos_cal + offset) < 0) { + errno = EINVAL; + return -1; + } else { + pos_cal += offset; + } + break; + case SEEK_END: + if (offset > 0 || sizeof(cal_file) + offset < 0) { + errno = EINVAL; + return -1; + } else { + pos_cal = sizeof(cal_file) + offset; + } + break; + default: + errno = ENXIO; + return -1; + break; + } + + return pos_cal; +} + + +/** + * @brief Opens calibration flash storage. + */ +void cal_open(void) +{ + +} + + +/** + * @brief Writes version/serial data to flash. + * + * @param[in] buf Pointer to data buffer. + * @param[in] count Number of bytes to write. + * + * @return Number of bytes written. + */ +ssize_t ser_write(const void *buf, size_t count) +{ + if (pos_ser >= sizeof(ser_file)) { + errno = ENOSPC; + return -1; + } + + int start_page = pos_ser >> 9; + + int end_page = ((pos_ser + count) < sizeof(ser_file) ? + (pos_ser + count - 1) : (sizeof(ser_file) - 1)) >> 9; + + int remain_bytes = count; + const char *remain_buf; + remain_buf = (const char *) buf; + + for (int i = start_page; i <= end_page; ++i) { + char buffer[512] __attribute__ ((aligned (sizeof(unsigned long)))); + + memcpy(buffer, &p_ser_disk[i << 9], 512); + + pADI_FEE->FEEADR0H = (((int) (&p_ser_disk[i << 9]) >> 16) & 0x1); + pADI_FEE->FEEADR0L = ((int) (&p_ser_disk[i << 9]) & 0xfe00); + + pADI_FEE->FEEKEY = FEEKEY_VALUE_USERKEY1; + pADI_FEE->FEEKEY = FEEKEY_VALUE_USERKEY2; + + pADI_FEE->FEECMD = FEECMD_CMD_ERASEPAGE; // erase + while (FEESTA_CMDBUSY_BBA) + ; + + int write_count = (pos_ser & 0x1ff) + remain_bytes > 512 ? 512 - + (pos_ser & 0x1ff) : remain_bytes; + + memcpy(&buffer[pos_ser & 0x1ff], remain_buf, write_count); + + FEECON0_WREN_BBA = true; + + unsigned long *p_src, *p_dst; + p_src = (unsigned long *) buffer; + p_dst = (unsigned long *) (&p_ser_disk[i << 9]); + + for (int i = 0; i < 128; ++i) { + while (FEESTA_WRBUSY_BBA) + ; + p_dst[i] = p_src[i]; + } + + FEECON0_WREN_BBA = false; + + pos_ser += write_count; + remain_bytes -= write_count; + remain_buf += write_count; + } + + return (count - remain_bytes); +} + + +/** + * @brief Reads version/serial data from flash. + * + * @param[out] buf Pointer to destination buffer. + * @param[in] count Number of bytes to read. + * + * @return Number of bytes read. + */ +ssize_t ser_read(void *buf, size_t count) +{ + if ((pos_ser + count) > sizeof(ser_file)) { + count = sizeof(ser_file) - pos_ser; + } + + memcpy(buf, &p_ser_disk[pos_ser], count); + + pos_ser += count; + + return count; +} + + +/** + * @brief Moves the version/serial flash file pointer. + * + * @param[in] offset Offset value. + * @param[in] whence Reference position. + * + * @return New offset location. + */ +off_t ser_lseek(off_t offset, int whence) +{ + switch (whence) { + case SEEK_SET: + if (offset > sizeof(ser_file) || offset < 0) { + errno = EINVAL; + return -1; + } else { + pos_ser = offset; + } + + break; + case SEEK_CUR: + if ((pos_ser + offset) > sizeof(ser_file) || (pos_ser + offset) < 0) { + errno = EINVAL; + return -1; + } else { + pos_ser += offset; + } + break; + case SEEK_END: + if (offset > 0 || sizeof(ser_file) + offset < 0) { + errno = EINVAL; + return -1; + } else { + pos_ser = sizeof(ser_file) + offset; + } + break; + default: + errno = ENXIO; + return -1; + break; + } + + return pos_ser; +} + + +/** + * @brief Opens version/serial flash storage. + */ +void ser_open(void) +{ + +} + +#ifdef __cplusplus +} // extern "C" +#endif + Index: ADuCM360_demo_cn0359/src/hal/syscalls.cpp =================================================================== diff -u -r8d80f35bf88694bd50d769b9bab31db8364a9004 -re68895e85fe32aca137ce08ac5d6accd67fec591 --- ADuCM360_demo_cn0359/src/hal/syscalls.cpp (.../syscalls.cpp) (revision 8d80f35bf88694bd50d769b9bab31db8364a9004) +++ ADuCM360_demo_cn0359/src/hal/syscalls.cpp (.../syscalls.cpp) (revision e68895e85fe32aca137ce08ac5d6accd67fec591) @@ -52,6 +52,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" @@ -76,6 +77,8 @@ #define ADC_HANDLE (0x24) #define PWM_HANDLE (0x25) #define AD8253_HANDLE (0x26) +#define CAL_HANDLE (0x27) +#define SER_HANDLE (0x28) ssize_t _read(int fd, void *buf, size_t count) { @@ -87,6 +90,12 @@ case FLASH_HANDLE: return flash_read(buf, count); break; + case CAL_HANDLE: + return cal_read(buf, count); + break; + case SER_HANDLE: + return ser_read(buf, count); + break; case DAC_HANDLE: return dac_read(buf, count); break; @@ -117,6 +126,12 @@ case FLASH_HANDLE: return flash_lseek(offset, whence); break; + case CAL_HANDLE: + return cal_lseek(offset, whence); + break; + case SER_HANDLE: + return ser_lseek(offset, whence); + break; case DAC_HANDLE: return dac_lseek(offset, whence); break; @@ -152,6 +167,12 @@ case FLASH_HANDLE: return flash_write(buf, count); break; + case CAL_HANDLE: + return cal_write(buf, count); + break; + case SER_HANDLE: + return ser_write(buf, count); + break; case DAC_HANDLE: return dac_write(buf, count); break; @@ -196,6 +217,16 @@ return FLASH_HANDLE; } + if (strcmp(pathname, "cal") == 0) { + cal_open(); + return CAL_HANDLE; + } + + if (strcmp(pathname, "ser") == 0) { + ser_open(); + return SER_HANDLE; + } + if (strcmp(pathname, "dac") == 0) { dac_open(); return DAC_HANDLE;