diff --git a/AMS_Master_Code/Core/Inc/swo_log.h b/AMS_Master_Code/Core/Inc/swo_log.h index 6368f67..093dd4a 100644 --- a/AMS_Master_Code/Core/Inc/swo_log.h +++ b/AMS_Master_Code/Core/Inc/swo_log.h @@ -14,33 +14,57 @@ #include #define MAX_MESSAGE_LENGTH 256 +#define USE_MULTIPLE_CHANNELS false // if true, each log level has its own channel (FATAL : 0, ERROR : 1, etc.) +#define USE_ANSI_ESCAPE_CODES true // if true, log messages will be colored according to their log level, and the console can be cleared + +#if !USE_MULTIPLE_CHANNELS +#define DEBUG_CHANNEL 0 // channel to output messages on +#define USE_CHANNEL_MASK_VARIABLE true +#endif + +#if USE_CHANNEL_MASK_VARIABLE +#define MASK_VARIABLE logging_mask // variable to store the channel mask, must be globally defined somewhere +extern volatile uint32_t MASK_VARIABLE; +#endif enum log_level_t { - LOG_LEVEL_NOISY, - LOG_LEVEL_DEBUG, - LOG_LEVEL_INFO, - LOG_LEVEL_WARNING, + LOG_LEVEL_FATAL, LOG_LEVEL_ERROR, - LOG_LEVEL_FATAL + LOG_LEVEL_WARNING, + LOG_LEVEL_INFO, + LOG_LEVEL_DEBUG, + LOG_LEVEL_NOISY }; -[[maybe_unused]] static const char * const log_level_names[] = { - "\033[37m[NOISY]\033[0m ", - "\033[37m[DEBUG]\033[0m ", - "\033[97m[INFO] \033[0m ", - "\033[93m[WARN] \033[0m ", - "\033[31m[ERROR]\033[0m ", - "\033[31m[FATAL]\033[0m " -}; +#if USE_ANSI_ESCAPE_CODES +[[maybe_unused]] static const char *const log_level_names[] = { + "\033[31m[FATAL]\033[0m ", "\033[31m[ERROR]\033[0m ", + "\033[93m[WARN] \033[0m ", "\033[97m[INFO] \033[0m ", + "\033[37m[DEBUG]\033[0m ", "\033[37m[NOISY]\033[0m "}; +#else +[[maybe_unused]] static const char *const log_level_names[] = { + "[FATAL] ", "[ERROR] ", "[WARN] ", "[INFO] ", "[DEBUG] ", "[NOISY] "}; +#endif static inline bool __ITM_channel_enabled(uint32_t channel) { - return (ITM->TER & (1UL << channel)) != 0UL; +#if !USE_MULTIPLE_CHANNELS + #if USE_CHANNEL_MASK_VARIABLE + return ((ITM->TER & (1UL << DEBUG_CHANNEL)) != 0UL) && + ((MASK_VARIABLE & (1UL << channel)) != 0UL); + #else + channel = DEBUG_CHANNEL; + #endif +#endif + return ((ITM->TER & (1UL << channel)) != 0UL); } // adapted from ITM_SendChar() in the CMSIS-Core // // channel should be between 0 and 31 static inline uint32_t __swo_putc(uint32_t c, unsigned int channel) { +#if !USE_MULTIPLE_CHANNELS + channel = DEBUG_CHANNEL; +#endif if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ ((ITM->TER & (1UL << channel)) != 0UL)) /* ITM Port enabled */ { @@ -68,15 +92,27 @@ static inline void __swo_print(unsigned int channel, const char *str) { } } +[[maybe_unused]] +static void debug_clear_console() { + for (int i = 0; i < LOG_LEVEL_NOISY; i++) { +#if USE_ANSI_ESCAPE_CODES + __swo_print(i, "\033[2J\033[;H"); // clear screen +#else + __swo_print(i, "\n\n\n\n\n-------------------\n\n\n\n\n"); // clear screen +#endif + } +} + #define debug_log(level, msg, ...) \ do { \ if (DEBUG_CHANNEL_ENABLED(level)) { \ - char buffer[MAX_MESSAGE_LENGTH]; \ - size_t len = snprintf(buffer, sizeof(buffer), msg, ##__VA_ARGS__); \ + char __swo_buffer[MAX_MESSAGE_LENGTH]; \ + size_t len = \ + snprintf(__swo_buffer, sizeof(__swo_buffer), msg, ##__VA_ARGS__); \ __swo_putc('\n', level); \ __swo_print(level, log_level_names[level]); \ - __swo_print(level, buffer); \ - if (len >= sizeof(buffer)) { \ + __swo_print(level, __swo_buffer); \ + if (len >= sizeof(__swo_buffer)) { \ __swo_print(level, " [message length exceeded] "); \ } \ } \ @@ -85,13 +121,13 @@ static inline void __swo_print(unsigned int channel, const char *str) { #define debug_log_cont(level, msg, ...) \ do { \ if (DEBUG_CHANNEL_ENABLED(level)) { \ - char buffer[MAX_MESSAGE_LENGTH]; \ - size_t len = snprintf(buffer, sizeof(buffer), msg, ##__VA_ARGS__); \ - __swo_print(level, buffer); \ - if (len >= sizeof(buffer)) { \ + char __swo_buffer[MAX_MESSAGE_LENGTH]; \ + size_t len = \ + snprintf(__swo_buffer, sizeof(__swo_buffer), msg, ##__VA_ARGS__); \ + __swo_print(level, __swo_buffer); \ + if (len >= sizeof(__swo_buffer)) { \ __swo_print(level, " [message length exceeded] "); \ } \ - __swo_putc('\n', level); \ } \ } while (0) diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c index d0611a0..267a82d 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c @@ -20,7 +20,7 @@ static const char* const HAL_Statuses[] = {"HAL_OK", "HAL_ERROR", "HAL_BUSY", "H do { \ HAL_StatusTypeDef status = x; \ if (status != 0) { \ - debug_log(LOG_LEVEL_ERROR, "@%s:%s:%d: %s failed with status %d (%s)", __FILE_NAME__, __func__, __LINE__, \ + debug_log(LOG_LEVEL_ERROR, "in %s:%d@%s: %s failed with status %d (%s)", __FILE_NAME__, __LINE__, __func__,\ #x, status, \ (status < (sizeof(HAL_Statuses) / sizeof(HAL_Statuses[0]))) ? HAL_Statuses[status] : "Unknown"); \ return status; \ @@ -57,9 +57,8 @@ HAL_StatusTypeDef amsReset() { for (size_t j = 0; j < SID_GROUP_SIZE; j++) { id |= sidbuffer[BUFFER_BMS_OFFSET(i, SID_GROUP_SIZE) + j] << (j * 8); } - debug_log_cont(LOG_LEVEL_INFO, "0x%llx ", id); + debug_log_cont(LOG_LEVEL_INFO, "0x%lx%lx ", (uint32_t)(id >> 32), (uint32_t)(id & 0xFFFFFFFF)); //newlib does not support %llu } - debug_log_cont(LOG_LEVEL_INFO, "\n"); } mcuDelay(10); diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c index 201df0d..309ce91 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c @@ -173,17 +173,17 @@ HAL_StatusTypeDef ___writeCMD(uint16_t command, uint8_t * args, size_t arglen) { args[1] = (command) & 0xFF; if (DEBUG_CHANNEL_ENABLED(LOG_LEVEL_NOISY)) { - debug_log(LOG_LEVEL_NOISY, "%lu W | %x %x ", HAL_GetTick(), args[0], args[1]); + debug_log(LOG_LEVEL_NOISY, "%lu W | %02X %02X ", HAL_GetTick(), args[0], args[1]); //print out data bytes - for (size_t i = 0; i < N_BMS; i++) { - debug_log_cont(LOG_LEVEL_NOISY, "%d: ", i); - for (size_t j = 0; j < arglen; j++) { - debug_log_cont(LOG_LEVEL_NOISY, "%x ", args[4 + (i * (arglen + 2)) + j]); + if (arglen > 0) { + for (size_t i = 0; i < N_BMS; i++) { + debug_log_cont(LOG_LEVEL_NOISY, "%d: ", i); + for (size_t j = 0; j < arglen; j++) { + debug_log_cont(LOG_LEVEL_NOISY, "%02X ", args[BUFFER_BMS_OFFSET(i, arglen) + j]); + } } } - - debug_log_cont(LOG_LEVEL_NOISY, "\n"); } calculateCommandPEC(args, 4); @@ -232,17 +232,17 @@ HAL_StatusTypeDef ___readCMD(uint16_t command, uint8_t * buffer, size_t arglen) //TODO: check command counter? if (DEBUG_CHANNEL_ENABLED(LOG_LEVEL_NOISY)) { - debug_log(LOG_LEVEL_NOISY, "%lu R | %x %x ", HAL_GetTick(), command >> 8, command & 0xFF); + debug_log(LOG_LEVEL_NOISY, "%lu R | %02X %02X ", HAL_GetTick(), command >> 8, command & 0xFF); //print out data bytes - for (size_t i = 0; i < N_BMS; i++) { - debug_log_cont(LOG_LEVEL_NOISY, "%d: ", i); - for (size_t j = 0; j < arglen; j++) { - debug_log_cont(LOG_LEVEL_NOISY, "%x ", buffer[4 + (i * (arglen + 2)) + j]); + if (arglen > 0) { + for (size_t i = 0; i < N_BMS; i++) { + debug_log_cont(LOG_LEVEL_NOISY, "%d: ", i); + for (size_t j = 0; j < arglen; j++) { + debug_log_cont(LOG_LEVEL_NOISY, "%02X ", buffer[BUFFER_BMS_OFFSET(i, arglen) + j]); + } } } - - debug_log_cont(LOG_LEVEL_NOISY, "\n"); } //check data PEC diff --git a/AMS_Master_Code/Core/Src/main.c b/AMS_Master_Code/Core/Src/main.c index b0a46ea..3a44aa1 100644 --- a/AMS_Master_Code/Core/Src/main.c +++ b/AMS_Master_Code/Core/Src/main.c @@ -22,6 +22,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "ADBMS_Driver.h" +#include "swo_log.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -58,7 +59,7 @@ static void MX_SPI1_Init(void); /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ - +uint32_t volatile logging_mask = 0b11111; // no LOG_LEVEL_NOISY /* USER CODE END 0 */ /** @@ -95,15 +96,29 @@ int main(void) MX_GPIO_Init(); MX_SPI1_Init(); /* USER CODE BEGIN 2 */ - AMS_Init(&hspi1); + debug_clear_console(); + debug_log(LOG_LEVEL_INFO, "Starting BMS..."); + int status = -1; + while (status != ADBMS_NO_ERROR) { + status = AMS_Init(&hspi1).status; + if (status != ADBMS_NO_ERROR) { + debug_log(LOG_LEVEL_ERROR, "Failed to initialize BMS, AMS_Init returned %d", status); + HAL_Delay(2000); + } + } /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { - AMS_Idle_Loop(); - HAL_Delay(20); + status = AMS_Idle_Loop().status; + if (status != ADBMS_NO_ERROR) { + debug_log(LOG_LEVEL_ERROR, "AMS_Idle_Loop returned %d", status); + HAL_Delay(2000); + AMS_Init(&hspi1); + } + HAL_Delay(100); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */