Skip to main content
欢迎来到PAWPAW技术文档网站了解更多信息

通过XN文件定义芯片

XMOS平台通过软件来定义芯片的硬件特性,您可以通过修改XN文件来定义其功能。每个XN文件都为XMOS编译工具链提供了目标硬件的详细信息,包括但不限于XMOS设备、端口、闪存以及振荡器等。

通过读取XN文件中的数据,XTC工具链能够生成用于特定平台的头文件——<platform.h>,并在多节点程序的编译、启动和调试过程中使用它。

.xn文件包含了哪些内容?

即使您需要自定义XMOS芯片的功能,您也不需要从头开始编写.xn文件。所有的应用项目中都包含了.xn,并且包含了常用的配置默认值。

但如果您对于配置的设计与实现方式有更深的了解,会对深入开发很有帮助。

XN的高级层次结构可以分为:

关于XN中每个字段的详细信息和默认配置,请查阅XN规范说明

XN文件通常位于sw_usb_audio/app_usb_aud_xxx/src/core目录中,下面我们将以XU316-1024-QF60B-PP24.xn文件为例,说明如何进行常见的配置操作。

总体配置

以下代码片段描述了XMOS芯片的封装方式与节点:

  <Packages>
<Package id="0" Type="XS3-UnA-1024-FB265">
<Nodes>
<Node Id="0" InPackageId="0" Type="XS3-L16A-1024" Oscillator="24MHz" SystemFrequency="600MHz" referencefrequency="100MHz">

让我们说明其中的关键部分:

Package

Package主要定义了从xCORE端口到封装引脚的映射关系。当你更换芯片封装时,可能需要对此进行修改。值得注意的是,大封装的pkg文件能够兼容小封装的芯片,比如在使用XU316-1024-QF60B-PP24时,可以采用XS3-UnA-1024-FB265的封装信息。这些封装信息可以在XTC安装目录下的configs文件夹中查找。

  • Type="XS3-UnA-1024-FB265":此处指定的是XML封装的名称。XTC工具链会在XCC_DEVICE_PATH所指定的路径中查找<type>.pkg文件。

Node

Node元素定义了网络中连接到xCONNECT的一组xCORE Tiles。可以通过修改此元素来调整参考时钟频率和每个tile的系统主频,从而影响芯片的运行速度、功耗以及硬件定时器。

具体参数说明如下:

  • Type="XS3-L16A-1024":此处定义了描述节点的XML文件名,XTC工具链会在XCC_DEVICE_PATH指定的路径中搜索<type>.xml文件。
  • Oscillator="24MHz":此项设置了该节点使用的晶振或时钟源频率为24MHz。
  • SystemFrequency="600MHz":此项设置了该节点的系统频率为600MHz。在更改此项时,通常以100MHz为步进。
  • referencefrequency="100MHz":此项设置了时钟的参考频率为100MHz,这将影响硬件定时器的ticks。

端口(引脚)配置

在XN文件中,每个<Tile>元素会定义一个或多个端口。端口是与外部设备交互的接口,XMOS芯片通过这些端口进行输入/输出操作。以下的代码片段展示了如何配置一组QSPI引脚:

<Tile Number="0" Reference="tile[0]">
<Port Location="XS1_PORT_1B" Name="PORT_SQI_CS"/>
<Port Location="XS1_PORT_1C" Name="PORT_SQI_SCLK"/>
<Port Location="XS1_PORT_4B" Name="PORT_SQI_SIO"/>
<!-- ... -->
</Tile>
<Tile Number="1" Reference="tile[1]">
<!-- ... -->
</Tile>

在使用端口资源之前,你需要定义它们所在的<Tile>元素:

  • Number:Tile在节点中的唯一编号,取值范围为0到n-1,其中n是在节点XML文件中定义的Tile数量。
  • Reference:将 Tile 与在 Declaration 中以 tile[n] 形式表达的标识符关联起来。

另外,<Port>元素定义了一个端口,并指定了该端口的引脚位置和用途名称。lib_xua库中的代码与此处的Name命名有关系,所以你需要使用规范的命名来快速定义引脚。关于常用的引脚定义,请参考常用的引脚定义

Location

Location属性定义了该端口在xCore tile中的位置,这是由标准头文件<xs1.h>中的端口标识符指定的。例如,"XS1_PORT_1B"表示该端口位于1B位置。更多关于端口的描述可以在XC编程指南中查阅。

