Log I2C error counts on a per slave and per error type basis and expose them via USB.
This commit is contained in:
24
right/src/i2c_error_logger.c
Normal file
24
right/src/i2c_error_logger.c
Normal file
@@ -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; errorIdx<i2cSlaveErrorCounter->errorTypeCount; 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
33
right/src/i2c_error_logger.h
Normal file
33
right/src/i2c_error_logger.h
Normal file
@@ -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
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#include "i2c_addresses.h"
|
#include "i2c_addresses.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "i2c_error_logger.h"
|
||||||
|
|
||||||
uint32_t I2cSlaveScheduler_Counter;
|
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;
|
uhk_slave_t *currentSlave = Slaves + currentSlaveId;
|
||||||
|
|
||||||
previousSlave->previousStatus = previousStatus;
|
previousSlave->previousStatus = previousStatus;
|
||||||
|
LogI2cError(previousSlaveId, previousStatus);
|
||||||
|
|
||||||
if (isFirstIteration) {
|
if (isFirstIteration) {
|
||||||
bool wasPreviousSlaveConnected = previousSlave->isConnected;
|
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);
|
status_t currentStatus = currentSlave->update(currentSlave->perDriverId);
|
||||||
|
LogI2cError(currentSlaveId, currentStatus);
|
||||||
isTransferScheduled = currentStatus != kStatus_Uhk_IdleSlave && currentStatus != kStatus_Uhk_NoTransfer;
|
isTransferScheduled = currentStatus != kStatus_Uhk_IdleSlave && currentStatus != kStatus_Uhk_NoTransfer;
|
||||||
if (isTransferScheduled) {
|
if (isTransferScheduled) {
|
||||||
currentSlave->isConnected = true;
|
currentSlave->isConnected = true;
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
// Macros:
|
// Macros:
|
||||||
|
|
||||||
#define SLAVE_COUNT (sizeof(Slaves) / sizeof(uhk_slave_t))
|
#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:
|
// Typedefs:
|
||||||
|
|
||||||
@@ -37,7 +39,7 @@
|
|||||||
} uhk_slave_t;
|
} uhk_slave_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
kStatusGroup_Uhk = -1,
|
kStatusGroup_Uhk = 200,
|
||||||
} uhk_status_group_t;
|
} uhk_status_group_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
19
right/src/usb_commands/usb_command_get_slave_i2c_errors.c
Normal file
19
right/src/usb_commands/usb_command_get_slave_i2c_errors.c
Normal file
@@ -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);
|
||||||
|
}
|
||||||
14
right/src/usb_commands/usb_command_get_slave_i2c_errors.h
Normal file
14
right/src/usb_commands/usb_command_get_slave_i2c_errors.h
Normal file
@@ -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
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "usb_commands/usb_command_get_debug_buffer.h"
|
#include "usb_commands/usb_command_get_debug_buffer.h"
|
||||||
#include "usb_commands/usb_command_jump_to_module_bootloader.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_send_kboot_command_to_module.h"
|
||||||
|
#include "usb_commands/usb_command_get_slave_i2c_errors.h"
|
||||||
|
|
||||||
void UsbProtocolHandler(void)
|
void UsbProtocolHandler(void)
|
||||||
{
|
{
|
||||||
@@ -65,6 +66,9 @@ void UsbProtocolHandler(void)
|
|||||||
case UsbCommandId_GetModuleProperty:
|
case UsbCommandId_GetModuleProperty:
|
||||||
UsbCommand_GetModuleProperty();
|
UsbCommand_GetModuleProperty();
|
||||||
break;
|
break;
|
||||||
|
case UsbCommandId_GetSlaveI2cErrors:
|
||||||
|
UsbCommand_GetSlaveI2cErrors();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
SetUsbTxBufferUint8(0, UsbStatusCode_InvalidCommand);
|
SetUsbTxBufferUint8(0, UsbStatusCode_InvalidCommand);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
UsbCommandId_GetAdcValue = 0x0c,
|
UsbCommandId_GetAdcValue = 0x0c,
|
||||||
UsbCommandId_SetLedPwmBrightness = 0x0d,
|
UsbCommandId_SetLedPwmBrightness = 0x0d,
|
||||||
UsbCommandId_GetModuleProperty = 0x0e,
|
UsbCommandId_GetModuleProperty = 0x0e,
|
||||||
|
UsbCommandId_GetSlaveI2cErrors = 0x0f,
|
||||||
} usb_command_id_t;
|
} usb_command_id_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
Reference in New Issue
Block a user