6.附录
6.1.从串行接口引导
DA14585/586/531可以在未编程OTP内存的情况下从外部串行设备启动。这是为了支持应用程序代码的开发。在上电时,系统进入开发模式,引导代码决定从哪个接口引导。本节描述所有支持的串行接口的引导顺序,并为开发人员提供必要的信息,以实现在外部设备和DA14585/586/531之间建立通信所需的协议。
请注意
有关引导DA14585/586/531的更多信息,请参阅相应的数据表。
6.1.1.简介
DA14585/586/531在两种模式下工作:正常的模式和发展模式。芯片上电后进入哪种模式的决定由驻留在ROM中的引导代码决定。引导代码的完整流程图如下:
引导ROM代码读取应用程序编程标志从OTP头识别芯片是否在发展模式或正常的模式。
请注意
DA14585/586:如果没有编程,OTP内存包含全0。
DA14531:如果没有编程,OTP内存包含所有1。
如果确定了预定义值,那么这就确保了OTP内存是有效的,并且编写了应用程序代码。但是,如果未标识预定义值,则OTP内存没有被编程(空白)或不可操作(随机数据)。
在发展模式,引导ROM代码初始化所有串行外围设备,DA14585/586/531可能从这些设备下载代码。的选项是:
UART
SPI(主和从)
I2C(只有硕士)
引导ROM代码一个接一个地在各种I/ o组合上搜索有效响应。还有一种选项,用户可以使用SPI接口的特定OTP字段来定义所需的I/ o。
引导引脚和串行外设搜索顺序将在下一节中介绍。
6.1.2.引导引脚和串行外设搜索序列
给出了DA14585/586/531引导引脚和串行外设的搜索序列表20,表21而且表22
接口 |
信号 |
一步一个 |
步骤B |
步骤C |
步骤D |
---|---|---|---|---|---|
SPI主 |
SCK |
P0_0 |
P0_0 |
||
CS |
P0_3 |
P0_1 |
|||
味噌 |
P0_6 |
P0_2 |
|||
莫西人 |
P0_5 |
P0_3 |
|||
UART |
TX |
P0_0 |
P0_2 |
P0_4 |
P0_6 |
处方 |
P0_1 |
P0_3 |
P0_5 |
P0_7 |
|
波特率 |
57600、8 - n - 1 |
115200、8 - n - 1 |
57600、8 - n - 1 |
9600、8 - n - 1 |
|
SPI的奴隶 |
SCK |
P0_0 |
|||
CS |
P0_3 |
||||
莫西人 |
P0_6 |
||||
味噌 |
P0_5 |
||||
I2C |
sci |
P0_0 |
P0_2 |
P0_4 |
P0_6 |
SDA |
P0_1 |
P0_3 |
P0_5 |
P0_7 |
序列 |
行动 |
---|---|
0 |
SPI主步骤A |
1 |
SPI主控步骤B |
2 |
UART一步一个 |
3. |
UART步骤B |
4 |
UART步骤C |
5 |
UART步骤D |
6 |
SPI从步A |
7 |
I2C一步一个 |
8 |
I2C步骤B |
9 |
I2C步骤C |
10 |
I2C步骤D |
步骤1:从外部SPI主机引导 |
步骤2:从1线UART引导(第一个选项) |
步骤3:从单线UART引导(第二个选项) |
步骤4:从2线UART引导 |
步骤5:从外部SPI从属引导 |
步骤6:从I2C启动 |
|
---|---|---|---|---|---|---|
P0_0 / RST |
味噌 |
Tx |
莫西人 |
|||
P0_1 |
莫西人 |
处方 |
SCS |
|||
P0_2 |
||||||
P0_3 |
SCS |
RxTx |
味噌 |
SDA |
||
P0_4 |
SCK |
SCK |
sci |
|||
P0_5 |
RxTx(默认) |
|||||
P0_6 |
||||||
P0_7 |
||||||
P0_8 |
||||||
P0_9 |
||||||
P0_10 |
||||||
P0_11 |
在每一步,引导ROM代码发送一个特定的字符到外设控制器,并等待一个回答。如果在一定的时间内没有收到答复,则超时指示代码继续进行下一步。如果检测到响应,则执行特定的协议,并在DA14585/586/531与外部串行设备之间建立通信。代码从外部串行设备下载到DA14585/586/531 RAM中。
6.1.4.DA14585/586/531引导协议
6.1.4.1.从SPI总线引导- DA14585/586/531作为SPI奴隶
引导ROM代码初始配置DA14585/586/531 SPI控制器,使用以下参数:
8位模式
奴隶的角色
模式0:SPI时钟最初预期为低,SPI相位为零。
建立成功通信和将软件下载到RAM所需的协议已经给出表23.
请注意
主SPI设备为DA14585/586生成SPI时钟。在连续SPI时钟的情况下,该时钟的频率不得高于500 kHz。对于高于500khz的SPI时钟频率,SPI时钟应该在每个字节之后暂停。
字节nr。 |
DA14585/586/531莫西人 |
DA14585/586/531味噌 |
---|---|---|
0 |
序言:0 x70 |
|
1 |
序言:0×50 |
|
2 |
空:0 x00 |
|
3. |
LS字节长度 |
序言ACK: 0 x02 序言纳:0 x20 |
4 |
长度字节女士 |
|
5 |
CRC字节 |
|
6 |
模式字节 |
长度ACK: 0 x02 长度纳:0 x20 |
7 |
空:0 x00 |
|
8 |
数据字节 |
代码/ ACK模式:0 x02 代码/模式纳:0 x20 |
外部SPI主设备首先发送Preamble字节(0x70和0x50),后面跟着一个零字节。DA14585/586/531用0x02(已确认)或0x20(未确认)确认Preamble的接收,以防出现错误。字节3和4定义接下来的有效负载的长度。优先发送最低有效位的字节。长度是一个数字,表示32位字的数据量。
接下来,SPI主机必须发送计算出的有效负载CRC。CRC是通过对前一个值的每个连续字节进行XORing计算的。初始CRC值为0xFF。
字节6定义了由SPI主程序指导的操作模式(8,16或32位模式),而DA14585/586/531 SPI从程序对长度字节的接收使用ACK/NACK进行应答。模式编码如下:
0x00 = 8位模式
0x01 = 16位模式
0x02 = 32位模式
0 x03 =保留
字节8是最后一个控制字节,DA14585/586/531就CRC和模式的接收应答ACK/NACK,而外部SPI主控程序开始发送有效负载的第一个字节(第一个单词的最低有效字节)。
数据部分在表24,并考虑到指示模式。数据流之后是2个额外的空槽,为DA14585/586/531 SPI控制器提供所需的时间来计算CRC和使用ACK/NACK进行应答。
在SPI主进程完成后,所有相关的pad被设置为输入和下拉。
槽nr。 |
莫西人(8位模式) |
莫西人(16位模式) |
莫西人(32位模式) |
味噌 |
---|---|---|---|---|
0 |
字节0 |
字节1,字节0 |
字节3,字节2,字节1,字节0 |
|
1 |
1字节 |
字节3,字节2 |
字节7,字节6,字节5,字节4 |
|
... |
||||
4 * Len-1或 2 * Len-1或 Len-1 |
字节(4 * Len-1) |
16位字(2 * Len-1) |
32位字(Len-1) |
|
所有0 x00 |
所有0 x00 |
所有0 x00 |
所有0 xaa |
|
所有0 x00 |
所有0 x00 |
所有0 x00 |
应答:0 x02 纳:0 x20 |
6.1.4.2.从UART引导
引导ROM代码初始配置DA14585/586/531 UART控制器,参数如下:
位:8
没有奇偶校验
1停止位
波特率:DA14531固定为115.2 Kbps, DA14585/586可变(参见表20).
建立成功通信和将SW映像下载到RAM所需的协议如下表所示,具体取决于芯片:
DA14585/586
字节nr。
DA14585/586 TX
DA14585/586 RX
0
STX = 0 x02
1
SOH = 0 x01
2
LEN_LSB字节(基本)
3.
LEN_MSB字节(基本)
4
LEN_LSB字节(扩展)
5
LEN_MSB字节(扩展)
6
ACK = 0x06或NACK = 0x15
7 N
SW代码字节
N + 1
儿童权利公约
N + 2
= 0 x06消
协议从传输0x02 (Start TX - STX)的DA14585/586 UART TX引脚开始。
外部设备被期望用0x01(报头开始- SOH)来回答。
如果基本LEN_LSB和LEN_MSB字节均为零,则SW映像等于或大于64kbyte。以下两个扩展LEN_LSB和LEN_MSB字节定义了64 KByte边界上的额外图像长度。在这种情况下,下载的SW图像的长度由以下公式计算:
长度= 64 KByte +由定义的附加长度扩展LEN_MSB和LEN_LSB字节。
如果接收到5个字节并识别出SOH, DA14585/586用0x06 (ACK)回答,如果出错,则用0x15 (NACK)回答。
如果至少有一个基本LEN_LSB或LEN_MSB字节不为零,则SW映像低于64kbyte。这些字节定义了下载的SW映像的长度。
DA14585/586回答0x06 (ACK)如果已经接收到3个字节并且已经识别出SOH,或者回答0x15 (NACK)如果发生了任何错误。
DA14531
字节nr。
DA14531 TX
DA14531 RX
0
STX = 0 x02
1
SOH = 0 x01
2
LEN_LSB字节
3.
LEN_MSB字节
4
ACK = 0x06或NACK = 0x15
5 N
SW代码字节
N + 1
儿童权利公约
N + 2
= 0 x06消
协议从传输0x02 (Start TX - STX)的DA14531 UART TX引脚开始。外部设备被期望用0x01(头- SOH的开始)字节和另外两个字节(LEN_LSB, LEN_MSB)来回答,这两个字节定义了要下载的代码的长度(第一个字节是最不重要的,第二个字节是最重要的)。如果已经接收到3个字节并且确定了SOH, DA14531就用0x06 (ACK)回答,如果发生了任何错误,则用0x15 (NACK)回答。
此时连接已经成功建立,SW代码将开始下载。接下来的N个字节被接收并放入RAM,并从地址0x07FC0000开始,如中所示表27.
地址 |
字节3 (MSB) |
2字节 |
1字节 |
字节0 (LSB) |
---|---|---|---|---|
0 x07fc0000 |
代码字节3 |
代码字节2 |
代码字节1 |
代码字节0 |
0 x07fc0004 |
... |
... |
代码5字节 |
代码字节4 |
完成所需的代码字节后,引导代码计算CRC并通过URX发送它。当在URX行读取值0x06 (ACK)时,引导序列结束。CRC是通过对前一个值的每个连续字节进行XORing计算的。初始CRC值为0x00。
在引导代码的最后一步,SYS_CTRL_REG寄存器被编程为:
重新映射到地址0以便执行到RAM (SYS_CTRL_REG[REMAP_ADR0] = 0x2)
应用SW复位,因此系统开始执行重映射地址(SYS_CTRL_REG[SW_RESET] = 0x1)上的代码。
6.1.4.3.从SPI总线引导- DA14585/586/531作为SPI主控
引导代码用以下参数配置SPI:
8位模式
主角色
模式3:SPI时钟初始高,SPI相位偏移90度。
SPI时钟频率默认设置为2兆赫兹。
建立成功通信和将SW映像下载到RAM所需的协议如下表所示,并取决于芯片:
DA14585/586作为SPI主
字节nr。
DA14585/586莫西人
DA14585/586味噌
0
读取命令
1
地址字节0 = 0x00
2
地址字节1 = 0x00
3 - N
虚字节= 0x00
N + 1
“p”= 0 x70
N + 2
“P”= 0×50
N + 3 N + 5
虚拟字节
N + 6
扩展字节长度
N + 7
LEN_MSB字节
N + 8
LEN_LSB字节
N + 9…
代码字节
如果长度的扩展字节等于1,那么SW下载的图像大小将等于或大于64kbyte。图像长度根据以下公式计算:
length = 64 KByte +由LEN_MSB和LEN_LSB字节定义的额外长度。
如果长度的扩展字节不等于1,那么SW下载的图像大小将低于64kbyte。图像长度由LEN_MSB和LEN_LSB字节定义。
DA14531作为SPI的主人
字节nr。
DA14585/586/531莫西人
DA14585/586/531味噌
0
读取命令
1
地址字节0 = 0x00
2
地址字节1 = 0x00
3 - N
虚字节= 0x00
N + 1
“p”= 0 x70
N + 2
“P”= 0×50
N + 3 N + 6
虚拟字节
N + 7
LEN_MSB字节
N + 8
LEN_LSB字节
N + 9…
代码字节
图像长度由LEN_MSB和LEN_LSB字节定义。
中所描述的序列表28或表29对于Read命令和Dummy字节参数重复了4种不同的情况,如表30.
nr。 |
读取命令操作码 |
虚拟字节数 |
---|---|---|
0 |
0 x03 |
0 |
1 |
0 x03 |
1 |
2 |
0 x0b |
2 |
3. |
0 xe8 |
5 |
请注意
第4个Read命令发出后接收到SW映像的长度(opcode = 0xE8)。
一旦接收到长度(2个字节- LEN_MSB和LEN_LSB),实际的代码下载就开始到RAM中。起始地址是RAM的基址。字节对齐是根据表27.
在引导代码的最后一步给出SW复位,系统开始执行下载的代码。
6.1.4.4.从I2C总线引导- DA14585/586/531作为I2C主
boot code通过以下参数将I2C控制器初始化到主模式:
I2C从地址= 0x50(7位地址)
I2C速度到标准模式(100kbit /s)
引导代码首先扫描以找到地址为0x50到0x57的I2C从设备。在成功识别从地址之后,将执行一个特定的协议将SW下载到RAM中,如下表所示。每个芯片都有一个特定的表。如果不成功,将在20毫秒后编程一个超时,使芯片退出I2C启动模式,进入下一个I2C启动模式。
DA14585/586作为I2C主控
字节nr。
DA14585/586 SDA
动作(DA14585/586 I2C主控)
0
0 x70
读取命令
1
0×50
读取命令
2
LEN_MSB字节(基本)
3.
LEN_LSB字节(基本)
4
仅对代码进行CRC校验(图像< 64KByte)
读取命令
5
LEN_MSB字节(扩展)
6
LEN_LSB字节(扩展)
7
仅对代码进行CRC校验(图像>= 64KByte)
读取命令
8 - 31
假
读取命令
32 +长度32
代码数据
读取命令
如果基本LEN_LSB和LEN_MSB字节均为零,则SW映像等于或大于64kbyte。以下两个扩展LEN_LSB和LEN_MSB字节定义了64 KByte边界上的额外图像长度。在这种情况下,下载的SW图像的长度由以下公式计算:
长度= 64KByte +由定义的附加长度扩展LEN_MSB和LEN_LSB字节。
Byte-4应1。Byte-7包括CRC字节(仅通过代码计算)。
如果至少有一个基本LEN_LSB或LEN_MSB字节不为零,则SW映像低于64kbyte。这些字节定义了下载的SW映像的长度。
Byte-4包括CRC字节(仅通过代码计算)。
DA14531作为I2C主机
字节nr。
DA14531 SDA
动作(DA14531 I2C主)
0
0 x70
读取命令
1
0×50
读取命令
2
LEN_MSB字节
读取命令
3.
LEN_LSB字节
读取命令
4
仅通过代码进行CRC校验
读取命令
5 - 31日
假
读取命令
32 +长度32
代码数据
读取命令
引导代码将通过用前一个值XORing每个连续字节来计算CRC。初始CRC值为0x00。CRC以32字节的倍数计算。当负载大小不是32字节的倍数时,需要用0填充。
在引导代码的最后一步给出SW复位,系统开始执行下载的代码。
6.2.创建辅助引导加载程序
本节描述为DA14585/586/531开发辅助引导加载程序应用程序的实现步骤。
6.2.1.简介
辅助引导加载程序允许DA14585/586/531从外部SPI闪存、I2C EEPROM或UART接口引导。在需要一个更快的引导序列的情况下,辅助引导加载程序可以用来取代ROM引导加载程序。本节还介绍了基于双映像的辅助引导加载程序的扩展。双映像引导加载程序是支持软件空中更新(SUOTA)的应用程序的构建块。最后给出了辅助引导加载程序的代码结构、测试步骤和测量引导时间的方法。
建议阅读附录6.1节,其中描述了DA14585/586/531 ROM代码支持的引导过程。
6.2.2.应用程序描述
6.2.2.1.文件结构
secondary_bootloader项目的文件结构如图64.
初始化文件和分散加载描述文件在文件夹中工具/ secondary_bootloader /启动:
bootloader_531.sct:DA14531的散点加载描述文件
bootloader_585.sct:DA14585/586的散点加载描述文件
sysram.ini:Keil调试器初始化脚本
应用程序(* . c)文件在文件夹中工具/ secondary_bootloader / src:
c:包含应用程序的主函数、系统初始化函数和主循环
bootloader.c:包含从SPI和EEPROM引导的函数,以及双映像引导加载程序的实现
uart_booter.c:包含从UART引导的函数
crc32.c:包含CRC32校验和计算算法
sw_aes.c:包含软件实现的AES加密。加密密钥和IV在应用程序代码中是硬编码的
解密包含软件实现的AES解密
应用程序(* . h)文件在文件夹中工具/ secondary_bootloader /包括:
periph_setup.h:包含辅助引导加载程序使用的外设(UART、SPI、SPI Flash)的配置设置。
bootloader.h:包含应用程序配置设置。详细信息请参见6.2.2.2节.
驱动程序文件(* . c)对于外设接口都在文件夹中/ sdk /平台/驱动程序.有关驱动程序的详细信息可以在API文档中找到。
sdk /平台/司机/ spi / spi_58x.c:DA14585/586 Soc SPI接口的驱动程序
sdk /平台/司机/ spi / spi_531.c:DA14531 Soc SPI接口驱动程序
sdk /平台/司机/ i2c / i2c.c:I2C接口驱动
sdk /平台/司机/ spi_flash / spi_flash.c:外部SPI闪存的驱动程序
sdk /平台/司机/ gpio / gpio.c:GPIO接口驱动程序
sdk /平台/司机/ dma / dma.c:DMA接口驱动程序
6.2.2.2.编译和配置设置
主要的编译和配置设置包含在头文件中bootloader.h而且user_periph_setup.h.
AES_ENCRYPTED_IMAGE_SUPPORTED:只有当双映像引导加载程序的映像是加密的时,才必须定义此设置。必须为辅助引导加载程序禁用。
UART_SUPPORTED:该设置定义是否启用UART下载固件。它被两个应用程序所支持:二级和双映像引导加载程序亚博国际官网平台网址。
请注意
对于DA14531, P0_0用于UART_TX。固件下载结束时,P0_0上的硬件复位功能被启用。外部应用程序应该驱动P0_0到低,以避免设备的硬件复位。
SPI_FLASH_SUPPORTED, EEPROM_FLASH_SUPPORTED:这些设置定义了产品支持的外部Flash内存类型。只需要定义一个。
SUPPORT_AN_B_001:该设置定义应用程序将被编译为辅助引导加载程序。
外设的配置设置包含在头文件中periph_setup.h.
//选择EEPROM特性#定义x20000 I2C_EEPROM_DEV_SIZE 0// EEPROM大小,单位为字节#定义I2C_EEPROM_PAGE_SIZE 256// EEPROM页面大小(以字节为单位#定义I2C_SLAVE_ADDRESS 0×50//设置从设备地址#定义I2C_SPEED_MODE I2C_SPEED_FAST//速度模式:I2C_SPEED_STANDARD (100kbits /s), I2C_SPEED_FAST (400kbits /s)#定义I2C_ADDRESS_MODE I2C_ADDRESSING_7B//寻址模式:{I2C_ADDRESSING_7B, I2C_ADDRESSING_10B}#定义I2C_ADDRESS_SIZE I2C_2BYTES_ADDR//地址宽度:{I2C_1BYTE_ADDR, I2C_2BYTES_ADDR, I2C_3BYTES_ADDR}// SPI Flash设置// SPI Flash制造商和ID#定义W25X10CL_MANF_DEV_ID (0 xef10)// W25X10CL制造商和ID#定义W25X20CL_MANF_DEV_ID (0 xef11)// W25X10CL制造商和ID#定义MX25R2035F_MANF_DEV_ID (0 xc212)// MX25R2035F制造商和ID// SPI Flash选项#定义W25X10CL_SIZE 131072// SPI Flash内存大小,单位为字节#定义W25X20CL_SIZE 262144// SPI Flash内存大小,单位为字节#定义MX25R2035F_SIZE 262144// SPI Flash内存大小,单位为字节#定义W25X10CL_PAGE 256// SPI Flash页面大小(以字节为单位)#定义W25X20CL_PAGE 256// SPI Flash页面大小(以字节为单位)#定义MX25R2035F_PAGE 256// SPI Flash页面大小(以字节为单位)#如果! (__DA14586__定义)#定义SPI_FLASH_DEV_SIZE (256 * 1024)# endif/ / SPI的初始化参数#定义SPI_WORD_MODE SPI_8BIT_MODE#定义SPI_SMN_MODE SPI_MASTER_MODE#定义SPI_POL_MODE SPI_CLK_INIT_HIGH#定义SPI_PHA_MODE SPI_PHASE_1#定义SPI_MINT_EN SPI_NO_MINT#如果! (__DA14531__定义)#定义SPI_CLK_DIV SPI_XTAL_DIV_2# endif// UART GPIOs分配#如果定义(__DA14531__)#定义UART_GPIO_PORT GPIO_PORT_0#定义UART_TX_PIN GPIO_PIN_0#定义UART_RX_PIN GPIO_PIN_1#定义UART_FRAC_BAUDRATE UART_BAUDRATE_115200其他##定义UART_GPIO_PORT GPIO_PORT_0#定义UART_TX_PIN GPIO_PIN_4#定义UART_RX_PIN GPIO_PIN_5#定义UART_FRAC_BAUDRATE UART_BAUDRATE_57600# endif// SPI GPIO分配#如果定义(__DA14531__)#定义SPI_EN_PORT GPIO_PORT_0#定义SPI_EN_PIN GPIO_PIN_1#定义SPI_CLK_PORT GPIO_PORT_0#定义SPI_CLK_PIN GPIO_PIN_4#定义SPI_DO_PORT GPIO_PORT_0#定义SPI_DO_PIN GPIO_PIN_0#定义SPI_DI_PORT GPIO_PORT_0#定义SPI_DI_PIN GPIO_PIN_3# elif ! (__DA14586__定义)#定义SPI_EN_PORT GPIO_PORT_0#定义SPI_EN_PIN GPIO_PIN_3#定义SPI_CLK_PORT GPIO_PORT_0#定义SPI_CLK_PIN GPIO_PIN_0#定义SPI_DO_PORT GPIO_PORT_0#定义SPI_DO_PIN GPIO_PIN_6#定义SPI_DI_PORT GPIO_PORT_0#定义SPI_DI_PIN GPIO_PIN_5# endif// EEPROM GPIO分配#定义I2C_SCL_PORT GPIO_PORT_0#定义I2C_SCL_PIN GPIO_PIN_2#定义I2C_SDA_PORT GPIO_PORT_0#定义I2C_SDA_PIN GPIO_PIN_3
支持W25X10CL SPI闪存设备。W25X10CL数组被组织成512个可编程页面,每个页面256字节。一次最多可编程256字节。W25X10CL有32个可擦扇区,分别为4kb、4个可擦32kb块和2个可擦64kb块。也支持W25X20CL SPI闪存设备。
如果更改了上述配置设置(SPI_FLASH_DEFAULT_SIZE, SPI_FLASH_DEFAULT_PAGE等),则可以支持其他SPI Flash内存类型。
GPIO端口0默认使用,因为所有DA14585/586 (WLCSP34、QFN40和QFN48)和DA14531 (WLCSP17和FCGQFN24)包都支持该端口。
6.2.3.系统初始化
辅助引导加载程序在保留内存中执行,并允许将应用程序代码加载到系统RAM中。辅助引导加载程序执行以下操作:
在主功能中,辅助引导加载程序用最大值重新加载看门狗定时器,并配置看门狗定时器在过期时触发HW重置。
SetBits(WATCHDOG_CTRL_REG,NMI_RST,1);// WDOG将在过期时生成HW重置SetWord16(WATCHDOG_REG,0 xff);/ /重置WDOGSetWord16(RESET_FREEZE_REG,FRZ_WDOG);/ /开始WDOG
初始化系统。
system_init();
如果启用了UART启动选项并且UART RX引脚为逻辑高,则从UART启动。否则从SPI或I2C引导。
6.2.4.开始
本节描述如何将辅助引导加载程序编程到OTP内存中,将一个应用程序示例(集成处理器邻近报告器)编程到SPI Flash内存中,并测量系统的引导时间。还提供了与普通启动程序(开发模式下的ROM启动程序)的比较。
的SmartSnippets工具箱为外部SPI Flash和OTP内存编程提供工具。
6.2.4.1.构建应用程序和辅助引导加载程序映像
为DA14585目标构建邻近报告应用程序映像,以生成可执行文件prox_reporter_585.hex。
根据以下步骤为相同的目标构建辅助引导加载程序映像:
打开Secondary Bootloader项目:
凯尔5:
\工具\ secondary_bootloader \ secondary_bootloader.uvprojx
.
根据章节配置项目6.2.2.2节.
编译项目以生成可执行文件secondary_bootloader_585.hex.这个文件在目录中
<事业\ secondary_bootloader \ out_DA14585 \对象
.
6.2.4.2.正在写入应用程序十六进制文件到SPI闪存
的SmartSnippetsSPI Flash程序员工具用于下载应用程序映像文件到连接到DA14585/586/531的外部SPI Flash存储器。
下面的说明演示了如何使用SmartSnippets工具箱当连接DA14585设备时,处于UART模式。
开放SmartSnippets并选择芯片版本。
打开板设置工具,并选择适当的UART和SPI闪光引脚配置如图所示图66.
打开SPI Flash程序员工具,选择应用程序映像文件,并在SPI闪存偏移量为0的位置刻录它。当被问及是否使SPI闪存可引导时,根据芯片版本和引导加载程序配置,有两个选项可以考虑:
可启动的SPI闪:smartsnippet将自动在SPI闪存的偏移量0处添加一个an - b -001头。辅助引导加载程序将只复制SPI Flash头中定义的字节数。
Non-bootable SPI闪:smartsnippet不会在SPI闪存的偏移量为0处添加an - b -001头。辅助引导加载程序将从偏移量0x0开始的SPI Flash内存中复制32 KB。使用这种设置,可以测量最大引导时间。
6.2.4.3.正在写入引导加载程序十六进制文件到OTP内存
的SmartSnippetsOTP程序员工具支持将默认固件下载到系统RAM中,并将用户定义的HEX或BIN文件写入OTP内存中。该工具可用于在DA14585/586/531的OTP内存中写入辅助引导加载程序。
编写可执行文件需要接下来的步骤secondary_bootloader_585.hex
进入OTP内存SmartSnippets
在UART模式:
开放SmartSnippets并选择芯片版本。
打开板设置工具并选择适当的UART配置。
打开OTP程序员工具,并选择要下载的镜像文件。
燃烧的
secondary_bootloader_585.hex
输入OTP内存的偏移量为0。启用应用程序标志1和应用程序标志2,设置DMA长度(长度= size / 4)并刻录OTP头
.
请注意
有关SmartSnippets工具箱的更多信息,请参阅“SmartSnippets工具箱,用户手册”。
6.2.4.4.mkimage工具
的mkimage工具是一个命令行Windows应用程序,根据双映像引导加载程序指定的内存映射格式化非易失性内存。
该工具支持两个用例:
单一的图片:创建二进制应用程序映像文件(* img),它包含应用程序映像头文件和应用程序固件。
多部分图片:将外部非易失性存储器的全部内容创建为一个由多个部分组成的二进制映像文件(* img),可以将其写入非易失性内存SmartSnippets工具箱.
的源代码mkimage工具在文件夹中\工具\ mkimage
SDK。
6.2.4.4.1.创建应用镜像文件
创建应用程序映像文件的命令行语法(* img)是:
mkimage.exe单<in_file><version_file><out_file>[内附[<关键><4>]]
单
指示工具创建应用程序映像(* img文件)。 < infile >
指定原始应用程序固件二进制文件(. bin文件)。< version_file >
C头文件,包含图像头的版本、时间戳和管理信息。它的格式必须类似于SDK头文件sdk \ \包括\ sdk_version.h平台
.它包含如下定义:
#定义SDK_VERSION“v_6.0.12.1020”#定义SDK_VERSION_DATE "2019-10-09 14:25 "#定义SDK_VERSION_STATUS " v_6.0.12.1020"
原始二值图像的加密(< in_file >)如果在命令末尾包含enc选项,则可以启用。用户可提供加密密钥(< >键)和初始化向量(<四>)作为32个十六进制字符的字符串(没有任何前缀)。当没有指定
关键:06A9214036B8A15B512E03D534120006初始化向量:3.DAFBA429D9EB430B422DA802C9FAC41
密钥和初始化向量的默认值在辅助引导加载程序固件中是硬编码的。
6.2.4.4.2.创建非易失性内存的全部内容
用于创建多部分二进制图像文件的命令行语法(* img),而非易失性记忆体的全部内容为:
mkimage.exe多spi|eepm[<bloader>]<in_img1><off1><in_img2><远比><off3>[cfgoff4[,bdaddr]]<out_file>
多
指示工具创建
多部分图像包括:
AN-B-001头加上偏移量为0的引导加载程序固件
,如果提供 。 < img1 > (* img图像)在偏移量
< img2 >(*。img图像)在偏移量
产品标头位于偏移量
cfg选项配置以下产品头字段:
特定于应用程序的“配置偏移量”从off4初始化。如果没有提供off4,那么' Configuration Offset '字段应该设置为0xFFFFFFFF。
BD地址由' baddr '初始化。如果未提供bdadr,则BD Address字段应设置为FF: FF: FF: FF: FF: FF.如果提供了bdaddr,则要求在off4、逗号字符和' bdaddr '之间不存在空格。
偏移量可以用十进制或十六进制数表示。
BD地址“bdadr”可以表示为XX: XX: XX: XX: XX: XX其中X是十六进制数字。例如,80: EA: CA: 01:02:03.
6.3.生产线工具参考命令行
6.3.1.简介
介绍DA14585/586/531生产测试工具的参考命令行接口。
该工具是一个Microsoft Windows命令行程序,它支持通过UART与运行生产测试固件的DA14585/586/531设备通信。
生产测试固件是一个特殊的固件,它支持:
蓝牙SIG标准接收器和发射器测试HCI命令。
额外的自定义测试HCI命令。
SmartSnippets工具箱的RF Master工具也支持所有测试命令。
对话还设计了一个生产测试和编程单元"PLT,使您能够在围绕DA145xx系列的单元的批量测试和编程中降低成本并提高吞吐量。
6.3.2.开始
6.3.2.1.预编译的二进制文件
预编译的二进制文件在以下SDK路径中为生产测试固件和工具提供:
固件
< sdk_root_directory > \二进制文件\ da14585 \ prod_test \ prod_test_585.hex
对于DA14585< sdk_root_directory > \二进制文件\ da14585 \ prod_test \ prod_test_586.hex
对于DA14586< sdk_root_directory > \二进制文件\ da14585 \ prod_test \ prod_test_531.hex
对于DA14531
工具
< sdk_root_directory > \二进制文件\ \ windows \ prod_test_cmds \ prod_test.exe
6.3.2.2.构建工具
对于SDK 6.0.4及以上版本,这是:< sdk_root_directory > \工具\ prod_test \ prod_test_cmds
.
6.3.2.3.建筑的固件
所需的固件包含在SDK文件夹中:(SDK 6.0.2及更高版本):< sdk_root_directory > \ \ target_apps \ prod_test \ prod_test项目
构建固件的步骤
打开文件夹
< sdk_root_directory > \ \ target_apps \ prod_test \ prod_test项目
.打开项目。
选择菜单
项目->重建所有目标文件
来构建项目。获取生成的十六进制文件:
DA14585:
。\ Keil_5 \ out_DA14585 \ \ prod_test_585.hex对象
DA14586:
。\ Keil_5 \ out_DA14586 \ \ prod_test_586.hex对象
DA14531:
。\ Keil_5 \ out_DA14531 \ \ prod_test_531.hex对象
6.3.3.一般的描述
该工具的一般语法是:
Prodtest
命令总是返回状态码和可选的返回值列表。返回状态码和值以一种简单的格式写入标准输出:
返回状态码也作为退出码返回。
状态码为零表示命令执行成功。非零状态码编码故障的类型。
该工具的所有其他输出都被写入stderr(使用-h选项时的帮助消息除外)。
6.3.4.命令行开关
6.3.5.命令
6.3.5.1.cont_pkt_tx
描述:这是蓝牙SIG标准化HCI_LE_Transmitter_Test命令。它不断地传输数据包,直到stoptest
命令执行。
语法:prodtest- p< COM_PORT_NUMBER >cont_pkt_tx<频率>< DATA_LENGTH >< PAYLOAD_TYPE >
参数:
FREQUENCY为2402 ~ 2480之间的偶数。例如,整数2480对应2.480 GHz。
DATA_LENGTH是以字节为单位的负载长度(一个介于37到255之间的数字)。
PAYLOAD_TYPE必须具有以下值之一:
0:伪-随机位序列91:模式的交替位“11110000”2:模式的交替位“10101010”3.:伪-随机位序列154:模式的所有' 1 '位5:模式的所有' 0 '位6:模式的交替位“00001111”7:模式的交替位“0101”
例子:
prodtest-p14cont_pkt_tx2402356
输出示例:
状态=0
6.3.5.2.pkt_tx
描述:发送指定数量的报文。
语法:prodtest- p< COM_PORT_NUMBER >pkt_tx<频率>< DATA_LENGTH >< PAYLOAD_TYPE >< NUMBER_OF_PACKETS >
参数:
FREQUENCY为2402 ~ 2480之间的偶数。例如,2480对应2.480 GHz。
DATA_LENGTH是以字节为单位的负载长度(一个介于37到255之间的数字)。
PAYLOAD_TYPE必须具有以下值之一:
0:伪-随机位序列91:模式的交替位“11110000”2:模式的交替位“10101010”3.:伪-随机位序列154:模式的所有' 1 '位5:模式的所有' 0 '位6:模式的交替位“00001111”7:模式的交替位“0101”
NUMBER_OF_PACKETS为1 ~ 65535之间的整数。
例子:发送1000个报文。
prodtest-p14pkt_tx24023561000
输出示例:
状态=0
6.3.5.3.start_pkt_rx
描述:这是蓝牙SIG标准化的HCI_LE_Receiver_Test命令。它不断地接收数据包,直到stoptest
命令执行。
语法:prodtest- p< COM_PORT_NUMBER >start_pkt_rx<频率>
参数:
FREQUENCY为2402 ~ 2480之间的偶数。例如,2480对应2.480 GHz。
例子:
prodtest-p14start_pkt_rx2402
输出示例:
状态=0
6.3.5.4.start_pkt_rx_stats
描述:启动带有附加统计信息的RX包。它不断地接收数据包,直到执行stop_pkt_rx_stats命令。
语法:prodtest- p< COM_PORT_NUMBER >start_pkt_rx_stats<频率>
参数:
FREQUENCY为2402 ~ 2480之间的偶数。例如,2480对应2.480 GHz。
例子:
prodtest-p14start_pkt_rx_stats2402
输出示例:
状态=0
6.3.5.5.stop_pkt_rx_stats
描述:用额外的统计信息结束RX包,并报告以下统计信息:
正确接收的数据包数(nb_packets_received_correct)
同步错误的数据包数(nb_packets_with_syncerror)
CRC错误包数(nb_packets_received_with_crcerr)
dBm中的RSSI (RSSI)
语法:prodtest- p< COM_PORT_NUMBER >stop_pkt_rx_stats
例子:
prodtest-p14stop_pkt_rx_stats
输出示例:
状态=0nb_packets_received_correctly=8529nb_packets_with_syncerror=0nb_packets_received_with_crcerr=1rssi=-37.30
6.3.5.6.stoptest
描述:这是蓝牙SIG标准化的HCI_LE_Test_End命令。使用它:
后
cont_pkt_tx
命令,结束标准报文TX测试模式。后
start_pkt_rx
命令结束标准报文RX模式,并报告收到的报文数。
语法:prodtest- p< COM_PORT_NUMBER >stoptest
例子:
prodtest-p14stoptest
输出示例(当执行cont_pkt_tx之后,包的数量总是0):
状态=0number_of_packets=0
输出示例(当执行start_pkt_rx之后):
状态=0number_of_packets=4360
6.3.5.7.未调制的TX
描述:开始连续波(CW)或无调制TX测试。
语法:prodtest- p< COM_PORT_NUMBER >未调整的TX<频率>
参数:
FREQUENCY为2402 ~ 2480之间的偶数。例如,2480对应2.480 GHz。
例子:
prodtest-p14未调整的TX2404
输出示例:
状态=0
6.3.5.8.未调制的处方
描述:启动无调制RX测试。
语法:prodtest- p< COM_PORT_NUMBER >未调整的处方<频率>
参数:
FREQUENCY为2402 ~ 2480之间的偶数。例如,2480对应2.480 GHz。
例子:
prodtest-p14未调整的处方2404
输出示例:
状态=0
6.3.5.9.未调整的了
描述:停止未调制的TX或RX测试。
语法:prodtest- p< COM_PORT_NUMBER >未调整的从
例子:
prodtest-p14未调整的从
输出示例:
状态=0
6.3.5.10.start_cont_tx
描述:开启连续TX测试模式。它连续地传输调制信号,直到stop_cont_tx
命令执行。
语法:prodtest- p< COM_PORT_NUMBER >start_cont_tx<频率>< PAYLOAD_TYPE >
参数:
FREQUENCY为2402 ~ 2480之间的偶数。例如,2480对应2.480 GHz。
PAYLOAD_TYPE必须具有以下值之一:
0:伪-随机位序列91:模式的交替位“11110000”2:模式的交替位“10101010”3.:伪-随机位序列154:模式的所有' 1 '位5:模式的所有' 0 '位6:模式的交替位“00001111”7:模式的交替位“0101”
例子:
prodtest-p14start_cont_tx24044
输出示例:
状态=0
6.3.5.11.stop_cont_tx
描述:停止连续TX测试模式。
语法:prodtest- p< COM_PORT_NUMBER >stop_cont_tx
例子:
prodtest-p14stop_cont_tx
输出示例:
状态=0
6.3.5.12.重置
描述:这是蓝牙SIG标准化的HCI_Reset命令。
语法:prodtest- p< COM_PORT_NUMBER >重置
例子:
prodtest-p14重置
输出示例:
状态=0
6.3.5.13.xtrim rd
描述:读取在DA14585和DA14586数据表中指定的XTAL16M修剪寄存器的值:CLK_FREQ_TRIM_REG (0x50000002)。
以十进制形式上报。
语法:prodtest- p< COM港口数>xtrim理查德·道金斯
例子:
prodtest-p14xtrim理查德·道金斯
输出示例:
状态=0trim_value=500
6.3.5.14.xtrim wr
描述:写入一个值到XTAL16M修剪寄存器。新值将立即写入,并且在prodtest程序执行完此命令时已经生效。
语法:prodtest- p< COM港口数>xtrim或者说是< trim_value >
参数:
trim_value是要写入XTAL16M微调寄存器的无符号16位十进制值。
例子:
prodtest-p14xtrim或者说是500
输出示例:
状态=0
6.3.5.15.xtrim en
描述:使能GPIO P0_5的XTAL16M输出。该命令立即生效。
语法:prodtest- p< COM港口数>xtrim在
例子:
prodtest-p14xtrim在
输出示例:
状态=0
请注意
该命令也可以用于使能GPIO 0_6的32khz时钟。为此,需要使用write_reg16命令设置另外两个寄存器(参见部分)部分6.3.5.29).在CLK_32K_REG中使能32khz时钟,将位0和位7设置为“1”,将GPIO P0_6设置为输出模式。在P06_MODE_REG中,设置位8和位9为' 1 '。
例子:
prodtest-p14write_reg1650000020079D
prodtest-p14write_reg16500030120300
输出示例:
状态=0
6.3.5.16.xtrim说
描述:关闭GPIO P0_5的XTAL16M输出。该命令立即生效。
请注意
此命令还禁用:GPIO P0_6上的XTAL32K输出P0_7上的RC16M输出P1_0上的RC32K输出。
语法:prodtest- p< COM港口数>xtrim说
例子:
prodtest-p14xtrim说
输出示例:
状态=0
6.3.5.17.xtrim公司
描述:增加XTAL16M微调寄存器。当prodtest程序完成此命令的执行时,寄存器的新值已经生效。
语法:prodtest- p< COM港口数>xtrim公司δ> <
参数:
delta是要添加到XTAL16M微调寄存器的无符号16位十进制值。
例子:
prodtest-p14xtrim公司5
输出示例:
状态=0
6.3.5.18.xtrim 12月
描述:对XTAL16M修边寄存器进行递减。当prodtest程序执行完此命令时,寄存器的新值已经生效。
语法:prodtest- p< COM港口数>xtrim12月δ> <
参数:
delta是要从XTAL16M微调寄存器中减去的无符号16位十进制值。
例子:
prodtest-p14xtrim12月5
输出示例:
状态=0
6.3.5.19.xtrim卡尔
描述:运行XTAL16M微调寄存器校准程序,使用外部施加的500毫秒高平方脉冲作为校准微调值的参考。该过程执行以下步骤:
校准XTAL16M修边寄存器。
在OTP中编程校准值(地址0x7F8C)。
在OTP中启用“XTAL16M trim value is valid”位(地址0x7F78)。
如果没有在给定的GPIO上应用平方脉冲,则校准过程将失败,状态码为27。
语法:prodtest- p< COM港口数>xtrim卡尔< Px_y >
参数:
Px_y是应用外部平方脉冲的GPIO。
例子:
prodtest-p14xtrim卡尔P1_0
输出示例:
状态=0
6.3.5.20.xtrim calt
描述:行为与" xtrim cal "相同,除了它不修改OTP。
语法:prodtest- p< COM港口数>xtrimcalt< Px_y >
参数:
Px_y是应用外部平方脉冲的GPIO。
例子:
prodtest-p14xtrimcaltP1_0
输出示例:
状态=0
6.3.5.21.睡眠
描述:使设备休眠指定的分秒数。
语法:prodtest- p< COM_PORT_NUMBER >睡眠<模式><分钟><秒>
参数:
Mode是以下功率模式之一:
“没有”为活跃的模式“扩展”为扩展睡眠模式“深度”为深睡眠模式
分钟是一个介于0到255之间的数字
秒是一个介于0到255之间的数字
如果分钟和秒都被设置为零,那么设备将永远休眠。每个睡眠模式下的活动外设显示在表33而且表34.
电源模式 |
PD_SYS |
PD_PER |
PD_DBG |
PD_RAD |
PD_SRx |
模拟 |
---|---|---|---|---|---|---|
扩展/深度睡眠 |
汽车了 |
可编程的 |
汽车了 |
可编程的 |
可编程的 |
汽车了 |
电源模式 |
PD_SYS |
PD_AON |
PD_SLP |
PD_RAD |
PD_TIM |
---|---|---|---|---|---|
|
汽车了 |
在 |
在 |
从 |
可编程的 |
已知的限制:
当设备从延长睡眠模式唤醒时,UART通信丢失
在OTP复制模式下,设备将不会从扩展睡眠中唤醒
示例1:
prodtest-p14睡眠没有一个10
示例2:
prodtest-p14睡眠扩展030.
示例3:
prodtest-p14睡眠深00
输出示例:
状态=0
6.3.5.22.otp wr_xtrim
描述:将XTAL16M trim值写入OTP报头。
语法:prodtest- p< COM港口数>otpwr_xtrim<小数修剪值>
参数:
十进制微调值是要写入OTP报头的无符号16位十进制XTAL16M微调值
例子:
prodtest-p14otpwr_xtrim500
输出示例:
状态=0
6.3.5.23.otp rd_xtrim
描述:从OTP报头读取XTAL16M trim值。输出值为十进制格式。
语法:prodtest- p< COM港口数>otprd_xtrim
例子:
prodtest-p14otprd_xtrim
输出示例:
状态=0otp_xtrim_value=500
6.3.5.24.otp wr_bdaddr
描述:将蓝牙设备地址写入OTP报头。
语法:prodtest- p< COM港口数>otpwr_bdaddr< BD地址>
参数:
BD地址是要写入OTP报头的蓝牙设备地址。BD地址格式必须为XX:XX:XX:XX:XX:XX,其中X为十六进制数字
例子:
prodtest-p14otpwr_bdaddr44:49:41:4c:4 f:47
输出示例:
状态=0
6.3.5.25.otp_read
描述:从OTP内存中读取连续的单词。
语法:prodtest- p< COM港口数>otp_read< otp地址><词数>
参数:
otp地址为要读取的otp内存区域的起始地址。这是一个字地址,因此必须能被4整除。它必须低于0x8000。必须格式化为16位十六进制数
字数是指阅读的字数。可接受的范围是1到60。字数必须满足公式:
+ 4 * <字数> <= 0x8000。它必须格式化为十进制数
例子:
prodtest-p16otp_read7 f直流5
输出示例:
状态=0[7 f直流]=1234A5A5[7 fE0]=A5A51234[7 fE4]=14121117[7 fE8]=24222127[7 f电子商务]=00000007
6.3.5.26.otp_write
描述:将连续的单词写入OTP内存。
语法:prodtest- p< COM港口数>otp_write< otp地址><词# 1 >...<词# n >
参数:
otp地址为要写入的otp内存区域的起始地址。这是一个字地址,因此必须能被4整除。它必须低于0x8000。必须格式化为16位十六进制数
Word #i为要写入address:
+ 4 * i的Word值,格式必须为32位十六进制数。字值参数的数量必须最多为60,并且必须满足公式: + 4 * n <= 0x8000
例子:
prodtest-p16otp_write7 f直流1234A5A5A5A51234
输出示例:
状态=0
6.3.5.27.read_reg16
描述:读取16位寄存器的值。输出值以十六进制打印。
语法:prodtest- p< COM港口数>read_reg16<注册地址>
参数:
寄存器地址是要读取的16位寄存器的地址。寄存器地址必须是半字对齐的,因此必须能被2整除。必须格式化为32位十六进制数
例子:下面的命令为TRIM_CTRL_REG (0x50000016)。
prodtest-p16read_reg1650000016
输出示例:
状态=0价值=00A2
6.3.5.28.read_reg32
描述:读取32位寄存器的值。输出值以十六进制打印。
语法:prodtest- p< COM港口数>read_reg32<注册地址>
参数:
寄存器地址是要读取的32位寄存器的地址。寄存器地址必须是字对齐的,因此必须能被4整除。必须格式化为32位十六进制数
例子:如下命令显示为PATCH_VALID_REG (0x40008400)。
prodtest-p16read_reg3240008400
输出示例:
状态=0价值=00000001
6.3.5.29.write_reg16
描述:写入16位寄存器。
语法:prodtest- p< COM港口数>write_reg16<注册地址><注册值>
参数:
寄存器地址是要读取的16位寄存器的地址。寄存器地址必须是半字对齐的,因此必须能被2整除。必须格式化为32位十六进制数
寄存器值是要写入寄存器的值。必须格式化为16位十六进制数
例子:在TRIM_CTRL_REG (0x50000016)中写入0x00B3。
prodtest-p16write_reg165000001600B3
输出示例:
状态=0
6.3.5.30.write_reg32
描述:写入32位寄存器。
语法:prodtest- p< COM港口数>write_reg32<注册地址><注册值>
参数:
寄存器地址是要读取的32位寄存器的地址。寄存器地址必须是字对齐的,因此必须能被4整除。必须格式化为32位十六进制数
寄存器值是要写入寄存器的值。必须格式化为32位十六进制数
例子:在PATCH_VALID_REG (0x40008400)中写入0x0000000F。
prodtest-p16write_reg32400084000000000 f
输出示例:
状态=0
6.3.6.返回状态码
表35总结了产品测试工具的返回代码。
状态码 |
描述 |
---|---|
0 |
SC_NO_ERROR |
1 |
SC_MISSING_COMMAND |
2 |
SC_INVALID_COMMAND |
3. |
SC_WRONG_NUMBER_OF_ARGUMENTS |
4 |
SC_INVALID_COM_PORT_NUMBER |
5 |
SC_INVALID_FREQUENCY_ARG |
6 |
SC_INVALID_DATA_LENGTH_ARG |
7 |
SC_INVALID_PAYLOAD_TYPE_ARG |
8 |
SC_COM_PORT_INIT_ERROR |
9 |
SC_RX_TIMEOUT |
12 |
SC_INVALID_UNMODULATED_CMD_MODE_ARG |
13 |
SC_COM_PORT_NOT_SPECIFIED |
14 |
SC_INVALID_SLEEP_CMD_MODE_ARG |
15 |
SC_INVALID_SLEEP_CMD_MINUTES_ARG |
16 |
SC_INVALID_SLEEP_CMD_SECONDS_ARG |
17 |
SC_INVALID_XTAL_TRIMMING_CMD_OPERATION_ARG |
18 |
SC_INVALID_XTAL_TRIMMING_CMD_TRIM_VALUE_ARG |
19 |
SC_INVALID_OTP_CMD_OPERATION_ARG |
20. |
SC_INVALID_OTP_CMD_TRIM_VALUE_ARG |
21 |
SC_INVALID_OTP_CMD_BDADDR_ARG |
22 |
SC_INVALID_OTP_ADDRESS_ARG |
23 |
SC_INVALID_NUMBER_OF_OTP_WORDS_ARG |
24 |
SC_INVALID_WORD_VALUE_ARG |
25 |
SC_INVALID_GPIO_ARG |
26 |
SC_XTAL_TRIMMING_CAL_OUT_OF_RANGE_ERROR |
27 |
SC_XTAL_TRIMMING_CAL_FREQ_NOT_CONNECTED |
28 |
SC_INVALID_REGISTER_ADDRESS_ARG |
29 |
SC_INVALID_REGISTER_VALUE_ARG |
1000 - 1063 |
SC_HCI_STANDARD_ERROR_CODE_BASE(1000) +标准HCI错误码 |
6.4.Flash程序员
6.4.1.概述
Flash程序员(flash_programmer)是一个目标端应用程序,用于上传和回读运行在DA14585/586/531系列集成电路支持的平台上的应用程序代码。在启动flash程序员应用程序后,平台通过UART或JTAG接口与主机应用程序通信,允许它向flash、EEPROM或OTP内存读写应用程序代码。双方交换包含操作代码、状态和与所定义的协议相关的有效负载的消息。
6.4.2.通信通道
通信通道在编译时被选择,并且被限制为以下选项:
6.4.2.1.UART (USE_UART标志定义)
在这种模式下,flash程序员从主机接收消息,并使用UART接口进行响应。它还为DA14585/585目标定义了大小为64K- 1字节(0xFFFF)的交换缓冲区,为DA14531定义了大小为32K - 1字节(0x7FFF)的交换缓冲区。这限制了可以在单个消息中写入或读取的数据量。这是2字节宽的长度指示器(连同CRC)在实际消息帧之前发送的含义。帧长度和CRC代码不缓存在缓冲区中,只保存实际消息(包括可能的报头和有效负载)。
有了这些知识,就很容易弄清楚,在OTP写操作的情况下,DA14585/586的实际固件块大小限制为0xFFF8 (0xFFFF减去这个特定消息的7字节头数据),DA14531的0x7FF8。由于通过UART的通信是同步的,因此定义的缓冲区用于传入和传出消息。
flash程序员默认通过引脚P0_0、P0_1与主机通信,DA14585/586目标的速率为57600,DA14531目标的速率为115200。这可以通过附加到二进制1字节来改变。这个字节根据下表选择引脚和波特率。
平台 |
选择器 |
TX销 |
RX销 |
波特率 |
---|---|---|---|---|
DA14585/586 |
0(默认) |
P0_0 |
P0_1 |
57600 |
2 |
P0_2 |
P0_3 |
115200 |
|
4 |
P0_4 |
P0_5 |
57600 |
|
6 |
P0_6 |
P0_7 |
9600 |
|
DA14531 |
0(默认) |
P0_0 |
P0_1 |
115200 |
3(单线UART) |
P0_3 |
P0_3 |
115200 |
|
5(单线UART) |
P0_5 |
P0_5 |
115200 |
6.4.2.2.JTAG(未定义标志)
使用共享内存进行消息交换。主机应用程序使用JTAG接口对某个内存区域进行读写。Flash程序员不断地在这些区域中轮询新消息,并相应地做出响应。定义了两个区域:
BASE_MEMORY—在这个区域中存储消息和响应
TARGET_MEMORY——有效载荷存储在这个区域中
DA14585/586的可用消息空间限制为64K, DA14531的可用消息空间限制为32K(实际消息头的限制也适用于这里。在写请求的情况下,偏移字段是2字节宽,包括前64K/32K内存地址)。
请注意
这两种情况下的消息交换协议略有不同,将在另一节中进行描述。
6.4.3.功能
Flash程序员支持以下操作:
操作FLASH、EEPROM、OTP外设所需的硬件设置(包括启用LDO和GPIO配置)
正在读取当前运行的flash程序员版本
从应用程序内存区域读取请求的数据量
将请求的数据量写入应用程序内存区域
从应用程序内存区域删除请求的数据量(所有非易失性内存类型都不支持)
6.4.4.数据交换协议
Flash程序员在无限循环中监听主机命令。宿主应该收到每个发出的操作的响应。这些文件应该在目标完成之前的文件后按顺序发放。对于每个支持的交换通道,该消息交换序列的执行方式不同。
6.4.4.1.UART
主机通过UART发送命令包,格式如下:
Len(16位) |
CRC(32位) |
Op的代码 |
地址(32位) |
长度(16位) |
数据…… |
---|---|---|---|---|---|
头部分 |
信息部分 |
第一个Len参数是消息部分的总长度,它从Op Code(8位)开始,在可变长度数据缓冲区结束的地方结束。还为消息部分计算CRC。消息段长度受2字节宽的Len限制。
发送到主机的结果响应因消息的不同而不同。确切的请求和响应消息将在本文档后面给出,但需要注意的是,它们也有头部部分,其中包含Len和CRC字段。
数据通过网络字节顺序(大端序)传输。
6.4.4.2.JTAG(内存映射API)
对象中的地址开始执行命令,主机向内存段写入一条消息以发出命令BASE_MEMORY
变量。信息结构如下:
内存偏移量 |
记忆的内容 |
订单 |
---|---|---|
ACTION_OFFSET |
Op的代码 |
LSB |
SIZE_OFFSET |
长度(16位) |
最高有效位 |
SIZE_OFFSET + 1 |
LSB |
|
ADDRESS_OFFSET |
地址偏移(32位) |
|
ADDRESS_OFFSET + 1 |
||
ADDRESS_OFFSET + 2 |
最高有效位 |
|
ADDRESS_OFFSET + 3 |
||
RESULT_OFFSET |
结果 |
LSB |
ERROR_OFFSET |
当Result不是ACTION_OK时的附加错误代码 |
|
ERROR_OFFSET + 1 |
||
ERROR_OFFSET + 2 |
最高有效位 |
|
ERROR_OFFSET + 3 |
内存偏移量 |
记忆的内容 |
---|---|
0 |
|
1 |
|
... |
对象所指向的数据缓冲区中TARGET_MEMORY
变量时适用。
请注意
主机以相对于BASE_MEMORY变量中保存的起始地址的一定偏移量写入包节。编写操作代码应该是最后一步,因为这会触发目标平台上的操作。一旦处理了消息并填充了Result部分中的响应,Op Code值就会变回0。这样,主机就知道什么时候读取触发动作的结果。与通过UART交换的消息类似,响应结构依赖于主机发送的命令。
为DA14585/586/531平台、内存地址和偏移量按下表设置:
平台 |
TARGET_MEMORY |
BASE_MEMORY |
ACTION_OFFSET |
SIZE_OFFSET |
ADDRESS_OFFSET |
RESULT_OFFSET |
---|---|---|---|---|---|---|
DA14585/586 |
0 x07fc8000 |
0 x07fc7c00 |
0 x00 |
0 x02 |
0 x04 |
( |
DA14531 |
0 x07fc4000 |
0 x07fc3c00 |
0 x00 |
0 x02 |
0 x04 |
( |
由于JTAG接口的性质,因此没有进行字节数转换。数据应该写入目标平台的端序(小端序)。
6.4.4.3.握手
主机应用程序需要从目标接收一个信号,以确定目标是否准备好接收请求。这对于两个沟通渠道来说是不同的:
UART:
目标通过UART发送" Hello "字符串报告准备就绪。
JTAG:
Target将结果状态值设置为ACTION_READY
在BASE_MEMORY
+RESULT_OFFSET
内存地址。主机应用程序可以监视这个内存地址以进行检测flash_programmer
准备就绪。
6.4.4.4.消息
注意,下面的消息列表没有列出报头部分(Length, CRC),这是随协议交换的每个UART消息一起发送的。
6.4.4.4.1.一般
- ACTION_READ_VERSION
-
(0x10) -读取flash程序员应用程序版本
UART:
Len(16位)
CRC(32位)
Op的代码
0 x07
儿童权利公约
0 x10
Len(16位)
CRC(32位)
Op的代码
0 x0d
儿童权利公约
0 x82
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 x10 (ACTION_READ_VERSION)
0 x00 (NO_ACTION)
SIZE_OFFSET
不在乎
不在乎
ADDRESS_OFFSET
不在乎
不在乎
RESULT_OFFSET
不在乎
0 x82 (ACTION_CONTENTS)
内存偏移量
请求内存内容
响应内存内容
0
不在乎
v
1
不在乎
_
2
不在乎
5
...
不在乎
...
- ACTION_VPP_ENABLE
-
(0x50) -当OTP内存写入时,使能控制高压(6.8v)的晶体管。
UART:
Len(16位)
CRC(32位)
操作码(8位)
VPP_ENABLE(8位)
0 x02
儿童权利公约
0×50
0 x00或0 x01
Len(16位)
CRC(32位)
状态(8位)
0 x01
儿童权利公约
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
- ACTION_READY
-
(0x5A) -当以共享内存模式(JTAG)运行时,这只被固件用来通知主机目标已经准备好处理主机请求。
JTAG:
内存偏移量
未准备好时的内存内容
准备好后的内存内容
ACTION_OFFSET
不在乎
不在乎
SIZE_OFFSET
不在乎
不在乎
ADDRESS_OFFSET
不在乎
不在乎
RESULT_OFFSET
0 x00
0 x82 (ACTION_READY)
- ACTION_UART_GPIOS
-
(0x31) -配置UART数据线。如果引脚错误,返回ACTION_ERROR。
UART:
Len(16位)
CRC(32位)
Op的代码
TX_PORT
TX_PIN
RX_PORT
RX_PIN
0 x05
儿童权利公约
0 x31
0 x00
0 x04
0 x00
0 x05
Len(16位)
CRC(32位)
状态(8位)
0 x01
儿童权利公约
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
JTAG:
不支持的
6.4.4.4.2.OTP存储器
- ACTION_OTP_READ
-
(0x80)——从OTP内存中读取给定偏移量的请求数据量。
UART:
Len(16位)
CRC(32位)
Op的代码
地址偏移(32位)
长度(16位)
Len(16位)
CRC(32位)
0 x07 +长度
儿童权利公约
0 x80
抵消
长度
0 x07 +长度
儿童权利公约
Len(16位)
CRC(32位)
状态(8位)
数据……
0x01 +数据长度
儿童权利公约
0 x82 (ACTION_CONTENTS)
读取数据
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 x80 (ACTION_OTP_READ)
0 x00 (NO_ACTION)
SIZE_OFFSET
数据长度
数据长度
ADDRESS_OFFSET
地址偏移量
地址偏移量
RESULT_OFFSET
不在乎
0 x82 (ACTION_CONTENTS)
内存偏移量
请求内存内容
响应内存内容
0
不在乎
data0
1
不在乎
data1
2
不在乎
data2
...
不在乎
data3
- ACTION_OTP_WRITE
-
(0x81) -将请求的数据量写入给定偏移量的OTP内存中。
UART:
Len(16位)
CRC(32位)
Op的代码
地址偏移(32位)
长度(16位)
数据(长* 8位)
0 x07 +长度
儿童权利公约
0 x81
内存地址
长度
数据写
Len(16位)
CRC(32位)
状态(8位)
错误码(32位)
0 x01 x05或0
儿童权利公约
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
附加错误码-仅当Status设置为ACTION_ERROR时。
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 x81 (ACTION_OTP_WRITE)
0 x00 (NO_ACTION)
SIZE_OFFSET
大小
大小
ADDRESS_OFFSET
地址偏移量
地址偏移量
RESULT_OFFSET
不在乎
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
ERROR_OFFSET
不在乎
错误码(32位)-仅当结果为ACTION_ERROR时
内存偏移量
请求内存内容
响应内存内容
0
data0
data0
1
data1
data1
2
data2
data2
...
data3
data3
6.4.4.4.3.SPI闪光
- ACTION_SPI_READ
-
(0x90) -从给定内存地址的SPI FLASH内存中读取请求的数据量。
UART:
Len(16位)
CRC(32位)
Op的代码
地址偏移(32位)
长度(16位)
数据(长* 8位)
0 x07 +长度
儿童权利公约
0 x90
内存地址
长度
数据写
Len(16位)
CRC(32位)
状态(8位)
数据……
0x01 +数据长度
儿童权利公约
0 x82 (ACTION_CONTENTS)
读取数据
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 x90 (ACTION_SPI_READ)
0 x00 (NO_ACTION)
SIZE_OFFSET
数据长度
数据长度
ADDRESS_OFFSET
地址
地址
RESULT_OFFSET
不在乎
0 x82 (ACTION_CONTENTS)
内存偏移量
请求内存内容
响应内存内容
0
不关心| data0
1
不关心| data1
2
不关心| data2
...
不关心| data3
- ACTION_SPI_WRITE
-
(0x91) -将请求的数据量写入给定偏移量的SPI FLASH内存。
UART:
Len(16位)
CRC(32位)
Op的代码
地址偏移(32位)
长度(16位)
数据(长* 8位)
0 x07 +长度
儿童权利公约
0 x91
内存地址
长度
数据写
Len(16位)
CRC(32位)
状态(8位)
错误码(32位)
0 x01 x05或0
儿童权利公约
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
附加错误码-仅当Status设置为ACTION_ERROR时。
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 x91 (ACTION_FLASH_WRITE)
0 x00 (NO_ACTION)
SIZE_OFFSET
大小
大小
ADDRESS_OFFSET
内存地址
内存地址
RESULT_OFFSET
不在乎
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
ERROR_OFFSET
不在乎
错误码(32位)-仅当结果为ACTION_ERROR时
内存偏移量
请求内存内容
响应内存内容
0
data0
data0
1
data1
data1
2
data2
data2
...
data3
data3
- ACTION_SPI_ERASE
-
(0x92) -删除SPI FLASH内存。
UART:
Len(16位)
CRC(32位)
Op的代码
0 x01
儿童权利公约
0 x92
状态(8位)
错误码(32位)
状态(8位)
错误码(32位)
0 x01 x05或0
儿童权利公约
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
附加错误码-仅当Status设置为ACTION_ERROR时。
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 x92 (ACTION_SPI_ERASE)
0 x00 (NO_ACTION)
SIZE_OFFSET
不在乎
不在乎
ADDRESS_OFFSET
不在乎
不在乎
RESULT_OFFSET
不在乎
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
ERROR_OFFSET
不在乎
错误码(32位)-仅当结果为ACTION_ERROR时
请注意
TARGET_MEMORY地址的数据缓冲区内存布局:不使用目标内存。
- ACTION_SPI_ID
-
(0x93) -读取flash JEDEC ID。
UART:
Len(16位)
CRC(32位)
Op的代码
0 x01
儿童权利公约
0 x93
Len(16位)
CRC(32位)
状态
(8位)
制造商ID(8位)
JEDEC ID 1(8位)
0 x05
儿童权利公约
0 x82 (ACTION_C内容)
0
id
id
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 x93 (ACTION_EEPROM_READ)
0 x00 (NO_ACTION)
SIZE_OFFSET
不在乎
不在乎
ADDRESS_OFFSET
不在乎
不在乎
RESULT_OFFSET
不在乎
0 x82 (ACTION_CONTENTS)
内存偏移量
请求内存内容
响应内存内容
0
不在乎
设备ID byte 2
1
不在乎
设备ID byte 1
2
不在乎
制造商ID
3.
不在乎
0
- ACTION_SPI_ERASE_BLOCK
-
(0x94) -从flash地址开始删除指定数量的扇区。
UART:
Len(16位)
CRC(32位)
Op的代码
地址(32位)
部门(16位)
0 x07
儿童权利公约
0 x94
地址
n
Len(16位)
CRC(32位)
状态
(8位)
制造商ID(8位)
JEDEC ID 1(8位)
0 x01 x05或0
儿童权利公约
0x83 (ACTION_O K)或0x84 (ACTION_E error)
附加错误码-仅当Status未设置为ACTION_OK时
0 x01 x05或0
儿童权利公约
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 x94 (ACTION_SPI_ERASE_BLO CK)
0 x00 (NO_ACTION)
SIZE_OFFSET
部门统计
不在乎
ADDRESS_OFFSET
地址
不在乎
RESULT_OFFSET
不在乎
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
ERROR_OFFSET
不在乎
错误码-仅当result为ACTION_ERROR时
- ACTION_SPI_GPIOS
-
(0x95) -配置SPI数据线如果任何引脚不正确,返回ACTION_ERROR。
UART:
Len(16位)
CRC(32位)
Op的代码
CS港口
CS销
CLK港口
CLK销
做的港口
做销
迪港口
DI销
0 x09
儿童权利公约
0 x95
0 x00
0 x03
0 x00
0 x00
0 x00
0 x06
0 x00
0 x05
Len(16位)
CRC(32位)
状态
0 x01
儿童权利公约
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 x95 (ACTION_SPI_GPIOS)
0 x00 (NO_ACTION)
SIZE_OFFSET
不在乎
不在乎
ADDRESS_OFFSET
不在乎
不在乎
RESULT_OFFSET
不在乎
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
内存偏移量
请求内存内容
响应内存内容
0
0 x00 (CS端口)
不在乎
1
0 x03 (CS销)
不在乎
2
0 x00 (sci端口)
不在乎
3.
0 x00 (sci销)
不在乎
4
0 x00(端口)
不在乎
5
0 x06(销)
不在乎
6
0 x00 (DI端口)
不在乎
- ACTION_SPI_HEADER
-
(0x96) -将图像头写入SPI flash。
UART:
Len(16位)
CRC(32位)
Op的代码
大小(24位)
0 x04
儿童权利公约
0 x96
0 x012345
Len(16位)
CRC(32位)
状态
0 x01
儿童权利公约
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 x96 (ACTION_SPI_HEADER)
0 x00 (NO_ACTION)
SIZE_OFFSET
不在乎
不在乎
ADDRESS_OFFSET
不在乎
不在乎
RESULT_OFFSET
不在乎
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
内存偏移量
请求内存内容
响应内存内容
0
0 x45(大小LSB)
不在乎
1
0 x23
不在乎
2
0 x01大小(MSB)
不在乎
3.
不在乎
不在乎
6.4.4.4.4.I2C eepm
- ACTION_EEPROM_READ
-
(0xA0) -从I2C EEPROM中指定地址读取n字节数据。
UART:
Len(16位)
CRC(32位)
Op的代码
地址(32位)
大小(16位)
0 x07
儿童权利公约
0 xa0
地址
n
Len(16位)
CRC(32位)
状态(8位)
数据……
0x01 +数据长度
儿童权利公约
0 x82 (ACTION_CONTENTS)
读取数据
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 xa0 (ACTION_EEPROM_READ)
0 x00 (NO_ACTION)
SIZE_OFFSET
n
不在乎
ADDRESS_OFFSET
地址
不在乎
RESULT_OFFSET
不在乎
0 x82 (ACTION_CONTENTS)
内存偏移量
请求内存内容
响应内存内容
0
不在乎
数据字节1
1
不在乎
数据字节2
...
不在乎
n - 1
不在乎
数据字节n
- ACTION_EEPROM_WRITE
-
(0xA1) -写入n字节的数据到I2C EEPROM的指定地址。
UART:
Len(16位)
CRC(32位)
Op的代码
地址偏移(32位)
长度(16位)
数据(长* 8位)
0 x07 +长度
儿童权利公约
0最后
内存地址
长度
数据写
Len(16位)
CRC(32位)
状态
0 x01
儿童权利公约
0 x83 (ACTION_OK)
或
Len(16位)
CRC(32位)
状态
错误码(32位)
0 x05
儿童权利公约
0 x84 (ACTION_ERROR)
错误代码
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 xa1 (ACTION_EEPROM_WRITE)
0 x00 (NO_ACTION)
SIZE_OFFSET
n
不在乎
ADDRESS_OFFSET
地址
不在乎
RESULT_OFFSET
不在乎
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
ERROR_OFFSET
不在乎
错误代码
内存偏移量
请求内存内容
响应内存内容
0
数据字节1
不在乎
1
数据字节2
不在乎
...
不在乎
n - 1
数据字节n
不在乎
- ACTION_I2C_GPIOS
-
(0xA3)—配置I2C数据线。如果引脚错误,返回ACTION_ERROR。
UART:
Len(16位)
CRC(32位)
Op的代码
地址偏移(32位)
长度(16位)
数据(长* 8位)
0 x07 +长度
儿童权利公约
0 xa3
内存地址
长度
数据写
Len(16位)
CRC(32位)
状态
0 x01
儿童权利公约
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 xa3 (ACTION_I2C_GPIOS)
0 x00 (NO_ACTION)
SIZE_OFFSET
不在乎
不在乎
ADDRESS_OFFSET
不在乎
不在乎
RESULT_OFFSET
不在乎
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
ACTION_OFFSET
0 xa3 (ACTION_I2C_GPIOS)
0 x00 (NO_ACTION)
内存偏移量
请求内存内容
响应内存内容
0
0 x00 (sci端口)
不在乎
1
0 x04 (SCL_PIN)
不在乎
2
0 x00 (SDA_PORT)
不在乎
3.
0 x05 (SDA_PIN)
不在乎
- ACTION_I2C_HEADER
-
(0xA4) -将图像头写入I2C EEPROM。
UART:
Len(16位)
CRC(32位)
Op的代码
大小(24位)
0 x07 +长度
儿童权利公约
0 xa4
内存地址
Len(16位)
CRC(32位)
状态
0 x01
儿童权利公约
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
JTAG:
内存偏移量
请求内存内容
响应内存内容
ACTION_OFFSET
0 xa4 (ACTION_I2C_HEADER)
0 x00 (NO_ACTION)
SIZE_OFFSET
不在乎
不在乎
ADDRESS_OFFSET
不在乎
不在乎
RESULT_OFFSET
不在乎
0x83 (ACTION_OK)或0x84 (ACTION_ERROR)
内存偏移量
请求内存内容
响应内存内容
0
0 x45(大小LSB)
不在乎
1
0 x23
不在乎
2
0 x01大小(MSB)
不在乎
3.
不在乎
不在乎
6.5.正在写入十六进制文件到OTP内存
的SmartSnippetsOTP程序员工具允许下载默认固件到系统RAM,并将用户定义的HEX或BIN文件写入OTP内存。该工具可用于在DA14585/586/531的OTP内存中写入辅助引导加载程序。
编写可执行文件需要以下步骤secondary_bootloader_585.hex
进入OTP内存SmartSnippets
在UART模式:
开放SmartSnippets并选择芯片版本。
打开板设置工具并选择适当的UART配置。
打开OTP程序员工具,并选择要下载的镜像文件。
燃烧的
secondary_bootloader_585.hex
输入OTP内存的偏移量为0。启用应用程序标志1和应用程序标志2,设置DMA长度(长度= size / 4)并刻录OTP头
.
请注意
有关SmartSnippets工具箱的更多信息,请参阅“SmartSnippets Toolbox用户手册”。
6.6.BLE与其他2.4GHz无线电共存
本章的目的是描述启用DA14585/586/531的WLAN共存支持的主要步骤。
6.6.1.简介
DA14585/586/531上的WLAN共存特性设计用于允许多个2.4 GHz设备工作,而不受一个无线电信号干扰相邻无线电的影响。这是通过BLE设备和另一个2.4 GHz设备之间的握手协议实现的,使用以下信号:
- WLAN_COEX_BLE_EIP信号
-
DA14585/586/531可以使用上述信号提前通信其无线电状态。WLAN_COEX_BLE_EIP是BLE无线电预定的TX和RX无线电活动的信封,它在实际无线电活动之前开始,因此它可以预先通知共存系统预定的射频活动。该信号在无线电活动结束后直接同步去断言。
- WLAN_COEX_BLE_PRIO信号
-
DA14585/586/531可以启用优先级行,以指示它不能被定义的活动中断。BLE需要优先级的活动可以通过API定义。
WLAN_COEX_BLE_PRIO信号由DA14585/586/531固件内部控制,遵循特定的用户可配置规则。下表列出了所有可用的优先级。
规则
命令
优先级类型
1
wlan_coex_prio_criteria_add (BLEMPRIO_SCAN LLD_ADV_HDL 0);
主动扫描
2
wlan_coex_prio_criteria_add (BLEMPRIO_ADV LLD_ADV_HDL 0);
做广告
3.
wlan_coex_prio_criteria_add (BLEMPRIO_CONREQ LLD_ADV_HDL 0);
连接请求
4
wlan_coex_prio_criteria_add (BLEMPRIO_LLCP, 0, 0);
控制封包
5
wlan_coex_prio_criteria_add (BLEMPRIO_DATA, 0, 0);
数据包
6
wlan_coex_prio_criteria_add (BLEMPRIO_MISSED 0 4);
遗漏的事件(在本例中,在4个坏包之后)
- WLAN_COEX_24G_EIP信号
-
输入信号到DA14585/586/531设备。外部2.4GHz设备事件进展指示。
请注意
关于WLAN共存驱动程序的详细信息可以在API文档中找到。
6.6.2.启用WLAN共存特性
作为一个例子,我们将继续概述如何在prox_reporter_ext项目中启用WLAN共存特性:
在da1458x_config_advanced.h中,使用以下预处理器定义,以启用WLAN共存模式,带或不带调试信号,并设置正在进行的BLE事件信号的首选极性:
/****************************************************************************************************************//* WLAN共存模式:启用/禁用该模式。* //****************************************************************************************************************/#定义CFG_COEX/****************************************************************************************************************//* WLAN共存模式:打开/关闭调试信号。* //****************************************************************************************************************/#定义CFG_WLAN_COEX_DEBUG/****************************************************************************************************************//* WLAN共存模式:控制正在进行的BLE事件信号的极性。* //* -定义:BLE事件正在进行信号是活跃的低。* //* - undefined: BLE事件正在进行的信号是活跃的高。* //****************************************************************************************************************/# undef CFG_WLAN_COEX_BLE_EVENT_INV
必须将以下源文件添加到项目中:
wlan_coex.c
组成WLAN共存特性实现并驻留在< sdk_root_directory > \ sdk \ \司机\无线平台
.通过右键单击相应的文件夹并选择添加现有的文件来群……
选择。
下面的include路径必须添加到项目中。点击
选项为目标……
然后在C/ c++选项卡。在include Paths字段中添加wifi文件夹,其中包含wlan_coex.h文件。
在
user_periph_setup.h
应该为WLAN共存引脚映射添加以下定义块:
/****************************************************************************************//* WLAN COEX引脚配置*//****************************************************************************************/#如果(WLAN_COEX_ENABLED)#如果定义(__DA14531__)///设备输入信号:2.4GHz外部设备事件进展指示。#定义WLAN_COEX_24G_EIP_PORT GPIO_PORT_0#定义WLAN_COEX_24G_EIP_PIN GPIO_PIN_5///设备输出信号:BLE事件正在进行指示。#定义WLAN_COEX_BLE_EIP_PORT GPIO_PORT_0#定义WLAN_COEX_BLE_EIP_PIN GPIO_PIN_6///设备输出信号:BLE优先级指示。#定义WLAN_COEX_BLE_PRIO_PORT GPIO_PORT_0#定义WLAN_COEX_BLE_PRIO_PIN GPIO_PIN_7#如果定义(CFG_WLAN_COEX_DEBUG)/// BLE无线电覆盖信号引脚定义。///当BLE无线电由于外部2.4GHz设备活动而被迫关闭时,此信号变高。#定义WLAN_COEX_DEBUG_A_PORT GPIO_PORT_0#定义WLAN_COEX_DEBUG_A_PIN GPIO_PIN_9///外部2.4GHz设备EIP处理程序信号引脚定义。///该信号指示外部2.4GHz设备何时启动或停止发送数据。#定义WLAN_COEX_DEBUG_B_PORT GPIO_PORT_0#定义WLAN_COEX_DEBUG_B_PIN GPIO_PIN_8# endif其他#///设备输入信号:2.4GHz外部设备事件进展指示。#定义WLAN_COEX_24G_EIP_PORT GPIO_PORT_0#定义WLAN_COEX_24G_EIP_PIN GPIO_PIN_0///设备输出信号:BLE事件正在进行指示。#定义WLAN_COEX_BLE_EIP_PORT GPIO_PORT_0#定义WLAN_COEX_BLE_EIP_PIN GPIO_PIN_3///设备输出信号:BLE优先级指示。#定义WLAN_COEX_BLE_PRIO_PORT GPIO_PORT_0#定义WLAN_COEX_BLE_PRIO_PIN GPIO_PIN_2#如果定义(CFG_WLAN_COEX_DEBUG)/// BLE无线电覆盖信号引脚定义。//当BLE无线电由于外部2.4GHz设备活动而被迫关闭时,该信号会升高。#定义WLAN_COEX_DEBUG_A_PORT GPIO_PORT_0#定义WLAN_COEX_DEBUG_A_PIN GPIO_PIN_1///外部2.4GHz设备EIP处理程序信号引脚定义。///该信号指示外部2.4GHz设备何时启动或停止发送数据。#定义WLAN_COEX_DEBUG_B_PORT GPIO_PORT_1#定义WLAN_COEX_DEBUG_B_PIN GPIO_PIN_3# endif# endif// GPIO IRQ号。当2.4GHz外部设备正在进行的事件信号被激活时,中断被触发。#定义WLAN_COEX_IRQ 4# endif/ / WLAN_COEX_ENABLED
在user_peri_setup .c中进行以下更改,以便正确启用WLAN共存特性:
添加所需的包含文件。包括
wlan_coex.h
在包含文件部分。
#如果(WLAN_COEX_ENABLED)# include“wlan_coex.h”# endif
添加以下全局变量定义(WLAN共存配置结构):
#如果(WLAN_COEX_ENABLED)// WLAN共存配置结构常量wlan_coex_cfg_twlan_coex_cfg={.ext_24g_eip_port=WLAN_COEX_24G_EIP_PORT,.ext_24g_eip_pin=WLAN_COEX_24G_EIP_PIN,.ble_eip_port=WLAN_COEX_BLE_EIP_PORT,.ble_eip_pin=WLAN_COEX_BLE_EIP_PIN,.ble_prio_port=WLAN_COEX_BLE_PRIO_PORT,.ble_prio_pin=WLAN_COEX_BLE_PRIO_PIN,#如果定义(CFG_WLAN_COEX_DEBUG).debug_a_port=WLAN_COEX_DEBUG_A_PORT,.debug_a_pin=WLAN_COEX_DEBUG_A_PIN,.debug_b_port=WLAN_COEX_DEBUG_B_PORT,.debug_b_pin=WLAN_COEX_DEBUG_B_PIN,# endif.硬中断请求优先级别=WLAN_COEX_IRQ,};# endif
通过在内部添加以下代码块来保留模块使用的gpio
GPIO_reservations ()
功能:
#如果(WLAN_COEX_ENABLED)RESERVE_GPIO(COEX_EIP,wlan_coex_cfg.ble_eip_port,wlan_coex_cfg.ble_eip_pin,PID_GPIO);RESERVE_GPIO(COEX_PRIO,wlan_coex_cfg.ble_prio_port,wlan_coex_cfg.ble_prio_pin,PID_GPIO);RESERVE_GPIO(COEX_REQ,wlan_coex_cfg.ext_24g_eip_port,wlan_coex_cfg.ext_24g_eip_pin,PID_GPIO);#如果定义(CFG_WLAN_COEX_DEBUG)RESERVE_GPIO(DEBUGPIN1,wlan_coex_cfg.debug_b_port,wlan_coex_cfg.debug_b_pin,PID_GPIO);RESERVE_GPIO(DEBUGPIN2,wlan_coex_cfg.debug_a_port,wlan_coex_cfg.debug_a_pin,PID_GPIO);# endif
调用
wlan_coex_gpio_cfg ()
函数的末尾set_pad_functions ()
初始化模块使用的GPIO,并配置2.4GHz外部设备正在进行的事件信号作为GPIO中断。
#如果(WLAN_COEX_ENABLED)wlan_coex_gpio_cfg();# endif
最后但并非最不重要的是,应该提到的是在
user_proxr.c
以初始化WLAN-BLE共存模式,并设置WLAN模块的BLE优先级。添加所需的包含文件。包括
wlan_coex.h
而且lld.h
在包含文件部分。
#如果(WLAN_COEX_ENABLED)# include“wlan_coex.h”# include“lld.h”# endif
电话里面
user_on_init ()
以下功能:wlan_coex_init ()
,以初始化WLAN-BLE共存模式;wlan_coex_prio_criteria_add ()
功能,配置WLAN共存特性的规则。
#如果(WLAN_COEX_ENABLED)wlan_coex_init();//为特定连接添加优先级casewlan_coex_prio_criteria_add(WLAN_COEX_BLE_PRIO_ADV,LLD_ADV_HDL,0);# endif
最后调用
wlan_coex_going_to_sleep ()
函数内部user_validate_sleep ()
以便准备WLAN COEX模式进入睡眠状态。
#如果(WLAN_COEX_ENABLED)wlan_coex_going_to_sleep();# endif