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

表20 DA14585/586开发模式外围引脚映射

接口

信号

一步一个

步骤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


表21 DA14585/586开发模式周边搜索序列

序列

行动

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


表22 DA14531引导顺序步骤

步骤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.3.启动顺序

DA14585的引导顺序如图所示图61

. . / _images / booting-image1.png

图61DA14585引导顺序

DA14586的引导顺序如图所示图62

. . / _images / booting-image2.png

图62DA14586引导顺序

DA14531的引导顺序如图所示图63

. . / _images / booting-image3.png

图63DA14531引导顺序

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时钟应该在每个字节之后暂停。

表23 引导协议- DA14585/586/531作为SPI Slave

字节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被设置为输入和下拉。

表24 SPI主数据通信

槽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

    表25 引导协议

    字节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消

    1. 协议从传输0x02 (Start TX - STX)的DA14585/586 UART TX引脚开始。

    2. 外部设备被期望用0x01(报头开始- SOH)来回答。

      1. 如果基本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)回答。

      2. 如果至少有一个基本LEN_LSB或LEN_MSB字节不为零,则SW映像低于64kbyte。这些字节定义了下载的SW映像的长度。

        DA14585/586回答0x06 (ACK)如果已经接收到3个字节并且已经识别出SOH,或者回答0x15 (NACK)如果发生了任何错误。

  • DA14531

    表26 引导协议

    字节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

表27 RAM词对齐

地址

字节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主

    表28 引导协议

    字节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. 如果长度的扩展字节等于1,那么SW下载的图像大小将等于或大于64kbyte。图像长度根据以下公式计算:

      • length = 64 KByte +由LEN_MSB和LEN_LSB字节定义的额外长度。

    2. 如果长度的扩展字节不等于1,那么SW下载的图像大小将低于64kbyte。图像长度由LEN_MSB和LEN_LSB字节定义。

  • DA14531作为SPI的主人

    表29 引导协议

    字节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

表30 SPI读和虚字节用例

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主控

    表31 引导协议

    字节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

    代码数据

    读取命令

    1. 如果基本LEN_LSB和LEN_MSB字节均为零,则SW映像等于或大于64kbyte。以下两个扩展LEN_LSB和LEN_MSB字节定义了64 KByte边界上的额外图像长度。在这种情况下,下载的SW图像的长度由以下公式计算:

      • 长度= 64KByte +由定义的附加长度扩展LEN_MSB和LEN_LSB字节。

      Byte-4应1。Byte-7包括CRC字节(仅通过代码计算)。

    2. 如果至少有一个基本LEN_LSB或LEN_MSB字节不为零,则SW映像低于64kbyte。这些字节定义了下载的SW映像的长度。

      Byte-4包括CRC字节(仅通过代码计算)。

  • DA14531作为I2C主机

    表32 引导协议- 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

. . / _images / secondary-bootloader-file-structure.png

图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中。辅助引导加载程序执行以下操作:

  1. 在主功能中,辅助引导加载程序用最大值重新加载看门狗定时器,并配置看门狗定时器在过期时触发HW重置。

    SetBitsWATCHDOG_CTRL_REGNMI_RST1);// WDOG将在过期时生成HW重置SetWord16WATCHDOG_REG0 xff);/ /重置WDOGSetWord16RESET_FREEZE_REGFRZ_WDOG);/ /开始WDOG
  2. 初始化系统。

    system_init();
  3. 如果启用了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。

根据以下步骤为相同的目标构建辅助引导加载程序映像:

  1. 打开Secondary Bootloader项目:

    • 凯尔5:\工具\ secondary_bootloader \ secondary_bootloader.uvprojx

  2. 根据章节配置项目6.2.2.2节

  3. 编译项目以生成可执行文件secondary_bootloader_585.hex.这个文件在目录中<事业\ secondary_bootloader \ out_DA14585 \对象

6.2.4.2.正在写入应用程序十六进制文件到SPI闪存

SmartSnippetsSPI Flash程序员工具用于下载应用程序映像文件到连接到DA14585/586/531的外部SPI Flash存储器。

下面的说明演示了如何使用SmartSnippets工具箱当连接DA14585设备时,处于UART模式。

  1. 开放SmartSnippets并选择芯片版本。

    . . / _images / secondary-bootloader-Open-SmartSnippets-and-select-the-chip-version.png

    图65选择芯片版本

  2. 打开板设置工具,并选择适当的UART和SPI闪光引脚配置如图所示图66

    . . / _images / secondary-bootloader-board-setup.png

    图66板设置

  3. 打开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。使用这种设置,可以测量最大引导时间。

    . . / _images / secondary-bootloader-write-SPI-flash.png

    图67SPI Flash程序员

