2021/9/7 ad9361 SPI 通信与数据接口

之前做过这部分工作,没有整理,现在回顾一下。

当FPGA 版本出来之后,怎么让AD9361 动起来 ,就是头等大事。当时十分在意,SPI是否通了?

  1. ENSM

AD9361收发器包括一个使能状态机(ENSM),允许对器件的当前状态进行实时控制。在正常运行过程中,器件可以置于多种不同状态,包括
       • 待机—节能,频率合成器被禁用
       • 休眠—待机,所有时钟/BB PLL被禁用
       • TX—TX信号链被使能
       • RX—RX信号链被使能
       • FDD—TX和RX信号链被使能
       • 报警—频率合成器被使能

      上图中灰色状态不需要用户控制,经过设定的时间后进入下一个状态。TO_ALERT位在ENSM配置寄存器中,如果要切换到WAIT状态,需要在RX或TX状态下清除TO_ALERT位,这样从 Rx, Tx或FDD状态移出时,ENSM将转移到WAIT状态,如果TO_ALERT被置1,ENSM将转换到ALERT 状态。
ENSM有两种可能的控制方法:SPI控制和引脚控制。

1)通过SPI写寄存器将当前状态推进到下一个状态,可以异步控制ENSM
2)使用ENABLETXNRX引脚实时控制当前状态

2.SPI控制

        在SPI控制模式下,通过写SPI寄存器,从当前状态进入下一状态,从而实现对ENSM的异步控制。SPI控制被认为与DATA_CLK异步,因为SPI_CLK可能派生自一个不同的参考时钟,而且仍然能正常工作。当不需要对频率合成器进行实时控制时,推荐采用SPI控制ENSM法。只要BBIC能够精确执行SPI写操作,SPI控制就可以用于实时控制。

     SPI接口
AD9361通过一个串行外设接口(SPI)与BBP通信。该接口可以配置为4线接口,带有专门的接收和发射端口,也可以配置为3线接口,带一个双向数据通信端口。该总线允许BBP通过一种简单地址数据串行总线协议,设置所有器件控制参数。

     数据格式

 分为3线模式和4线模式 控制字段由16bit组成,[15]为读写标志,高位读;[14:12]为读写的Byte数1~8Byte;[11:10]未使用;[9:0]为读写的起始字节地址;

前6位用于设置总线方向和需要传输的字节数。接下来的10位数据的写入地址。

/*
*	SPI Comm Helpers
*/
#define AD_READ		(0 << 15)
#define AD_WRITE		(1 << 15)
#define AD_CNT(x)	((((x) - 1) & 0x7) << 12)
#define AD_ADDR(x)	((x) & 0x3FF)

      写命令

最后8位是将被传输至指定寄存器地址(MSB至LSB)的数据。AD9361还支持LSB优先格式,允许命令以LSB至MSB格式写入。在该模式下,对于多字节写命令,寄存器地址将递增。



/**
 * SPI register write.
 * @param spi
 * @param reg The register address.
 * @param val The value of the register.
 * @return 0 in case of success, negative error code otherwise.
 */
int32_t ad9361_spi_write(struct spi_device *spi, uint32_t reg, uint32_t val)
{
	uint8_t buf[3];
	int32_t ret;
	uint16_t cmd;
	//uart_printf("ad9361_spi_write:reg[%d] = 0x%x\r\n",reg,val);
	cmd = AD_WRITE | AD_CNT(1) | AD_ADDR(reg);
	buf[0] = cmd >> 8;
	buf[1] = cmd & 0xFF;
	buf[2] = val;

	ret = spi_write_then_read(spi, buf, 3, NULL, 0);
	if (ret < 0) {
		dev_err(&spi->dev, "Write Error %"PRId32, ret);
		return ret;
	}
	return 0;
}

     读命令

遵循相似的格式,区别在于,前16位在SPI_DI引脚上传输,最后8位从AD9361中读取,如果是4线模式,则在SPI_DO引脚上完成,如果是3线模式,则在SPI_DI引脚上完成。

/**
 * SPI multiple bytes register read.
 * @param spi
 * @param reg The register address.
 * @param rbuf The data buffer.
 * @param num The number of bytes to read.
 * @return 0 in case of success, negative error code otherwise.
 */
int32_t ad9361_spi_readm(struct spi_device *spi, uint32_t reg,
	uint8_t *rbuf, uint32_t num)
{
	uint8_t buf[2];
	int32_t ret;
	uint16_t cmd;

	if (num > MAX_MBYTE_SPI)
		return -EINVAL;

	cmd = AD_READ | AD_CNT(num) | AD_ADDR(reg);
	buf[0] = cmd >> 8;
	buf[1] = cmd & 0xFF;

	ret = spi_write_then_read(spi, &buf[0], 2, rbuf, num);
	if (ret < 0) {
		dev_err(&spi->dev, "Read Error %"PRId32, ret);
		return ret;
	}
	return 0;
}

 SPI时序

3.  SPI  模式

官方选的 SPI 模式2,  也就是 下降沿 为数据的开始,第一个跳变沿采样

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值