STM32调试MIPI RFFE协议

目录

一、前言

二、RFFE总线

三、协议时序

四、器件状态

五、更改USID

六、程序代码

七、参考资料


一、前言

前阵子手里有几个天线调谐器芯片,1.5x1mm的BGA封装非常小,通信控制协议是MIPI RFFE协议,这个协议网上资料比较少,搜了一下搜到了一个标准的MIPI协议文档,里面各种控制时序和介绍都写的非常详细了,其实就和I2C这类的协议差不多吧,然后在CSDN上又找到了一个STM32用GPIO模拟MIPI RFFE协议的文档资料作参考,稍微改了改,调试的时候遇到了一些问题,然后用逻辑分析仪抓了抓波形改了改代码,然后调试成功了,本文进行调试总结。

 

二、RFFE总线

RFFE总线定义如下:

STM32调试MIPI RFFE协议_第1张图片

 

VIORFFE接口的基准电压,也可以作为复位和使能输入。一个施加到VIO 信号的逻辑低电平可以将RFFE接口关断。

SCLKRFFE 总线时钟输入。通常被连接至RF 或基带IC 上的RFFE 主机。当未施加VIO 时,SCLK 必须为低电平。时钟频率范围为32KHz到26MHz。

SDATARFFE 总线数据输入/输出。通常被连接至RF 或基带IC 上的RFFE 主机。当未施加VIO 时,SCLK 必须为低电平。

MIPI RFFE协议和I2C协议真的共性很多,都是一条数据线(SDATA)和一条时钟线(SCLK),然后所有的从设备都通过这两条线挂接到总线上,所有的从设备都可以设置独立的从设备地址,Master可以通过从设备地址来单独控制多个从设备中的单个设备,RFFE总线高电平为1.2到1.8V,VIO供电也是1.2到1.8V,注意不要用3.3V单片机IO直接驱动,要接个电平转换芯片。RFFE设备连接框图如下:

STM32调试MIPI RFFE协议_第2张图片

 

三、协议时序

时序操作基本上可以归为两类操作,寄存器写和寄存器读,其中寄存器写又分为寄存器0写入、普通寄存器写入和扩展寄存器写入;读可以分为普通寄存器读和扩展寄存器读。从机寄存器寻址如下。

STM32调试MIPI RFFE协议_第3张图片

写寄存器命令分好几种,区别就是可以访问的寄存器地址区间不一样,我手头上这个IC的有用数据都是定义在寄存器0到31上的,之后的地址没定义,所以用不到扩展寄存器写命令。不管是哪种操作,都可以归类为:SSC头+命令帧+数据帧+停止帧。

STM32调试MIPI RFFE协议_第4张图片

1、基本命令帧

(1)SSC(Sequence Start Condition)

 

STM32调试MIPI RFFE协议_第5张图片

 SSC具体时序是SCLK为低电平时,SDATA0变为两个周期的1,然后变为0。SSC相当于是启动信号,每次命令操作都需要先发送该时序。

(2)命令帧

STM32调试MIPI RFFE协议_第6张图片

命令帧前4bit为从机地址,接下来是8bit的命令+1bit的奇校验位(对前12bit数据进行奇校验),

(3)数据帧

STM32调试MIPI RFFE协议_第7张图片

8bit的数据+1bit的奇校验。

(4)Bus Park帧

最后在SCLK的一个下降沿SDATA保持一个以上周期的0电平来使总线挂起也就是Bus park

 

2、寄存器写操作

(1)寄存器0写入

STM32调试MIPI RFFE协议_第8张图片

SA0到SA3是从机地址,一般和器件的4位USID值是一致的,寄存器0写入命令的命令帧前8bit的最高位D7是固定为1的,剩下的D0到D6是写入到寄存器0的数据,实际上也就只能修改寄存器0的D0到D6的数据。

(2)非0寄存器写入

STM32调试MIPI RFFE协议_第9张图片

命令帧的前3位D7,D6,D5固定为0,1,0,剩下的5位表示寄存器地址,实际上能够寻址的寄存器范围只有0到31,命令帧接下来是数据帧,D0到D7是要写入到相应寄存器的数据。

