XVF3610 系统接口
XVF3610语音处理器提供以下额外的接口,以提高可用性并降低系统总成本:
-
4个通用的输出引脚。这 些可以被配置为简单的数字I/O引脚、脉冲宽度调制(PWM)输出和速率可调的LED闪光灯。
-
4个通用输入引脚。这些可以作为简单的逻辑输入或事件捕获(边缘检测)。
-
I2C和SPI主控,以控制外部设备,如ADC、DAC或外部关键字检测设备。
通用输入和输出及外围桥接
XVF3610分别为XVF3610-UA和XVF3610-INT支持通过USB和I2C的I/O扩展和协议桥接。这允许外围设备,如连接到XVF3610的音频硬件,由主机进行配置和监控。

-
四个GPI通道(引脚)
-
可直接读取端口值
-
使用 "粘性 "位捕获上升、下降或两个边沿,在读取时被清除
-
每个引脚的模式可配置
-
四个GPO通道(引脚)
-
可直接写入整个端口或引脚
-
高电平有效或低电平有效
-
500Hz的PWM可在0和100%的占空比之间配置
-
支持32个100ms状态序列的闪烁控制
-
SPI Master
-
1Mbps的SPI时钟
-
高达128字节的SPI写入
-
高达56字节的SPI读取
-
I2C Master(仅XVF3610-UA)
-
100kbps SCL时钟速度
-
寄存器读/写(字节)
-
高达56字节的I2C读/写
以下部分描述了每个外围接口的配置和使用:
GPIO
XVF3610 提供四个通用输入和四个通用输出引脚:
| Name | Description | I/O |
|---|---|---|
| IP_0 | General purpose input | I |
| IP_1 | General purpose input | I |
| IP_2 | General purpose input | I |
| IP_3 | General purpose input | I |
| OP_0 | General purpose output | O |
| OP_1 | General purpose output | O |
| OP_2 | General purpose output | O |
| OP_3 | General purpose output | O |
通用输入(GPI)
以下命令可用于读取和控制GPI。请注意,当检测到边缘时,中断寄存器被设置为1,当没有事件发生时,中断寄存器被设置为0。所有的中断寄存器在启动时都被初始化为0。
IP_0的特殊之处在于,当中断被启用时,它们会在芯片内部自动得到服务,并相应地通过USB生成HID报告。更多细节请参见USB HID部分。
以下参数可用于查询和配置GPI行为。
| COMMAND | TYPE | ARGS | DESCRIPTION |
|---|---|---|---|
| GET_GPI | uint32 | 1 | 读取所选GPIO端口的所有引脚的当前电平。引脚0对应于端口的LSB(Least significant bit) |
| GET_GPI_INT_PENDING_PIN | uint32 | 1 | 读取所选引脚的中断是否被触发。所选引脚的中断等待寄存器被此命令清零 |
| GET_GPI_INT_PENDING_PORT | uint32 | 1 | 读取所选端口的所有引脚是否被触发了中断。整个端口的中断等待寄存器被此命令清零 |
| SET_GPI_PIN_ACTIVE_LEVEL | uint8 | 3 | 为一个特定的GPI引脚设置有效电平。参数是<Port Index> <Pin Index> <0: active low, 1: active high>。默认情况下,所有的GPI引脚都被设置为高电平有效 |
| SET_GPI_INT_CONFIG | uint8 | 3 | 设置一个特定引脚的中断配置。参数是 <Port Index> <Pin Index> <Interrupt type 0=None, 1=Falling, 2=Rising, 3=Both> |
| SET_GPI_READ_HEADER | uint8 | 2 | 为下一个GPIO读数设置选定的端口和引脚。参数是<Port Index> <Pin Index> |
| GET_GPI_READ_HEADER | uint8 | 2 | 使用之前的 SET_GPI_READ_HEADER 命令获取当前选择的端口和针脚 |
| SET_KWD_INTERRUPT_PIN | uint8 | 1 | 设置GPI引脚索引以接收KWD中断 |
| GET_KWD_INTERRUPT_PIN | uint8 | 1 | 读取GPI引脚索引以接收KWD中断 |
通用输出(GPO)
以下命令可用于编写和控制GPO:
| COMMAND | TYPE | ARGS | DESCRIPTION |
|---|---|---|---|
| SET_GPO_PORT | uint32 | 2 | 向一个GPIO端口的所有引脚写一个值。 参数是 <Port Index> <Value> |
| SET_GPO_PIN | uint8 | 3 | 向一个特定的GPIO引脚写入值。 参数是 <Port Index> <Pin Index> <Value> |
| SET_GPO_PIN_ACTIVE_LEVEL | uint8 | 3 | 为一个特定的GPO引脚设置有效电平。 参数是 <Port Index> <Pin Index> <0: active low, 1: active high>默认情况下 ,所有GPO引脚都是高电平有效 |
| SET_GPO_PWM_DUTY | uint8 | 3 | 设置一个特定引脚的PWM占空比。其值以整数百分比给出。 参数是 <Port Index> <Pin Index> <Duty in percent> |
| SET_GPO_FLASHING | uint32 | 3 | 为一个特定的引脚设置串行闪存掩码。掩码中的每一位都描述了100ms间隔内的GPO状态。 参数是 <Port Index> <Pin Index> <Flash mask> |
所有的GPO在复位时都有一个弱的下拉(~30kΩ),并在设备启动时初始化为逻辑低电平,此后将始终驱动该引脚。
为了说明GPO的使用,以下部分考虑了四个常见的例子。写入一个GPO引脚,配置一个PWM输出,产生一个闪烁序列和驱动一个三色(RGB)LED。
下面的命令是将OP_2设置为先高后低(以XVF3610-UA为例):
vfctrl_usb SET_GPO_PIN 0 2 1
vfctrl_usb SET_GPO_PIN 0 2 0
如果要将所有GPO设置为先高后低:
vfctrl_usb SET_GPO_PORT 0 15
vfctrl_usb SET_GPO_PORT 0 0
PWM以固定的500Hz频率运行,目的是在调光LED时尽量减少可见的闪烁,并支持100个离散的占空比设置,以允许逐渐关闭到完全打开的控制。
下面的命令说明了通过设置GPO引脚0、1、2和3分别输出25%、50%、75%和100%的占空比来设置每个输出的PWM频率。
vfctrl_usb SET_GPO_PWM_DUTY 0 0 25
vfctrl_usb SET_GPO_PWM_DUTY 0 1 50
vfctrl_usb SET_GPO_PWM_DUTY 0 2 75
vfctrl_usb SET_GPO_PWM_DUTY 0 3 100
将一个引脚的占空比设置为100%就等于将该引脚设置为高电平。
每个GPO由内部32位寄存器的LSB驱动,每100mS旋转一个位。
下图显示了闪烁序列的工作方式。

