From 6ad425cbf9d34ee7dcd5247597ed50887e8ab412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Monda?= Date: Fri, 5 Jan 2018 03:23:48 +0100 Subject: [PATCH] Log I2C error counts on a per slave and per error type basis and expose them via USB. --- right/src/i2c_error_logger.c | 24 ++++++++++++++ right/src/i2c_error_logger.h | 33 +++++++++++++++++++ right/src/slave_scheduler.c | 3 ++ right/src/slave_scheduler.h | 4 ++- .../usb_command_get_slave_i2c_errors.c | 19 +++++++++++ .../usb_command_get_slave_i2c_errors.h | 14 ++++++++ right/src/usb_protocol_handler.c | 4 +++ right/src/usb_protocol_handler.h | 1 + 8 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 right/src/i2c_error_logger.c create mode 100644 right/src/i2c_error_logger.h create mode 100644 right/src/usb_commands/usb_command_get_slave_i2c_errors.c create mode 100644 right/src/usb_commands/usb_command_get_slave_i2c_errors.h diff --git a/right/src/i2c_error_logger.c b/right/src/i2c_error_logger.c new file mode 100644 index 0000000..4513895 --- /dev/null +++ b/right/src/i2c_error_logger.c @@ -0,0 +1,24 @@ +#include "i2c_error_logger.h" + +i2c_slave_error_counter_t I2cSlaveErrorCounters[MAX_SLAVE_COUNT]; + +void LogI2cError(uint8_t slaveId, status_t status) +{ + i2c_slave_error_counter_t *i2cSlaveErrorCounter = I2cSlaveErrorCounters + slaveId; + uint8_t errorIdx; + + for (errorIdx=0; errorIdxerrorTypeCount; errorIdx++) { + i2c_error_count_t *currentI2cError = i2cSlaveErrorCounter->errors + errorIdx; + if (currentI2cError->status == status) { + currentI2cError->count++; + break; + } + } + + if (errorIdx == i2cSlaveErrorCounter->errorTypeCount && errorIdx < MAX_LOGGED_I2C_ERROR_TYPES_PER_SLAVE) { + i2cSlaveErrorCounter->errorTypeCount++; + i2c_error_count_t *currentI2cError = i2cSlaveErrorCounter->errors + errorIdx; + currentI2cError->status = status; + currentI2cError->count = 1; + } +} diff --git a/right/src/i2c_error_logger.h b/right/src/i2c_error_logger.h new file mode 100644 index 0000000..51d5d34 --- /dev/null +++ b/right/src/i2c_error_logger.h @@ -0,0 +1,33 @@ +#ifndef __I2C_ERROR_LOGGER_H__ +#define __I2C_ERROR_LOGGER_H__ + +// Includes: + + #include "fsl_common.h" + #include "slave_scheduler.h" + +// Macros: + + #define MAX_LOGGED_I2C_ERROR_TYPES_PER_SLAVE 7 + +// Typedefs: + + typedef struct { + status_t status; + uint32_t count; + } i2c_error_count_t; + + typedef struct { + uint8_t errorTypeCount; + i2c_error_count_t errors[MAX_LOGGED_I2C_ERROR_TYPES_PER_SLAVE]; + } i2c_slave_error_counter_t; + +// Variables: + + extern i2c_slave_error_counter_t I2cSlaveErrorCounters[MAX_SLAVE_COUNT]; + +// Functions: + + void LogI2cError(uint8_t slaveId, status_t status); + +#endif diff --git a/right/src/slave_scheduler.c b/right/src/slave_scheduler.c index 20ad644..9cc19ed 100644 --- a/right/src/slave_scheduler.c +++ b/right/src/slave_scheduler.c @@ -7,6 +7,7 @@ #include "i2c.h" #include "i2c_addresses.h" #include "config.h" +#include "i2c_error_logger.h" uint32_t I2cSlaveScheduler_Counter; @@ -60,6 +61,7 @@ static void slaveSchedulerCallback(I2C_Type *base, i2c_master_handle_t *handle, uhk_slave_t *currentSlave = Slaves + currentSlaveId; previousSlave->previousStatus = previousStatus; + LogI2cError(previousSlaveId, previousStatus); if (isFirstIteration) { bool wasPreviousSlaveConnected = previousSlave->isConnected; @@ -75,6 +77,7 @@ static void slaveSchedulerCallback(I2C_Type *base, i2c_master_handle_t *handle, } status_t currentStatus = currentSlave->update(currentSlave->perDriverId); + LogI2cError(currentSlaveId, currentStatus); isTransferScheduled = currentStatus != kStatus_Uhk_IdleSlave && currentStatus != kStatus_Uhk_NoTransfer; if (isTransferScheduled) { currentSlave->isConnected = true; diff --git a/right/src/slave_scheduler.h b/right/src/slave_scheduler.h index e02599d..08aaa93 100644 --- a/right/src/slave_scheduler.h +++ b/right/src/slave_scheduler.h @@ -9,6 +9,8 @@ // Macros: #define SLAVE_COUNT (sizeof(Slaves) / sizeof(uhk_slave_t)) + #define MAX_SLAVE_COUNT 6 + #define IS_VALID_SLAVE_ID(slaveId) (0 <= slaveId && slaveId <= MAX_SLAVE_COUNT) // Typedefs: @@ -37,7 +39,7 @@ } uhk_slave_t; typedef enum { - kStatusGroup_Uhk = -1, + kStatusGroup_Uhk = 200, } uhk_status_group_t; typedef enum { diff --git a/right/src/usb_commands/usb_command_get_slave_i2c_errors.c b/right/src/usb_commands/usb_command_get_slave_i2c_errors.c new file mode 100644 index 0000000..441f849 --- /dev/null +++ b/right/src/usb_commands/usb_command_get_slave_i2c_errors.c @@ -0,0 +1,19 @@ +#include "fsl_common.h" +#include "usb_commands/usb_command_get_slave_i2c_errors.h" +#include "usb_protocol_handler.h" +#include "slave_scheduler.h" +#include "i2c_error_logger.h" + +void UsbCommand_GetSlaveI2cErrors() +{ + uint8_t slaveId = GetUsbRxBufferUint8(1); + + if (!IS_VALID_SLAVE_ID(slaveId)) { + SetUsbTxBufferUint8(0, UsbStatusCode_GetModuleProperty_InvalidSlaveId); + } + + i2c_slave_error_counter_t *i2cSlaveErrorCounter = I2cSlaveErrorCounters + slaveId; + + GenericHidOutBuffer[1] = i2cSlaveErrorCounter->errorTypeCount; + memcpy(GenericHidOutBuffer + 2, i2cSlaveErrorCounter->errors, sizeof(i2c_error_count_t) * MAX_LOGGED_I2C_ERROR_TYPES_PER_SLAVE); +} diff --git a/right/src/usb_commands/usb_command_get_slave_i2c_errors.h b/right/src/usb_commands/usb_command_get_slave_i2c_errors.h new file mode 100644 index 0000000..d62d459 --- /dev/null +++ b/right/src/usb_commands/usb_command_get_slave_i2c_errors.h @@ -0,0 +1,14 @@ +#ifndef __USB_COMMAND_GET_SLAVE_I2C_ERRORS_H__ +#define __USB_COMMAND_GET_SLAVE_I2C_ERRORS_H__ + +// Functions: + + void UsbCommand_GetSlaveI2cErrors(); + +// Typedefs: + + typedef enum { + UsbStatusCode_GetModuleProperty_InvalidSlaveId = 2, + } usb_status_code_get_slave_i2c_errors_t; + +#endif diff --git a/right/src/usb_protocol_handler.c b/right/src/usb_protocol_handler.c index 38cab76..e4611f6 100644 --- a/right/src/usb_protocol_handler.c +++ b/right/src/usb_protocol_handler.c @@ -14,6 +14,7 @@ #include "usb_commands/usb_command_get_debug_buffer.h" #include "usb_commands/usb_command_jump_to_module_bootloader.h" #include "usb_commands/usb_command_send_kboot_command_to_module.h" +#include "usb_commands/usb_command_get_slave_i2c_errors.h" void UsbProtocolHandler(void) { @@ -65,6 +66,9 @@ void UsbProtocolHandler(void) case UsbCommandId_GetModuleProperty: UsbCommand_GetModuleProperty(); break; + case UsbCommandId_GetSlaveI2cErrors: + UsbCommand_GetSlaveI2cErrors(); + break; default: SetUsbTxBufferUint8(0, UsbStatusCode_InvalidCommand); break; diff --git a/right/src/usb_protocol_handler.h b/right/src/usb_protocol_handler.h index 3eb27a0..71619d5 100644 --- a/right/src/usb_protocol_handler.h +++ b/right/src/usb_protocol_handler.h @@ -31,6 +31,7 @@ UsbCommandId_GetAdcValue = 0x0c, UsbCommandId_SetLedPwmBrightness = 0x0d, UsbCommandId_GetModuleProperty = 0x0e, + UsbCommandId_GetSlaveI2cErrors = 0x0f, } usb_command_id_t; typedef enum {