(3)扩展寄存器写入

STM32调试MIPI RFFE协议_第10张图片

命令帧的前4位固定为全0,只剩下BC0~BC3是可以自己填的,这4位表示要写入多少个字节的数据,0表示写一个字节,0xF表示写16个字节,其实一个寄存器只能写1个字节,多写的字节会根据当前寄存器的地址开始向后写入到后面的寄存器中。数据帧那里的8位用来填写寄存器的地址,之后的很多个帧根据BC0~BC3的值追加多个要写入的字节数据。

3、寄存器读操作

(1)寄存器读

STM32调试MIPI RFFE协议_第11张图片

读寄存器跟写寄存器一样的套路,先给4位从机地址,然后因为是普通读,命令帧的高三位定死了是0,1,1,剩下的5位可以自己填,实际只能寻址0到31这些寄存器,然后后面接8位的数据读取操作,这里读取操作的时候主机要把SDATA设为下拉模式,即默认电平为低电平,然后从机输出数据的话如果是1会把SDATA拉高,8位寄存器数据之后是1位寄校验(对前面8位数据校验),注意编程的时候还是要判断下器件给的奇校验位P,看下是不是校验能够通过,否则读到的数据是错的。

 

(2)扩展寄存器读

STM32调试MIPI RFFE协议_第12张图片

BC0到BC3表示读取的字节数目,为0时表示都1个字节,为0xF时表示读16个字节,读超过1个字节会返回当前寄存器地址往后的寄存器地址的内容,和扩展寄存器写套路一样的。

 

四、器件状态

以下是器件状态切换图:

STM32调试MIPI RFFE协议_第13张图片

RFFE的器件有几种状态可以切换,分别为STARTUP、ACTIVE、LOW POWER、SHUTDOWN。通过VIO电平状态切换和往PWR_MODE寄存器写值来跳转这些状态。操作IC的时候发现不激活IC的状态只能读寄存器,写寄存器时无效。

 

五、更改USID

单独更改USID寄存器的值是改不了USID的,发现读回来的数据还是原来的。改USID要同时更改PRODUCT_ID、MANUFACTURER_ID和USID,这样才能改动USID的值,然后从机地址就跟着一起变了,下次给SA0~SA3的时候记得要替换回新的从机地址。具体时序如下:

STM32调试MIPI RFFE协议_第14张图片

看着那么长一段,其实就是三个寄存器写命令拼在一起。

 

六、程序代码

代码是基于STM32F103XX调试的,如下:

MIPI.h

#ifndef _MIPI_H_
#define _MIPI_H_

#include "stm32f10x.h"
#include "public.h"
#include "systick.h"

#define REG_PAC_SPST_STATE  0x00
#define REG_VBODY_TIMERS    0x01
#define REG_VVAR            0x02
#define REG_CUSTOMER_SRATCH 0x17
#define REG_RFFE_STATUS     0x1A
#define REG_GROUP_SID       0x1B
#define REG_PM_TRIG         0x1C
#define REG_PRODUCT_ID      0x1D
#define REG_MANUFACTURER_ID 0x1E
#define REG_MAN_USID        0x1F
#define REG_CMOS_VERSION_ID 0x21
#define REG_SDATA_DRV_LVL   0x2B

#define CHECK_OK 	1
#define CHECK_FAIL 	0

#define RFFE_SDATA_PORT	GPIOA
#define RFFE_SDATA_PIN	GPIO_Pin_0

#define RFFE_SCLK_PORT	GPIOA
#define RFFE_SCLK_PIN	GPIO_Pin_1

#define RFFE_SDATA_HIGH GPIO_SetBits(RFFE_SDATA_PORT, RFFE_SDATA_PIN)
#define RFFE_SDATA_LOW	GPIO_ResetBits(RFFE_SDATA_PORT, RFFE_SDATA_PIN)

#define RFFE_SDATA_READ	GPIO_ReadInputDataBit(RFFE_SDATA_PORT, RFFE_SDATA_PIN)

#define RFFE_SCLK_HIGH GPIO_SetBits(RFFE_SCLK_PORT, RFFE_SCLK_PIN)
#define RFFE_SCLK_LOW	GPIO_ResetBits(RFFE_SCLK_PORT, RFFE_SCLK_PIN)

