130 lines
4.3 KiB
C
130 lines
4.3 KiB
C
#include "fsl_common.h"
|
|
#include "config_parser/config_globals.h"
|
|
#include "i2c_addresses.h"
|
|
#include "i2c.h"
|
|
#include "eeprom.h"
|
|
#include "config_parser/config_globals.h"
|
|
|
|
bool IsEepromBusy;
|
|
static eeprom_operation_t CurrentEepromOperation;
|
|
static config_buffer_id_t CurrentConfigBufferId;
|
|
status_t LastEepromTransferStatus;
|
|
void (*SuccessCallback)();
|
|
|
|
static i2c_master_handle_t i2cHandle;
|
|
static i2c_master_transfer_t i2cTransfer;
|
|
|
|
static uint8_t *sourceBuffer;
|
|
static uint16_t sourceOffset;
|
|
static uint16_t eepromStartAddress;
|
|
static uint16_t sourceLength;
|
|
static uint8_t writeLength;
|
|
static bool isReadSent;
|
|
static uint8_t addressBuffer[EEPROM_ADDRESS_LENGTH];
|
|
|
|
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(void)
|
|
{
|
|
static uint8_t buffer[EEPROM_BUFFER_SIZE];
|
|
uint16_t targetEepromOffset = sourceOffset + eepromStartAddress;
|
|
buffer[0] = targetEepromOffset >> 8;
|
|
buffer[1] = targetEepromOffset & 0xff;
|
|
writeLength = MIN(sourceLength - sourceOffset, EEPROM_PAGE_SIZE);
|
|
memcpy(buffer+EEPROM_ADDRESS_LENGTH, sourceBuffer+sourceOffset, writeLength);
|
|
status_t status = i2cAsyncWrite(buffer, writeLength+EEPROM_ADDRESS_LENGTH);
|
|
return status;
|
|
}
|
|
|
|
static void i2cCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *userData)
|
|
{
|
|
LastEepromTransferStatus = status;
|
|
|
|
switch (CurrentEepromOperation) {
|
|
case EepromOperation_Read:
|
|
if (isReadSent) {
|
|
IsEepromBusy = false;
|
|
if (SuccessCallback) {
|
|
SuccessCallback();
|
|
}
|
|
return;
|
|
}
|
|
LastEepromTransferStatus = i2cAsyncRead(
|
|
ConfigBufferIdToConfigBuffer(CurrentConfigBufferId)->buffer,
|
|
CurrentConfigBufferId == ConfigBufferId_HardwareConfig ? HARDWARE_CONFIG_SIZE : USER_CONFIG_SIZE
|
|
);
|
|
IsEepromBusy = true;
|
|
isReadSent = true;
|
|
break;
|
|
case EepromOperation_Write:
|
|
if (status == kStatus_Success) {
|
|
sourceOffset += writeLength;
|
|
}
|
|
IsEepromBusy = sourceOffset < sourceLength;
|
|
if (!IsEepromBusy) {
|
|
if (SuccessCallback) {
|
|
SuccessCallback();
|
|
}
|
|
return;
|
|
}
|
|
LastEepromTransferStatus = writePage();
|
|
break;
|
|
default:
|
|
IsEepromBusy = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void EEPROM_Init(void)
|
|
{
|
|
I2C_MasterTransferCreateHandle(I2C_EEPROM_BUS_BASEADDR, &i2cHandle, i2cCallback, NULL);
|
|
}
|
|
|
|
status_t EEPROM_LaunchTransfer(eeprom_operation_t operation, config_buffer_id_t config_buffer_id, void (*successCallback))
|
|
{
|
|
if (IsEepromBusy) {
|
|
return kStatus_I2C_Busy;
|
|
}
|
|
|
|
CurrentEepromOperation = operation;
|
|
CurrentConfigBufferId = config_buffer_id;
|
|
|
|
SuccessCallback = successCallback;
|
|
bool isHardwareConfig = CurrentConfigBufferId == ConfigBufferId_HardwareConfig;
|
|
eepromStartAddress = isHardwareConfig ? 0 : HARDWARE_CONFIG_SIZE;
|
|
addressBuffer[0] = eepromStartAddress >> 8;
|
|
addressBuffer[1] = eepromStartAddress & 0xff;
|
|
|
|
switch (CurrentEepromOperation) {
|
|
case EepromOperation_Read:
|
|
isReadSent = false;
|
|
LastEepromTransferStatus = i2cAsyncWrite(addressBuffer, EEPROM_ADDRESS_LENGTH);
|
|
break;
|
|
case EepromOperation_Write:
|
|
sourceBuffer = ConfigBufferIdToConfigBuffer(CurrentConfigBufferId)->buffer;
|
|
sourceOffset = 0;
|
|
sourceLength = isHardwareConfig ? HARDWARE_CONFIG_SIZE : USER_CONFIG_SIZE;
|
|
LastEepromTransferStatus = writePage();
|
|
break;
|
|
}
|
|
|
|
IsEepromBusy = LastEepromTransferStatus == kStatus_Success;
|
|
return LastEepromTransferStatus;
|
|
}
|