6.2.4.3.正在写入引导加载程序十六进制文件到OTP内存

SmartSnippetsOTP程序员工具支持将默认固件下载到系统RAM中,并将用户定义的HEX或BIN文件写入OTP内存中。该工具可用于在DA14585/586/531的OTP内存中写入辅助引导加载程序。

编写可执行文件需要接下来的步骤secondary_bootloader_585.hex进入OTP内存SmartSnippets在UART模式:

  1. 开放SmartSnippets并选择芯片版本。

    . . / _images / writing-hex-open-SS.png

    图68开放的党卫军工具箱

  2. 打开板设置工具并选择适当的UART配置。

    . . / _images / writing-hex-UART-setup.png

    图69板设置

  3. 打开OTP程序员工具,并选择要下载的镜像文件。

    . . / _images / writing-hex-in-OTP-programmer.png

    图70OTP程序员

  4. 燃烧的secondary_bootloader_585.hex输入OTP内存的偏移量为0。启用应用程序标志1和应用程序标志2,设置DMA长度(长度= size / 4)并刻录OTP

    . . / _images / writing-hex-in-OTP.png

    图71OTP程序员

请注意

有关SmartSnippets工具箱的更多信息,请参阅“SmartSnippets工具箱,用户手册”。

6.2.4.4.mkimage工具

mkimage工具是一个命令行Windows应用程序,根据双映像引导加载程序指定的内存映射格式化非易失性内存。

该工具支持两个用例:

  • 单一的图片:创建二进制应用程序映像文件(* img),它包含应用程序映像头文件和应用程序固件。

  • 多部分图片:将外部非易失性存储器的全部内容创建为一个由多个部分组成的二进制映像文件(* img),可以将其写入非易失性内存SmartSnippets工具箱

的源代码mkimage工具在文件夹中\工具\ mkimageSDK。

6.2.4.4.1.创建应用镜像文件

创建应用程序映像文件的命令行语法(* img)是:

mkimageexe<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),而非易失性记忆体的全部内容为:

mkimageexespi|eepm<bloader><in_img1><off1><in_img2><远比><off3>cfgoff4[,bdaddr]]<out_file>

指示工具创建二进制图像文件(* img)与SPI闪存(选项:SPI)或I2C EEPROM(选项:EEPROM)的全部内容。

多部分图像包括:

  1. AN-B-001头加上偏移量为0的引导加载程序固件,如果提供

  2. < img1 > (* img图像)在偏移量

  3. < img2 >(*。img图像)在偏移量

  4. 产品标头位于偏移量

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项目

构建固件的步骤

  1. 打开文件夹< sdk_root_directory > \ \ target_apps \ prod_test \ prod_test项目

  2. 打开项目。

  3. 选择菜单项目->重建所有目标文件来构建项目。

  4. 获取生成的十六进制文件:

  • 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.4.1.开关- h

描述:在命令行终端打印出prodtest的所有命令

语法prodtest- h

6.3.4.2.开关- p

描述:选择PC的COM端口号。所有命令都需要此开关。

语法prodtest- p< COM_PORT_NUMBER >...

6.3.4.3.开关- v

描述:显示工具版本信息

语法prodtest- v

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_correctly8529nb_packets_with_syncerror0nb_packets_received_with_crcerr1rssi-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_packets0

输出示例(当执行start_pkt_rx之后):

状态0number_of_packets4360

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_value500

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毫秒高平方脉冲作为校准微调值的参考。该过程执行以下步骤:

  1. 校准XTAL16M修边寄存器。

  2. 在OTP中编程校准值(地址0x7F8C)。

  3. 在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

表33 DA1585/586扩展和深度睡眠模式的功率域操作

电源模式

PD_SYS

PD_PER

PD_DBG

PD_RAD

PD_SRx

模拟

扩展/深度睡眠

汽车了

可编程的

汽车了

可编程的

可编程的

汽车了


表34 DA14531扩展和深度睡眠模式的功率域操作

电源模式

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_value500

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_bdaddr4449414c4 f47

输出示例

状态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

输出示例

状态07 f直流1234A5A57 fE0A5A512347 fE4141211177 fE8242221277 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总结了产品测试工具的返回代码。