#define Delay_nop(x) delay_us(x);

//#define Delay_nop(x) {;;;;;};

#define Bus_Park()	RFFE_SDATA_LOW

//GPIO初始化
extern void RFFE_Init(void);
//寄存器读
extern unsigned char Register_Read(unsigned char USID_Address, unsigned char Reg_address, unsigned char *Reg_Value);
//0寄存器写
extern void Register_0_Write(unsigned char USID_Address, unsigned char Reg_data);
//非0寄存器写,实验中发现写0寄存器也生效
extern void Register_Write(unsigned char USID_Address, unsigned char Reg_Address, unsigned char Reg_data);
//器件使能
extern void Active_Product(unsigned char USID_Address);
//必须连续一起修改Product_ID、MANUFACTURER_ID、USID才能使新的USID生效,单独修改USID寄存器不生效
extern void Register_Write_USID(unsigned char Old_USID_Address, unsigned char Product_ID, unsigned short MANUFACTURER_ID, unsigned char MAN_USID);
//写一个字节到扩展寄存器,扩展寄存器指地址大于0x1F的寄存器
extern void Extended_Register_Write(unsigned char USID_Address, unsigned char Reg_Address, unsigned char Reg_data);
//扩展寄存器读一个字节
extern unsigned char Extended_Register_Read(unsigned char USID_Address, unsigned char Reg_address, unsigned char *Reg_Value);

#endif

MIPI.c

#include "MIPI.h"

void RFFE_SDATA_Output_Mode(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;	

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 
		
	GPIO_InitStructure.GPIO_Pin = RFFE_SDATA_PIN;	 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	  
	GPIO_Init(RFFE_SDATA_PORT, &GPIO_InitStructure); 

	RFFE_SDATA_LOW;
}

void RFFE_SDATA_Input_Mode(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;	

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 
		
	GPIO_InitStructure.GPIO_Pin = RFFE_SDATA_PIN;	 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	  
	GPIO_Init(RFFE_SDATA_PORT, &GPIO_InitStructure); 

	//RFFE_SDATA_LOW;
}

void RFFE_SCLK_Output_Mode(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;	

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 
		
	GPIO_InitStructure.GPIO_Pin = RFFE_SCLK_PIN;	 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	  
	GPIO_Init(RFFE_SCLK_PORT, &GPIO_InitStructure); 

	RFFE_SCLK_LOW;
}

void RFFE_Init(void)
{
	RFFE_SCLK_Output_Mode();
	RFFE_SDATA_Output_Mode();
	
}

void SSC_Head(void)
{
	RFFE_SCLK_LOW;
	RFFE_SDATA_LOW;
	Delay_nop(10);

	RFFE_SDATA_HIGH;
	Delay_nop(1);
	Delay_nop(1);
	Delay_nop(1);

	RFFE_SDATA_LOW;
	Delay_nop(1);
}

// void Bus_Park()
// {
// 	RFFE_SDATA_LOW;
// 	// Delay_nop(1);
// 	// RFFE_SCLK_HIGH;
// }

void Register_0_Write(unsigned char USID_Address, unsigned char Reg_data)
{
	int i;
	unsigned char P_Bit = 1;
	unsigned char Reg_frame_13bit[13];

	//前四位为USID地址
	for(i = 0; i < 4; i++)
	{
		if(USID_Address & 0x80)
		{
			Reg_frame_13bit[i] = 1;
		}
		else
		{
			Reg_frame_13bit[i] = 0;
		}
		USID_Address = USID_Address << 1;
	}

	//八位数据位,首位1为寄存器0写入标志位
	Reg_data = Reg_data | 0x80;  //加入1000b的0寄存器写入标志位
	for(i = 0; i < 8; i++)
	{
		if(Reg_data & 0x80)
		{
			Reg_frame_13bit[i + 4] = 1;
		}
		else
		{
			Reg_frame_13bit[i + 4] = 0;
		}
		Reg_data = Reg_data << 1;
	}

	//前12位进行奇校验
	P_Bit = 1;
	for(i = 0; i < 12; i++)
	{
		if(Reg_frame_13bit[i])
		{
			P_Bit ^= 0x01;
		}
	}
	Reg_frame_13bit[12] = P_Bit;

	//开始发送总线时序
	RFFE_SDATA_Output_Mode();
	//SSC_Head
	SSC_Head();
	RFFE_SCLK_HIGH;
	//data frame写入
	for(i = 0; i < 13; i++)
	{
		if(Reg_frame_13bit[i])
		{
			RFFE_SDATA_HIGH;
		}
		else
		{
			RFFE_SDATA_LOW;
		}

		Delay_nop(1);
		RFFE_SCLK_HIGH;
		Delay_nop(1);
		RFFE_SCLK_LOW;
		//Delay_nop(1);
		//RFFE_SCLK_HIGH;
	}

	//bus park
	Bus_Park();
	Delay_nop(1);
	RFFE_SCLK_HIGH;
	Delay_nop(1);
	RFFE_SCLK_LOW;
}

