概况:采用飞思卡尔IMAX6Q作为主芯片,主芯片总线外接MAC芯片和PHY芯片实现网络功能以及通过专用的物理层芯片实现1588时钟同步功能。本节只介绍几本原理,具体的驱动开发流程及1588时钟同步协议开发移植流程暂不分享。
参考资料:DM9000中文手册、IMAX6Q datasheet
分三部分讲解:一、arm总线简单讲解 二、DM9000接口设计 三、DM9000和DP83640的控制流程
一、arm总线
cpu框架如下:
arm常规的总线结构如下:
二、DM9000接口设计
常见的arm外设接口设计:
本例子采用方案三,具体接口设计如下图:
三、DM9000和DP83640的控制流程
DM9000控制DP83640寄存器读写原理(读写的实现可发到流驱动去做,应用程序只发送DP83640寄存器的索引和要写的数据给驱动)
DP83640通过DM9000去控制,DP83640作为DM9000的外部物理层。对DM9000的读写可通过一个流驱动来实现。DM9000中只有INDEX端口与DATA端口2个寄存器可以直接被CPU访问,其它的内部控制和状态寄存器都是通过这2个端口寄存器间接访问;对这2个寄存器的访问是通过控制网络控制器DM9000的CMD引脚来实现的:当CMD=0时,主机访问的是INDEX端口寄存器;当CMD=1时,访问的是DATA端口寄存器。本设计将CMD引脚与处理器的地址线A2相连,则DM9000的2个端口地址分别为:INDEX端口地址=IOaddress+0x00;DATA端口地址=IOaddress+0x04。由于INDEX端口寄存器保存的是处理器要访问的DATA端口寄存器的内部寄存器的地址,因而对DM9000的控制或状态寄存器的访问顺序是:首先写要访问寄存器的地址到INDEX端口,然后通过DATA端口来读/写数据。
DM9000访问PHY寄存器的方法是:
(1)寄存器地址写到EPAR/PHY_AR(0CH)寄存器中,注意将寄存器地址的第6位置1(地址与0x40或运算即可),以表明写的是PHY地址,而不是EEPROM地址。
(2)将数据高字节写到PHY_DRH(0EH)寄存器中。
(3)将数据低字节写到PHY_DRL(0DH)寄存器中。
(4)发送PHY命令(0x0a)到EPCR/PHY_CR(0BH)寄存器中。
(5)延时5us,发送命令0x08到EPCR/PHY_CR(0BH)寄存器中,清除PHY写操作。
DP83640功能控制说明(具体的寄存器说明见DP83640手册)
1、 接口通信说明
DM9000与DP83640之间的接口通信主要分两种,MDIO和MII。
任何时候都能通过MDIO接口来配置DP83640的寄存器,即通过DM9000设置物理寄存器的方式。
MII接口主要用于网络字符串的收发,即对应应用层的socket编程,但是配置了DP83640PHY Control Frames Configuration Register(PCFCR),使能PCF后,MII接口也可以用来配置DP83640的寄存器,方式是运用socket发送PCF格式的网络串。
PCF网络串格式如下:
时间设置:
通过PTP Time Data Regiser设置或读取时间,流程如下:
to set the time:
Write Clock_time_ns[15:0] to PTP_TDR
Write Clock_time_ns[31:16] to PTP_TDR
Write Clock_time_sec[15:0] to PTP_TDR
Write Clock_time_sec[31:16] to PTP_TDR
Write to PTP_CTL with the PTP_Load_Clk bit set
To read the time:
Write to PTP_CTL with the PTP_Rd_Clk bit set
Read Clock_time_ns[15:0] from PTP_TDR
Read Clock_time_ns[31:16] from PTP_TDR
Read Clock_time_sec[15:0] from PTP_TDR
Read Clock_time_sec[31:16] from PTP_TDR
步进调整,步骤如下:
Write Clock_time_ns[15:0] to PTP_TDR
Write Clock_time_ns[31:16] to PTP_TDR
Write Clock_time_sec[15:0] to PTP_TDR
Write Clock_time_sec[31:16] to PTP_TDR
Write to PTP_CTL with the PTP_Step_Clk bit set
速率调整,步骤如下:
Write Temp_Rate[25:16] to PTP Rate High Register(PTP_RATEH) with PTP_TMP_RATE bit set to 0.
Write Temp_Rate[15:0] to PTP Rate Low Register (PTP_RATEL)
临时速率调整,步骤如下:(12为持续时间设置,34为临时速率设置,标志位不设置时则不是临时速率)
1. Write Temp_Rate_duration[25:16] to PTP Temporary RateDuration High Register (PTP_TRDH)
2. Write Temp_Rate_duration[15:0] to PTP Temporary RateDuration Low Register (PTP_TRDL)
3. Write Temp_Rate[25:16] to PTP Rate High Register(PTP_RATEH) with PTP_TMP_RATE bit set to 1.
4. Write Temp_Rate[15:0] to PTP Rate Low Register(PTP_RATEL)
3、 时间戳
传输时间戳参数配置
通过PTP_TXCFG0和PTP_TXCFG1两个寄存器来配置。
接收时间戳参数配置
通过PTP_RXCFG0, PTP_RXCFG1, PTP_RXCFG2, 和PTP_RXCFG3寄存器来配置。
获取传输时间戳
连续读四次PHY_PG4_PTP_TXTS寄存器,具体流程见PTPGetTransmitTimestamp函数
获取接收时间戳
连续读六次PHY_PG4_PTP_RXTS寄存器,具体流程见PTPGetReceiveTimestamp函数。
Hash Value
配置PTP_RXHASH寄存器,用于消息的过滤3002
4、 触发
通过配置相关寄存器,可实现从GPIO输出一个触发信号。通过一个秒脉冲触发信号可实现FPGA时钟的调整。
初始化触发,使能触发设置时间等:
1. Set the Trig_Load bit in the PTP Control Register(PTP_CTL) along with the Trig_Sel setting for
the trigger. This will disable the trigger if it waspreviously enabled.
2. Write to PTP_TDR: Start_time_ns[15:0]
3. Write to PTP_TDR: Initial state, Wait for Rollover,Start_time_ns[29:16]
4. Write to PTP_TDR: Start_time_sec[15:0]
5. Write to PTP_TDR: Start_time_sec[31:16]
6. Write to PTP_TDR: Pulsewidth[15:0]
7. Write to PTP_TDR: Pulsewidth[31:16]
8. Write to PTP_TDR: Pulsewidth2[15:0] (for Triggers 0 and1 only)
9. Write to PTP_TDR: Pulsewidth2[31:16] (for Triggers 0 and1 only)
10. Set the Trig_En bit in the PTP_CTL register along withthe Trig_Sel setting for the trigger
读触发控制信息:
1. Set the Trig_Read bit in the PTP Control Register(PTP_CTL) along with the Trig_Sel setting for the trigger.
2. Read fields from PTP_TDR in same order as written above.
设置触发:
设置PHY_PG5_PTP_TRIG寄存器。
取消触发:
设置PHY_PG4_PTP_CTL寄存器。
5、 事件设置
设置事件,当事件到来时,可存储一个事件时间戳,最多可存储8个事件时间戳。
使能事件:
设置PHY_PG5_PTP_EVNT寄存器。
查询事件:
读取PHY_PG4_PTP_STS寄存器可以查询是否有事件产生,也可以检测接收发送或触发。
获取事件时间戳:
1. Read PTP_ESTS to determine if an event timestamp is available.
2. Read from PTP_EDATA: Extended Event Status[15:0] (available only ifPTP_ESTS:MULT_EVNT
is set to 1)
3. Read from PTP_EDATA: Timestamp_ns[15:0]
4. Read from PTP_EDATA: Timestamp_ns[29:16] (upper 2 bits are always 0)
5. Read from PTP_EDATA: Timestamp_sec[15:0]
6. Read from PTP_EDATA: Timestamp_sec[31:16]
7. Repeat Steps 1-6 until PTP_ESTS = 0
6、 中断
触发、事件、时间戳都可以产生中断,可通过PTP Status Register使能相关的中断。中断的输出有两种方式,一是共享中断通过PWRDN_INTN引脚输出中断信号,二是GPIO引脚输出中断信号。
共享中断:
配置MII Interrupt Control Register (MICR)寄存器可设置PWRDN_INTN中断。
中断处理流程,
1. Read MISR to determine if PTP interrupt has occurred
2. Read PTP_STS to determine which PTP function hasgenerated an interrupt
3. Process Trigger, Event, or Timestamp as indicated byPTP_STS
4. Repeat steps 2 and 3 until PTP_STS[11:8] = 0
GPIO中断:
配置PTP_INTCTL寄存器可配置相关的GPIO中断。
中断处理流程,
1. Read PTP_STS to determine which PTP function hasgenerated an interrupt
2. Process trigger, event, or timestamp as indicated by PTP_STS
3. Repeat steps 1 and 2 until PTP_STS[11:8] = 0