Name

Name属性为端口设定了一个名称或别名,这使得程序员在进行编程时能够更容易识别和使用各个端口。例如"PORT_SQI_CS"就是这个端口的名称。如需了解关于端口使用的更多信息,请参考XC编程语言

在上述代码片段中,我们定义了三个位于XS1_PORT_1BXS1_PORT_1CXS1_PORT_4B的端口,并分别命名为PORT_SQI_CSPORT_SQI_SCLKPORT_SQI_SIO

你可以根据实际需求,按照同样的方式修改或增加端口配置。

示例:点亮LED灯
XU316-1024-QF60B-PP24.xn
<Tile Number="0" Reference="tile[0]">
<Port Location="XS1_PORT_1A" Name="PORT_LED"/>
<!-- ... -->
</Tile>
led.xc
#include <platform.h>
on tile[0]: out port p_leds = PORT_LED;
p_leds <: 0x1;//点亮LED

Flash配置

下面的代码段展示了如何描述连接到XMOS Tile[0]的Flash的硬件配置信息,这里以UC25HQ16B为例:

<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" PageSize="256" SectorSize="4096" NumPages="8192">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>
<Attribute Name="QE_REGISTER" Value="flash_qe_location_status_reg_1"/>
<Attribute Name="QE_BIT" Value="flash_qe_bit_1"/>
</Device>
</ExternalDevices>

Devices

Device元素描述了一个连接到xCORE Tile的Flash设备。定义该元素需要以下必备信息:

  • NodeId:设备所连接节点的标识符

  • Tile:设备所连接的节点内的tile

  • Name:命名设备的标识符

为正确配置上述项目,你需要参考Flash的datasheet。相关信息可以在UC25HQ16B的第四页找到:

  • Class:描述了设备的类型,可选值有SPIFlash(对应SPI)和QSIFlash(对应QSPI)

  • PageSize:设备的页面大小,此处为 256 bytes

  • SectorSize:设备的擦除扇区大小,此处为 4096 bits

  • NumPages:设备的总页数,需要根据总容量计算,此处为 DensitiesPageSize=16Mbit256×8bit=8192 pages\frac{\text{Densities}}{\text{PageSize}} = \frac{16\text{Mbit}}{256 \times 8\text{bit}} = 8192 \text{ pages}

  • Attribute

    • PORT_SQI_CS:表示QuadSPI的芯片选择信号。
    • PORT_SQI_SCLK:表示QuadSPI的时钟信号。
    • PORT_SQI_SIO:表示QuadSPI的输入/输出信号。
image-20230731135905136
UC25HQ16B 表4:状态寄存器

根据UC25HQ16B第9页的表4,我们得知QE状态位是第2组寄存器(即S8-S15)的第2个bit(即S9),因此可以按照如下方式配置:

  • QE_REGISTER:此项为可选,此处需要配置为flash_qe_location_status_reg_1
  • QE_BIT:此项为可选,此处需要配置为flash_qe_bit_1

常用的引脚定义

lib_xua中,XMOS预定义了一系列端口,并在代码中使用这些名称。

当你使用lib_xua中的功能或接口(例如I2S/TDM,或者Mixer时),你需要按照约定好的命名将这些名称 Name 映射到硬件设计的端口位置 Location 中。这种方式的优势在于,你可以灵活地改变接口所在的引脚位置,以适配不同的产品应用。

I2S/TDM接口

I2S/TDM接口定义了使用I2S/TDM协议传输数据时,连接到XMOS的时钟与数据的引脚。为保证低延迟的音频传输,减少代码开销,尽量在1bit 端口上定义这些引脚,下面的代码定义了至高8通道I2S,32通道TDM的音频I/O接口,支持DSD格式。

<Tile Number="0" Reference="tile[0]">
<!-- Audio Ports: I2S -->
<Port Location="XS1_PORT_1L" Name="PORT_MCLK_IN"/>
<Port Location="XS1_PORT_1M" Name="PORT_I2S_BCLK"/>
<Port Location="XS1_PORT_1N" Name="PORT_I2S_LRCLK"/>
<Port Location="XS1_PORT_1O" Name="PORT_I2S_DAC0"/>
<Port Location="XS1_PORT_1D" Name="PORT_I2S_DAC1"/>
<Port Location="XS1_PORT_1P" Name="PORT_I2S_DAC2"/>
<Port Location="XS1_PORT_1A" Name="PORT_I2S_DAC3"/>

