From 8ed4a6ba096c36d884ba1e5260c6e62f5eadce4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Monda?= Date: Sat, 22 Jul 2017 23:49:47 +0200 Subject: [PATCH] Separate the configuration to hardware configuration and user configuration. Implement async I2C EEPROM handling. Remove USB functions that dealt with EEPROM and individual LEDs because they were dependent on sync I2C functions. --- right/src/config/config_state.c | 6 +- right/src/config/config_state.h | 7 ++- right/src/eeprom.c | 103 +++++++++++++++++++++++++++++++ right/src/eeprom.h | 30 +++++++++ right/src/init_peripherals.c | 2 + right/src/usb_protocol_handler.c | 36 +++-------- shared/i2c_addresses.c | 28 --------- shared/i2c_addresses.h | 5 -- 8 files changed, 153 insertions(+), 64 deletions(-) create mode 100644 right/src/eeprom.c create mode 100644 right/src/eeprom.h delete mode 100644 shared/i2c_addresses.c diff --git a/right/src/config/config_state.c b/right/src/config/config_state.c index 23aa2b2..79e6b12 100644 --- a/right/src/config/config_state.c +++ b/right/src/config/config_state.c @@ -1,6 +1,10 @@ #include "config_state.h" -config_buffer_t ConfigBuffer; +static uint8_t hardwareConfig[HARDWARE_CONFIG_SIZE]; +config_buffer_t HardwareConfigBuffer = {hardwareConfig}; + +static uint8_t userConfig[USER_CONFIG_SIZE]; +config_buffer_t UserConfigBuffer = {userConfig}; uint8_t readUInt8(config_buffer_t *buffer) { return buffer->buffer[buffer->offset++]; diff --git a/right/src/config/config_state.h b/right/src/config/config_state.h index 67dec2b..5d21357 100644 --- a/right/src/config/config_state.h +++ b/right/src/config/config_state.h @@ -9,17 +9,20 @@ // Macros: #define EEPROM_SIZE (32*1024) + #define HARDWARE_CONFIG_SIZE 64 + #define USER_CONFIG_SIZE (EEPROM_SIZE - HARDWARE_CONFIG_SIZE) // Typedefs: typedef struct { - uint8_t buffer[EEPROM_SIZE]; + uint8_t *buffer; uint16_t offset; } config_buffer_t; // Variables: - extern config_buffer_t ConfigBuffer; + extern config_buffer_t HardwareConfigBuffer; + extern config_buffer_t UserConfigBuffer; // Functions: diff --git a/right/src/eeprom.c b/right/src/eeprom.c new file mode 100644 index 0000000..5f91ebc --- /dev/null +++ b/right/src/eeprom.c @@ -0,0 +1,103 @@ +#include "fsl_common.h" +#include "config/config_state.h" +#include "i2c_addresses.h" +#include "i2c.h" +#include "eeprom.h" + +bool IsEepromBusy; +eeprom_transfer_t CurrentEepromTransfer; +status_t LastEepromTransferStatus; + +static i2c_master_handle_t i2cHandle; +static i2c_master_transfer_t i2cTransfer; + +static uint8_t *sourceBuffer; +static uint16_t sourceOffset; +static uint16_t sourceLength; + +static status_t i2cAsyncWrite(uint8_t *data, size_t dataSize) +{ + i2cTransfer.slaveAddress = I2C_ADDRESS_EEPROM; + i2cTransfer.direction = kI2C_Write; + i2cTransfer.data = data; + i2cTransfer.dataSize = dataSize; + return I2C_MasterTransferNonBlocking(I2C_EEPROM_BUS_BASEADDR, &i2cHandle, &i2cTransfer); +} + +static status_t i2cAsyncRead(uint8_t *data, size_t dataSize) +{ + i2cTransfer.slaveAddress = I2C_ADDRESS_EEPROM; + i2cTransfer.direction = kI2C_Read; + i2cTransfer.data = data; + i2cTransfer.dataSize = dataSize; + return I2C_MasterTransferNonBlocking(I2C_EEPROM_BUS_BASEADDR, &i2cHandle, &i2cTransfer); +} + +static status_t writePage() +{ + static uint8_t buffer[EEPROM_BUFFER_SIZE]; + uint8_t pageLength = MIN(sourceLength - sourceOffset, EEPROM_PAGE_SIZE); + buffer[0] = sourceOffset & 0xff; + buffer[1] = sourceOffset >> 8; + memcpy(buffer+EEPROM_ADDRESS_LENGTH, sourceBuffer+sourceOffset, pageLength); + status_t status = i2cAsyncWrite(buffer, pageLength); + sourceOffset += pageLength; + return status; +} + +static void i2cCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *userData) +{ + bool isHardwareConfig = CurrentEepromTransfer == EepromTransfer_ReadHardwareConfiguration; + switch (CurrentEepromTransfer) { + case EepromTransfer_ReadHardwareConfiguration: + case EepromTransfer_ReadUserConfiguration: + LastEepromTransferStatus = i2cAsyncRead( + isHardwareConfig ? HardwareConfigBuffer.buffer : UserConfigBuffer.buffer, + isHardwareConfig ? HARDWARE_CONFIG_SIZE : USER_CONFIG_SIZE + ); + IsEepromBusy = false; + break; + case EepromTransfer_WriteHardwareConfiguration: + case EepromTransfer_WriteUserConfiguration: + LastEepromTransferStatus = writePage(); + IsEepromBusy = sourceOffset < sourceLength; + break; + default: + IsEepromBusy = false; + break; + } +} + +void EEPROM_Init(void) +{ + I2C_MasterTransferCreateHandle(I2C_EEPROM_BUS_BASEADDR, &i2cHandle, i2cCallback, NULL); +} + +status_t EEPROM_LaunchTransfer(eeprom_transfer_t transferType) +{ + if (IsEepromBusy) { + return kStatus_I2C_Busy; + } + + uint16_t setStartAddressCommand; + bool isHardwareConfig = CurrentEepromTransfer == EepromTransfer_ReadHardwareConfiguration || + CurrentEepromTransfer == EepromTransfer_WriteHardwareConfiguration; + CurrentEepromTransfer = transferType; + + switch (transferType) { + case EepromTransfer_ReadHardwareConfiguration: + case EepromTransfer_ReadUserConfiguration: + setStartAddressCommand = isHardwareConfig ? 0 : HARDWARE_CONFIG_SIZE; + LastEepromTransferStatus = i2cAsyncWrite((uint8_t*)&setStartAddressCommand, 2); + break; + case EepromTransfer_WriteHardwareConfiguration: + case EepromTransfer_WriteUserConfiguration: + sourceBuffer = isHardwareConfig ? HardwareConfigBuffer.buffer : UserConfigBuffer.buffer; + sourceOffset = 0; + sourceLength = isHardwareConfig ? HARDWARE_CONFIG_SIZE : USER_CONFIG_SIZE; + LastEepromTransferStatus = writePage(); + break; + } + IsEepromBusy = LastEepromTransferStatus == kStatus_Success; + return LastEepromTransferStatus; +} diff --git a/right/src/eeprom.h b/right/src/eeprom.h new file mode 100644 index 0000000..9205c3d --- /dev/null +++ b/right/src/eeprom.h @@ -0,0 +1,30 @@ +#ifndef __EEPROM_H__ +#define __EEPROM_H__ + +// Macros: + + #define EEPROM_ADDRESS_LENGTH 2 + #define EEPROM_PAGE_SIZE 64 + #define EEPROM_BUFFER_SIZE (EEPROM_ADDRESS_LENGTH + EEPROM_PAGE_SIZE) + +// Typedefs: + + typedef enum { + EepromTransfer_ReadHardwareConfiguration, + EepromTransfer_WriteHardwareConfiguration, + EepromTransfer_ReadUserConfiguration, + EepromTransfer_WriteUserConfiguration, + } eeprom_transfer_t; + +// Variables: + + extern bool IsEepromBusy; + extern eeprom_transfer_t CurrentEepromTransfer; + extern status_t EepromTransferStatus; + +// Functions: + + extern void EEPROM_Init(void); + extern status_t EEPROM_LaunchTransfer(eeprom_transfer_t transferType); + +#endif diff --git a/right/src/init_peripherals.c b/right/src/init_peripherals.c index ddf25b0..19cd3a4 100644 --- a/right/src/init_peripherals.c +++ b/right/src/init_peripherals.c @@ -10,6 +10,7 @@ #include "slave_scheduler.h" #include "peripherals/adc.h" #include "init_peripherals.h" +#include "eeprom.h" volatile uint32_t temp, counter; @@ -60,4 +61,5 @@ void InitPeripherals(void) InitTestLed(); LedPwm_Init(); InitI2cWatchdog(); + EEPROM_Init(); } diff --git a/right/src/usb_protocol_handler.c b/right/src/usb_protocol_handler.c index bb67926..0e0a1b7 100644 --- a/right/src/usb_protocol_handler.c +++ b/right/src/usb_protocol_handler.c @@ -18,7 +18,6 @@ void usbProtocolHandler(); void getSystemProperty(); void reenumerate(); void setTestLed(); -void writeLedDriver(); void readLedDriver(); void writeEeprom(); void readEeprom(); @@ -62,7 +61,6 @@ void usbProtocolHandler() setTestLed(); break; case USB_COMMAND_WRITE_LED_DRIVER: - //writeLedDriver(); break; case USB_COMMAND_WRITE_EEPROM: writeEeprom(); @@ -128,24 +126,6 @@ void setTestLed() UhkModuleStates[0].isTestLedOn = ledState; } -void writeLedDriver() -{ - uint8_t i2cAddress = GenericHidInBuffer[1]; - uint8_t i2cPayloadSize = GenericHidInBuffer[2]; - - if (!IS_I2C_LED_DRIVER_ADDRESS(i2cAddress)) { - setError(WRITE_LED_DRIVER_RESPONSE_INVALID_ADDRESS); - return; - } - - if (i2cPayloadSize > USB_GENERIC_HID_OUT_BUFFER_LENGTH-3) { - setError(WRITE_LED_DRIVER_RESPONSE_INVALID_PAYLOAD_SIZE); - return; - } - - I2cWrite(I2C_MAIN_BUS_BASEADDR, i2cAddress, GenericHidInBuffer+3, i2cPayloadSize); -} - void writeEeprom() { uint8_t i2cPayloadSize = GenericHidInBuffer[1]; @@ -155,7 +135,7 @@ void writeEeprom() return; } - I2cWrite(I2C_EEPROM_BUS_BASEADDR, I2C_ADDRESS_EEPROM, GenericHidInBuffer+2, i2cPayloadSize); +// I2cWrite(I2C_EEPROM_BUS_BASEADDR, I2C_ADDRESS_EEPROM, GenericHidInBuffer+2, i2cPayloadSize); } void readEeprom() @@ -167,8 +147,8 @@ void readEeprom() return; } - I2cWrite(I2C_EEPROM_BUS_BASEADDR, I2C_ADDRESS_EEPROM, GenericHidInBuffer+2, 2); - I2cRead(I2C_EEPROM_BUS_BASEADDR, I2C_ADDRESS_EEPROM, GenericHidOutBuffer+1, i2cPayloadSize); +// I2cWrite(I2C_EEPROM_BUS_BASEADDR, I2C_ADDRESS_EEPROM, GenericHidInBuffer+2, 2); +// I2cRead(I2C_EEPROM_BUS_BASEADDR, I2C_ADDRESS_EEPROM, GenericHidOutBuffer+1, i2cPayloadSize); GenericHidOutBuffer[0] = PROTOCOL_RESPONSE_SUCCESS; } @@ -188,15 +168,15 @@ void uploadConfig() return; } - memcpy(ConfigBuffer.buffer+memoryOffset, GenericHidInBuffer+4, byteCount); + memcpy(UserConfigBuffer.buffer+memoryOffset, GenericHidInBuffer+4, byteCount); } void applyConfig() { - ConfigBuffer.offset = 0; - GenericHidOutBuffer[0] = ParseConfig(&ConfigBuffer); - GenericHidOutBuffer[1] = ConfigBuffer.offset; - GenericHidOutBuffer[2] = ConfigBuffer.offset >> 8; + UserConfigBuffer.offset = 0; + GenericHidOutBuffer[0] = ParseConfig(&UserConfigBuffer); + GenericHidOutBuffer[1] = UserConfigBuffer.offset; + GenericHidOutBuffer[2] = UserConfigBuffer.offset >> 8; } void setLedPwm() diff --git a/shared/i2c_addresses.c b/shared/i2c_addresses.c deleted file mode 100644 index 3f3a650..0000000 --- a/shared/i2c_addresses.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "fsl_i2c.h" -#include "i2c_addresses.h" - -status_t I2cRead(I2C_Type *baseAddress, uint8_t i2cAddress, uint8_t *data, uint8_t size) -{ - i2c_master_transfer_t masterXfer; - masterXfer.slaveAddress = i2cAddress; - masterXfer.direction = kI2C_Read; - masterXfer.subaddress = 0; - masterXfer.subaddressSize = 0; - masterXfer.data = data; - masterXfer.dataSize = size; - masterXfer.flags = kI2C_TransferDefaultFlag; - return I2C_MasterTransferBlocking(baseAddress, &masterXfer); -} - -status_t I2cWrite(I2C_Type *baseAddress, uint8_t i2cAddress, uint8_t *data, uint8_t size) -{ - i2c_master_transfer_t masterXfer; - masterXfer.slaveAddress = i2cAddress; - masterXfer.direction = kI2C_Write; - masterXfer.subaddress = 0; - masterXfer.subaddressSize = 0; - masterXfer.data = data; - masterXfer.dataSize = size; - masterXfer.flags = kI2C_TransferDefaultFlag; - return I2C_MasterTransferBlocking(baseAddress, &masterXfer); -} diff --git a/shared/i2c_addresses.h b/shared/i2c_addresses.h index 5678d77..2d00db1 100644 --- a/shared/i2c_addresses.h +++ b/shared/i2c_addresses.h @@ -27,9 +27,4 @@ #define IS_I2C_LED_DRIVER_ADDRESS(address) \ (I2C_ADDRESS_LED_DRIVER_LEFT <= (address) && (address) <= I2C_ADDRESS_LED_DRIVER_RIGHT) -// Functions: - - status_t I2cRead(I2C_Type *baseAddress, uint8_t i2cAddress, uint8_t *data, uint8_t size); - status_t I2cWrite(I2C_Type *baseAddress, uint8_t i2cAddress, uint8_t *data, uint8_t size); - #endif