表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字节来改变。这个字节根据下表选择引脚和波特率。

表36 DA14585/586/531的UART选项

平台

选择器

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发送命令包,格式如下:

表37 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变量。信息结构如下:

表38 内存布局在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

表39 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

记忆的内容

0

1

...

对象所指向的数据缓冲区中TARGET_MEMORY变量时适用。

请注意

主机以相对于BASE_MEMORY变量中保存的起始地址的一定偏移量写入包节。编写操作代码应该是最后一步,因为这会触发目标平台上的操作。一旦处理了消息并填充了Result部分中的响应,Op Code值就会变回0。这样,主机就知道什么时候读取触发动作的结果。与通过UART交换的消息类似,响应结构依赖于主机发送的命令。

DA14585/586/531平台、内存地址和偏移量按下表设置:

表40 内存地址和偏移量

平台

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_READYBASE_MEMORY+RESULT_OFFSET内存地址。主机应用程序可以监视这个内存地址以进行检测flash_programmer准备就绪。

6.4.4.4.消息

注意,下面的消息列表没有列出报头部分(Length, CRC),这是随协议交换的每个UART消息一起发送的。

6.4.4.4.1.一般
ACTION_READ_VERSION

(0x10) -读取flash程序员应用程序版本

UART:

表41 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

0 x07

儿童权利公约

0 x10

表42 UART_RESPONSE

Len(16位)

CRC(32位)

Op的代码

0 x0d

儿童权利公约

0 x82

JTAG:

表43 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

ACTION_OFFSET

0 x10 (ACTION_READ_VERSION)

0 x00 (NO_ACTION)

SIZE_OFFSET

不在乎

不在乎

ADDRESS_OFFSET

不在乎

不在乎

RESULT_OFFSET

不在乎

0 x82 (ACTION_CONTENTS)

表44 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

0

不在乎

v

1

不在乎

_

2

不在乎

5

...

不在乎

...

ACTION_VPP_ENABLE

(0x50) -当OTP内存写入时,使能控制高压(6.8v)的晶体管。

UART:

表45 UART_REQUEST

Len(16位)

CRC(32位)

操作码(8位)

VPP_ENABLE(8位)

0 x02

儿童权利公约

0×50

0 x00或0 x01

表46 UART_RESPONSE

Len(16位)

CRC(32位)

状态(8位)

0 x01

儿童权利公约

0x83 (ACTION_OK)或0x84 (ACTION_ERROR)

ACTION_READY

(0x5A) -当以共享内存模式(JTAG)运行时,这只被固件用来通知主机目标已经准备好处理主机请求。

JTAG:

表47 内存布局在BASE_MEMORY地址

内存偏移量

未准备好时的内存内容

准备好后的内存内容

ACTION_OFFSET

不在乎

不在乎

SIZE_OFFSET

不在乎

不在乎

ADDRESS_OFFSET

不在乎

不在乎

RESULT_OFFSET

0 x00

0 x82 (ACTION_READY)

ACTION_UART_GPIOS

(0x31) -配置UART数据线。如果引脚错误,返回ACTION_ERROR。

UART:

表48 UART_REQUEST

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

表49 UART_RESPONSE

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:

表50 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

地址偏移(32位)

长度(16位)

Len(16位)

CRC(32位)

0 x07 +长度

儿童权利公约

0 x80

抵消

长度

0 x07 +长度

儿童权利公约

表51 UART_RESPONSE

Len(16位)

CRC(32位)

状态(8位)

数据……

0x01 +数据长度

儿童权利公约

0 x82 (ACTION_CONTENTS)

读取数据

JTAG:

表52 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

ACTION_OFFSET

0 x80 (ACTION_OTP_READ)

0 x00 (NO_ACTION)

SIZE_OFFSET

数据长度

数据长度

ADDRESS_OFFSET

地址偏移量

地址偏移量

RESULT_OFFSET

不在乎

0 x82 (ACTION_CONTENTS)

表53 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

0

不在乎

data0

1

不在乎

data1

2

不在乎

data2

...

不在乎

data3

ACTION_OTP_WRITE

(0x81) -将请求的数据量写入给定偏移量的OTP内存中。

UART:

表54 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

地址偏移(32位)

长度(16位)

数据(长* 8位)

0 x07 +长度

儿童权利公约

0 x81

内存地址

长度

数据写

表55 UART_RESPONSE

Len(16位)

