/*
 * Eeprom.c
 *
 *  Created on: Jun 26, 2024
 *      Author: remy.cluze
 */


#include "stm32l4xx_hal.h"
#include "i2c.h"

// Adresse de l'EEPROM (à ajuster selon la configuration de votre matériel)
#define EEPROM_ADDRESS 0xA0

void EEPROM_WriteEnable(void) {
	HAL_GPIO_WritePin(WC_GPIO_Port, WC_Pin, GPIO_PIN_RESET);
}

void EEPROM_WriteDisable(void) {
	HAL_GPIO_WritePin(WC_GPIO_Port, WC_Pin, GPIO_PIN_SET);
}


HAL_StatusTypeDef EEPROM_WriteByte(uint16_t addr, uint8_t data) {
	uint8_t buffer[3];
	buffer[0] = (uint8_t)(addr >> 8); // MSB
	buffer[1] = (uint8_t)(addr & 0xFF); // LSB
	buffer[2] = data;

	EEPROM_WriteEnable();
	HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, buffer, 3, HAL_MAX_DELAY);
	EEPROM_WriteDisable();

	return status;
}

HAL_StatusTypeDef EEPROM_ReadByte(uint16_t addr, uint8_t *data) {
	uint8_t buffer[2];
	buffer[0] = (uint8_t)(addr >> 8); // MSB
	buffer[1] = (uint8_t)(addr & 0xFF); // LSB

	HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, buffer, 2, HAL_MAX_DELAY);
	if (status != HAL_OK) {
		return status;
	}

	return HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDRESS, data, 1, HAL_MAX_DELAY);
}

HAL_StatusTypeDef EEPROM_WritePage(uint16_t addr, uint8_t *data, uint8_t length) {
	if (length > 32) {
		return HAL_ERROR; // La taille maximale d'une page est de 32 octets
	}

	uint8_t buffer[34];
	buffer[0] = (uint8_t)(addr >> 8); // MSB
	buffer[1] = (uint8_t)(addr & 0xFF); // LSB

	for (uint8_t i = 0; i < length; i++) {
		buffer[2 + i] = data[i];
	}

	EEPROM_WriteEnable();
	HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, buffer, length + 2, HAL_MAX_DELAY);
	EEPROM_WriteDisable();


	return status;
}

HAL_StatusTypeDef EEPROM_ReadPage(uint16_t addr, uint8_t *data, uint8_t length) {
	if (length > 32) {
		return HAL_ERROR; // La taille maximale d'une page est de 32 octets
	}

	uint8_t buffer[2];
	buffer[0] = (uint8_t)(addr >> 8); // MSB
	buffer[1] = (uint8_t)(addr & 0xFF); // LSB

	HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, buffer, 2, HAL_MAX_DELAY);
	if (status != HAL_OK) {
		return status;
	}

	return HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDRESS, data, length, HAL_MAX_DELAY);
}

HAL_StatusTypeDef EEPROM_WriteUInt16(uint16_t addr, uint16_t data) {
	uint8_t buffer[2];
	buffer[0] = (uint8_t)(data >> 8); // MSB du uint16_t
	buffer[1] = (uint8_t)(data & 0xFF); // LSB du uint16_t

	return EEPROM_WritePage(addr, buffer, 2);
}

HAL_StatusTypeDef EEPROM_ReadUInt16(uint16_t addr, uint16_t *data) {
	uint8_t buffer[2];
	HAL_StatusTypeDef status = EEPROM_ReadPage(addr, buffer, 2);
	if (status == HAL_OK) {
		*data = ((uint16_t)buffer[0] << 8) | buffer[1];
	}
	return status;
}

HAL_StatusTypeDef EEPROM_WriteFloat(uint16_t addr, float data) {
	uint8_t buffer[4];
	memcpy(buffer, &data, sizeof(float));

	return EEPROM_WritePage(addr, buffer, 4);
}

HAL_StatusTypeDef EEPROM_ReadFloat(uint16_t addr, float *data) {
	uint8_t buffer[4];
	HAL_StatusTypeDef status = EEPROM_ReadPage(addr, buffer, 4);
	if (status == HAL_OK) {
		memcpy(data, buffer, sizeof(float));
	}
	return status;
}
