///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