CRC(32位)

状态(8位)

错误码(32位)

0 x01 x05或0

儿童权利公约

0x83 (ACTION_OK)或0x84 (ACTION_ERROR)

附加错误码-仅当Status设置为ACTION_ERROR时。

JTAG:

表56 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

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时

表57 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

0

data0

data0

1

data1

data1

2

data2

data2

...

data3

data3

6.4.4.4.3.SPI闪光
ACTION_SPI_READ

(0x90) -从给定内存地址的SPI FLASH内存中读取请求的数据量。

UART:

表58 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

地址偏移(32位)

长度(16位)

数据(长* 8位)

0 x07 +长度

儿童权利公约

0 x90

内存地址

长度

数据写

表59 UART_RESPONSE

Len(16位)

CRC(32位)

状态(8位)

数据……

0x01 +数据长度

儿童权利公约

0 x82 (ACTION_CONTENTS)

读取数据

JTAG:

表60 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

ACTION_OFFSET

0 x90 (ACTION_SPI_READ)

0 x00 (NO_ACTION)

SIZE_OFFSET

数据长度

数据长度

ADDRESS_OFFSET

地址

地址

RESULT_OFFSET

不在乎

0 x82 (ACTION_CONTENTS)

表61 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

0

不关心| data0

1

不关心| data1

2

不关心| data2

...

不关心| data3

ACTION_SPI_WRITE

(0x91) -将请求的数据量写入给定偏移量的SPI FLASH内存。

UART:

表62 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

地址偏移(32位)

长度(16位)

数据(长* 8位)

0 x07 +长度

儿童权利公约

0 x91

内存地址

长度

数据写

表63 UART_RESPONSE

Len(16位)

CRC(32位)

状态(8位)

错误码(32位)

0 x01 x05或0

儿童权利公约

0x83 (ACTION_OK)或0x84 (ACTION_ERROR)

附加错误码-仅当Status设置为ACTION_ERROR时。

JTAG:

表64 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

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时

表65 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

0

data0

data0

1

data1

data1

2

data2

data2

...

data3

data3

ACTION_SPI_ERASE

(0x92) -删除SPI FLASH内存。

UART:

表66 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

0 x01

儿童权利公约

0 x92

表67 UART_RESPONSE

状态(8位)

错误码(32位)

状态(8位)

错误码(32位)

0 x01 x05或0

儿童权利公约

0x83 (ACTION_OK)或0x84 (ACTION_ERROR)

附加错误码-仅当Status设置为ACTION_ERROR时。

JTAG:

表68 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

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:

表69 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

0 x01

儿童权利公约

0 x93

表70 UART_RESPONSE

Len(16位)

CRC(32位)

状态

(8位)

制造商ID(8位)

JEDEC ID 1(8位)

0 x05

儿童权利公约

0 x82 (ACTION_C内容)

0

id

id

JTAG:

表71 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

ACTION_OFFSET

0 x93 (ACTION_EEPROM_READ)

0 x00 (NO_ACTION)

SIZE_OFFSET

不在乎

不在乎

ADDRESS_OFFSET

不在乎

不在乎

RESULT_OFFSET

不在乎

0 x82 (ACTION_CONTENTS)

表72 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

0

不在乎

设备ID byte 2

1

不在乎

设备ID byte 1

2

不在乎

制造商ID

3.

不在乎

0

ACTION_SPI_ERASE_BLOCK

(0x94) -从flash地址开始删除指定数量的扇区。

UART:

表73 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

地址(32位)

部门(16位)

0 x07

儿童权利公约

0 x94

地址

n

表74 UART_RESPONSE

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:

表75 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

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:

表76 UART_REQUEST

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

表77 UART_RESPONSE

Len(16位)

CRC(32位)

状态

0 x01

儿童权利公约

0x83 (ACTION_OK)或0x84 (ACTION_ERROR)

JTAG:

表78 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

ACTION_OFFSET

0 x95 (ACTION_SPI_GPIOS)

0 x00 (NO_ACTION)

SIZE_OFFSET

不在乎

不在乎

ADDRESS_OFFSET

不在乎

不在乎

RESULT_OFFSET

不在乎

0x83 (ACTION_OK)或0x84 (ACTION_ERROR)

表79 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

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:

表80 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

大小(24位)

0 x04

儿童权利公约

0 x96

0 x012345

表81 UART_RESPONSE

Len(16位)

CRC(32位)

状态

0 x01