下面的命令配置了以下内容。
GPO第0针闪烁,开1.6秒,然后关1.6秒,即周期为3.2秒。
GPO针脚1闪烁,开0.8秒,然后关0.8秒,即周期为1.6秒。
GPO针脚2闪烁,接通0.1秒,然后断开0.1秒,即周期为0.2秒。
vfctrl_usb SET_GPO_FLASHING 0 0 4294901760 # equivalent to pattern: xFFFF0000
vfctrl_usb SET_GPO_FLASHING 0 1 4042322160 # equivalent to pattern: xFF00FF00
vfctrl_usb SET_GPO_FLASHING 0 2 2863311530 # equivalent to pattern: xAAAAAAAA
请注意,一个GPO引脚可以被设置为PWM占空比,也可以通过对同一端口和引脚发出GPO_SET_PWM_DUTY指令和SET_GPO_FLASHING指令来设置为闪烁。
当RGB LED被连接到三个GPO引脚(0=红,1=绿,2=蓝)时,可以对自动颜色排序进行编程。例如,每3.2秒在红-黄-绿-青-蓝之间进行颜色循环。
vfctrl_usb SET_GPO_FLASHING 0 0 65535 # 0 x0000FFFF
vfctrl_usb SET_GPO_FLASHING 0 1 16776960 # 0 x00FFFF00
vfctrl_usb SET_GPO_FLASHING 0 2 4294901760 # 0 xFFFF0000
I2C Master外围接口(仅限XVF3610-UA)
XVF3610-UA变体提供了一个I2C主接口,可以作为:
-
来自USB接口的桥梁,即VFCTRL_USB命令可以从主机用来读写连接到I2C外围端口的设备。
-
一种机制,通过将命令纳入数据分区(在外部闪存中)来初始化连接到I2C外围端口的设备,在启动时执行。
该接口支持:
-
100kbps的固定速度
-
仅7位寻址
-
支持字节式I2C寄存器的读/写。
下表显示了用于配置I2C主接口的命令:
| COMMAND | TYPE | NUM ARGS | NUM VALUES | DEFINITION |
|---|---|---|---|---|
| SET_I2C_READ _HEADER | uint8 | 3 | 0 | 设置下一条GET_I2C或GET_I2C_WITH_REG命令使用的参数。参数:1:7位I2C从属设备地址。 2:设备中的寄存器地址。 3:要读取的字节数。 |
| GET_I2C_READ _HEADER | uint8 | 0 | 3 | 获取下一个GET_I2C或GET_I2C_WITH_REG命令使用的参数。返回值: 1:7位I2C从属设备地址。 2:设备内的寄存器地址。 3:要读取的字节数。 |
| GET_I2C | uint8 | 0 | 56 | 从SET_I2C_READ_HEADER命令定义的I2C设备中读取。返回值:1到56:SET_I2C_READ_HEADER命令定义的读取的字节数,后面是额外的未定义值。执行GET_I2C时,从I2C设备中读取的字节数是用SET_I2C_READ_HEADER设置的。 |
| GET_I2C_WITH_REG | uint8 | 0 | 56 | 从SET_I2C_READ_HEADER命令定义的I2C设备的寄存器中读取。返回值:1到56:SET_I2C_READ_HEADER命令定义的读取的字节数,后面是额外的未定义值。执行GET_I2C时从I2C设备中读取的字节数是用SET_I2C_READ_HEADER设置的。 |
| SET_I2C | uint8 | 56 | 0 | 写入一个I2C从属设备。参数: 1:7位I2C从属设备地址。 2:要写入的数据字节数(n)。3至56:数据字节。 必须给出所有的54个值,但只有n会被发送。 |
| SET_I2C_WITH_REG | uint8 | 56 | 0 | 写入一个I2C从属设备的特定寄存器。参数: 1:7位的I2C从属设备地址。 2:设备中的寄存器地址。 3:要写入的数据字节数(n)。 4到56:数据字节。 必须给出所有的53个值,但只有n会被发送。 |


