MW22-02A/BSP/Driver/mb85rc64/mb85rc64.c

363 lines
6.1 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.

///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();
}