儿童权利公约

0x83 (ACTION_OK)或0x84 (ACTION_ERROR)

JTAG:

表82 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

ACTION_OFFSET

0 x96 (ACTION_SPI_HEADER)

0 x00 (NO_ACTION)

SIZE_OFFSET

不在乎

不在乎

ADDRESS_OFFSET

不在乎

不在乎

RESULT_OFFSET

不在乎

0x83 (ACTION_OK)或0x84 (ACTION_ERROR)

表83 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

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:

表84 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

地址(32位)

大小(16位)

0 x07

儿童权利公约

0 xa0

地址

n

表85 UART_RESPONSE

Len(16位)

CRC(32位)

状态(8位)

数据……

0x01 +数据长度

儿童权利公约

0 x82 (ACTION_CONTENTS)

读取数据

JTAG:

表86 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

ACTION_OFFSET

0 xa0 (ACTION_EEPROM_READ)

0 x00 (NO_ACTION)

SIZE_OFFSET

n

不在乎

ADDRESS_OFFSET

地址

不在乎

RESULT_OFFSET

不在乎

0 x82 (ACTION_CONTENTS)

表87 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

0

不在乎

数据字节1

1

不在乎

数据字节2

...

不在乎

n - 1

不在乎

数据字节n

ACTION_EEPROM_WRITE

(0xA1) -写入n字节的数据到I2C EEPROM的指定地址。

UART:

表88 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

地址偏移(32位)

长度(16位)

数据(长* 8位)

0 x07 +长度

儿童权利公约

0最后

内存地址

长度

数据写

表89 UART_RESPONSE

Len(16位)

CRC(32位)

状态

0 x01

儿童权利公约

0 x83 (ACTION_OK)

表90 UART_RESPONSE

Len(16位)

CRC(32位)

状态

错误码(32位)

0 x05

儿童权利公约

0 x84 (ACTION_ERROR)

错误代码

JTAG:

表91 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

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

不在乎

错误代码

表92 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

0

数据字节1

不在乎

1

数据字节2

不在乎

...

不在乎

n - 1

数据字节n

不在乎

ACTION_I2C_GPIOS

(0xA3)—配置I2C数据线。如果引脚错误,返回ACTION_ERROR。

UART:

表93 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

地址偏移(32位)

长度(16位)

数据(长* 8位)

0 x07 +长度

儿童权利公约

0 xa3

内存地址

长度

数据写

表94 UART_RESPONSE

Len(16位)

CRC(32位)

状态

0 x01

儿童权利公约

0x83 (ACTION_OK)或0x84 (ACTION_ERROR)

JTAG:

表95 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

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)

表96 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

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:

表97 UART_REQUEST

Len(16位)

CRC(32位)

Op的代码

大小(24位)

0 x07 +长度

儿童权利公约

0 xa4

内存地址

表98 UART_RESPONSE

Len(16位)

CRC(32位)

状态

0 x01

儿童权利公约

0x83 (ACTION_OK)或0x84 (ACTION_ERROR)

JTAG:

表99 内存布局在BASE_MEMORY地址

内存偏移量

请求内存内容

响应内存内容

ACTION_OFFSET

0 xa4 (ACTION_I2C_HEADER)

0 x00 (NO_ACTION)

SIZE_OFFSET

不在乎

不在乎

ADDRESS_OFFSET

不在乎

不在乎

RESULT_OFFSET

不在乎

0x83 (ACTION_OK)或0x84 (ACTION_ERROR)

表100 TARGET_MEMORY地址的数据缓冲区内存布局

内存偏移量

请求内存内容

响应内存内容

0

0 x45(大小LSB)

不在乎

1

0 x23

不在乎

2

0 x01大小(MSB)

不在乎

3.

不在乎

不在乎

6.4.4.4.5.响应状态

以下代码用于通信由主机触发的操作的结果。

ACTION_CONTENTS

(0x82) -返回数据时的普通状态。

ACTION_OK

(0x83) -普通成功状态。

ACTION_ERROR

(0x84) -常见错误状态。

ACTION_DATA

(0x85) -未使用。

ACTION_INVALID_COMMAND

(0x86) -当目标接收到未知命令时发送到主机。

ACTION_INVALID_CRC

(0x87) -如果CRC与消息内容不匹配,可以通过UART发送作为对任何请求的响应。

6.5.正在写入十六进制文件到OTP内存

