【嵌入式硬件】网络交换芯片BCM5396

目录

1.硬件系统结构

​编辑2.BCM5396概述

2.1 BCM5396基本功能

2.2 基本特性

3.系统接口

3.1 串行接口

3.1.1 SGMII模式

3.1.2 SerDes模式

3.1.3 SerDes/SGMII自协商

3.2 编程接口(SPI)

4.硬件信号描述

4.1 串行接口信号(SGMII)

​编辑4.2 时钟复位

​编辑4.3 SPI接口信号

4.4 配置引脚

5.原理图参考设计

5.1 port接口

5.2 电气和配置引脚

6.接口程序设计(SPI)

6.1 SPI初始化

6.2 SPI读

6.3 SPI写


1.硬件系统结构

图中PHY芯片已经在前文做出详细的讲解。


2.BCM5396概述


2.1 BCM5396基本功能

         实现支持网络传输交换拓扑结构设计,使得各个处理器或设备网络互联互通。

2.2 基本特性

1、 BCM5396是一个16port的以太网交换机,集成了16个1.25G的SerDes/SGMII port接口,用于连接外部的PHY物理接口或光纤接口。
2、 嵌入了一个256KB大小的分组缓冲。
3、 支持最大9728字节的巨帧。
4、 支持低成本芯片EEPROM的配置。
5、 第17th接口支持GMII/RGMII/MII/RvMII接口连接CPU。
6、 GMAC控制器在10/100Mbps工作模式下支持全双工和半双工模式,在1000Mbps模式下只支持全双工模式。
7、 媒体接入控制。
8、 集成高性能存储(集成了256MB的SRAM)和转换控制。

3.系统接口

3.1 串行接口

        每个lvds兼容的串口可以配置为SGMII或SerDes模式。

3.1.1 SGMII模式

        SGMII接口通过TXDN和TXDP引脚以1.25 Gbaud差分传输串行数据,通过RXDN和RXDP引脚差分接收串行数据,传输数据定时从传入数据信号中恢复。附加的链接伙伴也做同样的事。SGMII接口引脚与SerDes接口引脚共享。
        数据信号工作在1.25 Gbaud。这些信号中的每一个都实现为微分对,因为操作的速度,提供信号的完整性,同时最大限度地减少系统噪声。SGMII信号使用LVDS电压等级。数据和时钟信号均采用直流平衡;因此,满足交流参数但不满足直流参数的实现可以进行交流耦合。
        SGMII的1.25 Gbaud传输速率高于BCM5396收发器10mbps或100mbps要求。当这些情况发生时,BCM5396通过复制每个帧字节10次以100 Mbps和100次以10 Mbps延长帧。这种帧延伸发生在IEEE标准802.3z PCS层之上,使得起始帧分隔符每帧只出现一次。

3.1.2 SerDes模式

        SerDes接口工作在1000BASE-X下,接口共享SGMII接口引脚的差分数据,SerDes接口可以用于以下情况:
① SerDes接口可以连接到创建交换光纤端口的SerDes光纤模块。
② SerDes接口可以连接到创建转换铜线接口的SerDes转铜线PHY。
③ SerDes接口可以连接到SerDes MAC或SerDes switch -to- switch应用程序的交换机。

3.1.3 SerDes/SGMII自协商

        在建立链路的时候,可以通过自协商的方式进行接口选择,但是,当一篇BCM5396同时连接了这两种接口的时候,就需要通过寄存器配置指定腰使用的接口。

3.2 编程接口(SPI)

        BCM5396可以通过SPI接口和EEPROM接口进行寄存器空间配置,这两种接口共用同一pin,何种接口使用这些pin是通过寄存器CPU_EEPROM_SEL来选择,EEPROM接口可以外接EEPROM来上电初始化寄存器的值。
        BCM5396寄存器采用分页的机制,每页逻辑地址空间是256字节。
        SPI接口为通用的摩托罗拉SPI接口,但是,对于BCM5396而言,只能作为从机设备,仅被动等待主机的读或写。
        SPI分为快速和标准两种模式,通过命令字来区分,在实现中这两种模式不可以同时使用,CPU必须一直使用同一种模式传输。两种模式的命令字见下图:

        图9表示的是普通模式下的SPI命令,mode(bit4)=0,表示标准模式,并且决定了bit[7:5]=011b。图10表示快速SPI模式,通过mode(bit4)=1决定的,同时读取字节内部寄存器的偏移量赋值bit{7:5}。
        这两种机制的bit[3:1]均为CHIP_ID,因为BCM5396设备作为一个单片系统,所以CHIP_ID=000b,注意SS信号在设备被正在识别访问的时候必须是有效的,低电平有效。
