/* * 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