moved libs to the lib directory

This commit is contained in:
2025-11-13 18:40:06 +03:00
parent 4678ff1690
commit dda7ed6db8
634 changed files with 3 additions and 2 deletions

171
lib/l502/l502api_eeprom.c Normal file
View File

@ -0,0 +1,171 @@
#include "l502api_private.h"
#include "ltimer.h"
#include "l502_fpga_regs.h"
#define L502_EEPROM_BIG_SECTOR_SIZE (64*1024)
#define L502_EEPROM_SMALL_SECTOR_SIZE (4*1024)
#define L502_FLASH_WRITE_TOUT 500
#define L502_FLASH_ERASE_TOUT 500
/** биты регистра статуса */
typedef enum {
SST25_STATUS_BUSY = 0x01,
SST25_STATUS_WEL = 0x02,
SST25_STATUS_BP0 = 0x04,
SST25_STATUS_BP1 = 0x08,
SST25_STATUS_BP2 = 0x10,
SST25_STATUS_BP3 = 0x20,
SST25_STATUS_AAI = 0x40,
SST25_STATUS_BPL = 0x80
} t_sst25_status_bits;
static uint8_t f_prot_bits[] = {
SST25_STATUS_BP2 | SST25_STATUS_BP1 | SST25_STATUS_BP0,
SST25_STATUS_BP2 | SST25_STATUS_BP0,
SST25_STATUS_BP2,
SST25_STATUS_BP0,
0
};
static LINLINE int32_t f_eeprom_rd_status(t_x502_hnd hnd, uint8_t* stat) {
uint32_t val;
int32_t err = l502_port_fpga_reg_read(hnd, L502_REGS_EEPROM_RD_STATUS, &val);
if (err == X502_ERR_OK)
*stat = (val>>24)&0xFF;
return err;
}
static LINLINE int32_t f_eeprom_wr_status(t_x502_hnd hnd, uint8_t stat) {
int32_t err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_STATUS_EN, 1);
if (err == X502_ERR_OK) {
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_STATUS, stat);
}
return err;
}
static int32_t f_eeprom_wr_byte(t_x502_hnd hnd, uint32_t addr, uint8_t val) {
int32_t err = X502_ERR_OK;
t_ltimer tmr;
uint8_t stat = SST25_STATUS_BUSY;
/* разрешаем запись в EEPROM */
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_EN, 1);
if (err == X502_ERR_OK) {
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_BYTE, ((addr & 0xFFFFFF) << 8) | val);
if (err != X502_ERR_OK)
l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_DIS, 1);
}
if (err == X502_ERR_OK)
ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(L502_FLASH_WRITE_TOUT));
/* Ожидаем завершения записи */
while ((err == X502_ERR_OK) && (stat & SST25_STATUS_BUSY) && !ltimer_expired(&tmr)) {
err = f_eeprom_rd_status(hnd, &stat);
}
if ((err == X502_ERR_OK) && (stat & SST25_STATUS_BUSY)) {
err = X502_ERR_FLASH_WRITE_TOUT;
}
return err;
}
int32_t l502_iface_flash_rd(t_x502_hnd hnd, uint32_t addr, uint8_t* data, uint32_t size) {
int32_t err = X502_ERR_OK;
uint32_t val;
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_SET_RD_ADDR, (addr & 0xFFFFFF) << 8);
if (err == X502_ERR_OK)
err = l502_port_fpga_reg_read(hnd, L502_REGS_EEPROM_RD_DWORD, &val);
if (err == X502_ERR_OK) {
unsigned int i;
for (i=0; (i < sizeof(val)) && size; i++, size--) {
*data++ = val & 0xFF;
val >>= 8;
}
}
return err;
}
int32_t l502_iface_flash_wr(t_x502_hnd hnd, uint32_t addr, const uint8_t* data, uint32_t size) {
uint32_t i;
int32_t err = X502_ERR_OK;
for (i=0; (i < size) && (err == X502_ERR_OK); i++) {
err = f_eeprom_wr_byte(hnd, addr+i, data[i]);
}
return err;
}
int32_t l502_iface_flash_erase(t_x502_hnd hnd, uint32_t addr, uint32_t size) {
int32_t err = X502_ERR_OK;
if (((addr & (L502_EEPROM_SMALL_SECTOR_SIZE-1)) ||
(size & (L502_EEPROM_SMALL_SECTOR_SIZE-1)))) {
err = X502_ERR_FLASH_SECTOR_BOUNDARY;
}
while((size != 0) && (err == X502_ERR_OK)) {
uint32_t er_size;
/* разрешаем запись в EEPROM */
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_EN, 1);
if (err == X502_ERR_OK) {
uint8_t stat = SST25_STATUS_BUSY;
t_ltimer tmr;
/* проверяем - можем ли стереть целиком большой сектор или
придется писать в мелкий */
if ((size >= L502_EEPROM_BIG_SECTOR_SIZE) &&
!(size & (L502_EEPROM_BIG_SECTOR_SIZE-1))) {
er_size = L502_EEPROM_BIG_SECTOR_SIZE;
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_ERASE_64K, addr<<8);
} else {
er_size = L502_EEPROM_SMALL_SECTOR_SIZE;
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_ERASE_4K, addr<<8);
}
if (err == X502_ERR_OK)
ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(L502_FLASH_ERASE_TOUT));
/* ожидаем завершения стирания */
while ((err == X502_ERR_OK) && (stat & SST25_STATUS_BUSY) && !ltimer_expired(&tmr)) {
err = f_eeprom_rd_status(hnd, &stat);
}
if ((err == X502_ERR_OK) && (stat & SST25_STATUS_BUSY)) {
err = X502_ERR_FLASH_ERASE_TOUT;
}
/* запрещаем запись, если произошла ошибка. при успешном стирании
запись будут запрещена атоматически */
if (err != X502_ERR_OK)
l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_EN, 0);
if (err == X502_ERR_OK) {
addr += er_size;
size -= er_size;
}
}
}
return err;
}
int32_t l502_iface_flash_set_prot(t_x502_hnd hnd, uint32_t prot, const uint8_t* prot_data, uint32_t size) {
int32_t err = X502_ERR_OK;
uint16_t prot_code = 0;
if (size == 2) {
prot_code = ((uint16_t)prot_data[1] << 8) | prot_data[0];
}
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_STATUS_EN, 1);
if ((err == X502_ERR_OK) && (prot_code != 0))
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_HARD_WR_STATUS_EN, prot_code);
if (err == X502_ERR_OK)
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_STATUS, f_prot_bits[prot]);
return err;
}