/*****************************************************************************/ /* FILENAME : Log.c */ /* */ /* DESCRIPTION : Generic Uart Logger Library */ /* */ /* NOTES : Copyright Sathish Kumar P. All rights reserved. */ /* */ /* AUTHOR : Sathish Kumar */ /* sathishembeddedgeek@gmail.com */ /* */ /* START DATE : 3rd May 2021 */ /* */ /* VERSION DATE WHO DETAIL */ /* 00.00.01 03MAY21 Sathish Kumar initial version */ /* */ /*****************************************************************************/ //TODO: Logging using Uart DMA or interrupt /*****************************************************************************/ /* I N C L U D E S */ /*****************************************************************************/ #include "Log.h" #include #if(LOG_USE_BUFFERING == 1) #include #endif /*****************************************************************************/ /* D E F I N I N T I O N S */ /*****************************************************************************/ #if (LOG_USE_PRETTY_PRINT) /* Pretty prints */ #define PREFIX "\033[" #define SUFFIX "\033[0m" /* color */ #define RED ";31m" #define GREEN ";32m" #define YELLOW ";33m" #define BLUE ";34m" #define MAGENTA ";35m" #define CYAN ";36m" #define WHITE ";37m" /* Effect */ #define NORMAL "0" #define BOLD "1" #else /* Pretty prints */ #define PREFIX #define SUFFIX /* color */ #define RED #define GREEN #define YELLOW #define BLUE #define MAGENTA #define CYAN #define WHITE /* Effect */ #define NORMAL #define BOLD #endif #define FORMAT_COLOR(STR, COLOR) PREFIX COLOR STR SUFFIX /*****************************************************************************/ /* CONSTANTS & VARIABLES */ /*****************************************************************************/ #if(LOG_USE_BUFFERING == 1) static queue_param_t LogMsgQ; static uint8_t LogBuff[LOG_MSG_QUEUE_SIZE]; #endif static char local_buf[LOG_LOCAL_BUF_SIZE]; __IO ITStatus TracePeripheralReady = SET; const uint8_t *log_type[]= { (uint8_t*)FORMAT_COLOR("[DEBUG]", WHITE), (uint8_t*)FORMAT_COLOR("[INFO]", GREEN), (uint8_t*)FORMAT_COLOR("[WARN]", YELLOW), (uint8_t*)FORMAT_COLOR("[ERROR]", RED), (uint8_t*)FORMAT_COLOR("[FATAL]", RED), (uint8_t*)FORMAT_COLOR("[ALL]", CYAN), }; static LogLevel_t cur_log_lvl = LOG_INFO; static uint8_t log_enabled = 0; //static uint32_t log_uart_baudrate = 921600; /*****************************************************************************/ /* F U N C T I O N S */ /*****************************************************************************/ /* Call back function for Tx Complete */ void Log_UartTxCpltCallback(void); /*****************************************************************************/ /* see header file for description. */ /*****************************************************************************/ uint8_t Log_Init() { uint8_t ret_val=0; //TODO: Logging using Uart DMA or interrupt /* Enable low level Uart settings for logging */ //UartRegisterTxCb(Log_UartTxCpltCallback); #if(LOG_USE_BUFFERING == 1) /* Q initialization */ circular_queue_init(&LogMsgQ, LogBuff, LOG_MSG_QUEUE_SIZE); #endif return ret_val; } /*****************************************************************************/ /* see header file for description. */ /*****************************************************************************/ void Log_Task(uint32_t call_rate) { (void)call_rate; /* unused warning removal */ } /*****************************************************************************/ /* see header file for description. */ /*****************************************************************************/ void Log_Enable(uint8_t enable) { if((uint8_t)1 == enable) { //TODO: Logging using Uart DMA or interrupt //Uart_ReInit(); log_enabled = 1; } else { log_enabled = 0; TracePeripheralReady = SET; #if(LOG_USE_BUFFERING == 1) /* Clears the buffers and elements */ circular_queue_init(&LogMsgQ, LogBuff, LOG_MSG_QUEUE_SIZE); #endif //TODO: Logging using Uart DMA or interrupt //Uart_DeInit(); } } /*****************************************************************************/ /* see header file for description. */ /*****************************************************************************/ uint8_t Log_GetEnabledStatus(void) { return log_enabled; } /*****************************************************************************/ /* see header file for description. */ /*****************************************************************************/ uint8_t Log_IsPendingTx(void) { uint8_t ret_val = true; CRITICAL_SECTION_BEGIN(); #if(LOG_USE_BUFFERING == 1) if((TracePeripheralReady == SET)&&(circular_queue_sense(&LogMsgQ) == -1)) #else if(TracePeripheralReady == SET) #endif { ret_val = false; } CRITICAL_SECTION_END(); return ret_val; } /*****************************************************************************/ /* see header file for description. */ /*****************************************************************************/ void Log_LowPowerMode(uint8_t enable) { /* Only when logging is enabled */ if((uint8_t)1 == log_enabled) { if((uint8_t)1 == enable) { #if(LOG_USE_BUFFERING == 1) /* Clears the buffers and elements */ circular_queue_init(&LogMsgQ, LogBuff, LOG_MSG_QUEUE_SIZE); #endif //TODO: Logging using Uart DMA or interrupt //Uart_DeInit(); } else { //TODO: Logging using Uart DMA or interrupt //Uart_ReInit(); } } } ///*****************************************************************************/ ///* see header file for description. */ ///*****************************************************************************/ //void Log_SetUartBaudrate(uint32_t new_baudrate) //{ // if(0 == UartSetBaudrate(new_baudrate)) // { // log_uart_baudrate = new_baudrate; // } //} // ///*****************************************************************************/ ///* see header file for description. */ ///*****************************************************************************/ //uitn32_t Log_GetUartBaudrate() //{ // return log_uart_baudrate; //} /*****************************************************************************/ /* see header file for description. */ /*****************************************************************************/ void Log_SetLogLvl(LogLevel_t new_log_lvl) { if(new_log_lvl < LOG_MAX) { cur_log_lvl = new_log_lvl; } } /*****************************************************************************/ /* see header file for description. */ /*****************************************************************************/ LogLevel_t Log_GetLogLvl(void) { return cur_log_lvl; } /*****************************************************************************/ /* see header file for description. */ /*****************************************************************************/ void Log_TString(LogLevel_t log_lvl,const char *str, ...) { if((cur_log_lvl <= log_lvl)&&(1 == log_enabled)) { va_list arg; int indx=0; indx = snprintf (&local_buf[0], LOG_LOCAL_BUF_SIZE, "%s\t: ", (char*)log_type[log_lvl]); va_start (arg, str); indx = vsnprintf (&local_buf[indx], (LOG_LOCAL_BUF_SIZE-(size_t)indx), str, arg); va_end (arg); strncat(local_buf,"\r\n",3); Log_UartSend((uint8_t *)local_buf,(uint16_t)strlen(local_buf)); } } /*****************************************************************************/ /* see header file for description. */ /*****************************************************************************/ void Log_UartSend(uint8_t *buf,uint16_t bufLen) { #if(LOG_USE_BUFFERING == 0) Log_WriteToHWUart(buf,bufLen); #else int status; CRITICAL_SECTION_BEGIN(); status = circular_queue_add(&LogMsgQ,buf, bufLen); if((status==0) && (TracePeripheralReady==SET)) { uint8_t* buffer; uint16_t bufSize; TracePeripheralReady = RESET; circular_queue_get(&LogMsgQ,&buffer,&bufSize); CRITICAL_SECTION_END(); Log_WriteToHWUart_NonBlocking(buffer, bufSize); //TODO: Logging using Uart DMA or interrupt. Remove after implemention // Log_UartTxCpltCallback(); } else { CRITICAL_SECTION_END(); } if(status!=0) { //TODO: log queue is full } #endif } /*****************************************************************************/ /* see header file for description. */ /*****************************************************************************/ void Log_UartTxCompleteCallback(void) { #if(LOG_USE_BUFFERING == 1) /* buffer transmission complete*/ int status; uint8_t* buffer; uint16_t bufSize; //TODO: Logging using Uart DMA or interrupt CRITICAL_SECTION_BEGIN(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ /* Remove element just sent to UART */ circular_queue_remove(&LogMsgQ); /* Sense if new data to be sent */ status=circular_queue_sense(&LogMsgQ); if (status == 0) { circular_queue_get(&LogMsgQ,&buffer,&bufSize); CRITICAL_SECTION_END(); //TODO: Logging using Uart DMA or interrupt. Remove after implemention Log_WriteToHWUart_NonBlocking(buffer, bufSize); } else { TracePeripheralReady = SET; CRITICAL_SECTION_END(); } #endif } /*****************************************************************************/ /* E N D O F F I L E */ /*****************************************************************************/