void Register_Write(unsigned char USID_Address, unsigned char Reg_Address, unsigned char Reg_data)
{
	int i;
	unsigned char P_Bit = 1;
	unsigned char Reg_frame_13bit[13];
	unsigned char Reg_data_frame_9Bit[9];

	//前四位为USID地址
	for(i = 0; i < 4; i++)
	{
		if(USID_Address & 0x80)
		{
			Reg_frame_13bit[i] = 1;
		}
		else
		{
			Reg_frame_13bit[i] = 0;
		}
		USID_Address = USID_Address << 1;
	}

	//八位数据位,首位1为寄存器0写入标志位
	Reg_Address &= ~((unsigned char)7 << 5);
	Reg_Address = Reg_Address | 0x40;  //加入010b的0寄存器写入标志位
	for(i = 0; i < 8; i++)
	{
		if(Reg_Address & 0x80)
		{
			Reg_frame_13bit[i + 4] = 1;
		}
		else
		{
			Reg_frame_13bit[i + 4] = 0;
		}
		Reg_Address = Reg_Address << 1;
	}

	//前12位进行奇校验
	P_Bit = 1;
	for(i = 0; i < 12; i++)
	{
		if(Reg_frame_13bit[i])
		{
			P_Bit ^= 0x01;
		}
	}
	Reg_frame_13bit[12] = P_Bit;
	
	//处理写入寄存器的数据
	for(i = 0; i < 8; i++)
	{
		if(Reg_data & 0x80)
		{
			Reg_data_frame_9Bit[i] = 1;
		}
		else
		{
			Reg_data_frame_9Bit[i] = 0;
		}
		Reg_data = Reg_data << 1;
	}

	//前8位进行奇校验
	P_Bit = 1;
	for(i = 0; i < 8; i++)
	{
		if(Reg_data_frame_9Bit[i])
		{
			P_Bit ^= 0x01;
		}
	}
	Reg_data_frame_9Bit[8] = P_Bit;

	//开始发送总线时序
	RFFE_SDATA_Output_Mode();
	//SSC_Head
	SSC_Head();

	//Reg frame写入
	for(i = 0; i < 13; i++)
	{
		if(Reg_frame_13bit[i])
		{
			RFFE_SDATA_HIGH;
		}
		else
		{
			RFFE_SDATA_LOW;
		}

		Delay_nop(1);
		RFFE_SCLK_HIGH;
		Delay_nop(1);
		RFFE_SCLK_LOW;
		//Delay_nop(1);
	}

	//data frame写入
	for(i = 0; i < 9; i++)
	{
		if(Reg_data_frame_9Bit[i])
		{
			RFFE_SDATA_HIGH;
		}
		else
		{
			RFFE_SDATA_LOW;
		}

		Delay_nop(1);
		RFFE_SCLK_HIGH;
		Delay_nop(1);
		RFFE_SCLK_LOW;
		//Delay_nop(1);
	}
	
	//bus park
	Bus_Park();
	Delay_nop(1);
	RFFE_SCLK_HIGH;
	Delay_nop(1);
	RFFE_SCLK_LOW;
}