可以进行原始的I2C读/写操作

I2C从属控制接口(仅限XVF3610-INT)
XVF3610-INT实现了一个用于控制和设置设备的I2C从属接口。该接口符合以下规格。
| Specification | Value |
|---|---|
| Maximum I2C operation speed | 100kbps |
| I2C Slave Address | 0x2C |
使用I2C Master向一个设备写入数据
通常,字节寄存器的读/写是用来配置外部I2C控制的硬件。
举个例子,假设有一个设备连接在地址0x40(64),有三个单字节的寄存器。下面的命令将把77写入寄存器0,48写入寄存器1,33写入寄存器2。
vfctrl_usb SET_I2C_WITH_REG 64 0 1 77 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
vfctrl_usb SET_I2C_WITH_REG 64 1 1 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
vfctrl_usb SET_I2C_WITH_REG 64 2 1 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
注意:控制协议不支持变量(可变数量的)参数。因此,即使在写一个字节时,也必须传递完整的参数数。未写的值将被忽略。
使用I2C Master从一个设备上读取数据
为了验证之前对地址为0x40(64)的寄存器0的I2C寄存器的写入,可以进行如下的I2C寄存器读取:
vfctrl_usb SET_I2C_READ_HEADER 64 0 1
vfctrl_usb GET_I2C_WITH_REG
> 77 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
读取的字节是56个返回值中的第一个,在这种情况下,它是77。下面的55 个值是未定义的,因为该命令只执行了一个寄存器的读取。
SPI Master
XVF3610_UA和XVF3610-INT变体提供了一个SPI主接口,可以作为:
-
来自USB接口的桥梁,即VFCTRL_USB命令可以从主机用来读写连接到SPI外围端口的设备;以及
-
通过将命令纳入数据分区(在外部闪存中)来初始化连接到SPI外围端口的设备的机制,这些命令在启动时被执行。
注意:从4.1版本开始,SPI Master外围接口在已被SPI启动的XVF3610_UA和XVF3610_INT器件上不可用,以防止可能的总线争用问题。
SPI主外设支持以下固定规格:
-
单个芯片选择线
-
1Mbps的固定时钟速度
-
支持读或写。不支持双工读/写。
-
最高有效位会被先传输
-
模式0传输(CPOL=0,CPHA=0)
芯片选择(CS)在传输开始前至少20ns被置位(active),在传输结束后至少20ns被复位(inactive)。
SPI主控器是通过以下命令来控制的:
| COMMAND | TYPE | ARGS | DESCRIPTION |
|---|---|---|---|
| GET_SPI | uint8 | 56 | 获取SPI read buffer的内容 |
| GET_SPI_READ_HEADER | uint8 | 2 | 获取下一个SPI read的地址和计数 |
| SET_SPI_PUSH | uint8 | 56 | 将SPI命令数据推入执行队列 |
| SET_SPI_PUSH_AND_EXEC | uint8 | 56 | 推送SPI命令数据,并从堆栈中执行命令。然后数据将被发送到SPI设备 |
| SET_SPI_READ_HEADER | uint8 | 2 | 设置下一个SPI读数的地址和计数 |
一次最多可读56字节,但通过将多个命令推入命令栈并一次性执行,一次可写128字节。该交易是在一次片选断言中进行的。

