driver/epprom/eeprom_lc02b.c

173 lines
5.3 KiB
C
Raw Permalink 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.

#include "eeprom_lc02b.h"
#include "delay.h"
#include "i2cs.h"
#define W_ADD_COM 0xa8 // 写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0
#define R_ADD_COM 0xa9 // 读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1
#define PAGE_SIZE 8U
#define SIZE 256U
#define EEPROM_LC02B_SDA_PORT I2C1_SDA_GPIO_Port
#define EEPROM_LC02B_SDA_PIN I2C1_SDA_Pin
#define EEPROM_LC02B_SCL_PORT I2C1_SCL_GPIO_Port
#define EEPROM_LC02B_SCL_PIN I2C1_SCL_Pin
static i2c_t *_eeprom_24lc028bt_i2c;
static TIM_TypeDef *_timer_us;
static void _delay_us(uint32_t us)
{
if (_timer_us != NULL)
{
delay_hardware_us(_timer_us, us);
}
else
{
delay_us(us);
}
}
void eeprom_lc02b_test(void)
{
#define TEST_SIZE 15
uint16_t test_address = SIZE - TEST_SIZE;
uint8_t buf[TEST_SIZE];
for (uint8_t i = 0; i < TEST_SIZE; i++)
{
buf[i] = i + 1;
}
eeprom_lc02b_write(test_address, buf, TEST_SIZE);
_delay_us(10000);
osel_memset(buf, 0, ARRAY_LEN(buf));
eeprom_lc02b_read(test_address, buf, TEST_SIZE);
__NOP();
}
/**
* @brief 获取EEPROM LC02B的状态
*
* 此函数用于获取EEPROM LC02B的当前状态。
*
* @return 如果EEPROM LC02B处于正常状态则返回TRUE否则返回FALSE。
* 注意在本实现中总是返回TRUE因为这是一个简单的示例函数。
*/
BOOL eeprom_lc02b_status_get(void)
{
return TRUE;
}
/**
* @brief EEPROM LC02B初始化
* @return {*}
* @note
*/
void eeprom_lc02b_init(TIM_TypeDef *timer_us)
{
if (timer_us != NULL)
{
_timer_us = timer_us;
ENABLE_TIM_COUNT(_timer_us);
}
i2c_gpio_group_t gpios;
gpios.scl = gpio_create(EEPROM_LC02B_SCL_PORT, EEPROM_LC02B_SCL_PIN);
gpios.sda = gpio_create(EEPROM_LC02B_SDA_PORT, EEPROM_LC02B_SDA_PIN);
_eeprom_24lc028bt_i2c = i2c_create(gpios, 10);
// eeprom_lc02b_test();
}
/**
* @brief EEPROM LC02B反初始化
* @return {*}
* @note
*/
void eeprom_lc02b_dinit(void)
{
GPIO_SET_ANALOG(EEPROM_LC02B_SDA_PORT, EEPROM_LC02B_SDA_PIN);
GPIO_SET_ANALOG(EEPROM_LC02B_SCL_PORT, EEPROM_LC02B_SCL_PIN);
}
/**
* @brief 写入数据
* @param {uint32_t} write_addr
* @param {uint8_t} *data
* @param {uint16_t} length
* @return {*}
* @note
*/
void eeprom_lc02b_write(uint32_t write_addr, uint8_t *data, uint16_t length)
{
// 发送开始信号
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
// 发送写入地址命令
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, W_ADD_COM);
// 等待写入地址命令响应
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
// 发送要写入的地址
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, (uint8_t)write_addr);
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
// 循环写入数据
for (uint16_t i = 0; i < length; i++)
{
// 写入一个字节数据
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, *data++);
// 等待响应
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
write_addr++;
if (write_addr % PAGE_SIZE == 0)
{
_eeprom_24lc028bt_i2c->interface.stop(_eeprom_24lc028bt_i2c);
_delay_us(10000); // 延时10ms等待写入完成
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, W_ADD_COM);
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, (uint8_t)write_addr);
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
}
}
// 写入完成停止I2C总线
_eeprom_24lc028bt_i2c->interface.stop(_eeprom_24lc028bt_i2c);
}
/**
* @brief 读取数据
* @param {uint32_t} read_addr
* @param {uint8_t} *data
* @param {uint16_t} length
* @return {*}
* @note
*/
void eeprom_lc02b_read(uint32_t read_addr, uint8_t *data, uint16_t length)
{
// 发送开始信号
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
// 发送写入地址命令
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, W_ADD_COM);
// 等待写入地址命令响应
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
// 发送要读取的地址
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, (uint8_t)read_addr);
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
// 发送开始信号
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
// 发送读取地址命令
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, R_ADD_COM);
// 等待读取地址命令响应
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
// 循环读取数据
for (uint16_t i = 0; i < length - 1; i++)
{
// 读取一个字节数据
*data++ = _eeprom_24lc028bt_i2c->interface.read_byte(_eeprom_24lc028bt_i2c, TRUE);
}
*data++ = _eeprom_24lc028bt_i2c->interface.read_byte(_eeprom_24lc028bt_i2c, FALSE);
// 停止I2C总线
_eeprom_24lc028bt_i2c->interface.stop(_eeprom_24lc028bt_i2c);
}