363 lines
6.1 KiB
C
363 lines
6.1 KiB
C
///Copyright (c) 2022, 四川汇源光通信有限公司
|
||
///All rights reserved.
|
||
///@file mb85rc64.h
|
||
///@brief mb85rc64驱动程序 铁电存储器
|
||
///
|
||
///@details
|
||
///@note
|
||
///@author lqc
|
||
///@date 2022/05/26
|
||
///
|
||
///@version v1.0 2022/05/26 初始版本
|
||
|
||
#include "mb85rc64.h"
|
||
|
||
|
||
/*
|
||
@ brief 延时函数
|
||
@ param
|
||
@ return
|
||
@ note 2022-5-23
|
||
*/
|
||
static void delay_us(int us)
|
||
{
|
||
for(int i = 0; i < us; i++ )
|
||
{
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
asm("nop");
|
||
}
|
||
}
|
||
|
||
/*
|
||
@ brief 芯片初始化
|
||
@ param
|
||
@ return
|
||
@ note 2022-05-26
|
||
*/
|
||
void mb85rc64_gpio_init()
|
||
{
|
||
//配置引脚时钟
|
||
rcu_periph_clock_enable(RCU_GPIOB);
|
||
//设置引脚为输出模式:PB6
|
||
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);
|
||
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
|
||
|
||
//设置引脚PB7输出模式
|
||
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
|
||
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
|
||
|
||
MB85RC64_SCL_HIGH;
|
||
MB85RC64_SDA_HIGH;
|
||
}
|
||
|
||
/*
|
||
@ brief 设置SDA引脚为输出模式
|
||
@ param
|
||
@ return
|
||
@ note 2022-5-26 lqc
|
||
*/
|
||
static void mb85rc64_sda_output()
|
||
{
|
||
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
|
||
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
|
||
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, GPIO_PIN_7);
|
||
gpio_output_options_set(GPIOB, GPIO_PUPD_NONE, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
|
||
}
|
||
|
||
/*
|
||
@ 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_page_write(unsigned short int addr, unsigned char* data, int data_len)
|
||
{
|
||
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);
|
||
//ack信号
|
||
mb85rc64_ack();
|
||
//写高8位地址
|
||
mb85rc64_write_byte(addr_H);
|
||
//ack信号
|
||
mb85rc64_ack();
|
||
//写低8位地址
|
||
mb85rc64_write_byte(addr_L);
|
||
//ack信号
|
||
mb85rc64_ack();
|
||
for(int i = 0; i < data_len; i++)
|
||
{
|
||
mb85rc64_write_byte(*data);
|
||
mb85rc64_ack();
|
||
data++;
|
||
}
|
||
//停止信号
|
||
i2c_stop();
|
||
return 1;
|
||
}
|
||
|
||
/*
|
||
@ brief 读取数据 ,顺序读取,指定地址,连续接收数据
|
||
@ param addr :需要读取数据的地址,data:数据, data_len:数据长度
|
||
@ return
|
||
@ note 2022-05-27 lqc
|
||
*/
|
||
char mb85rc64_add_read(unsigned short int addr, unsigned char *data, int data_len)
|
||
{
|
||
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);
|
||
//ack信号
|
||
mb85rc64_ack();
|
||
//写高8位地址
|
||
mb85rc64_write_byte(addr_H);
|
||
//ack信号
|
||
mb85rc64_ack();
|
||
//写低8位地址
|
||
mb85rc64_write_byte(addr_L);
|
||
//ack信号
|
||
mb85rc64_ack();
|
||
|
||
//启动信号
|
||
i2c_start();
|
||
//写地址,R/W为为1,读数据
|
||
mb85rc64_write_byte(MB85RC64_ADDRESS_READ);
|
||
//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_WRITE);
|
||
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();
|
||
}
|