SPI外设,读取序列

SPI外设,写 入序列
控制协议不支持变量(可变数量)的参数。因此,即使在写一个字节时,传递的参数总数也必须是最大的。未写的值被忽略。
见下面的例子。
下面的例子将一个字节的数据(值为122)写入地址为6的控制寄存器中。
vfctrl_i2c SET_SPI_PUSH_AND_EXEC 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 1 122
注意:所有数字都是十进制。有必要将有效载荷填充到56字节,其中包括地址、长度和数据值。这是VFCTRL工具的要求,SPI接口本身只传输有效数据。
使用SET_SPI_PUSH命令可以传输超过54字节的数据,在执行推送之前使用多个命令排队。下面的例子将0到69的数值写入地址100(共70个字节),使用命令将56个数据值推入队列,接着推送剩余的14个数据字,然后执行传输。
vfctrl_i2c SET_SPI_PUSH 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
vfctrl_i2c SET_SPI_PUSH_AND_EXEC 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56
要读取地址6的一个字节,其中包含数值122,我们可以做如下操作:
vfctrl SET_SPI_READ_HEADER 6 1
vfctrl GET_SPI
> GET_SPI: 122 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
要从地址0读取16个字节,这些字节都包含数值33,我们可以做如下操作:
vfctrl SET_SPI_READ_HEADER 0 16
vfctrl GET_SPI
> GET_SPI: 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 0 0 0 0
-> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0