diff --git a/firmware/app/structs/obdh_data.h b/firmware/app/structs/obdh_data.h index dca2474b..98087a47 100644 --- a/firmware/app/structs/obdh_data.h +++ b/firmware/app/structs/obdh_data.h @@ -24,8 +24,9 @@ * \brief OBDH data structure definition. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.10.17 + * \version 0.10.18 * * \date 2020/07/16 * @@ -151,20 +152,20 @@ typedef struct uint16_t temperature; /**< Temperature of the uC in Kelvin. */ uint16_t current; /**< Input current in mA. */ uint16_t voltage; /**< Input voltage in mV. */ - uint8_t last_reset_cause; /**< Last reset cause code. */ uint16_t reset_counter; /**< Reset counter. */ + uint8_t last_reset_cause; /**< Last reset cause code. */ uint8_t last_valid_tc; /**< Last valid telecommand ID. */ + uint8_t mode; /**< Satellite mode. */ + uint8_t ant_deployment_counter; /**< Antenna deployment counter. */ + uint8_t initial_hib_time_count; /**< Initial hibernation time counter in minutes. */ uint8_t hw_version; /**< Hardware version. */ uint32_t fw_version; /**< Firmware version (ex.: "v1.2.3" = 0x00010203). */ - uint8_t mode; /**< Satellite mode. */ sys_time_t ts_last_mode_change; /**< Timestamp of the last change in the operation mode. */ sys_time_t mode_duration; /**< Mode duration (valid only in hibernation mode). */ bool initial_hib_executed; /**< Initial hibernation executed flag. */ - uint8_t initial_hib_time_count; /**< Initial hibernation time counter in minutes. */ bool ant_deployment_executed; /**< Antenna deployment executed flag. */ - uint8_t ant_deployment_counter; /**< Antenna deployment counter. */ - position_data_t position; /**< Current position of the satellite. */ media_data_t media; /**< Memories data. */ + position_data_t position; /**< Current position of the satellite. */ } obdh_data_t; #endif /* OBDH_DATA_H_ */ diff --git a/firmware/app/tasks/data_log.c b/firmware/app/tasks/data_log.c index eb6b86a8..b1dc9194 100644 --- a/firmware/app/tasks/data_log.c +++ b/firmware/app/tasks/data_log.c @@ -24,8 +24,9 @@ * \brief Data log task implementation. * * \author Gabriel Mariano Marcelino - * - * \version 0.10.17 + * \author Carlos Augusto Porto Freitas + * + * \version 0.10.18 * * \date 2021/05/24 * @@ -34,33 +35,18 @@ */ #include +#include #include #include #include +#include #include "data_log.h" #include "startup.h" xTaskHandle xTaskDataLogHandle; -/** - * \brief Writes data to a given flash memory page. - * - * \param[in] is the array of bytes to write. - * - * \param[in,out] page is a pointer to the current page to write. - * - * \param[in] page_size is the page size, in bytes, of the flash memory. - * - * \param[in] start_page is the possible start page to write. - * - * \param[in] end_page is the possible end page to write. - * - * \return The status/error code. - */ -int write_data_to_flash_page(uint8_t *data, uint32_t *page, uint32_t page_size, uint32_t start_page, uint32_t end_page); - void vTaskDataLog(void) { /* Wait startup task to finish */ @@ -68,119 +54,87 @@ void vTaskDataLog(void) media_info_t nor_info = media_get_info(MEDIA_NOR); - uint32_t mem_page = 0U; uint8_t page_buf[256] = {0}; - void *null_ptr; while(1) { TickType_t last_cycle = xTaskGetTickCount(); + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_DATA_LOG_NAME, "Saving data to flash memory..."); + sys_log_new_line(); + /* OBDH data */ - if (memcpy(&page_buf[0], &sat_data_buf.obdh, sizeof(obdh_telemetry_t)) == &page_buf[0]) + (void)memcpy(&page_buf[0], &sat_data_buf.obdh, sizeof(obdh_telemetry_t)); + if (mem_mng_write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_obdh_data, nor_info.page_size, CONFIG_MEM_OBDH_DATA_START_PAGE, CONFIG_MEM_OBDH_DATA_END_PAGE) != 0) { - if (write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_obdh_data, nor_info.page_size, CONFIG_MEM_OBDH_DATA_START_PAGE, CONFIG_MEM_OBDH_DATA_END_PAGE) != 0) - { - sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the OBDH data to the flash memory!"); - sys_log_new_line(); - } + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the OBDH data to the flash memory!"); + sys_log_new_line(); } - null_ptr = memset(&page_buf[0], 0, 256); + (void)memset(&page_buf[0], 0, 256); /* EPS data */ - if (memcpy(&page_buf[0], &sat_data_buf.eps, sizeof(eps_telemetry_t)) == &page_buf[0]) + (void)memcpy(&page_buf[0], &sat_data_buf.eps, sizeof(eps_telemetry_t)); + if (mem_mng_write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_eps_data, nor_info.page_size, CONFIG_MEM_EPS_DATA_START_PAGE, CONFIG_MEM_EPS_DATA_END_PAGE) != 0) { - if (write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_eps_data, nor_info.page_size, CONFIG_MEM_EPS_DATA_START_PAGE, CONFIG_MEM_EPS_DATA_END_PAGE) != 0) - { - sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the EPS data to the flash memory!"); - sys_log_new_line(); - } + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the EPS data to the flash memory!"); + sys_log_new_line(); } - null_ptr = memset(&page_buf[0], 0, 256); + (void)memset(&page_buf[0], 0, 256); /* TTC 0 data */ - if (memcpy(&page_buf[0], &sat_data_buf.ttc_0, sizeof(ttc_telemetry_t)) == &page_buf[0]) + (void)memcpy(&page_buf[0], &sat_data_buf.ttc_0, sizeof(ttc_telemetry_t)); + if (mem_mng_write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_ttc_0_data, nor_info.page_size, CONFIG_MEM_TTC_0_DATA_START_PAGE, CONFIG_MEM_TTC_0_DATA_END_PAGE) != 0) { - if (write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_ttc_0_data, nor_info.page_size, CONFIG_MEM_TTC_0_DATA_START_PAGE, CONFIG_MEM_TTC_0_DATA_END_PAGE) != 0) - { - sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the TTC 0 data to the flash memory!"); - sys_log_new_line(); - } + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the TTC 0 data to the flash memory!"); + sys_log_new_line(); } - null_ptr = memset(&page_buf[0], 0, 256); + (void)memset(&page_buf[0], 0, 256); /* TTC 1 data */ - if (memcpy(&page_buf[0], &sat_data_buf.ttc_1, sizeof(ttc_telemetry_t)) == &page_buf[0]) + (void)memcpy(&page_buf[0], &sat_data_buf.ttc_1, sizeof(ttc_telemetry_t)); + if (mem_mng_write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_ttc_1_data, nor_info.page_size, CONFIG_MEM_TTC_1_DATA_START_PAGE, CONFIG_MEM_TTC_1_DATA_END_PAGE) != 0) { - if (write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_ttc_1_data, nor_info.page_size, CONFIG_MEM_TTC_1_DATA_START_PAGE, CONFIG_MEM_TTC_1_DATA_END_PAGE) != 0) - { - sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the TTC 1 data to the flash emory!"); - sys_log_new_line(); - } + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the TTC 1 data to the flash emory!"); + sys_log_new_line(); } - null_ptr = memset(&page_buf[0], 0, 256); + (void)memset(&page_buf[0], 0, 256); /* Antenna data */ - if (memcpy(&page_buf[0], &sat_data_buf.antenna, sizeof(antenna_telemetry_t)) == &page_buf[0]) + (void)memcpy(&page_buf[0], &sat_data_buf.antenna, sizeof(antenna_telemetry_t)); + if (mem_mng_write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_ant_data, nor_info.page_size, CONFIG_MEM_ANT_DATA_START_PAGE, CONFIG_MEM_ANT_DATA_END_PAGE) != 0) { - if (write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_ant_data, nor_info.page_size, CONFIG_MEM_ANT_DATA_START_PAGE, CONFIG_MEM_ANT_DATA_END_PAGE) != 0) - { - sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the antenna data to the flash memory!"); - sys_log_new_line(); - } + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the antenna data to the flash memory!"); + sys_log_new_line(); } - null_ptr = memset(&page_buf[0], 0, 256); + (void)memset(&page_buf[0], 0, 256); /* EDC data */ - if (memcpy(&page_buf[0], &sat_data_buf.edc_0, sizeof(payload_telemetry_t)) == &page_buf[0]) + (void)memcpy(&page_buf[0], &sat_data_buf.edc_0, sizeof(payload_telemetry_t)); + if (mem_mng_write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_edc_data, nor_info.page_size, CONFIG_MEM_EDC_DATA_START_PAGE, CONFIG_MEM_EDC_DATA_END_PAGE) != 0) { - if (write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_edc_data, nor_info.page_size, CONFIG_MEM_EDC_DATA_START_PAGE, CONFIG_MEM_EDC_DATA_END_PAGE) != 0) - { - sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the EDC data to the flash memory!"); - sys_log_new_line(); - } + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the EDC data to the flash memory!"); + sys_log_new_line(); } - null_ptr = memset(&page_buf[0], 0, 256); + (void)memset(&page_buf[0], 0, 256); /* Payload-X data */ - if (memcpy(&page_buf[0], &sat_data_buf.payload_x, sizeof(payload_telemetry_t)) == &page_buf[0]) + (void)memcpy(&page_buf[0], &sat_data_buf.payload_x, sizeof(payload_telemetry_t)); + if (mem_mng_write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_px_data, nor_info.page_size, CONFIG_MEM_PX_DATA_START_PAGE, CONFIG_MEM_PX_DATA_END_PAGE) != 0) { - if (write_data_to_flash_page(page_buf, &sat_data_buf.obdh.data.media.last_page_px_data, nor_info.page_size, CONFIG_MEM_PX_DATA_START_PAGE, CONFIG_MEM_PX_DATA_END_PAGE) != 0) - { - sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the Payload-X data to the flash memory!"); - sys_log_new_line(); - } + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DATA_LOG_NAME, "Error writing the Payload-X data to the flash memory!"); + sys_log_new_line(); } - null_ptr = memset(&page_buf[0], 0, 256); + (void)memset(&page_buf[0], 0, 256); vTaskDelayUntil(&last_cycle, pdMS_TO_TICKS(TASK_DATA_LOG_PERIOD_MS)); } } -int write_data_to_flash_page(uint8_t *data, uint32_t *page, uint32_t page_size, uint32_t start_page, uint32_t end_page) -{ - int err = -1; - - if (media_write(MEDIA_NOR, (*page) * page_size, data, page_size) == 0) - { - (*page)++; // cppcheck-suppress misra-c2012-17.8 - - if (*page > end_page) - { - *page = start_page; - } - - err = 0; - } - - return err; -} - /** \} End of file_system group */ diff --git a/firmware/app/tasks/housekeeping.c b/firmware/app/tasks/housekeeping.c index 1bae9159..4ec7506a 100644 --- a/firmware/app/tasks/housekeeping.c +++ b/firmware/app/tasks/housekeeping.c @@ -24,8 +24,9 @@ * \brief Housekeeping task implementation. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.10.17 + * \version 0.10.18 * * \date 2021/04/27 * @@ -68,11 +69,16 @@ void vTaskHousekeeping(void) /* Save the last available OBDH data at every minute */ if ((system_get_time() % 60U) == 0U) { - if (mem_mng_save_obdh_data_to_fram(sat_data_buf.obdh) != 0) + if (mem_mng_save_obdh_data_to_fram(&sat_data_buf.obdh) != 0) { sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HOUSEKEEPING_NAME, "Error writing data to the FRAM memory!"); sys_log_new_line(); } + else + { + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_HOUSEKEEPING_NAME, "Saving obdh data to fram..."); + sys_log_new_line(); + } } vTaskDelayUntil(&last_cycle, pdMS_TO_TICKS(TASK_HOUSEKEEPING_PERIOD_MS)); diff --git a/firmware/app/tasks/mem_check.c b/firmware/app/tasks/mem_check.c new file mode 100644 index 00000000..c4e573da --- /dev/null +++ b/firmware/app/tasks/mem_check.c @@ -0,0 +1,429 @@ +/* + * mem_check.c + * + * Copyright The OBDH 2.0 Contributors. + * + * This file is part of OBDH 2.0. + * + * OBDH 2.0 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OBDH 2.0 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OBDH 2.0. If not, see . + * + */ + +/** + * \brief Memory Health Check Tasks definitions + * + * \author Carlos Augusto Porto Freitas + * + * \version 0.10.18 + * + * \date 2024/07/24 + * + * \addtogroup mem_check + * \{ + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "mem_check.h" +#include "startup.h" + +#define PAGE_SIZE ((uint32_t)256UL) +#define SEG_SIZE ((uint32_t)128UL) +#define PAGE_TO_ADDR(page) ((page) * PAGE_SIZE) +#define PAGE_CHECK_DEPTH ((uint32_t)10UL) +#define ARR_SIZE(arr) (sizeof((arr))/sizeof((arr)[0])) +#define ADDR_TO_PAGE(addr) ((uint32_t)(addr) / PAGE_SIZE) + +TaskHandle_t xTaskHealthCheckMemHandle; + +static void prepare_obdh_s(obdh_telemetry_t *tel); +static void nor_sector_check(const char *msg, const uint8_t *data, uint32_t first_page); +static void fram_sector_check(const char *msg, const uint8_t *data, uint32_t addr); +static void int_flash_sector_check(const char *msg, const uint8_t *data, uint32_t addr); +static bool mem_check_pages(media_t media, const uint8_t *page_data, uint32_t first_page, uint32_t last_page, uint32_t *pages_left); +static int32_t mem_full_clean(void); + +void vTaskHealthCheckMem(void) +{ + /* Wait startup task to finish */ + xEventGroupWaitBits(task_startup_status, TASK_STARTUP_DONE, pdFALSE, pdTRUE, pdMS_TO_TICKS(TASK_HEALTH_CHECK_MEM_INIT_TIMEOUT_MS)); + + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_HEALTH_CHECK_MEM_NAME, "Preparing Health Check on memories..."); + sys_log_new_line(); + + vTaskDelay(pdMS_TO_TICKS(10U)); + + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_HEALTH_CHECK_MEM_NAME, "Cleaning memories..."); + sys_log_new_line(); + + if (mem_full_clean() < 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to clean memories"); + sys_log_new_line(); + } + + uint8_t test_data[PAGE_SIZE]; + + for (uint16_t i = 0U; i < PAGE_SIZE; ++i) + { + test_data[i] = i; + } + + vTaskDelay(pdMS_TO_TICKS(10U)); + + while (true) + { + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_HEALTH_CHECK_MEM_NAME, "Starting Health Check..."); + sys_log_new_line(); + + const uint32_t nor_pages[] = {CONFIG_MEM_OBDH_DATA_START_PAGE, CONFIG_MEM_EPS_DATA_START_PAGE, + CONFIG_MEM_TTC_0_DATA_START_PAGE, CONFIG_MEM_TTC_1_DATA_START_PAGE, + CONFIG_MEM_ANT_DATA_START_PAGE, CONFIG_MEM_EDC_DATA_START_PAGE, + CONFIG_MEM_PX_DATA_START_PAGE, CONFIG_MEM_SBCD_PKTS_START_PAGE}; + + const char *nor_msgs[] = {"OBDH", "EPS", "TTC 0", "TTC 1", "ANT", "EDC", "PX", "SBDC"}; + + for (uint8_t i = 0U; i < ARR_SIZE(nor_pages); ++i) + { + nor_sector_check(nor_msgs[i], test_data, nor_pages[i]); + } + + vTaskDelay(pdMS_TO_TICKS(10U)); + + const uint32_t fram_addrs[] = {CONFIG_MEM_ADR_INIT_WORD, CONFIG_MEM_ADR_SYS_PARAM, CONFIG_MEM_ADR_SYS_TIME}; + const char *fram_msgs[] = {"INIT_WORD", "SYS_PARAM", "SYS_TIME"}; + + for (uint8_t i = 0U; i < ARR_SIZE(fram_addrs); ++i) + { + fram_sector_check(fram_msgs[i], test_data, fram_addrs[i]); + } + + vTaskDelay(pdMS_TO_TICKS(10U)); + + int_flash_sector_check("Internal Flash Seg A Test", test_data, 0ULL); + + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_HEALTH_CHECK_MEM_NAME, "Health Check finished. Cleaning up..."); + sys_log_new_line(); + + vTaskDelay(pdMS_TO_TICKS(10U)); + + if (mem_full_clean() < 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to clean memories after test"); + sys_log_new_line(); + } + + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_HEALTH_CHECK_MEM_NAME, "Preparing load config test..."); + sys_log_new_line(); + + obdh_telemetry_t test_params; + obdh_telemetry_t loaded_params; + + prepare_obdh_s(&test_params); + + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_HEALTH_CHECK_MEM_NAME, "Starting load config test..."); + sys_log_new_line(); + + if (mem_mng_save_obdh_data_to_fram(&test_params) != 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Could not save params to FRAM"); + sys_log_new_line(); + } + + if (mem_mng_load_obdh_data_from_fram(&loaded_params) != 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Could not read params from FRAM"); + sys_log_new_line(); + } + + bool param_test_result = (memcmp(&test_params, &loaded_params, sizeof(obdh_telemetry_t)) == 0); + + sys_log_print_test_result(param_test_result, "System param loading from FRAM Test"); + sys_log_new_line(); + + /* TODO */ + /* Test Redundancy from internal FLASH **COMPLETELY** */ + + (void)memset(&loaded_params, 0, sizeof(obdh_telemetry_t)); + + mem_mng_save_obdh_data_bak(&test_params); + + vTaskDelay(pdMS_TO_TICKS(10U)); + + if (mem_mng_load_obdh_data_bak(&loaded_params) != 0) + { + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_HEALTH_CHECK_MEM_NAME, "Could not load media info from INT FLASH Correctly"); + sys_log_new_line(); + } + + vTaskDelay(pdMS_TO_TICKS(10U)); + + bool int_flash_res = (memcmp(&test_params, &loaded_params, BAK_DATA_SIZE) == 0); + + sys_log_print_test_result(int_flash_res, "Media info backup Test"); + sys_log_new_line(); + + vTaskDelay(pdMS_TO_TICKS(10U)); + + uint8_t *test_ptr = (uint8_t*)&test_params; + uint8_t *pos_ptr = (uint8_t*)&test_params.data.position; + bool offset_test = (pos_ptr == &test_ptr[BAK_DATA_SIZE]); + + sys_log_print_test_result(offset_test, "Struct Offset Test"); + sys_log_new_line(); + + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_HEALTH_CHECK_MEM_NAME, "Cleaning up..."); + sys_log_new_line(); + + vTaskDelay(pdMS_TO_TICKS(10U)); + + if (mem_full_clean() < 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to clean memories after test"); + sys_log_new_line(); + } + + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_HEALTH_CHECK_MEM_NAME, "Health Check finished!!"); + sys_log_new_line(); + + vTaskSuspend(NULL); + } +} + +static void int_flash_sector_check(const char *msg, const uint8_t *data, uint32_t addr) +{ + uint8_t buf[SEG_SIZE]; + bool test_result; + + (void)memcpy(buf, data, SEG_SIZE); + + if (media_write(MEDIA_INT_FLASH, addr, buf, SEG_SIZE) != 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to write to Int Flash segment: "); + sys_log_print_hex(addr); + sys_log_new_line(); + + sys_log_print_test_result(false, msg); + sys_log_new_line(); + + return; // cppcheck-suppress misra-c2012-15.5 + } + + vTaskDelay(pdMS_TO_TICKS(10U)); + + (void)memset(buf, 0U, SEG_SIZE); + + if (media_read(MEDIA_INT_FLASH, addr, buf, SEG_SIZE) != 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to read from Int Flash segment: "); + sys_log_print_hex(addr); + sys_log_new_line(); + + sys_log_print_test_result(false, msg); + sys_log_new_line(); + + return; // cppcheck-suppress misra-c2012-15.5 + } + + vTaskDelay(pdMS_TO_TICKS(10U)); + + test_result = (memcmp(data, buf, SEG_SIZE) == 0); + + sys_log_print_test_result(test_result, msg); + sys_log_new_line(); +} + +static void fram_sector_check(const char *msg, const uint8_t *data, uint32_t addr) +{ + uint32_t page = ADDR_TO_PAGE(addr); + uint32_t last_page = page + (uint32_t)1ULL; + uint32_t pages_left; + bool test_result; + + do { + test_result = mem_check_pages(MEDIA_FRAM, data, page, last_page, &pages_left); + + sys_log_print_test_result(test_result, msg); + sys_log_print_msg(" Sector Test"); + sys_log_new_line(); + + page++; + } while (pages_left > 0ULL); +} + +static void nor_sector_check(const char *msg, const uint8_t *data, uint32_t first_page) +{ + uint32_t page; + uint32_t last_page; + uint32_t pages_left; + bool test_result; + + page = first_page; + last_page = page + PAGE_CHECK_DEPTH; + + do { + test_result = mem_check_pages(MEDIA_NOR, data, page, last_page, &pages_left); + + sys_log_print_test_result(test_result, msg); + sys_log_print_msg(" Sector, Page: "); + sys_log_print_uint(page); + sys_log_print_msg(" Test"); + sys_log_new_line(); + + page++; + } while (pages_left > 0ULL); +} + +static bool mem_check_pages(media_t media, const uint8_t *page_data, uint32_t first_page, uint32_t last_page, uint32_t *pages_left) +{ + uint8_t buf[PAGE_SIZE]; + bool test_result = false; + uint32_t addr = PAGE_TO_ADDR(first_page); + + *pages_left = last_page - first_page; + + (void)memcpy(buf, page_data, PAGE_SIZE); + + if (media_write(media, addr, buf, PAGE_SIZE) != 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to write to NOR page: "); + sys_log_print_uint(first_page); + sys_log_new_line(); + return false; // cppcheck-suppress misra-c2012-15.5 + } + + vTaskDelay(pdMS_TO_TICKS(10U)); + + (void)memset(buf, 0U, PAGE_SIZE); + + if (media_read(media, addr, buf, PAGE_SIZE) != 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to read NOR page: "); + sys_log_print_uint(first_page); + sys_log_new_line(); + return false; // cppcheck-suppress misra-c2012-15.5 + } + + vTaskDelay(pdMS_TO_TICKS(10U)); + + test_result = (memcmp(page_data, buf, PAGE_SIZE) == 0); + + (*pages_left)--; + + return test_result; +} + +static int32_t mem_full_clean(void) +{ + int32_t err = 0; + + if (media_erase(MEDIA_NOR, MEDIA_ERASE_DIE, 0U) != 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to erase NOR die "); + sys_log_print_uint((uint32_t) 0ULL); + sys_log_new_line(); + err--; + } + + if (media_erase(MEDIA_NOR, MEDIA_ERASE_DIE, 1U) != 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to erase NOR die "); + sys_log_print_uint((uint32_t) 1ULL); + sys_log_new_line(); + err--; + } + + if (media_erase(MEDIA_INT_FLASH, MEDIA_ERASE_SECTOR, FLASH_SEG_A_ADR) != 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to erase Int Flash Segment A"); + sys_log_new_line(); + err--; + } + + if (media_erase(MEDIA_INT_FLASH, MEDIA_ERASE_SECTOR, FLASH_SEG_B_ADR) != 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to erase Int Flash Segment B"); + sys_log_new_line(); + err--; + } + + const uint32_t addrs[] = {CONFIG_MEM_ADR_INIT_WORD, CONFIG_MEM_ADR_SYS_PARAM, CONFIG_MEM_ADR_SYS_TIME}; + uint8_t buf[PAGE_SIZE]; + + (void)memset(buf, 0xFFU, PAGE_SIZE); + + for (uint8_t i = 0U; i < ARR_SIZE(addrs); ++i) + { + if (media_write(MEDIA_FRAM, addrs[i], buf, PAGE_SIZE) != 0) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_HEALTH_CHECK_MEM_NAME, "Failed to erase FRAM on addr: "); + sys_log_print_hex(addrs[i]); + sys_log_new_line(); + err--; + } + } + + return err; +} + +static void prepare_obdh_s(obdh_telemetry_t *tel) +{ + tel->timestamp = 0xaaaaaaaa; + tel->data.temperature = 300U; + tel->data.current = 40U; + tel->data.voltage = 3300U; + tel->data.last_reset_cause = 0x01; + tel->data.reset_counter = 0xa0; + tel->data.last_valid_tc = 0x10; + tel->data.hw_version = 0x02; + tel->data.fw_version = 0x1018; + tel->data.mode = 0x01; + tel->data.ts_last_mode_change = 0xbbbbbbbb; + tel->data.mode_duration = 0xcccccccc; + tel->data.initial_hib_executed = true; + tel->data.initial_hib_time_count = 40U; + tel->data.ant_deployment_executed = true; + tel->data.ant_deployment_counter = 5U; + tel->data.position.timestamp = OBDH_PARAM_POSITION_TIMESTAMP_DEFAULT_VAL; + + uint8_t tle_line1[70] = OBDH_PARAM_POSITION_TLE_LINE1_DEFAULT_VAL; + uint8_t tle_line2[70] = OBDH_PARAM_POSITION_TLE_LINE2_DEFAULT_VAL; + + (void)memcpy(&tel->data.position.tle_line1, &tle_line1[0], 70U); + (void)memcpy(&tel->data.position.tle_line2, &tle_line2[0], 70U); + + tel->data.position.latitude = OBDH_PARAM_POSITION_LATITUDE_DEFAULT_VAL; + tel->data.position.longitude = OBDH_PARAM_POSITION_LONGITUDE_DEFAULT_VAL; + tel->data.position.altitude = OBDH_PARAM_POSITION_ALTITUDE_DEFAULT_VAL; + tel->data.media.last_page_obdh_data = OBDH_PARAM_MEDIA_LAST_OBDH_DATA_DEFAULT_VAL; + tel->data.media.last_page_eps_data = OBDH_PARAM_MEDIA_LAST_EPS_DATA_DEFAULT_VAL; + tel->data.media.last_page_ttc_0_data = OBDH_PARAM_MEDIA_LAST_TTC_0_DATA_DEFAULT_VAL; + tel->data.media.last_page_ttc_1_data = OBDH_PARAM_MEDIA_LAST_TTC_1_DATA_DEFAULT_VAL; + tel->data.media.last_page_ant_data = OBDH_PARAM_MEDIA_LAST_ANT_DATA_DEFAULT_VAL; + tel->data.media.last_page_edc_data = OBDH_PARAM_MEDIA_LAST_EDC_DATA_DEFAULT_VAL; + tel->data.media.last_page_px_data = OBDH_PARAM_MEDIA_LAST_PX_DATA_DEFAULT_VAL; + tel->data.media.last_page_sbcd_pkts = OBDH_PARAM_MEDIA_LAST_SBCD_PKTS_DEFAULT_VAL; +} + +/** \} End of mem_check group */ diff --git a/firmware/app/tasks/mem_check.h b/firmware/app/tasks/mem_check.h new file mode 100644 index 00000000..0fd4a178 --- /dev/null +++ b/firmware/app/tasks/mem_check.h @@ -0,0 +1,62 @@ +/* + * mem_check.h + * + * Copyright The OBDH 2.0 Contributors. + * + * This file is part of OBDH 2.0. + * + * OBDH 2.0 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OBDH 2.0 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OBDH 2.0. If not, see . + * + */ + +/** + * \brief Memory Health Check Tasks definitions + * + * \author Carlos Augusto Porto Freitas + * + * \version 0.10.18 + * + * \date 2024/07/24 + * + * \defgroup mem_check Memory Check + * \ingroup tasks + * \{ + */ + +#ifndef MEM_CHECK_H_ +#define MEM_CHECK_H_ + +#include +#include + +#define TASK_HEALTH_CHECK_MEM_NAME "HealthCheck Mem" /**< Task name. */ +#define TASK_HEALTH_CHECK_MEM_STACK_SIZE 1024U /**< Stack size in bytes. */ +#define TASK_HEALTH_CHECK_MEM_PRIORITY 4U /**< Task priority. */ +#define TASK_HEALTH_CHECK_MEM_INIT_TIMEOUT_MS 5000U /**< Task priority. */ + +/** + * \brief Health Check Memory Task Handle + */ +extern TaskHandle_t xTaskHealthCheckMemHandle; + +/** + * \brief Health Check Memory Task + * + * \return None. + */ +void vTaskHealthCheckMem(void); + +#endif + +/** \} End of mem_check group */ diff --git a/firmware/app/tasks/read_edc.c b/firmware/app/tasks/read_edc.c index 260e43c4..17aec0bb 100644 --- a/firmware/app/tasks/read_edc.c +++ b/firmware/app/tasks/read_edc.c @@ -24,8 +24,9 @@ * \brief Read EDC task implementation. * * \author Gabriel Mariano Marcelino - * - * \version 0.10.9 + * \author Carlos Augusto Porto Freitas + * + * \version 0.10.18 * * \date 2020/08/16 * @@ -71,11 +72,11 @@ void vTaskReadEDC(void) /* Read packets */ uint8_t state_arr[10] = {0}; - uint32_t state_len = 0; + int32_t state_len = 0; if (payload_get_data(pl_edc_active, PAYLOAD_EDC_STATE, state_arr, &state_len) == 0) { - if (state_len >= sizeof(edc_state_t)) + if (state_len >= (int32_t)sizeof(edc_state_t)) { edc_state_t state = *(edc_state_t*)&state_arr[0]; @@ -90,20 +91,11 @@ void vTaskReadEDC(void) for(i = 0; i < state.ptt_available; i++) { uint8_t ptt_arr[50] = {0}; - uint32_t ptt_len = 0; + int32_t ptt_len = 0; if (payload_get_data(pl_edc_active, PAYLOAD_EDC_PTT, ptt_arr, &ptt_len) == 0) { - if (media_write(MEDIA_NOR, sat_data_buf.obdh.data.media.last_page_sbcd_pkts * nor_info.page_size, ptt_arr, nor_info.page_size) == 0) - { - sat_data_buf.obdh.data.media.last_page_sbcd_pkts++; - - if (sat_data_buf.obdh.data.media.last_page_sbcd_pkts > CONFIG_MEM_SBCD_PKTS_END_PAGE) - { - sat_data_buf.obdh.data.media.last_page_sbcd_pkts = CONFIG_MEM_SBCD_PKTS_START_PAGE; - } - } - else + if (mem_mng_write_data_to_flash_page(ptt_arr, &sat_data_buf.obdh.data.media.last_page_sbcd_pkts, nor_info.page_size, CONFIG_MEM_SBCD_PKTS_START_PAGE, CONFIG_MEM_SBCD_PKTS_END_PAGE) != 0) { sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_READ_EDC_NAME, "Error writing the PTT packet to the flash memory!"); sys_log_new_line(); diff --git a/firmware/app/tasks/read_edc.h b/firmware/app/tasks/read_edc.h index 1a91be4b..6df713fd 100644 --- a/firmware/app/tasks/read_edc.h +++ b/firmware/app/tasks/read_edc.h @@ -24,8 +24,9 @@ * \brief Read EDC data task definition. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.9.14 + * \version 0.10.18 * * \date 2020/08/16 * @@ -52,7 +53,7 @@ typedef struct { uint8_t buffer[30]; - uint32_t length; + int32_t length; } pl_edc_hk_raw_t; /** diff --git a/firmware/app/tasks/read_px.c b/firmware/app/tasks/read_px.c index f044aa4c..71ecd0c9 100644 --- a/firmware/app/tasks/read_px.c +++ b/firmware/app/tasks/read_px.c @@ -24,8 +24,9 @@ * \brief Read PX task implementation. * * \author Augusto Cezar Boldori Vassoler - * - * \version 0.0.1 + * \author Carlos Augusto Porto Freitas + * + * \version 0.10.18 * * \date 2023/08/28 * @@ -33,6 +34,8 @@ * \{ */ +#include + #include #include #include @@ -61,8 +64,8 @@ void vTaskReadPX(void) { sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_READ_PX_NAME, "Error reading the ping-pong data!"); - uint8_t i = 0; - for(i=0;i - * - * \version 0.0.1 + * \author Carlos Augusto Porto Freitas + * + * \version 0.10.18 * * \date 2023/08/28 * @@ -52,7 +53,7 @@ typedef struct { uint8_t buffer[4]; - uint32_t length; + int32_t length; } pl_px_buf_t; /** diff --git a/firmware/app/tasks/startup.c b/firmware/app/tasks/startup.c index ffa039a7..dd79cac6 100644 --- a/firmware/app/tasks/startup.c +++ b/firmware/app/tasks/startup.c @@ -24,8 +24,9 @@ * \brief Startup task implementation. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.10.17 + * \version 0.10.18 * * \date 2019/12/04 * @@ -49,16 +50,22 @@ #include #include #include +#include #include "startup.h" +#define MEDIA_INIT_MAX_RETRY 3 + xTaskHandle xTaskStartupHandle; EventGroupHandle_t task_startup_status; +static int media_nor_clean(void); + void vTaskStartup(void) { unsigned int error_counter = 0; + int err = -1; /* Logger device initialization */ sys_log_init(); @@ -97,62 +104,82 @@ void vTaskStartup(void) } #endif /* CONFIG_DEV_MEDIA_INT_ENABLED */ +#if defined(CONFIG_DEV_MEDIA_NOR_ENABLED) && (CONFIG_DEV_MEDIA_NOR_ENABLED == 1) + /* NOR memory initialization */ + for (int i = 0; i < MEDIA_INIT_MAX_RETRY; ++i) + { + if (media_init(MEDIA_NOR) == 0) + { + err = 0; + break; + } + } + + if (err != 0) + { + error_counter++; + } + else + { + err = -1; + } +#endif /* CONFIG_DEV_MEDIA_NOR_ENABLED */ + #if defined(CONFIG_DEV_MEDIA_FRAM_ENABLED) && (CONFIG_DEV_MEDIA_FRAM_ENABLED == 1) /* FRAM memory initialization */ if (system_get_hw_version() >= HW_VERSION_1) { - if (media_init(MEDIA_FRAM) == 0) - { - /* Check if FRAM is initialized */ - if (mem_mng_check_fram() == 0) + for (int i = 0; i < MEDIA_INIT_MAX_RETRY; ++i) + { // cppcheck-suppress misra-c2012-15.4 + if (media_init(MEDIA_FRAM) == 0) { - /* Load last saved OBDH data from FRAM */ - if (mem_mng_load_obdh_data_from_fram(&sat_data_buf.obdh) != 0) + /* Check if FRAM is initialized */ + if (mem_mng_check_fram() == 0) { - error_counter++; + /* Load last saved OBDH data from FRAM */ + if (mem_mng_load_obdh_data_from_fram(&sat_data_buf.obdh) == 0) + { + err = 0; + break; + } } - } - else - { - sys_log_print_event_from_module(SYS_LOG_WARNING, TASK_STARTUP_NAME, "FRAM was not initialized in previous cycles"); - sys_log_new_line(); - - /* Initialize FRAM */ - if (mem_mng_init_fram() == 0) + else { - /* Load default values to the OBDH data buffer */ - mem_mng_load_obdh_data_from_default_values(&sat_data_buf.obdh); + sys_log_print_event_from_module(SYS_LOG_WARNING, TASK_STARTUP_NAME, "FRAM was not initialized in previous cycles!"); + sys_log_new_line(); - sys_log_print_event_from_module(SYS_LOG_WARNING, TASK_STARTUP_NAME, "Loading default values to FRAM..."); + sys_log_print_event_from_module(SYS_LOG_WARNING, TASK_STARTUP_NAME, "Trying to clean NOR memory!"); sys_log_new_line(); - /* Write the OBDH data to the FRAM memory */ - if (mem_mng_save_obdh_data_to_fram(&sat_data_buf.obdh) != 0) + (void)media_nor_clean(); + + /* Initialize FRAM */ + if (mem_mng_init_fram() == 0) { - error_counter++; + /* Load default values to the OBDH data buffer */ + mem_mng_load_obdh_data_from_default_values(&sat_data_buf.obdh); + + sys_log_print_event_from_module(SYS_LOG_WARNING, TASK_STARTUP_NAME, "Loading default values to FRAM!"); + sys_log_new_line(); + + /* Write the OBDH data to the FRAM memory */ + if (mem_mng_save_obdh_data_to_fram(&sat_data_buf.obdh) == 0) + { + err = 0; + break; + } } } - else - { - error_counter++; - } } } - else + + if (err != 0) { error_counter++; } } #endif /* CONFIG_DEV_MEDIA_FRAM_ENABLED */ -#if defined(CONFIG_DEV_MEDIA_NOR_ENABLED) && (CONFIG_DEV_MEDIA_NOR_ENABLED == 1) - /* NOR memory initialization */ - if (media_init(MEDIA_NOR) != 0) - { - error_counter++; - } -#endif /* CONFIG_DEV_MEDIA_NOR_ENABLED */ - #if defined(CONFIG_DEV_LEDS_ENABLED) && (CONFIG_DEV_LEDS_ENABLED == 1) /* LEDs device initialization */ if (leds_init() != 0) @@ -250,4 +277,21 @@ void vTaskStartup(void) vTaskSuspend(xTaskStartupHandle); } +static int media_nor_clean(void) +{ + int err = 0; + + if (media_erase(MEDIA_NOR, MEDIA_ERASE_DIE, 0U) != 0) + { + err--; + } + + if (media_erase(MEDIA_NOR, MEDIA_ERASE_DIE, 1U) != 0) + { + err--; + } + + return err; +} + /** \} End of startup group */ diff --git a/firmware/app/tasks/tasks.c b/firmware/app/tasks/tasks.c index 384772e8..97da4fc1 100644 --- a/firmware/app/tasks/tasks.c +++ b/firmware/app/tasks/tasks.c @@ -24,8 +24,9 @@ * \brief Tasks implementation. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.10.17 + * \version 0.10.18 * * \date 2019/11/02 * @@ -55,6 +56,7 @@ #include "pos_det.h" #include "read_px.h" #include "housekeeping.h" +#include "mem_check.h" void create_tasks(void) { @@ -214,6 +216,16 @@ void create_tasks(void) } #endif /* CONFIG_TASK_HOUSEKEEPING_ENABLED */ +#if defined(CONFIG_TASK_HEALTH_CHECK_MEM_ENABLED) && (CONFIG_TASK_HEALTH_CHECK_MEM_ENABLED == 1) + xTaskCreate(vTaskHealthCheckMem, TASK_HEALTH_CHECK_MEM_NAME, TASK_HEALTH_CHECK_MEM_STACK_SIZE, NULL, TASK_HEALTH_CHECK_MEM_PRIORITY, &xTaskHealthCheckMemHandle); + + if (xTaskHealthCheckMemHandle == NULL) + { + /* Error creating the Housekeeping task */ + } +#endif /* CONFIG_TASK_HOUSEKEEPING_ENABLED */ + + create_event_groups(); } diff --git a/firmware/app/tasks/time_control.c b/firmware/app/tasks/time_control.c index 4936f016..47d6b6ea 100644 --- a/firmware/app/tasks/time_control.c +++ b/firmware/app/tasks/time_control.c @@ -24,8 +24,9 @@ * \brief Time control task implementation. * * \author Gabriel Mariano Marcelino - * - * \version 0.10.9 + * \author Carlos Augusto Porto Freitas + * + * \version 0.10.18 * * \date 2020/08/09 * @@ -120,6 +121,13 @@ void vTaskTimeControl(void) sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_TIME_CONTROL_NAME, "Error saving the system time!"); sys_log_new_line(); } + else + { + sys_log_print_event_from_module(SYS_LOG_INFO, TASK_TIME_CONTROL_NAME, "Saving system time (epoch): "); + sys_log_print_uint(sys_tm); + sys_log_print_msg(" sec"); + sys_log_new_line(); + } } vTaskDelayUntil(&last_cycle, pdMS_TO_TICKS(TASK_TIME_CONTROL_PERIOD_MS)); diff --git a/firmware/app/utils/mem_mng.c b/firmware/app/utils/mem_mng.c index 21dc9cc1..51b4b712 100644 --- a/firmware/app/utils/mem_mng.c +++ b/firmware/app/utils/mem_mng.c @@ -24,8 +24,9 @@ * \brief Memory management routines implementation. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.10.17 + * \version 0.10.18 * * \date 2024/02/24 * @@ -38,9 +39,18 @@ #include #include +#include +#include +#include #include "mem_mng.h" +#define CRC8_POLYNOMIAL 0x07U +#define CRC8_INITIAL_VAL 0x00U +#define BAK_INIT_VAL 0xAAU + +static uint8_t crc8(uint8_t *data, uint8_t len); + int mem_mng_check_fram(void) { int err = -1; @@ -129,7 +139,7 @@ void mem_mng_load_obdh_data_from_default_values(obdh_telemetry_t *tel) tel->data.media.last_page_sbcd_pkts = OBDH_PARAM_MEDIA_LAST_SBCD_PKTS_DEFAULT_VAL; } -int mem_mng_save_obdh_data_to_fram(obdh_telemetry_t* tel) +int mem_mng_save_obdh_data_to_fram(obdh_telemetry_t *tel) { int err = -1; @@ -160,4 +170,85 @@ int mem_mng_load_obdh_data_from_fram(obdh_telemetry_t *tel) return err; } +int mem_mng_write_data_to_flash_page(uint8_t *data, uint32_t *page, uint32_t page_size, uint32_t start_page, uint32_t end_page) +{ + int err = -1; + + if (media_write(MEDIA_NOR, (*page) * page_size, data, page_size) == 0) + { + (*page)++; // cppcheck-suppress misra-c2012-17.8 + + if (*page > end_page) + { + *page = start_page; + } + + err = 0; + } + + return err; +} + +void mem_mng_save_obdh_data_bak(obdh_telemetry_t *tel) +{ + uintptr_t base_addr = CONFIG_MEM_ADR_SYS_PARAM_BAK; + uint8_t buf[BAK_DATA_SIZE + 2U]; + + flash_erase(base_addr); + + (void)memcpy(buf, tel, BAK_DATA_SIZE); + + buf[BAK_DATA_SIZE] = crc8(buf, BAK_DATA_SIZE); + buf[BAK_DATA_SIZE + 1U] = BAK_INIT_VAL; + + for (uint8_t i = 0U; i < BAK_DATA_SIZE + 2U; ++i) + { + uintptr_t addr = base_addr + i; + flash_write_single(buf[i], addr); + } +} + +int mem_mng_load_obdh_data_bak(obdh_telemetry_t *tel) +{ + int err = -1; + + uintptr_t base_addr = CONFIG_MEM_ADR_SYS_PARAM_BAK; + uint8_t buf[BAK_DATA_SIZE + 2U]; + + for (uint8_t i = 0U; i < BAK_DATA_SIZE + 2U; ++i) + { + uintptr_t addr = base_addr + i; + buf[i] = flash_read_single(addr); + } + + if ((buf[BAK_DATA_SIZE] == crc8(buf, BAK_DATA_SIZE)) && (buf[BAK_DATA_SIZE + 1U] == BAK_INIT_VAL)) + { + (void)memcpy(tel, buf, BAK_DATA_SIZE); + err = 0; + } + + return err; +} + +static uint8_t crc8(uint8_t *data, uint8_t len) +{ + uint8_t crc = CRC8_INITIAL_VAL; + + uint8_t i = 0U; + for(i = 0; i < len; i++) + { + crc ^= data[i]; + + uint8_t j = 0U; + for (j = 0U; j < 8U; j++) + { + crc = (crc << 1) ^ ((crc & 0x80U) ? CRC8_POLYNOMIAL : 0U); + } + + crc &= 0xFFU; + } + + return crc; +} + /** \} End of mem_mng group */ diff --git a/firmware/app/utils/mem_mng.h b/firmware/app/utils/mem_mng.h index f35cc1e5..292a3169 100644 --- a/firmware/app/utils/mem_mng.h +++ b/firmware/app/utils/mem_mng.h @@ -24,8 +24,9 @@ * \brief Memory management routines. * * \author Gabriel Mariano Marcelino - * - * \version 0.10.17 + * \author Carlos Augusto Porto Freitas + * + * \version 0.10.18 * * \date 2024/02/24 * @@ -43,6 +44,8 @@ #define MEM_MNG_NAME "Memory Management" +#define BAK_DATA_SIZE (sizeof(obdh_telemetry_t) - sizeof(position_data_t)) + /** * \brief Checks if the FRAM memory is initialized or not. * @@ -91,6 +94,41 @@ int mem_mng_save_obdh_data_to_fram(obdh_telemetry_t *tel); */ int mem_mng_load_obdh_data_from_fram(obdh_telemetry_t *tel); +/** + * \brief Saves the OBDH data to internal flash as backup. + * + * \param[in] tel is the OBDH telemetry data to be saved. + * + * \return None. + */ +void mem_mng_save_obdh_data_bak(obdh_telemetry_t *tel); + +/** + * \brief Loads the last saved OBDH data from the backup on internal flash. + * + * \param[in] tel is a pointer to store the read data. + * + * \return None. + */ +int mem_mng_load_obdh_data_bak(obdh_telemetry_t *tel); + +/** + * \brief Writes data to a given flash memory page. + * + * \param[in] is the array of bytes to write. + * + * \param[in,out] page is a pointer to the current page to write. + * + * \param[in] page_size is the page size, in bytes, of the flash memory. + * + * \param[in] start_page is the possible start page to write. + * + * \param[in] end_page is the possible end page to write. + * + * \return The status/error code. + */ +int mem_mng_write_data_to_flash_page(uint8_t *data, uint32_t *page, uint32_t page_size, uint32_t start_page, uint32_t end_page); + #endif /* MEM_MNG_H_ */ /** \} End of mem_mng group */ diff --git a/firmware/config/config.h b/firmware/config/config.h index 6f8cb064..a2b190ad 100644 --- a/firmware/config/config.h +++ b/firmware/config/config.h @@ -24,8 +24,9 @@ * \brief Configuration parameters definition. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.10.17 + * \version 0.10.18 * * \date 2019/10/26 * @@ -54,6 +55,7 @@ #define CONFIG_TASK_POSITION_DETERMINATION_ENABLED 1 #define CONFIG_TASK_PAYLOAD_X_ENABLED 1 #define CONFIG_TASK_HOUSEKEEPING_ENABLED 1 +#define CONFIG_TASK_HEALTH_CHECK_MEM_ENABLED 0 /* Devices */ #define CONFIG_DEV_MEDIA_INT_ENABLED 1 @@ -72,6 +74,9 @@ #define CONFIG_DRV_ISIS_ANTENNA_ENABLED 1 #define CONFIG_DRV_SL_ANTENNA_ENABLED 0 +/* Health Check */ +#define CONFIG_HEALTH_CHECK_ENABLED 0 + /* Debug and log messages */ #define CONFIG_DRIVERS_DEBUG_ENABLED 0 @@ -154,6 +159,55 @@ #define CONFIG_MEM_PX_DATA_END_PAGE 398999U #define CONFIG_MEM_SBCD_PKTS_START_PAGE 399000U #define CONFIG_MEM_SBCD_PKTS_END_PAGE 499999U +#define CONFIG_MEM_ADR_SYS_TIME_BAK 0x1980U +#define CONFIG_MEM_ADR_SYS_PARAM_BAK 0x1900U + +/* Health Check Config Parameters */ +#if defined(CONFIG_HEALTH_CHECK_ENABLED) && (CONFIG_HEALTH_CHECK_ENABLED == 1) + +/* Tasks */ +#define CONFIG_TASK_STARTUP_ENABLED 1 +#define CONFIG_TASK_WATCHDOG_RESET_ENABLED 1 +#define CONFIG_TASK_HEARTBEAT_ENABLED 0 +#define CONFIG_TASK_SYSTEM_RESET_ENABLED 0 +#define CONFIG_TASK_READ_SENSORS_ENABLED 0 +#define CONFIG_TASK_BEACON_ENABLED 0 +#define CONFIG_TASK_TIME_CONTROL_ENABLED 0 +#define CONFIG_TASK_READ_EDC_ENABLED 0 +#define CONFIG_TASK_READ_EPS_ENABLED 0 +#define CONFIG_TASK_READ_TTC_ENABLED 0 +#define CONFIG_TASK_READ_ANTENNA_ENABLED 0 +#define CONFIG_TASK_DATA_LOG_ENABLED 0 +#define CONFIG_TASK_PROCESS_TC_ENABLED 0 +#define CONFIG_TASK_ANTENNA_DEPLOYMENT_ENABLED 0 +#define CONFIG_TASK_POSITION_DETERMINATION_ENABLED 0 +#define CONFIG_TASK_PAYLOAD_X_ENABLED 0 +#define CONFIG_TASK_HOUSEKEEPING_ENABLED 0 +#define CONFIG_TASK_HEALTH_CHECK_MEM_ENABLED 1 + +/* Devices */ +#define CONFIG_DEV_MEDIA_INT_ENABLED 1 +#define CONFIG_DEV_MEDIA_FRAM_ENABLED 1 +#define CONFIG_DEV_MEDIA_NOR_ENABLED 1 +#define CONFIG_DEV_LEDS_ENABLED 0 +#define CONFIG_DEV_CURRENT_SENSOR_ENABLED 0 +#define CONFIG_DEV_VOLTAGE_SENSOR_ENABLED 0 +#define CONFIG_DEV_TEMP_SENSOR_ENABLED 0 +#define CONFIG_DEV_EPS_ENABLED 0 +#define CONFIG_DEV_PAYLOAD_EDC_ENABLED 0 +#define CONFIG_DEV_ANTENNA_ENABLED 0 +#define CONFIG_DEV_PAYLOAD_X_ENABLED 0 + +/* Drivers */ +#define CONFIG_DRV_ISIS_ANTENNA_ENABLED 0 +#define CONFIG_DRV_SL_ANTENNA_ENABLED 0 + +#endif + +#if defined (CONFIG_TASK_HEALTH_CHECK_MEM_ENABLED) && defined (CONFIG_HEALTH_CHECK_ENABLED) && \ + (CONFIG_TASK_HEALTH_CHECK_MEM_ENABLED == 1) && (CONFIG_HEALTH_CHECK_ENABLED == 0) +#error To enable memory Health Check please set the CONFIG_HEALTH_CHECK_ENABLED flag on config.h +#endif #endif /* CONFIG_H_ */ diff --git a/firmware/devices/media/media.c b/firmware/devices/media/media.c index 807c85c5..7c0535c7 100644 --- a/firmware/devices/media/media.c +++ b/firmware/devices/media/media.c @@ -24,8 +24,9 @@ * \brief Media device implementation. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.8.10 + * \version 0.10.18 * * \date 2020/07/21 * @@ -65,7 +66,13 @@ int media_init(media_t med) if (cy15x102qn_init(&fram_conf) == 0) { - err = 0; + /* BP0 = 0, BP1 = 0, WPEN = 0 */ + cy15x102qn_status_t status = 0x00U; + + if (cy15x102qn_write_status_reg(&fram_conf, status) == 0) + { + err = 0; + } } else { @@ -146,15 +153,22 @@ int media_write(media_t med, uint32_t adr, uint8_t *data, uint16_t len) { case MEDIA_INT_FLASH: { + if ((adr + len) > INFO_SEG_SIZE) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, MEDIA_MODULE_NAME, "Error writing to Int Flash!! Segment would overflow!"); + sys_log_new_line(); + break; + } + /* Address index */ - uint32_t adr_idx = adr + FLASH_SEG_A_ADR; + uintptr_t adr_idx = adr + FLASH_SEG_A_ADR; uint16_t i = 0; - for(i=0; i INFO_SEG_SIZE) + { + sys_log_print_event_from_module(SYS_LOG_ERROR, MEDIA_MODULE_NAME, "Error reading from Int Flash!! Segment would overflow!"); + sys_log_new_line(); + break; + } + /* Address index */ - uint32_t adr_idx = adr + FLASH_SEG_A_ADR; + uintptr_t adr_idx = adr + FLASH_SEG_A_ADR; uint16_t i = 0; - for(i=0; i UINT8_MAX) + if ((sector == FLASH_SEG_A_ADR) || (sector == FLASH_SEG_B_ADR)) { - sector_conv = UINT8_MAX; + flash_erase((uintptr_t)sector); + err = 0; } - else + else { - sector_conv = (uint8_t)sector; + sys_log_print_event_from_module(SYS_LOG_ERROR, MEDIA_MODULE_NAME, "Error erasing the Int Flash, invalid sector!"); + sys_log_new_line(); } - - flash_write_single(0xFF, §or_conv); - - err = 0; - break; } case MEDIA_FRAM: diff --git a/firmware/devices/payload/payload.c b/firmware/devices/payload/payload.c index b9885791..38cdf1c3 100644 --- a/firmware/devices/payload/payload.c +++ b/firmware/devices/payload/payload.c @@ -25,8 +25,9 @@ * * \author Gabriel Mariano Marcelino * \author João Cláudio Elsen Barcellos + * \author Carlos Augusto Porto Freitas * - * \version 0.10.10 + * \version 0.10.18 * * \date 2021/08/15 * @@ -326,7 +327,7 @@ int payload_write_cmd(payload_t pl, payload_cmd_t cmd) return err; } -int payload_get_data(payload_t pl, payload_data_id_t id, uint8_t *data, uint32_t *len) +int payload_get_data(payload_t pl, payload_data_id_t id, uint8_t *data, int32_t *len) { int err = -1; diff --git a/firmware/devices/payload/payload.h b/firmware/devices/payload/payload.h index bb6aa830..e8effa75 100644 --- a/firmware/devices/payload/payload.h +++ b/firmware/devices/payload/payload.h @@ -24,8 +24,9 @@ * \brief Payload device definition. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.10.10 + * \version 0.10.18 * * \date 2021/08/15 * @@ -160,7 +161,7 @@ int payload_write_cmd(payload_t pl, payload_cmd_t cmd); * * \return The status/error code. */ -int payload_get_data(payload_t pl, payload_data_id_t id, uint8_t *data, uint32_t *len); +int payload_get_data(payload_t pl, payload_data_id_t id, uint8_t *data, int32_t *len); #endif /* PAYLOAD_H_ */ diff --git a/firmware/drivers/cy15x102qn/cy15x102qn.c b/firmware/drivers/cy15x102qn/cy15x102qn.c index d070e5ab..518e64a4 100644 --- a/firmware/drivers/cy15x102qn/cy15x102qn.c +++ b/firmware/drivers/cy15x102qn/cy15x102qn.c @@ -26,7 +26,7 @@ * \author Gabriel Mariano Marcelino * \author Carlos Augusto Porto Freitas * - * \version 0.10.17 + * \version 0.10.18 * * \date 2021/06/04 * @@ -114,7 +114,7 @@ int cy15x102qn_read_status_reg(cy15x102qn_config_t *conf, cy15x102qn_status_t *s int err = -1; uint8_t cmd[2] = {CY15X102QN_OPCODE_RDSR, 0}; - uint8_t ans[2] = {0}; + uint8_t ans[2]; if (cy15x102qn_spi_transfer(conf, cmd, ans, 2) == 0) { @@ -158,7 +158,7 @@ int cy15x102qn_write(cy15x102qn_config_t *conf, uint32_t adr, uint8_t *data, uin int err = -1; uint8_t cmd = CY15X102QN_OPCODE_WRITE; - uint8_t adr_arr[3] = {0}; + uint8_t adr_arr[3]; adr_arr[0] = (adr >> 16) & 0xFFU; adr_arr[1] = (adr >> 8) & 0xFFU; @@ -166,26 +166,40 @@ int cy15x102qn_write(cy15x102qn_config_t *conf, uint32_t adr, uint8_t *data, uin if (cy15x102qn_mutex_take() == 0) { - if (cy15x102qn_spi_select(conf) == 0) + if (cy15x102qn_set_write_enable(conf) == 0) { - /* Write opcode */ - if (cy15x102qn_spi_write_only(conf, &cmd, 1) == 0) + if (cy15x102qn_spi_select(conf) == 0) { - /* Write address */ - if (cy15x102qn_spi_write_only(conf, adr_arr, 3) == 0) + /* Write opcode */ + if (cy15x102qn_spi_write_only(conf, &cmd, 1) == 0) { - /* Write data */ - if (cy15x102qn_spi_write_only(conf, data, len) == 0) + /* Write address */ + if (cy15x102qn_spi_write_only(conf, adr_arr, 3) == 0) { - if (cy15x102qn_spi_unselect(conf) == 0) + /* Write data */ + if (cy15x102qn_spi_write_only(conf, data, len) == 0) { - err = 0; + if (cy15x102qn_spi_unselect(conf) == 0) + { + err = 0; + } + } + else + { + #if defined(CONFIG_DRIVERS_DEBUG_ENABLED) && (CONFIG_DRIVERS_DEBUG_ENABLED == 1) + sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the data during WRITE command!"); + sys_log_new_line(); + #endif /* CONFIG_DRIVERS_DEBUG_ENABLED */ + if (cy15x102qn_spi_unselect(conf) != 0) + { + err = -2; + } } } else { #if defined(CONFIG_DRIVERS_DEBUG_ENABLED) && (CONFIG_DRIVERS_DEBUG_ENABLED == 1) - sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the data during WRITE command!"); + sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the address during WRITE command!"); sys_log_new_line(); #endif /* CONFIG_DRIVERS_DEBUG_ENABLED */ if (cy15x102qn_spi_unselect(conf) != 0) @@ -197,7 +211,7 @@ int cy15x102qn_write(cy15x102qn_config_t *conf, uint32_t adr, uint8_t *data, uin else { #if defined(CONFIG_DRIVERS_DEBUG_ENABLED) && (CONFIG_DRIVERS_DEBUG_ENABLED == 1) - sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the address during WRITE command!"); + sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the opcode during WRITE command!"); sys_log_new_line(); #endif /* CONFIG_DRIVERS_DEBUG_ENABLED */ if (cy15x102qn_spi_unselect(conf) != 0) @@ -206,17 +220,6 @@ int cy15x102qn_write(cy15x102qn_config_t *conf, uint32_t adr, uint8_t *data, uin } } } - else - { - #if defined(CONFIG_DRIVERS_DEBUG_ENABLED) && (CONFIG_DRIVERS_DEBUG_ENABLED == 1) - sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the opcode during WRITE command!"); - sys_log_new_line(); - #endif /* CONFIG_DRIVERS_DEBUG_ENABLED */ - if (cy15x102qn_spi_unselect(conf) != 0) - { - err = -2; - } - } } (void)cy15x102qn_mutex_give(); @@ -230,7 +233,7 @@ int cy15x102qn_read(cy15x102qn_config_t *conf, uint32_t adr, uint8_t *data, uint int err = -1; uint8_t cmd = CY15X102QN_OPCODE_READ; - uint8_t adr_arr[3] = {0}; + uint8_t adr_arr[3]; adr_arr[0] = (adr >> 16) & 0xFFU; adr_arr[1] = (adr >> 8) & 0xFFU; @@ -302,7 +305,7 @@ int cy15x102qn_fast_read(cy15x102qn_config_t *conf, uint32_t adr, uint8_t *data, int err = -1; uint8_t cmd = CY15X102QN_OPCODE_FSTRD; - uint8_t adr_arr[3] = {0}; + uint8_t adr_arr[3]; uint8_t dummy = CY15X102QN_DUMMY_BYTE; adr_arr[0] = (adr >> 16) & 0xFFU; @@ -388,24 +391,38 @@ int cy15x102qn_special_sector_write(cy15x102qn_config_t *conf, uint8_t adr, uint if (cy15x102qn_spi_select(conf) == 0) { - /* Write opcode */ - if (cy15x102qn_spi_write_only(conf, &cmd, 1) == 0) - { - /* Write address */ - if (cy15x102qn_spi_write_only(conf, &adr, 1) == 0) + if (cy15x102qn_set_write_enable(conf) == 0) + { + /* Write opcode */ + if (cy15x102qn_spi_write_only(conf, &cmd, 1) == 0) { - /* Write data */ - if (cy15x102qn_spi_write_only(conf, data, len) == 0) + /* Write address */ + if (cy15x102qn_spi_write_only(conf, &adr, 1) == 0) { - if (cy15x102qn_spi_unselect(conf) == 0) + /* Write data */ + if (cy15x102qn_spi_write_only(conf, data, len) == 0) { - err = 0; + if (cy15x102qn_spi_unselect(conf) == 0) + { + err = 0; + } + } + else + { + #if defined(CONFIG_DRIVERS_DEBUG_ENABLED) && (CONFIG_DRIVERS_DEBUG_ENABLED == 1) + sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the data during SSWR command!"); + sys_log_new_line(); + #endif /* CONFIG_DRIVERS_DEBUG_ENABLED */ + if (cy15x102qn_spi_unselect(conf) != 0) + { + err = -2; + } } } else { #if defined(CONFIG_DRIVERS_DEBUG_ENABLED) && (CONFIG_DRIVERS_DEBUG_ENABLED == 1) - sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the data during SSWR command!"); + sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the address during SSWR command!"); sys_log_new_line(); #endif /* CONFIG_DRIVERS_DEBUG_ENABLED */ if (cy15x102qn_spi_unselect(conf) != 0) @@ -417,7 +434,7 @@ int cy15x102qn_special_sector_write(cy15x102qn_config_t *conf, uint8_t adr, uint else { #if defined(CONFIG_DRIVERS_DEBUG_ENABLED) && (CONFIG_DRIVERS_DEBUG_ENABLED == 1) - sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the address during SSWR command!"); + sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the opcode during SSWR command!"); sys_log_new_line(); #endif /* CONFIG_DRIVERS_DEBUG_ENABLED */ if (cy15x102qn_spi_unselect(conf) != 0) @@ -426,17 +443,6 @@ int cy15x102qn_special_sector_write(cy15x102qn_config_t *conf, uint8_t adr, uint } } } - else - { - #if defined(CONFIG_DRIVERS_DEBUG_ENABLED) && (CONFIG_DRIVERS_DEBUG_ENABLED == 1) - sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the opcode during SSWR command!"); - sys_log_new_line(); - #endif /* CONFIG_DRIVERS_DEBUG_ENABLED */ - if (cy15x102qn_spi_unselect(conf) != 0) - { - err = -2; - } - } } return err; @@ -509,7 +515,7 @@ int cy15x102qn_read_device_id(cy15x102qn_config_t *conf, cy15x102qn_device_id_t int err = -1; uint8_t cmd = CY15X102QN_OPCODE_RDID; - uint8_t raw_id[9] = {0}; + uint8_t raw_id[9]; if (cy15x102qn_spi_select(conf) == 0) { @@ -572,7 +578,7 @@ int cy15x102qn_read_unique_id(cy15x102qn_config_t *conf, cy15x102qn_uid_t *uid) int err = -1; uint8_t cmd = CY15X102QN_OPCODE_RUID; - uint8_t raw_uid[8] = {0}; + uint8_t raw_uid[8]; if (cy15x102qn_spi_select(conf) == 0) { @@ -629,7 +635,7 @@ int cy15x102qn_write_serial_number(cy15x102qn_config_t *conf, cy15x102qn_serial_ int err = -1; uint8_t cmd = CY15X102QN_OPCODE_WRSN; - uint8_t s_num_arr[8] = {0}; + uint8_t s_num_arr[8]; s_num_arr[0] = s_num.customer_id >> 8; s_num_arr[1] = s_num.customer_id & 0xFFU; @@ -642,21 +648,35 @@ int cy15x102qn_write_serial_number(cy15x102qn_config_t *conf, cy15x102qn_serial_ if (cy15x102qn_spi_select(conf) == 0) { - /* Write opcode */ - if (cy15x102qn_spi_write_only(conf, &cmd, 1) == 0) + if (cy15x102qn_set_write_enable(conf) == 0) { - /* Write data */ - if (cy15x102qn_spi_write_only(conf, s_num_arr, 8) == 0) + /* Write opcode */ + if (cy15x102qn_spi_write_only(conf, &cmd, 1) == 0) { - if (cy15x102qn_spi_unselect(conf) == 0) + /* Write data */ + if (cy15x102qn_spi_write_only(conf, s_num_arr, 8) == 0) { - err = 0; + if (cy15x102qn_spi_unselect(conf) == 0) + { + err = 0; + } + } + else + { + #if defined(CONFIG_DRIVERS_DEBUG_ENABLED) && (CONFIG_DRIVERS_DEBUG_ENABLED == 1) + sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the data during WRSN command!"); + sys_log_new_line(); + #endif /* CONFIG_DRIVERS_DEBUG_ENABLED */ + if (cy15x102qn_spi_unselect(conf) != 0) + { + err = -2; + } } } else { #if defined(CONFIG_DRIVERS_DEBUG_ENABLED) && (CONFIG_DRIVERS_DEBUG_ENABLED == 1) - sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the data during WRSN command!"); + sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the opcode during WRSN command!"); sys_log_new_line(); #endif /* CONFIG_DRIVERS_DEBUG_ENABLED */ if (cy15x102qn_spi_unselect(conf) != 0) @@ -665,17 +685,6 @@ int cy15x102qn_write_serial_number(cy15x102qn_config_t *conf, cy15x102qn_serial_ } } } - else - { - #if defined(CONFIG_DRIVERS_DEBUG_ENABLED) && (CONFIG_DRIVERS_DEBUG_ENABLED == 1) - sys_log_print_event_from_module(SYS_LOG_ERROR, CY15X102QN_MODULE_NAME, "Error writing the opcode during WRSN command!"); - sys_log_new_line(); - #endif /* CONFIG_DRIVERS_DEBUG_ENABLED */ - if (cy15x102qn_spi_unselect(conf) != 0) - { - err = -2; - } - } } return err; @@ -686,7 +695,7 @@ int cy15x102qn_read_serial_number(cy15x102qn_config_t *conf, cy15x102qn_serial_n int err = -1; uint8_t cmd = CY15X102QN_OPCODE_SNR; - uint8_t raw_snr[8] = {0}; + uint8_t raw_snr[8]; if (cy15x102qn_spi_select(conf) == 0) { diff --git a/firmware/drivers/flash/flash.c b/firmware/drivers/flash/flash.c index b4e0fe43..157c7e76 100644 --- a/firmware/drivers/flash/flash.c +++ b/firmware/drivers/flash/flash.c @@ -24,8 +24,9 @@ * \brief Flash driver implementation. * * \author Gabriel Mariano Marcelino - * - * \version 0.8.8 + * \author Carlos Augusto Porto Freitas + * + * \version 0.10.18 * * \date 2020/03/17 * @@ -133,6 +134,7 @@ uint32_t flash_read_long(uint32_t *addr) void flash_erase(uint32_t *region) { uint32_t *erase_ptr = region; + uintptr_t seg = region; if ((FCTL3 & LOCKA) > 0) { @@ -143,7 +145,7 @@ void flash_erase(uint32_t *region) FCTL3 = FWKEY; /* Clear Lock bit */ } - switch(*region) + switch(seg) { case FLASH_BANK_0_ADR: FCTL1 = FWKEY | MERAS; break; case FLASH_BANK_1_ADR: FCTL1 = FWKEY | MERAS; break; diff --git a/firmware/drivers/flash/flash.h b/firmware/drivers/flash/flash.h index 886f2ab0..ddb98033 100644 --- a/firmware/drivers/flash/flash.h +++ b/firmware/drivers/flash/flash.h @@ -24,8 +24,9 @@ * \brief Flash driver definition. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.7.4 + * \version 0.10.18 * * \date 2020/03/17 * @@ -65,6 +66,8 @@ /* Last adress that can write a data(beyond this will enter the overflow) */ #define FLASH_LAST_WRITE_ADDR 0x00087FFF +#define INFO_SEG_SIZE 128U + /** * \brief Flash memory initialization. * diff --git a/firmware/system/sys_log/sys_log.c b/firmware/system/sys_log/sys_log.c index 03643934..a8e1a5b6 100644 --- a/firmware/system/sys_log/sys_log.c +++ b/firmware/system/sys_log/sys_log.c @@ -24,8 +24,9 @@ * \brief System log implementation. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.10.7 + * \version 0.10.18 * * \date 2019/11/03 * @@ -34,6 +35,7 @@ */ #include +#include #include #include @@ -117,7 +119,7 @@ void sys_log_print_event(uint8_t type, const char *event) switch(type) { - case SYS_LOG_INFO: break; + case SYS_LOG_INFO: sys_log_set_color(SYS_LOG_INFO_COLOR); break; case SYS_LOG_WARNING: sys_log_set_color(SYS_LOG_WARNING_COLOR); break; case SYS_LOG_ERROR: sys_log_set_color(SYS_LOG_ERROR_COLOR); break; default: break; @@ -140,7 +142,7 @@ void sys_log_print_event_from_module(uint8_t type, const char *module, const cha switch(type) { - case SYS_LOG_INFO: break; + case SYS_LOG_INFO: sys_log_set_color(SYS_LOG_INFO_COLOR); break; case SYS_LOG_WARNING: sys_log_set_color(SYS_LOG_WARNING_COLOR); break; case SYS_LOG_ERROR: sys_log_set_color(SYS_LOG_ERROR_COLOR); break; default: break; @@ -391,4 +393,27 @@ void sys_log_print_firmware_version(void) sys_log_print_msg(FIRMWARE_VERSION); } +void sys_log_print_test_result(bool result, const char *check_msg) +{ + (void)sys_log_mutex_take(); + + sys_log_print_msg("["); + + if (result) + { + sys_log_set_color(SYS_LOG_COLOR_GREEN); + sys_log_print_msg(" OK "); + sys_log_reset_color(); + } + else + { + sys_log_set_color(SYS_LOG_COLOR_RED); + sys_log_print_msg("FAILED"); + sys_log_reset_color(); + } + + sys_log_print_msg("] "); + sys_log_print_msg(check_msg); +} + /** \} End of sys_log group */ diff --git a/firmware/system/sys_log/sys_log.h b/firmware/system/sys_log/sys_log.h index 260c1d17..0a32b0a0 100644 --- a/firmware/system/sys_log/sys_log.h +++ b/firmware/system/sys_log/sys_log.h @@ -24,8 +24,9 @@ * \brief Functions for printing messages and variables over an UART port. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.7.25 + * \version 0.10.18 * * \date 2019/11/03 * @@ -38,6 +39,7 @@ #define SYS_LOG_H_ #include +#include /** * \brief Event types. @@ -262,6 +264,20 @@ void sys_log_print_splash_screen(void); */ void sys_log_print_firmware_version(void); +/** + * \brief Prints a systemd like check message for a test. + * + * The function takes the xSysLogMutex, but it does not give the mutex back, very much like + * the sys_log_print_event_from_module function. + * + * \param[in] result is the result of the test, True for "OK" and False for "FAILED". + * + * \param[in] check_msg is the message explaining the test. + * + * \return None. + */ +void sys_log_print_test_result(bool result, const char *check_msg); + /** * \brief Initialization of the system log UART port. * diff --git a/firmware/system/sys_log/sys_log_config.h b/firmware/system/sys_log/sys_log_config.h index 8a55f339..027815d9 100644 --- a/firmware/system/sys_log/sys_log_config.h +++ b/firmware/system/sys_log/sys_log_config.h @@ -24,8 +24,9 @@ * \brief System log configuration parameters. * * \author Gabriel Mariano Marcelino + * \author Carlos Augusto Porto Freitas * - * \version 0.3.11 + * \version 0.10.18 * * \date 22/02/2019 * @@ -48,11 +49,12 @@ #define SYS_LOG_UART_BAUDRATE_BPS 115200 /* Mutex config. */ -#define SYS_LOG_MUTEX_WAIT_TIME_MS 100 +#define SYS_LOG_MUTEX_WAIT_TIME_MS 200 /* Log messages colors */ #define SYS_LOG_SYSTEM_TIME_COLOR SYS_LOG_COLOR_GREEN #define SYS_LOG_MODULE_NAME_COLOR SYS_LOG_COLOR_MAGENTA +#define SYS_LOG_INFO_COLOR SYS_LOG_COLOR_WHITE #define SYS_LOG_WARNING_COLOR SYS_LOG_COLOR_YELLOW #define SYS_LOG_ERROR_COLOR SYS_LOG_COLOR_RED diff --git a/firmware/tests/devices/media_test.c b/firmware/tests/devices/media_test.c index e7f3c18a..9f2e3056 100644 --- a/firmware/tests/devices/media_test.c +++ b/firmware/tests/devices/media_test.c @@ -34,6 +34,7 @@ * \{ */ +#include #include #include #include @@ -65,6 +66,16 @@ static void media_init_test(void **state) will_return(__wrap_cy15x102qn_init, 0); + uint8_t status = 0x00U; + + expect_value(__wrap_cy15x102qn_write_status_reg, conf->port, MEDIA_FRAM_SPI_PORT); + expect_value(__wrap_cy15x102qn_write_status_reg, conf->cs_pin, MEDIA_FRAM_SPI_CS_PIN); + expect_value(__wrap_cy15x102qn_write_status_reg, conf->clock_hz, MEDIA_FRAM_SPI_CLOCK_HZ); + expect_value(__wrap_cy15x102qn_write_status_reg, conf->wp_pin, MEDIA_FRAM_WP_PIN); + expect_value(__wrap_cy15x102qn_write_status_reg, status, status); + + will_return(__wrap_cy15x102qn_write_status_reg, 0); + assert_return_code(media_init(MEDIA_FRAM), 0); /* NOR memory */ diff --git a/firmware/tests/drivers/cy15x102qn_test.c b/firmware/tests/drivers/cy15x102qn_test.c index 29f1acdd..82e88ead 100644 --- a/firmware/tests/drivers/cy15x102qn_test.c +++ b/firmware/tests/drivers/cy15x102qn_test.c @@ -149,8 +149,17 @@ static void cy15x102qn_write_status_reg_test(void **state) static void cy15x102qn_write_test(void **state) { + uint8_t cmd = CY15X102QN_OPCODE_WREN; + will_return(__wrap_spi_mutex_take, 0); + expect_value(__wrap_spi_write, port, CY15X102QN_SPI_PORT); + expect_value(__wrap_spi_write, cs, CY15X102QN_SPI_CS); + expect_memory(__wrap_spi_write, data, (void*)&cmd, 1); + expect_value(__wrap_spi_write, len, 1); + + will_return(__wrap_spi_write, 0); + /* Select device */ expect_value(__wrap_spi_select_slave, port, CY15X102QN_SPI_PORT); expect_value(__wrap_spi_select_slave, cs, CY15X102QN_SPI_CS); @@ -159,7 +168,7 @@ static void cy15x102qn_write_test(void **state) will_return(__wrap_spi_select_slave, 0); /* Write opcode */ - uint8_t cmd = CY15X102QN_OPCODE_WRITE; + cmd = CY15X102QN_OPCODE_WRITE; expect_value(__wrap_spi_write, port, CY15X102QN_SPI_PORT); expect_value(__wrap_spi_write, cs, SPI_CS_NONE); @@ -367,6 +376,15 @@ static void cy15x102qn_fast_read_test(void **state) static void cy15x102qn_special_sector_write_test(void **state) { + uint8_t cmd = CY15X102QN_OPCODE_WREN; + + expect_value(__wrap_spi_write, port, CY15X102QN_SPI_PORT); + expect_value(__wrap_spi_write, cs, CY15X102QN_SPI_CS); + expect_memory(__wrap_spi_write, data, (void*)&cmd, 1); + expect_value(__wrap_spi_write, len, 1); + + will_return(__wrap_spi_write, 0); + /* Select device */ expect_value(__wrap_spi_select_slave, port, CY15X102QN_SPI_PORT); expect_value(__wrap_spi_select_slave, cs, CY15X102QN_SPI_CS); @@ -375,7 +393,7 @@ static void cy15x102qn_special_sector_write_test(void **state) will_return(__wrap_spi_select_slave, 0); /* Write opcode */ - uint8_t cmd = CY15X102QN_OPCODE_SSWR; + cmd = CY15X102QN_OPCODE_SSWR; expect_value(__wrap_spi_write, port, CY15X102QN_SPI_PORT); expect_value(__wrap_spi_write, cs, SPI_CS_NONE); @@ -616,6 +634,15 @@ static void cy15x102qn_read_unique_id_test(void **state) static void cy15x102qn_write_serial_number_test(void **state) { + uint8_t cmd = CY15X102QN_OPCODE_WREN; + + expect_value(__wrap_spi_write, port, CY15X102QN_SPI_PORT); + expect_value(__wrap_spi_write, cs, CY15X102QN_SPI_CS); + expect_memory(__wrap_spi_write, data, (void*)&cmd, 1); + expect_value(__wrap_spi_write, len, 1); + + will_return(__wrap_spi_write, 0); + /* Select device */ expect_value(__wrap_spi_select_slave, port, CY15X102QN_SPI_PORT); expect_value(__wrap_spi_select_slave, cs, CY15X102QN_SPI_CS); @@ -624,7 +651,7 @@ static void cy15x102qn_write_serial_number_test(void **state) will_return(__wrap_spi_select_slave, 0); /* Write opcode */ - uint8_t cmd = CY15X102QN_OPCODE_WRSN; + cmd = CY15X102QN_OPCODE_WRSN; expect_value(__wrap_spi_write, port, CY15X102QN_SPI_PORT); expect_value(__wrap_spi_write, cs, SPI_CS_NONE);