SmartSnippetsOTP程序员工具允许下载默认固件到系统RAM,并将用户定义的HEX或BIN文件写入OTP内存。该工具可用于在DA14585/586/531的OTP内存中写入辅助引导加载程序。

编写可执行文件需要以下步骤secondary_bootloader_585.hex进入OTP内存SmartSnippets在UART模式:

  1. 开放SmartSnippets并选择芯片版本。

. . / _images / writing-hex-open-SS.png

图72开放的党卫军工具箱

  1. 打开板设置工具并选择适当的UART配置。

. . / _images / writing-hex-UART-setup.png

图73板设置

  1. 打开OTP程序员工具,并选择要下载的镜像文件。

. . / _images / writing-hex-in-OTP-programmer.png

图74OTP程序员

  1. 燃烧的secondary_bootloader_585.hex输入OTP内存的偏移量为0。启用应用程序标志1和应用程序标志2,设置DMA长度(长度= size / 4)并刻录OTP

. . / _images / writing-hex-in-OTP.png

图75OTP程序员

请注意

有关SmartSnippets工具箱的更多信息,请参阅“SmartSnippets Toolbox用户手册”。

6.6.BLE与其他2.4GHz无线电共存

本章的目的是描述启用DA14585/586/531的WLAN共存支持的主要步骤。

6.6.1.简介

. . / _images / wlan_coex_setup.png

图76WLAN与BLE共存

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固件内部控制,遵循特定的用户可配置规则。下表列出了所有可用的优先级。

表101 WLAN共存特性的优先级配置命令

规则

命令

优先级类型

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文件。

. . / _images / wlan_coex_include_path.png

图77WLAN COEX包含路径

  • 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_cfgext_24g_eip_portWLAN_COEX_24G_EIP_PORText_24g_eip_pinWLAN_COEX_24G_EIP_PINble_eip_portWLAN_COEX_BLE_EIP_PORTble_eip_pinWLAN_COEX_BLE_EIP_PINble_prio_portWLAN_COEX_BLE_PRIO_PORTble_prio_pinWLAN_COEX_BLE_PRIO_PIN#如果定义(CFG_WLAN_COEX_DEBUG)debug_a_portWLAN_COEX_DEBUG_A_PORTdebug_a_pinWLAN_COEX_DEBUG_A_PINdebug_b_portWLAN_COEX_DEBUG_B_PORTdebug_b_pinWLAN_COEX_DEBUG_B_PIN# endif硬中断请求优先级别WLAN_COEX_IRQ};# endif
  • 通过在内部添加以下代码块来保留模块使用的gpioGPIO_reservations ()功能:

#如果(WLAN_COEX_ENABLED)RESERVE_GPIOCOEX_EIPwlan_coex_cfgble_eip_portwlan_coex_cfgble_eip_pinPID_GPIO);RESERVE_GPIOCOEX_PRIOwlan_coex_cfgble_prio_portwlan_coex_cfgble_prio_pinPID_GPIO);RESERVE_GPIOCOEX_REQwlan_coex_cfgext_24g_eip_portwlan_coex_cfgext_24g_eip_pinPID_GPIO);#如果定义(CFG_WLAN_COEX_DEBUG)RESERVE_GPIODEBUGPIN1wlan_coex_cfgdebug_b_portwlan_coex_cfgdebug_b_pinPID_GPIO);RESERVE_GPIODEBUGPIN2wlan_coex_cfgdebug_a_portwlan_coex_cfgdebug_a_pinPID_GPIO);# endif
. . / _images / changes_in_GPIO_reservations_function.png

图78GPIO_reservations()函数中的更改

  • 调用wlan_coex_gpio_cfg ()函数的末尾set_pad_functions ()初始化模块使用的GPIO,并配置2.4GHz外部设备正在进行的事件信号作为GPIO中断。

#如果(WLAN_COEX_ENABLED)wlan_coex_gpio_cfg();# endif
. . / _images / changes_in_set_pad_functions.png

图79set_pad_functions变化()

  • 最后但并非最不重要的是,应该提到的是在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_addWLAN_COEX_BLE_PRIO_ADVLLD_ADV_HDL0);# endif
  • 最后调用wlan_coex_going_to_sleep ()函数内部user_validate_sleep ()以便准备WLAN COEX模式进入睡眠状态。

#如果(WLAN_COEX_ENABLED)wlan_coex_going_to_sleep();# endif
. . / _images / changes_in_user_proxr_file.png

图80user_proxr.c文件中的更改