228 lines
6.4 KiB
C
228 lines
6.4 KiB
C
/**
|
||
* @file eeprom_fm24.c
|
||
* @author xxx
|
||
* @date 2023-08-29 07:58:27
|
||
* @brief 用于实现FM24 EEPROM相关的读写操作
|
||
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
|
||
*/
|
||
#include "eeprom_fm24.h"
|
||
#include "delay.h"
|
||
|
||
//========在此设定芯片地址=============
|
||
|
||
#define W_ADD_COM 0xa0 // 写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0
|
||
|
||
#define R_ADD_COM 0xa1 // 读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1
|
||
|
||
//=======在此设定芯片型号, 1代表24C01; 16代表24C16; 512代表24C512
|
||
|
||
//=======在此设定芯片型号, 1代表24C01; 16代表24C16; 512代表24C512
|
||
|
||
#define FM24_SPI SPI1
|
||
|
||
#define EEPROM_FM24_CS_PORT EE3_CS_GPIO_Port
|
||
#define EEPROM_FM24_CS_PIN EE3_CS_Pin
|
||
#define EEPROM_FM24_MOSI_PORT SPI_MOSI_GPIO_Port
|
||
#define EEPROM_FM24_MOSI_PIN SPI_MOSI_Pin
|
||
#define EEPROM_FM24_MISO_PORT SPI_MISO_GPIO_Port
|
||
#define EEPROM_FM24_MISO_PIN SPI_MISO_Pin
|
||
#define EEPROM_FM24_SCK_PORT SPI_CLK_GPIO_Port
|
||
#define EEPROM_FM24_SCK_PIN SPI_CLK_Pin
|
||
|
||
static fm24_t _eeprom_fm24;
|
||
|
||
void eeprom_fm24_init(void)
|
||
{
|
||
spi_gpio_group_t gpios;
|
||
spi_normal_config_t cfg;
|
||
osel_memset((uint8_t *)&cfg, 0, sizeof(spi_normal_config_t));
|
||
// 创建CS引脚
|
||
gpios.cs = gpio_create(EEPROM_FM24_CS_PORT, EEPROM_FM24_CS_PIN);
|
||
gpios.mosi = gpio_create(EEPROM_FM24_MOSI_PORT, EEPROM_FM24_MOSI_PIN);
|
||
gpios.sck = gpio_create(EEPROM_FM24_SCK_PORT, EEPROM_FM24_SCK_PIN);
|
||
gpios.miso = gpio_create(EEPROM_FM24_MISO_PORT, EEPROM_FM24_MISO_PIN);
|
||
gpios.rst = gpio_create(NULL, 0);
|
||
gpios.rdy = gpio_create(NULL, 0);
|
||
|
||
// 创建SPI对象
|
||
eeprom_fm24_get()->spi = spi_create(SPI_TYPE_NORMAL, gpios, 0);
|
||
DBG_ASSERT(eeprom_fm24_get() != NULL __DBG_LINE);
|
||
cfg.cmd_rdsr = FM24_CMD_RDSR;
|
||
cfg.cmd_wrsr = FM24_CMD_WRSR;
|
||
cfg.cmd_wren = FM24_CMD_WREN;
|
||
cfg.cmd_wrdi = FM24_CMD_WRDI;
|
||
cfg.cmd_write = FM24_CMD_WRITE;
|
||
cfg.cmd_read = FM24_CMD_READ;
|
||
cfg.dummy_byte = FM24_DUMMY_BYTE;
|
||
cfg.address_bytes = 2;
|
||
cfg.page_size = FM24_PAGE_SIZE;
|
||
cfg.total_size = FM24_SIZE;
|
||
cfg.continuous_write = FALSE;
|
||
osel_memcpy((uint8_t *)&eeprom_fm24_get()->spi->cfg, (uint8_t *)&cfg, sizeof(spi_normal_config_t));
|
||
// 使能SPI
|
||
eeprom_fm24_get()->spi->interface.hardware_enable(eeprom_fm24_get()->spi, FM24_SPI);
|
||
// 这里需要复位下SPI,否则读出的数据不对
|
||
eeprom_fm24_get()->spi->interface.u.normal.spi_reset(eeprom_fm24_get()->spi);
|
||
|
||
eeprom_fm24_write_protection_close();
|
||
// eeprom_fm24_test();
|
||
}
|
||
|
||
fm24_t *eeprom_fm24_get(void)
|
||
{
|
||
return &_eeprom_fm24;
|
||
}
|
||
|
||
void eeprom_fm24_dinit(void)
|
||
{
|
||
LL_SPI_Disable(FM24_SPI);
|
||
GPIO_SET_ANALOG(eeprom_fm24_get()->spi->gpios.mosi->port, eeprom_fm24_get()->spi->gpios.mosi->pin);
|
||
GPIO_SET_ANALOG(eeprom_fm24_get()->spi->gpios.miso->port, eeprom_fm24_get()->spi->gpios.miso->pin);
|
||
GPIO_SET_ANALOG(eeprom_fm24_get()->spi->gpios.sck->port, eeprom_fm24_get()->spi->gpios.sck->pin);
|
||
GPIO_SET_ANALOG(eeprom_fm24_get()->spi->gpios.cs->port, eeprom_fm24_get()->spi->gpios.cs->pin);
|
||
}
|
||
|
||
void eeprom_fm24_enable(void)
|
||
{
|
||
uint16_t count = 100;
|
||
LL_SPI_Enable(FM24_SPI);
|
||
// 判断SPI是否使能成功
|
||
while (LL_SPI_IsEnabled(FM24_SPI) != 1)
|
||
{
|
||
if (count-- == 0)
|
||
{
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
__NOP();
|
||
}
|
||
}
|
||
}
|
||
|
||
void eeprom_fm24_disable(void)
|
||
{
|
||
uint16_t count = 100;
|
||
LL_SPI_Disable(FM24_SPI);
|
||
// 判断SPI是否关闭成功
|
||
while (LL_SPI_IsEnabled(FM24_SPI) != 0)
|
||
{
|
||
if (count-- == 0)
|
||
{
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
__NOP();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 关闭EEPROM FM24的写保护
|
||
*
|
||
* 此函数用于关闭EEPROM FM24的写保护功能,允许对其进行写操作。
|
||
*
|
||
* 调用此函数前,应确保EEPROM FM24的SPI接口已正确初始化。
|
||
*/
|
||
void eeprom_fm24_write_protection_close(void)
|
||
{
|
||
DBG_ASSERT(eeprom_fm24_get()->spi != NULL __DBG_LINE);
|
||
eeprom_fm24_enable();
|
||
eeprom_fm24_get()->spi->interface.u.normal.spi_write_reg(eeprom_fm24_get()->spi, eeprom_fm24_get()->spi->cfg.cmd_wrsr, 0);
|
||
eeprom_fm24_disable();
|
||
}
|
||
|
||
/**
|
||
* @brief 获取EEPROM FM24的写保护状态
|
||
*
|
||
* 获取EEPROM FM24的写保护状态。
|
||
*
|
||
* @return BOOL 返回TRUE表示没有写保护,返回FALSE表示有写保护
|
||
*/
|
||
BOOL eeprom_fm24_write_protection_state(void)
|
||
{
|
||
DBG_ASSERT(eeprom_fm24_get()->spi != NULL __DBG_LINE);
|
||
eeprom_fm24_enable();
|
||
eeprom_fm24_get()->write_protection.data = eeprom_fm24_get()->spi->interface.u.normal.spi_read_reg(eeprom_fm24_get()->spi, eeprom_fm24_get()->spi->cfg.cmd_rdsr);
|
||
eeprom_fm24_disable();
|
||
|
||
if (eeprom_fm24_get()->write_protection.bits.bp0 == 1 ||
|
||
eeprom_fm24_get()->write_protection.bits.bp1 == 1 ||
|
||
eeprom_fm24_get()->write_protection.bits.wpen == 1)
|
||
{
|
||
return FALSE;
|
||
}
|
||
else
|
||
{
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
BOOL eeprom_fm24_write(uint32_t write_addr, uint8_t *data, uint16_t length)
|
||
{
|
||
BOOL ret = FALSE;
|
||
if (length == 0)
|
||
{
|
||
return ret;
|
||
}
|
||
// 开启和关闭SPI对读写实时性有影响
|
||
eeprom_fm24_enable();
|
||
ret = eeprom_fm24_get()->spi->interface.u.normal.spi_write(eeprom_fm24_get()->spi, write_addr, data, length);
|
||
eeprom_fm24_disable();
|
||
return ret;
|
||
}
|
||
|
||
BOOL eeprom_fm24_read(uint32_t read_addr, uint8_t *data, uint16_t length)
|
||
{
|
||
BOOL ret = FALSE;
|
||
if (length == 0)
|
||
{
|
||
return ret;
|
||
}
|
||
// 开启和关闭SPI对读写实时性有影响
|
||
eeprom_fm24_enable();
|
||
ret = eeprom_fm24_get()->spi->interface.u.normal.spi_read(eeprom_fm24_get()->spi, read_addr, data, length);
|
||
eeprom_fm24_disable();
|
||
return ret;
|
||
}
|
||
|
||
BOOL eeprom_fm24_test(void)
|
||
{
|
||
const uint8_t buf_size = 5;
|
||
uint16_t test_address = FM24_TEST_PAGE * FM24_PAGE_SIZE;
|
||
uint8_t buf[buf_size];
|
||
uint8_t rbuf[buf_size];
|
||
osel_memset(buf, 0, buf_size);
|
||
osel_memset(rbuf, 0, buf_size);
|
||
buf[0] = 0xD5;
|
||
buf[1] = 0xC8;
|
||
buf[2] = 0x00;
|
||
buf[3] = 0x01;
|
||
buf[4] = 0x02;
|
||
buf[buf_size - 1] = 0xfe;
|
||
eeprom_fm24_write(test_address, buf, buf_size);
|
||
__NOP();
|
||
eeprom_fm24_read(test_address, rbuf, buf_size);
|
||
if (osel_memcmp(buf, rbuf, buf_size) == 0)
|
||
{
|
||
return TRUE;
|
||
}
|
||
else
|
||
{
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 获取FM24 EEPROM的状态
|
||
*
|
||
* 获取FM24 EEPROM的当前状态。该函数始终返回TRUE,表示EEPROM正常工作。
|
||
*
|
||
* @return BOOL 始终返回TRUE
|
||
*/
|
||
BOOL eeprom_fm24_status_get(void)
|
||
{
|
||
return TRUE;
|
||
}
|