unsigned char Register_Read(unsigned char USID_Address, unsigned char Reg_address, unsigned char *Reg_Value)
{
	int i = 0;
	unsigned char P_Bit = 1;
	unsigned char Reg_frame_13bit[13];
	unsigned char Receive_Bit9_frame[9];

	//实验发现需要先拉高SDATA和SCLK才能读正确
	RFFE_SDATA_Output_Mode();
	RFFE_SCLK_HIGH;
	RFFE_SDATA_HIGH;
	Delay_nop(10);
	
	RFFE_SCLK_LOW;
	Delay_nop(1);
	RFFE_SDATA_LOW;
	Delay_nop(10);
	
	//前四位为USID地址
	for(i = 0; i < 4; i++)
	{
		if(USID_Address & 0x80)
		{
			Reg_frame_13bit[i] = 1;
		}
		else
		{
			Reg_frame_13bit[i] = 0;
		}
		USID_Address = USID_Address << 1;
	}

	//八位寄存器地址转换
	Reg_address = Reg_address | 0x60;  //加入0110b读取指令标志位

	for(i = 4; i < 12; i++)
	{
		if(Reg_address & 0x80)
		{
			Reg_frame_13bit[i] = 1;
		}
		else
		{
			Reg_frame_13bit[i] = 0;
		}
		Reg_address = Reg_address << 1;
	}

	//前12位进行奇校验P
	P_Bit = 1;
	for(i = 0; i < 12; i++)
	{
		if(Reg_frame_13bit[i])
		{
			P_Bit ^= 0x01;
		}
	}

	Reg_frame_13bit[12] = P_Bit;

	//开始发送总线时序
	RFFE_SDATA_Output_Mode();
	//SSC_Head
	SSC_Head();

	//data frame写入
	for(i = 0; i < 13; i++)
	{
		if(Reg_frame_13bit[i])
		{
			RFFE_SDATA_HIGH;
		}
		else
		{
			RFFE_SDATA_LOW;
		}

		Delay_nop(1);
		RFFE_SCLK_HIGH;
		Delay_nop(1);
		RFFE_SCLK_LOW;
		//Delay_nop(1);
	}

	//bus park
	Bus_Park();
	Delay_nop(1);
	RFFE_SCLK_HIGH;
	Delay_nop(1);
	RFFE_SCLK_LOW;
	RFFE_SDATA_Input_Mode();

	//read data数据读出,同时对数据进行奇校验
	P_Bit = 1;

	for(i = 0; i < 9; i++)
	{
		Delay_nop(2);
		RFFE_SCLK_HIGH;
		Delay_nop(2);
		RFFE_SCLK_LOW;

		if(RFFE_SDATA_READ)
		{
			Receive_Bit9_frame[i] = 1;
			P_Bit ^= 0x01;
		}
		else
		{
			Receive_Bit9_frame[i] = 0;
		}
	}

	*Reg_Value = 0;
	for(i = 0; i < 8; i++)
	{
		*Reg_Value <<= 1;
		*Reg_Value |=  Receive_Bit9_frame[i] ? 1 : 0;
	}

	//bus park
	RFFE_SDATA_Output_Mode();
	Bus_Park();
	Delay_nop(2);
	RFFE_SCLK_HIGH;
	Delay_nop(2);
	RFFE_SCLK_LOW;
	
	if(P_Bit)
	{
		//奇校验失败
		return CHECK_FAIL;
	}
	else
	{
		//奇校验成功
		return CHECK_OK;
	}
}

//器件使能
void Active_Product(unsigned char USID_Address)
{
	Register_Write(USID_Address, 0x1C, 0x38);
	Register_Write(USID_Address, 0x02, 0x02);
}

//必须连续一起修改Product_ID、MANUFACTURER_ID、USID才能使新的USID生效,单独修改USID寄存器不生效
void Register_Write_USID(unsigned char Old_USID_Address, unsigned char Product_ID, unsigned short MANUFACTURER_ID, unsigned char MAN_USID)
{
	Register_Write(Old_USID_Address, 0x1D, Product_ID);
	Register_Write(Old_USID_Address, 0x1E, MANUFACTURER_ID);
	Register_Write(Old_USID_Address, 0x1F, MAN_USID);
}