两种机制下,bit[0]位为读写控制位,0表示读,1表示写。确定数据传输的方向。
        接下来的字节命令是一个8bit字节,最初,表示设置页面地址,然后表示另一种命令字节,表示页面的基地址,这个地址被用作存放在写操作中接收到的数据的下一个字节的位置,那么在读操作中,表示检索下一个被读数据的地址。在一次传输中,允许从一个寄存器存储/读取连续的数据块。
        不连续的块也可以通过多次传输完成数据的存取/读取操作,允许指定新的命令字和基地址,在读取或者存储的时候SS信号必须保持低,最后通过主机控制SS信号终止传输。
关于串行接口读写操作时序如下所示:

这个串行SPI接口支持高达2MHz的工作频率,支持四个设备级联/寻址。

重点讲解标准SPI模式:
        标准SPI模式允许单字节读和多字节字符串写操作,使用CPU轮询来监视进程,读操作使用page175 SPI状态寄存器和SPI数据I/O实现。
对于读操作,其形式如下所示:
        <CMD, CHIP_ID, W>
对于写操作,其形式如下所示:
        <CMD, CHIP_ID, W>…
关于具体的读操作,详细流程见以下的流程图:


        对于读一个寄存器,首先写入Page175的页面寄存器<CMD, CHIP ID, W><DATA = NEW PAGE>,当移动到新的页面才需要写入新的页面地址,一旦进入这页面,执行一个读操作来读取寄存器的值<CMD, CHIP ID, R>。一旦通过Page175 SPI状态寄存器得知数据可用(RACK=1),那么这个数据就会被读取,读取数据是通过Page175上Data I/O寄存器读取,数据位于每一页的F0h-F7h。
再看看写流程:


        写一个寄存器,如果有必要的话,页寄存器要被写,(<CMD, CHIP ID, W><DATA = NEW PAGE>),然后数据被写到选择的寄存器,(<CMD, CHIP ID, W>…),其中DATA0是寄存器里面最低的有效字节,准确的字节数是由寄存器的宽度决定的,没有为写操作提供字节偏移量,所有字节必须存在以激活BCM5396内部的写进程。

下面是一些应用于标准SPI模式下简单的规则:

① 写页面寄存器在任何时候都会充值SPI的状态。
② 读操作可以使用SPI Data I/O寄存器访问任何偏移量的任何数量的字节。
③ 写操作必须向被写入的寄存器写一个准确的字节数。
④ SPI状态寄存器中的RXRDY/TXRDY标记必须在每个8字节的字符串被读/写之后检查,以确保下一个字符串已经准备好并可以接受(因为最大的内部寄存器是8字节,这个限制只适用于通过SPI读写帧)。

还有EEPROM、MDC/MDIO、LED接口暂时不使用,不做介绍。

4.硬件信号描述

4.1 串行接口信号(SGMII)


4.2 时钟复位


4.3 SPI接口信号

4.4 配置引脚

        关于这个引脚配置的内容,主要看你工程实际需要使能哪些接口,根据接口使用配置哪些功能,以及PHY的轮询功能,还有就是时钟设置。具体的配置在工程设计时介绍。

5.原理图参考设计

5.1 port接口

        16个port口使用SGMII接口,分别连接到四个DSP,四个背面板,另外两个连接到PHY芯片,本次使用的ZYNQ PS通过RGMII接口连接到PHY芯片的port3,PHY芯片的port3通过RGMII接口转SGMII接口出来,连接到PHY芯片的port2,然后转接铜线至RJ45。相关的系统结构连接方式可参考第一章给出的框图进行理解。

5.2 电气和配置引脚

        引出了EEPROM和SPI两种编程接口,同时引出了BCM_EEPROM_SEL引脚,用于选择编程接口是EEPROM或SPI;使能了自动全双工流控;使能了QoS功能;没有设置TX和RX时钟延时,因为在PHY芯片设置的时候已经进行了延时,使得时钟和数据同步。配置了工作时钟156.3MHz。

6.接口程序设计(SPI)

6.1 SPI初始化

void spi_init(void)
{
	instSPI.Config = XSpiPs_ConfigTable[XPAR_XSPIPS_0_DEVICE_ID];
	XSpiPs_CfgInitialize(&instSPI, &instSPI.Config, instSPI.Config.BaseAddress);

	XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXWR_OFFSET, 1); // TX FIFO Threadhold
	XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_RXWR_OFFSET, 1); // RX FIFO Threadhold

	XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_SR_OFFSET, 0xFFFFFFFF); // clear interrupt

	XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_CR_OFFSET,
			0x0|(1<<15)|(0<<14)|(0<<10)|(6<<3)|(1<<2)|(1<<1)|0x1);

	XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_ER_OFFSET, 1); // Enable SPI
}

        首先,查表并初始化SPI接口基本信息,包括基地址和ID号,然后设置了TX FIFO和RX FIFO最低临界值,必要时产生中断,然后清除中断,再写配置寄存器,设置主机模式,设置时钟来源和分频,等等。最后使能SPI接口。

