PingPong/Core/Src/EEPROM.c
2024-09-10 01:40:51 +03:00

165 lines
4.9 KiB
C

#include "EEPROM.h"
#include "pca9685.h"
#include "usbd_cdc_if.h"
#include "Print.h"
MemoryStatus saveInfoBlock(InfoBlock *infoBlock) {
return FLASH_WriteBlock(START_ADR_STAT, 0, (uint8_t *)infoBlock, sizeof(InfoBlock));
}
MemoryStatus getInfoBlock(InfoBlock *infoBlock) {
MemoryStatus status = FLASH_ReadBlock(START_ADR_STAT, 0, (uint8_t *)infoBlock, sizeof(InfoBlock));
if (status != EEPROM_OK) {
return EEPROM_FAIL;
}
return EEPROM_OK;
}
MemoryStatus saveShot(unsigned char number, Shot* shot)
{
if (FLASH_WriteBlock(START_ADR_SHOT, number, (uint8_t*)shot, SHOT_BLOCKSIZE) == EEPROM_OK) {
return EEPROM_OK;
}
return EEPROM_FAIL;
}
MemoryStatus getShot(unsigned char number, Shot* shot)
{
if (FLASH_ReadBlock(START_ADR_SHOT, number, (uint8_t*)shot, SHOT_BLOCKSIZE) != EEPROM_OK) {
return EEPROM_FAIL;
}
if (!shot->isExist) {
return EEPROM_MISSING_ELEMENT;
}
return EEPROM_OK;
}
MemoryStatus saveProg(unsigned char number, Program* prog)
{
MemoryStatus result = EEPROM_OK;
for (uint16_t i = 0; i < MAX_NUMBER_SHOTS_IN_PROGRAMS; ++i) {
Shot shot;
MemoryStatus stat = getShot(prog->shots[i].id, &shot);
if (!(stat == EEPROM_OK || stat == EEPROM_MISSING_ELEMENT)) {
return EEPROM_FAIL;
}
if (!shot.isExist) {
// todo: добавить в запросы для загрузки снимков
result = EEPROM_MISSING_ELEMENT;
}
}
if (FLASH_WriteBlock(START_ADR_PROGRAM, number, (uint8_t*)prog, PROGRAM_BLOCKSIZE) != EEPROM_OK) {
return EEPROM_FAIL;
}
return result;
}
MemoryStatus getProg(unsigned char number, Program* prog)
{
if (FLASH_ReadBlock(START_ADR_PROGRAM, number, (uint8_t*)prog, PROGRAM_BLOCKSIZE) != EEPROM_OK) {
return EEPROM_FAIL;
}
if (!prog->header.isExist) {
return EEPROM_MISSING_ELEMENT;
}
return EEPROM_OK;
}
MemoryStatus saveMacro(unsigned char number, Macro* macro)
{
MemoryStatus result = EEPROM_OK;
for (uint16_t i = 0; i < MAX_NUMBER_PROGRAMS_IN_MACRO; ++i) {
Program prog;
MemoryStatus stat = getProg(macro->programs[i].id, &prog);
if (!(stat == EEPROM_OK || stat == EEPROM_MISSING_ELEMENT)) {
return EEPROM_FAIL;
}
if (!prog.header.isExist) {
result = EEPROM_MISSING_ELEMENT;
// todo: добавить в запросы для загрузки программ
}
}
if (FLASH_WriteBlock(START_ADR_MACRO, number, (uint8_t*)macro, MACRO_BLOCKSIZE) != EEPROM_OK) {
return EEPROM_FAIL;
}
return result;
}
MemoryStatus getMacro(unsigned char number, Macro* macro)
{
if (FLASH_ReadBlock(START_ADR_MACRO, number, (uint8_t*)macro, MACRO_BLOCKSIZE) != EEPROM_OK) {
return EEPROM_FAIL;
}
if (!macro->header.isExist) {
return EEPROM_MISSING_ELEMENT;
}
return EEPROM_OK;
}
MemoryStatus FLASH_WriteBlock(uint16_t startAddr, uint8_t number, uint8_t *writeData, uint8_t dataSize)
{
HAL_StatusTypeDef result;
// Проверка на корректность входных данных
if ((startAddr == START_ADR_SHOT && number > MAX_NUMBER_SHOTS) ||
(startAddr == START_ADR_PROGRAM && number > MAX_NUMBER_PROGRAMS) ||
(startAddr == START_ADR_MACRO && number > MAX_NUMBER_MACRO)) {
return EEPROM_OUT_OF_RANGE;
}
uint16_t blockAddr16 = (uint16_t)(startAddr + (uint16_t)(number * dataSize));
uint8_t blockAddr[2] = {HIBYTE(blockAddr16), LOBYTE(blockAddr16)};
unsigned char Buf[dataSize + 2];
memset(Buf, 0x00, sizeof(Buf));
Buf[0] = blockAddr[0];
Buf[1] = blockAddr[1];
for (unsigned char i = 0; i < dataSize; i++) Buf[i + 2] = writeData[i];
result = HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), Buf, (dataSize + 2), 10);
HAL_Delay(1);
if(result != HAL_OK){
return EEPROM_FAIL;
}
return EEPROM_OK;
}
MemoryStatus FLASH_ReadBlock(uint16_t startAddr, uint8_t number, uint8_t *readData, uint8_t dataSize)
{
HAL_StatusTypeDef result;
// Проверка на корректность входных данных
if ((startAddr == START_ADR_SHOT && number > MAX_NUMBER_SHOTS) ||
(startAddr == START_ADR_PROGRAM && number > MAX_NUMBER_PROGRAMS) ||
(startAddr == START_ADR_MACRO && number > MAX_NUMBER_MACRO)) {
return EEPROM_OUT_OF_RANGE;
}
memset(readData, 0x00, dataSize);
uint16_t blockAddr16 = (uint16_t)(startAddr + (uint16_t)(number * dataSize));
uint8_t blockAddr[2] = {HIBYTE(blockAddr16), LOBYTE(blockAddr16)};
result = HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), blockAddr, 2, 10);
HAL_Delay(1);
result = HAL_I2C_Master_Receive(&hi2c1, (AT24C_ADRESS << 1) | 1, readData, dataSize, 10);
HAL_Delay(1);
if(result != HAL_OK){
return EEPROM_FAIL;
}
return EEPROM_OK;
}