//写一个字节到扩展寄存器,扩展寄存器指地址大于0x1F的寄存器
void Extended_Register_Write(unsigned char USID_Address, unsigned char Reg_Address, unsigned char Reg_data)
{
	int i;
	unsigned char P_Bit = 1;
	unsigned char Byte_len = 0;  //0代表写一个字节
	unsigned char Reg_frame_22bit[22];
	unsigned char Reg_data_frame_9Bit[9];

	//前四位为USID地址
	for(i = 0; i < 4; i++)
	{
		if(USID_Address & 0x80)
		{
			Reg_frame_22bit[i] = 1;
		}
		else
		{
			Reg_frame_22bit[i] = 0;
		}
		USID_Address = USID_Address << 1;
	}

	//默认写一个字节,可以改成写多个字节,多个字节会顺推写到后面的寄存器地址,最多连续写16个字节
	Byte_len &= 0x0F;
	Byte_len = Byte_len | 0x00;  
	for(i = 0; i < 8; i++)
	{
		if(Byte_len & 0x80)
		{
			Reg_frame_22bit[i + 4] = 1;
		}
		else
		{
			Reg_frame_22bit[i + 4] = 0;
		}
		Byte_len = Byte_len << 1;
	}

	//前12位进行奇校验
	P_Bit = 1;
	for(i = 0; i < 12; i++)
	{
		if(Reg_frame_22bit[i])
		{
			P_Bit ^= 0x01;
		}
	}
	Reg_frame_22bit[12] = P_Bit;

	//八位寄存器地址
	for(i = 0; i < 8; i++)
	{
		if(Reg_Address & 0x80)
		{
			Reg_frame_22bit[i + 13] = 1;
		}
		else
		{
			Reg_frame_22bit[i + 13] = 0;
		}
		Reg_Address = Reg_Address << 1;
	}

	//第13 ~ 20位进行奇校验
	P_Bit = 1;
	for(i = 0; i < 8; i++)
	{
		if(Reg_frame_22bit[i + 13])
		{
			P_Bit ^= 0x01;
		}
	}
	Reg_frame_22bit[21] = P_Bit;
	
	//处理写入寄存器的数据
	for(i = 0; i < 8; i++)
	{
		if(Reg_data & 0x80)
		{
			Reg_data_frame_9Bit[i] = 1;
		}
		else
		{
			Reg_data_frame_9Bit[i] = 0;
		}
		Reg_data = Reg_data << 1;
	}

	//前8位进行奇校验
	P_Bit = 1;
	for(i = 0; i < 8; i++)
	{
		if(Reg_data_frame_9Bit[i])
		{
			P_Bit ^= 0x01;
		}
	}
	Reg_data_frame_9Bit[8] = P_Bit;

	//开始发送总线时序
	RFFE_SDATA_Output_Mode();
	//SSC_Head
	SSC_Head();

	//Reg frame写入
	for(i = 0; i < 22; i++)
	{
		if(Reg_frame_22bit[i])
		{
			RFFE_SDATA_HIGH;
		}
		else
		{
			RFFE_SDATA_LOW;
		}

		Delay_nop(1);
		RFFE_SCLK_HIGH;
		Delay_nop(1);
		RFFE_SCLK_LOW;
		//Delay_nop(1);
	}

	//data frame写入
	for(i = 0; i < 9; i++)
	{
		if(Reg_data_frame_9Bit[i])
		{
			RFFE_SDATA_HIGH;
		}
		else
		{
			RFFE_SDATA_LOW;
		}

		Delay_nop(1);
		RFFE_SCLK_HIGH;
		Delay_nop(1);
		RFFE_SCLK_LOW;
		//Delay_nop(1);
	}
	
	//bus park
	Bus_Park();
	Delay_nop(1);
	RFFE_SCLK_HIGH;
	Delay_nop(1);
	RFFE_SCLK_LOW;
}