6.2 SPI读

        关于SPI读的基本流程在前面已经讲的比较详细,现在借助代码的形式梳理。

第一步:首先写入(写命令+页面寄存器地址+新的页面地址)。调用官方SPI写函数XSpiPs_WriteReg()实现。

   //------ Write PAGE -------------------
	XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, 0x61|((chipID&0x7)<<1)); // TXFIFO WR_CMD
	XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, 0xFF); // TXFIFO  SELECT PAGE
	XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, page); // TXFIFO

        WR_CMD命令为什么是或上一个0x61,这是根据写命令格式决定的,可以参看数据手册写命令的定义。chipID定义为000b,因为只有一个设备。新的页地址为用户传入的参数,需要读取哪个页的数据在这里指定。

第二步:写入一个读命令,读取指定页指定寄存器的值。

  //------ First RD (Discard) -------------------
	XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, 0x60|((chipID&0x7)<<1)); // TXFIFO RD_CMD  
	XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, regAddr);                // TXFIFO  SELECT regaddr
    XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, 0x00);                   // TXFIFO  PAD

        RD_CMD命令中包含0x60,原因同样是命令格式里面参数属性决定的,regAddr 参数是函数传入的,用户通过这个参数指定需要读取哪个寄存器的值。最后写了一个0x00,这是因为这一次会读取到一个无效的数据到RX FIFO,并舍弃,所以直接写入0x00,防止读取到一些奇怪的值,影响后面读取寄存器的实际值。

第三步:开始读取DATA I/O上的数据以获取指定页面指定寄存器的实际值。

  //------ RD SPI_DIO[0:7] ALLPAGE,ADDR_0xF0-0xF7 -------------------
	reg_value=0;
    for(int i=0; i<byteLen; i++) {
		XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, 0x60|((chipID&0x7)<<1)); // TXFIFO RD_CMD
		XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, 0xF0+i);              // SPI_DIO[7:0] ADDRESS
	    XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, 0x00);                   // TXFIFO  PAD

		XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_CR_OFFSET,         // START TRANSPORT
			XSpiPs_ReadReg(instSPI.Config.BaseAddress, XSPIPS_CR_OFFSET)|0x00010000 );

		do {
			reg_value_tmp = XSpiPs_ReadReg( instSPI.Config.BaseAddress, XSPIPS_SR_OFFSET);
			if ( (reg_value_tmp & XSPIPS_IXR_MODF_MASK) != 0U) { //Clear the mode fail bit
				XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_SR_OFFSET, XSPIPS_IXR_MODF_MASK);
				while(1);
			}
		} while(!(reg_value_tmp & XSPIPS_IXR_TXOW_MASK));   // WAIT TRANSPORT END: 1 when TXFIFO_NUM < TXFIFO_THRESHOLD(1)

		while ( (XSpiPs_ReadReg(instSPI.Config.BaseAddress,XSPIPS_SR_OFFSET) & XSPIPS_IXR_RXNEMPTY_MASK) != 0U ) { //if RXFIFO not EMPTY
			reg_value_tmp = XSpiPs_ReadReg(instSPI.Config.BaseAddress, XSPIPS_RXD_OFFSET);
		}

		reg_value = reg_value | (((u64)reg_value_tmp & 0xff)<<(8*i));
    }
	return reg_value;
}

        因为所有的页数据ADDR均为0xF0-0xF7,所以每页一次最多可以读取8个字节的数据,定义接收数据的变量为u64,SPI控制器决定了TX和RX FIFO均为128字节的大小,不需要进行设置。最后通过移位的方式将读取的数据存放在变量reg_value中。
可以通过读取model ID来验证读函数的正确性。

        这里有一个错误,手册里面写的是8’d96,实际是0x96。如果读出来的值为0x96,表示读函数正确。

6.3 SPI写

第一步:通过写入(写命令+页面寄存器+新的页面地址),将待访问的页面地址写入。

XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, 0x61|((chipID&0x7)<<1)); // TXFIFO WR_CMD
XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, 0xFF); // TXFIFO  SELECT PAGE
XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, page); // TXFIFO


第二步:直接依次写入数据即可。

XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, 0x61|((chipID&0x7)<<1)); // TXFIFO WR_CMD
XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, regAddr);                // TXFIFO  SELECT regaddr
for(int i=0; i<byteLen; i++) {
	XSpiPs_WriteReg(instSPI.Config.BaseAddress, XSPIPS_TXD_OFFSET, (wrRegValue>>(i*8))&0xff);             // TXFIFO
}

最后发送数据,完成寄存器的写操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值