<Port Location="XS1_PORT_8D" Name="PORT_I2S_ADC0"/>
<Port Location="XS1_PORT_4D" Name="PORT_I2S_ADC1"/>
<Port Location="XS1_PORT_1C" Name="PORT_I2S_ADC2"/>
<Port Location="XS1_PORT_1B" Name="PORT_I2S_ADC3"/>

<!-- Audio Ports: DSD -->
<Port Location="XS1_PORT_1M" Name="PORT_DSD_CLK"/>
<Port Location="XS1_PORT_1O" Name="PORT_DSD_DAC0"/>
<port Location="XS1_PORT_1D" Name="PORT_DSD_DAC1"/>
</Tile>
  • PORT_MCLK_INPORT_I2S_LRCLKPORT_I2S_BCLK:这一组名称定义了音频的主时钟(MCLK)、位时钟(BCLK)以及采样率时钟(LRCLK),这些引脚通常与Codec或DSP的对应的时钟引脚相连。

  • PORT_I2S_DACn :这一组名称定义了由XMOS输出到DAC的数据引脚,其中n为序列号。

  • PORT_I2S_ADCn :这一组名称定义了由ADC输入到XMOS的数据引脚,其中n为序列号。

设备需要使用DSD/Dop功能时,定义以下引脚:

  • PORT_DSD_CLKPORT_DSD_DACn:这一组名称定义了DSD的时钟(CLK)以及数据引脚(Data)。DSD相关引脚的定义与I2S的引脚定义保持一致,以兼容DSD/Dop格式音频的播放。

S/PDIF&ADAT接口

接口定义了使用S/PDIF协议传输数据流时,连接到XMOS的引脚。与I2S类似,尽量在1bit 端口上定义这些引脚。下面代码定义了2通道S/PDIF I/O接口,以及ADAT I/O接口:

<Tile Number="0" Reference="tile[0]">    
<Port Location="XS1_PORT_1O" Name="PORT_ADAT_IN"/>
<Port Location="XS1_PORT_1E" Name="PORT_ADAT_OUT"/>
<Port Location="XS1_PORT_1P" Name="PORT_SPDIF_IN"/>
<Port Location="XS1_PORT_1D" Name="PORT_SPDIF_OUT"/>
</Tile>
  • PORT_ADAT_INPORT_ADAT_OUT:定义了ADAT的I/O流接口
  • PORT_SPDIF_INPORT_SPDIF_OUT:定义了S/PDIF的I/O流接口

USB接口

XMOS芯片内置了USB PHY,当你使用lib_xualib_xud库时,你需要在tile[0]或tile[1]上定义这些引脚,以使用USB PHY的功能。

<Tile Number="1" Reference="tile[1]">
<Port Location="XS1_PORT_1E" Name="PORT_USB_FLAG0"/>
<Port Location="XS1_PORT_1F" Name="PORT_USB_FLAG1"/>
<Port Location="XS1_PORT_1G" Name="PORT_USB_FLAG2"/>
<Port Location="XS1_PORT_1H" Name="PORT_USB_TX_READYIN"/>
<Port Location="XS1_PORT_1I" Name="PORT_USB_RX_READY"/>
<Port Location="XS1_PORT_1J" Name="PORT_USB_CLK"/>
<Port Location="XS1_PORT_1K" Name="PORT_USB_TX_READYOUT"/>
<Port Location="XS1_PORT_8A" Name="PORT_USB_TXD"/>
<Port Location="XS1_PORT_8B" Name="PORT_USB_RXD"/>

<!-- Ports for USB feedback calculation -->
<Port Location="XS1_PORT_16B" Name="PORT_MCLK_COUNT"/>
<Port Location="XS1_PORT_1G" Name="PORT_MCLK_IN_USB"/>
</Tile>

对于QFN封装的XU316(例如:XU316-1024-QF60B-PP24),有以下几点需注意:

  • 当USB功能定义在Tile[0]上时:USB使用的全部是未引出的引脚,不会占用任何GPIO。
  • 当USB功能定义在Tile[1]上时:在封装内部,USB会占用Tile[1]上的XS1_PORT_1FXS1_PORT_1K引脚。此时,这两个GPIO不应连接到任何外设。