//扩展寄存器读一个字节
unsigned char Extended_Register_Read(unsigned char USID_Address, unsigned char Reg_address, unsigned char *Reg_Value)
{
	int i = 0;
	unsigned char P_Bit = 1;
	unsigned char Byte_Len = 0;  //读一个字节
	unsigned char Reg_frame_22bit[22];
	unsigned char Receive_Bit9_frame[9];

	//实验发现需要先拉高SDATA和SCLK才能读正确
	RFFE_SDATA_Output_Mode();
	RFFE_SCLK_HIGH;
	RFFE_SDATA_HIGH;
	Delay_nop(10);
	
	RFFE_SCLK_LOW;
	Delay_nop(1);
	RFFE_SDATA_LOW;
	Delay_nop(10);
	
	//前四位为USID地址
	for(i = 0; i < 4; i++)
	{
		if(USID_Address & 0x80)
		{
			Reg_frame_22bit[i] = 1;
		}
		else
		{
			Reg_frame_22bit[i] = 0;
		}
		USID_Address = USID_Address << 1;
	}

	//字节数目
	Byte_Len &= 0x0F;
	Byte_Len = Byte_Len | 0x20;  

	for(i = 4; i < 12; i++)
	{
		if(Byte_Len & 0x80)
		{
			Reg_frame_22bit[i] = 1;
		}
		else
		{
			Reg_frame_22bit[i] = 0;
		}
		Byte_Len = Byte_Len << 1;
	}

	//前12位进行奇校验P
	P_Bit = 1;
	for(i = 0; i < 12; i++)
	{
		if(Reg_frame_22bit[i])
		{
			P_Bit ^= 0x01;
		}
	}
	Reg_frame_22bit[12] = P_Bit;

	//八位寄存器地址转换
	for(i = 13; i < 21; i++)
	{
		if(Reg_address & 0x80)
		{
			Reg_frame_22bit[i] = 1;
		}
		else
		{
			Reg_frame_22bit[i] = 0;
		}
		Reg_address = Reg_address << 1;
	}

	//进行奇校验P
	P_Bit = 1;
	for(i = 13; i < 21; i++)
	{
		if(Reg_frame_22bit[i])
		{
			P_Bit ^= 0x01;
		}
	}

	Reg_frame_22bit[21] = P_Bit;

	//开始发送总线时序
	RFFE_SDATA_Output_Mode();
	//SSC_Head
	SSC_Head();

	//data frame写入
	for(i = 0; i < 22; i++)
	{
		if(Reg_frame_22bit[i])
		{
			RFFE_SDATA_HIGH;
		}
		else
		{
			RFFE_SDATA_LOW;
		}

		Delay_nop(1);
		RFFE_SCLK_HIGH;
		Delay_nop(1);
		RFFE_SCLK_LOW;
		//Delay_nop(1);
	}

	//bus park
	Bus_Park();
	Delay_nop(1);
	RFFE_SCLK_HIGH;
	Delay_nop(1);
	RFFE_SCLK_LOW;
	RFFE_SDATA_Input_Mode();

	//read data数据读出,同时对数据进行奇校验
	P_Bit = 1;

	for(i = 0; i < 9; i++)
	{
		Delay_nop(2);
		RFFE_SCLK_HIGH;
		Delay_nop(2);
		RFFE_SCLK_LOW;

		if(RFFE_SDATA_READ)
		{
			Receive_Bit9_frame[i] = 1;
			P_Bit ^= 0x01;
		}
		else
		{
			Receive_Bit9_frame[i] = 0;
		}
	}

	*Reg_Value = 0;
	for(i = 0; i < 8; i++)
	{
		*Reg_Value <<= 1;
		*Reg_Value |=  Receive_Bit9_frame[i] ? 1 : 0;
	}

	//bus park
	RFFE_SDATA_Output_Mode();
	Bus_Park();
	Delay_nop(2);
	RFFE_SCLK_HIGH;
	Delay_nop(2);
	RFFE_SCLK_LOW;
	
	if(P_Bit)
	{
		//奇校验失败
		return CHECK_FAIL;
	}
	else
	{
		//奇校验成功
		return CHECK_OK;
	}
}

 

七、参考资料

《MIPI RFFE协议文档V1.10》链接:https://pan.baidu.com/s/1mnxA9TehKzA8tdSM7bdcOg  提取码:xdk3

 

你可能感兴趣的:(STM32,MIPI,MIPI,RFFE)