318 lines
5.1 KiB
C
318 lines
5.1 KiB
C
///Copyright (c) 2022, 四川汇源光通信有限公司
|
||
///All rights reserved.
|
||
///@file mb85rc64.h
|
||
///@brief mb85rc64驱动程序 铁电存储器
|
||
///
|
||
///@details
|
||
///@note
|
||
///@author dufresne
|
||
///@date 2025/09/26
|
||
///
|
||
///@version v1.0 2022/05/26 初始版本
|
||
|
||
#include "mb85rc64.h"
|
||
|
||
#ifdef SOFTWARE_I2C
|
||
|
||
/*
|
||
@ brief 设置SDA引脚为输出模式
|
||
@ param
|
||
@ return
|
||
@ note 2022-5-26 lqc
|
||
*/
|
||
static void mb85rc64_sda_output()
|
||
{
|
||
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, I2C_SDA_PIN);
|
||
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
|
||
MB85RC64_SDA_HIGH;
|
||
}
|
||
|
||
/*
|
||
@ brief 设置SDA引脚为输入模式
|
||
@ param
|
||
@ return
|
||
@ note 2022-5-26 lqc
|
||
*/
|
||
static void mb85rc64_sda_input()
|
||
{
|
||
gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, I2C_SDA_PIN);
|
||
gpio_output_options_set(GPIOB, GPIO_PUPD_NONE, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
|
||
}
|
||
|
||
/*
|
||
@ brief I2C start信号
|
||
@ param
|
||
@ return
|
||
@ note 2022-5-25
|
||
*/
|
||
static void i2c_start()
|
||
{
|
||
MB85RC64_SDA_HIGH;
|
||
delay_us(5);
|
||
MB85RC64_SCL_HIGH;
|
||
delay_us(5);
|
||
MB85RC64_SDA_LOW;
|
||
delay_us(4);
|
||
}
|
||
|
||
/*
|
||
@ brief I2C stop信号
|
||
@ param
|
||
@ return
|
||
@ note 2022-05-25
|
||
*/
|
||
static void i2c_stop()
|
||
{
|
||
MB85RC64_SDA_LOW;
|
||
delay_us(5);
|
||
MB85RC64_SCL_HIGH;
|
||
delay_us(5);
|
||
MB85RC64_SDA_HIGH;
|
||
delay_us(4);
|
||
}
|
||
|
||
/*
|
||
@ brief mb85rc64接收数据产生ACK信号
|
||
@ param SDA被从设备拉为低电平表示应答
|
||
@ return
|
||
@ note 2022-05-26
|
||
*/
|
||
static void mb85rc64_ack()
|
||
{
|
||
int i = 0;
|
||
mb85rc64_sda_input();
|
||
delay_us(5);
|
||
MB85RC64_SCL_HIGH;
|
||
delay_us(5);
|
||
while((MB85RC64_SDA_GET) && i<1000)
|
||
{
|
||
i++;
|
||
}
|
||
delay_us(5);
|
||
MB85RC64_SCL_LOW;
|
||
delay_us(5);
|
||
mb85rc64_sda_output();
|
||
}
|
||
|
||
/*
|
||
@ brief 主机读取数据发送ACK信号,SDA为低电平
|
||
@ param SCL下降沿发送
|
||
@ return
|
||
@ note 2022-05-26
|
||
*/
|
||
static void master_ack()
|
||
{
|
||
MB85RC64_SDA_LOW;
|
||
delay_us(5);
|
||
MB85RC64_SCL_HIGH;
|
||
delay_us(5);
|
||
MB85RC64_SCL_LOW;
|
||
delay_us(5);
|
||
}
|
||
|
||
/*
|
||
@ brief 主机读取数据完毕,发送no_ack信号,SDA为高电平
|
||
@ param
|
||
@ return
|
||
@ note 2022-05-26
|
||
*/
|
||
static void master_no_ack()
|
||
{
|
||
MB85RC64_SDA_HIGH;
|
||
delay_us(5);
|
||
MB85RC64_SCL_HIGH;
|
||
delay_us(5);
|
||
MB85RC64_SCL_LOW;
|
||
delay_us(5);
|
||
}
|
||
|
||
/*
|
||
@ brief 写一个字节数据
|
||
@ param
|
||
@ return
|
||
@ note 2022-05-26
|
||
*/
|
||
static void mb85rc64_write_byte(uint8_t byte)
|
||
{
|
||
for(int i = 0; i < 8; i++)
|
||
{
|
||
MB85RC64_SCL_LOW;
|
||
delay_us(5);
|
||
if(byte & 0x80)
|
||
{
|
||
MB85RC64_SDA_HIGH;
|
||
}
|
||
else
|
||
{
|
||
MB85RC64_SDA_LOW;
|
||
}
|
||
|
||
MB85RC64_SCL_HIGH;
|
||
delay_us(5);
|
||
byte <<= 1;
|
||
}
|
||
MB85RC64_SCL_LOW;
|
||
}
|
||
|
||
/*
|
||
@ brief 读一个字节数据
|
||
@ param
|
||
@ return
|
||
@ note 2022-05-26
|
||
*/
|
||
static uint8_t mb85rc64_read_byte()
|
||
{
|
||
uint8_t value = 0;
|
||
MB85RC64_SCL_LOW;
|
||
delay_us(5);
|
||
mb85rc64_sda_input();
|
||
|
||
|
||
for(int i = 0; i < 8; i++)
|
||
{
|
||
|
||
value <<= 1;
|
||
MB85RC64_SCL_LOW;
|
||
delay_us(5);
|
||
MB85RC64_SCL_HIGH;
|
||
|
||
delay_us(5);
|
||
if(MB85RC64_SDA_GET)
|
||
{
|
||
value = value | 0x01;
|
||
}
|
||
else {
|
||
value = value & 0xfe;
|
||
}
|
||
}
|
||
MB85RC64_SCL_LOW;
|
||
delay_us(5);
|
||
mb85rc64_sda_output();
|
||
return value;
|
||
}
|
||
|
||
/*
|
||
@ brief 保存数据,页写
|
||
@ param addr:保存数据的地址,data:需保存的数据,data_len:保存数据的长度
|
||
@ return
|
||
@ note 2022-05-27
|
||
*/
|
||
char mb85rc64_write_read(unsigned short int addr, unsigned char* data, int data_len, bool statues)
|
||
{
|
||
uint8_t addr_H = 0;
|
||
uint8_t addr_L = 0;
|
||
|
||
addr_H = (addr >> 8) & 0x00ff;
|
||
addr_L = addr & 0x00ff;
|
||
//启动信号
|
||
i2c_start();
|
||
//写地址,R/W位=0
|
||
// mb85rc64_write_byte(MB85RC64_ADDRESS_WRITE);
|
||
mb85rc64_write_byte(MB85RC64_ADDRESS << 1);
|
||
//ack信号
|
||
mb85rc64_ack();
|
||
//写高8位地址
|
||
mb85rc64_write_byte(addr_H);
|
||
//ack信号
|
||
mb85rc64_ack();
|
||
//写低8位地址
|
||
mb85rc64_write_byte(addr_L);
|
||
//ack信号
|
||
mb85rc64_ack();
|
||
|
||
if (statues == PAGE_WRITE)
|
||
{
|
||
for(int i = 0; i < data_len; i++)
|
||
{
|
||
mb85rc64_write_byte(*data);
|
||
mb85rc64_ack();
|
||
data++;
|
||
}
|
||
}
|
||
else if (statues == ADDR_READ)
|
||
{
|
||
//启动信号
|
||
i2c_start();
|
||
//写地址,R/W为为1,读数据
|
||
mb85rc64_write_byte((MB85RC64_ADDRESS << 1) + 1);
|
||
//ack信号
|
||
mb85rc64_ack();
|
||
for(int i = 0; i < data_len; i++)
|
||
{
|
||
//读数据
|
||
data[i] = mb85rc64_read_byte();
|
||
if(i == data_len - 1)
|
||
{
|
||
master_no_ack();
|
||
}
|
||
else
|
||
{
|
||
master_ack();
|
||
}
|
||
}
|
||
}
|
||
//停止信号
|
||
i2c_stop();
|
||
return 1;
|
||
}
|
||
|
||
void read_mb_id(uint8_t* buff)
|
||
{
|
||
i2c_start();
|
||
mb85rc64_write_byte(0xf8);
|
||
mb85rc64_ack();
|
||
mb85rc64_write_byte(MB85RC64_ADDRESS << 1);
|
||
mb85rc64_ack();
|
||
i2c_start();
|
||
mb85rc64_write_byte(0xf9);
|
||
mb85rc64_ack();
|
||
for(int i = 0; i < 3; i++)
|
||
{
|
||
//读数据
|
||
buff[i] = mb85rc64_read_byte();
|
||
if(i == 3 - 1)
|
||
{
|
||
master_no_ack();
|
||
}
|
||
else
|
||
{
|
||
master_ack();
|
||
}
|
||
}
|
||
i2c_stop();
|
||
}
|
||
|
||
#endif
|
||
|
||
// #ifdef HARDWARE_I2C
|
||
|
||
// void read_mb_id(uint8_t* buff)
|
||
// {
|
||
// i2c_start();
|
||
// mb85rc64_write_byte(0xf8);
|
||
// mb85rc64_ack();
|
||
// mb85rc64_write_byte(MB85RC64_ADDRESS << 1);
|
||
// mb85rc64_ack();
|
||
// i2c_start();
|
||
// mb85rc64_write_byte(0xf9);
|
||
// mb85rc64_ack();
|
||
// for(int i = 0; i < 3; i++)
|
||
// {
|
||
// //读数据
|
||
// buff[i] = mb85rc64_read_byte();
|
||
// if(i == 3 - 1)
|
||
// {
|
||
// master_no_ack();
|
||
// }
|
||
// else
|
||
// {
|
||
// master_ack();
|
||
// }
|
||
// }
|
||
// i2c_stop();
|
||
|
||
|
||
// i2c_read(buff, 3, MB85RC64_ADDRESS);
|
||
// }
|
||
|
||
// #endif
|