system/lib/driver/eeprom_fm24.c

220 lines
6.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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 "entity.h"
#include "board.h"
#include "eeprom_fm24.h"
#include "delay.h"
#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;
}