CC1310手册的射频核心介绍

最近在使用CC1310的射频核心传进行无线数据收发任务,由于是第一次接触到射频方面的知识,阅读CC1310手册也费了不少劲,于是想着既然看了不如做些记录,于是有了本篇翻译性质的文章。

阅读到一半突然一些感言,CC1310手册中的内容大多是建立在某些底层通信协议的基础之上的,并不会涵盖很多通信协议方面的知识,如果向了解某些协议,比如蓝牙,zigbee原理方面的知识,阅读本片文章并不能对该方面有半点提升,手册中讲述的内容多半是建立在通信协议之上的偏向于应用的知识,如果是向了解CC1310是如何实现系统CPU和射频CPU通信,射频CPU又是如何处理发送前的数据的,则可以CC1310的手册,本篇文章难免带有个人主观理解,若想请配合CC1310手册一起阅读,或许会加快手册内容的理解,另外如有错误,恳请大家即时指认,希望可以和大家一起学习一起进步,感谢~



射频核心包含一个ARM Cortex-M0处理器(连接模拟射频和内部电路),该核心处理来自系统端的数据,并在给定的包结构中组装信息位。

射频核心为系统CPU (ARM®Cortex®-M3)提供了一个高级的、基于命令的应用程序接口(API)。射频核心可以自主地按照无线电协议(802.15.4 RF4CE和ZigBee®、蓝牙®低能耗等)的严格时序要求完成任务,从而减轻系统CPU负担,为用户应用程序留下更多资源。

射频核心有一个专用的4 kb SRAM块,几乎完全从单独的ROM运行。

此处对在下文中提到的一些中文释义做出说明:

中文释义英文原义含义
无线电Radio修饰一些器件,表明该器件是存在于射频核内部的
武装ARM使被配置的RAT通道可以产生中断事件
条目Entry在数据队列中用于存储数据包的基本单位
条目元素Entry element一个条目元素对于着一个射频数据包
一个条目中可以有多个条目元素

一、概述

1、射频核的基本特性

CPU与RF Core之间的事务处理有一个通用的架构,这个架构使得RF核心必须有以下几个特性:

射频核心可以直接访问系统的RAM,可以从中读取命令或数据,也可以将接收到的数据写入到系统RAM中。出于协议机密性和认证支持的目的,射频核心也可以访问安全子系统。

一般情况下,射频核心识别来自系统CPU的复杂命令(CCA传输、RX自动确认等),并将其划分为若干子命令,而无需系统CPU的进一步干预。
射频核的概述和外部依赖如下图所示:​​Alt
其中被框起来的是射频核内部的基本结构,可以看到CPU和RF CPU都处于同一条总线上,并且RF CPU可以通过总线与外部的RAM, Security subsystem通信,这里只需要有个大体的认识就好

二、无线电门铃(Radio Doorbell)

无线电门铃模块(RFC_DBELL)是系统CPU和无线电CPU之间的主要通信手段,也被称为Command and Packet engine(CPE)

无线电门铃包含一组专用的寄存器和一组到CPU和RF CPU中的中断。

此外,射频配置参数和传输数据通过系统RAM或无线电RAM传输。需要注意的是,如果参数或数据是存在系统RAM中的,系统CPU必须在RF工作时处于正常工作状态,若这些参数或数据都是存在无线电RAM中的,在RF核工作时,系统CPU可以进入掉电模式。

在RF核运作期间,无线电CPU会更新存在RAM中的相关参数和传输数据,并引发中断。这些中断是可以被系统CPU屏蔽(Mask out)的,因此这保证了在无线电操作全部完成前,系统CPU可以一直处于空闲或掉电状态。

因为系统CPU和无线电CPU共享一个公共RAM区域,所以要确保不会发生争用或竞用情况。这是通过在无线电硬件抽象层(HAL)中建立的规则在软件中实现的。

下图是无线电硬件抽象层的硬件支持图:
Alt
从硬件支持图中可以看到很多有用的信息,下面将对这些内容进行详细介绍

1、命令和状态寄存器

  • CMDR:射频命令通过CMDR寄存器发送到无线电
  • CMDSTA:只读寄存器,CMDSTA会提供从无线电执行命令后返回的状态

CMDR寄存器只能在读取其为0时才能被写入,否则此次写操作被忽略。当CMDR寄存器为0并写入一个非零值时,无线电CPU将被通知通知,CMDSTA寄存器变为0。在此之后,从CMDR寄存器写入的值是可读的,直到无线电CPU处理完该命令,会再次将CMDR清零,允许下一条命令写入。

当该命令被无线电CPU处理后,CMDSTA寄存器包含一个非零状态,这是在CMDR寄存器返回0时提供的。同时发生RFCMDACK中断。这个中断也被映射到RFACKIFG寄存器,当中断已被处理时RFACKIFG寄存器被清零。

2、射频核的中断

射频核可以产生的中断主要有以下四种,这四种中断均有无线电门铃控制:

  • RF_CPE0 (interrupt number 9
  • RF_CPE1 (interrupt number 2)
  • RF_HW (interrupt number 10)
  • RF_CMD_ACK (interrupt number 11)

2.1 射频命令和数据包引擎中断

射频命令和数据包引擎(RF Command and Packet Engine)可以产生许多低级中断,这些低级中断都可以使用RFCPEISL寄存器映射到RF_CPE0和RF_CPE1中。
此外,可以使用RFCPEIEN寄存器在系统级上切换中断生成。

在触发某个低级中断的情况下,RFCPEIFG寄存器中的相应位被设置为1。当RFCPEIFG中的一个位和RFCPEIEN中的相应位都为1时,将引发在RFCPEISL中选择的系统级中断。这意味着中断服务程序(ISR)必须清除RFCPEIFG中与已处理的低级中断相对应的位,即向该位写入0。

注意:这里对RFCPEIFG寄存器的清楚操作并非常规的“读-改-写”操作,因为在该操作期间,随时可能有新的中断产生,这意味着可能会有中断丢失的风险,我们不允许这种情况发生。因此,实际中清除一个中断标志位的方法应该是: HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFCPEIFG) = ~(1 << irq_no)​;

2.2 射频核硬件中断

系统级中断RF_HW可以由射频核心硬件产生的许多低级中断产生 。

这些中断的中断源的开启或关闭是由RFHWIEN控制的,开启中断源时中断产生的必要条件。

在触发低级中断的事件的情况下,RFHWIFG寄存器中的相应位被设置为1。此时RFHWIEN和RFHWIFG的相应位都被置为1,相关的RF_HW中断产生。
当该中断被处理后,ISR需要清除掉RFHWIFG中的相应位。

但是TI并不建议在主CPU中服务这些中断,但可用的无线电计时器通道中断可以通过这种方式服务。

2.3 射频核命令响应中断

当RF核心命令被确认时(CMDSTA=1),系统级中断RF_CMD_ACK产生。

当CMDSTA=1,即状态变为可用时,RFACKIFG.ACKFLAG寄存器位被设置为1。当此位为1时,将引发RF_CMD_ACK中断,这意味着ISR必须清除RFACKIFG.ACKFLAG位来清除RF_CMD_ACK中断。

3 无线电定时器

无线电有自己专用的定时器——Radio timer(RAT)模块。
RAT是一个32位的运行在4MHz上的自动运行定时器。
RAT拥有8个通道来进行比较和捕获模式,其中前五个为无线电CPU保留,剩余的三个5、6、7是可以被系统CPU使用的。

RAT只能在RF核上电时工作,并且RAT必须通过CMD_START_RAT 或 CMD_SYNC_START_RAT命令开始工作。
当执行延时启动命令或接收\发送模式的无线电操作命令时,必须要保证RAT已经被开启。

当RAT运行时,定时器的当前值可以从RATCNT寄存器中读取。

3.1 比较和捕获模式

只有可用的通道5.6.7可以设置为比较或捕获模式

比较模式

RAT的比较模式可以使用CMD_SET_RAT_CMP命令来设置

当RAT设置为比较模式时,计数器达到compareTime给定的值时,定时器产生一个中断。中断被映射到RFHWIFG。对于可用的RAT通道,正在使用的中断标志位为RATCH5,RATCH6和RATCH7。

另外,当计数器达到compareTime给定的值时,也可以控制I/O引脚的动作,这个在后面再说。

当CMD_SET_RAT_CMP命令发送后,compareTime的值存在所选信道的RATCHnVAL寄存器中。

捕获模式

捕获模式可用于捕获输入引脚上的转换,并在转换发生时记录RAT计数器的值。
捕获模式可以使用CMD_SET_RAT_CPT命令来设置。
当转换发生时,RAT的当前值被存储在与所选通道对应的RATCHnVAL寄存器中,同时计时器产生中断,与比较模式一样,该中断也会被映射到RFHWIFG中,中断标志位为RATCH5、RATCH6或RATCH7。

注意:RATCHnVAL中的值要即使取出并处理,否则很容易被下一时刻的中断覆盖

被比较模式或单捕获模式命令设置的通道可以武装或解除武装,当发送通道设置命令时,该通道自动武装,当有比较或捕获事件产生时,通道自动解除武装。解除武装的通道不会产生任何中断或导致任何计时器值被捕获,只有等到下一次配置命令产生时,通道才会被再次武装。

但是无论使武装或解除武装,该通道的配置都不会被清除。
因此,通道可以使用CMD_ARM_RAT_CH或CMD_DISARM_RAT_CH(见23.3.3.2.14到)来武装或解除。上述命令会使的之前对该通道的配置有效或失效。

3.2 RAT 输出

RAT模块有四种可控制的输出模式——RAT_GPO0~RAT_GPO3。
这些输出信号可以被某一个RAT通道控制,并通过SYSGPOCTL寄存器映射到I/O控制器(IOC)中。
RAT_GPO0被保存用于启动传输模式,由无线电CPU在内部控制。
其他三个信号可以使用CMD_SET_RAT_OUTPUT命令进行配置。除了always-0和always-1配置外,不同的输出模式决定了所选RAT通道发生中断时输出的转换。
always-0和always-1配置立即生效,并可用于初始化。

3.3 与RTC时钟的同步

当无线电掉电时,RAT模块并不会计数,但是为了保证某些同步协议能有一致的时间基准,可以将RAT与实时时钟(RTC)同步。
要在RF核上电后允许同步,CMD_SYNC_STOP_RAT命令必须在RF核下电之前发送。此命令(直到下一个RTC tick)停止RAT并返回一个参数rat0,该参数应该在重启RAT时存储并提供。
下一次RF核心上电和RAT启动时,必须使用CMD_SYNC_START_RAT进行同步,其中必须提供从CMD_SYNC_STOP_RAT获得的rat0参数。这个命令启动RAT,等待RTC滴答,并根据RTC数据修改RAT。
根据应用程序的不同,可能没有必要在每次关闭无线电时运行CMD_SYNC_STOP_RAT命令;之前的rat0值可以重用。然而,在某些情况下,如果无线电已经供电很长时间,而低频和高频晶体振荡器相对于彼此有很大的误差,这可能会引起问题。为了获得准确的同步,重要的是,系统运行在高频晶体振荡器上,在CMD_SYNC_START_RAT命令运行之前开始,并在CMD_SYNC_STOP_RAT命令完成之后继续运行。

三、射频核的硬件抽象层HAL

射频核心通过向系统CPU提供统一的HAL来隐藏无线电操作的复杂性。
注意下面的描述都不涉及射频的底层通信原理,所以工作都是在通信协议之上的高级语言。

1 硬件支持

无线HAL由硬件支持,通过射频核心区的无线电门铃模块和系统RAM中的命令描述符来实现。

2 固件支持

射频核心支持一套高级的通信语言,它使得射频核心与主CPU之间的通信都是建立在较高水平上的。

2.1 命令

无线电CPU允许用户从系统CPU运行一组高级语言或命令。
向CMDR寄存器写入命令后该命令就视为被系统CPU发布,无线电CPU会检查该命令并决定执行过程。

2.1.1 命令的分类

其命令类型主要有以下三种:

  • Radio operation command:无线电操作命令会导致射频核的硬件被访问,这种命令可以使射频核执行如:数据的发送、接收,设置射频核的硬件寄存器或执行更复杂的、依赖某些协议的操作。
  • Immediate command :即时命令是更改、请求无线电状态或操作TX\RX队列的命令。即时命令可以监视命令执行的状态,比如接收到的信号强度。即使命令可以在任何时刻被发布,但是一般情况下,我们仅在无线电操作命令执行过程中才会使用它来监控某种状态。
  • Direct command:直接命令是不带参数的即时命令,或只带有一两个字节的参数的,并且其带有的参数一般是执行的命令所需要的参数。
2.1.2命令在寄存器中的存储格式

根据命令的种类不同,被存入CMDR寄存器中的方式也不同
对于Radio operation 和 immediate 命令,CMDR包含一个指向命令结构的指针。该指针必须是一个32位字对齐的有效指针,因此两个最低有效位(lsb)必须为0 0,其结构如下所示。
在这里插入图片描述
Direct命令通过将2个lsb设置为01并放置命令ID号到CMDR寄存器的16~31位,CMDR中的第8位到第15位或者第2位到第15位可以用来存放可选的字节参数。Direct命令格式如下图所示。
在这里插入图片描述

2.1.3 命令的存储位置

CMDR寄存器为Radio operation和immediate命令时,其所指向的数据结构可以在系统RAM或无线电RAM中。

若使用射频核RAM作为命令的存储位置,系统CPU必须确保正在使用的内存区域是可自由访问的,特别是在使用无线电RAM时,其中一部分内存是预留给无线电CPU使用的。
可用的radio RAM信息可以通过CMD_GET_FW_INFO命令获得。

决定使用那种内存区域存放命令一般从设备有效性和功耗两方面考虑:

  • 无线电RAM 是Radio CPU最容易访问的地方,因此功耗也最低,但当Radio CPU掉电后,Radio RAM就会失效,因此需要考虑每次CPU掉电和上电时,必须保存的数据的转存到消耗的功耗。
  • 系统RAM在大多数低功耗模式下都具有数据保存能力。因此在系统侧掉电时,无线电CPU重新上电时也可以申请对系统RAM的访问。但无线电CPU访问系统RAM的功耗要大于无线电RAM。
  • Flash总是具有数据保存能力,但是Flash只能保存系统CPU写入的参数。无线电CPU访问Flash时必须保证系统CPU处于正常工做状态,且其功耗是要高于访问系统RAM的。
  • 通过将所有数据结构放在无线电RAM中,并在无线电CPU运行时将系统侧下电,可以获得最低的峰值功耗。在某些情况下,通过将数据结构放在系统RAM中,平均功耗可能会更低,因为在无线电CPU掉电时需要的复制的内容更少,而且系统侧仍然可以长时间断电。

2.2 命令状态

2.2.1 CMDSTA寄存器

当命令被发布后,CMDSTA寄存器会会在一定时间内被无线电CPU更新,并导致RFCMDACK中断返回到系统CPU。

这个更新发生在即时命令和直接命令完成之后或无线电操作命令被调度之后,在状态更新之前,其他命令无法发布。

CMDSTA寄存器是一个32位寄存器,其低8位给出了命令处理结果,其余的高24位可以用在具体的命令格式要求上,它最多可以传回三字节参数,其格式如下图所示:
在这里插入图片描述
其中Result的第7位表示是否有错误产生,0是没有错误,1表明有错误。
Result的值表达的含义,可由下表查看:
在这里插入图片描述
值得一提的是:结果字节0x00表示等待,在命令发布时由无线电门铃硬件自动产生,该状态会将CMDSTA寄存器全部清0,这是CMDSTA在引发RF_CMD_ACK中断前所具有的值。

2.2.2 命令结果中的状态

每个无线电操作命令都包含一段状态位,该状态位的值可以在命令执行的过程在被无线电CPU修改,并可以随时被系统CPU获取。
这段值包含以下几种状态:

  • Idle:命令还没开始执行
  • Pending:命令已经被解析,但还未开始触发
  • Active:命令正在被执行
  • Suspended:该命令一直处于活动状态,并且可能再次变为活动状态。该命令仅被部分IEEE 802.15.4命令支持。
  • Finished:命令已经完成,系统CPU可自由修改命令结构或释放内存
  • Skippped:命令已经被忽略,并且永远不会执行。

status状态位的数值对应的状态含义可以查看手册中的“Common Radio Operation Status Codes”表。

当系统CPU准备命令结构时,需要将status字段初始化为Idle。
如果有一组命令是被循环执行的,系统CPU在此过程中不能修改命令结构,直到无线电CPU变为空闲(即系统CPU收到一个LAST_COMMAND_DONE中断)。

2.3 中断

无线电CPU有32个软件中断源,它们可以在系统CPU中产生RFCPE0和RFCPE1中断,这些中断在RFCPEIFG寄存器的描述中列出。
中断标志寄存器可以指示哪个软件中断被触发,并且中断被单独启用。
此外,当CMDSTA更新时,RFCMDACK中断会自动触发。

一些软件定义的中断在所有命令中有一个共同的含义;还有一些中断是为每个使用特定中断的协议定义的。在使用中断时也要注意一些中断只在一个协议中使用,而有些中断能在几个协议中使用。

2.4 数据传播

通过射频传播数据的基本方式有两种:直接传播或通过队列传播。

传播数据最直接的方法是将其作为命令参数的一部分追加(直接或通过指针)。确切的格式取决于正在运行的命令。对于传输端而言,通常有一个长度字段和一个传输数据缓冲区;对于接收端而言,通常有一个最大长度,接收长度(如果是可变长度),和一个接收缓冲区。

对于某些操作,无法预先知道接收或传输的包的数量(或者在少数包中实际传输的是哪个包)。对于这种操作,使用队列的概念。一个操作可以使用一个或多个队列,例如,一个RX和一个TX队列用于组合的RX/TX操作,或者根据接收到的数据包中的信息使用多个队列。
任何使用队列的操作都使用一个公共系统来维护它们,这个在后面再说。

无线电操作命令会声明本次命令使用的数据传播类型。

2.5 命令调度器

射频命令的调度也是由系统CPU负责。当系统CPU工作在低功耗模式下时,系统CPU会根据RTC在下一个操作命令开始前的短时间内唤醒。

无线电操作命令可以通过延迟启动来调度。如果命令是延迟启动的方式,在延迟期间无线电CPU将进入空闲模式,直到命令启动。但注意在此延迟期间内无线电操作命令被认为正在运行状态,除该命令首先被中止或停止,否则不能调度其他无线电操作命令。

系统CPU可以通过任意无线电操作命令中的下一个操作指针位来调度该指针指向的命令,通过这种方法,可以执行复杂的操作。当调用指向的下一个命令时发生了某些意外情况(例如错误或计时器过期),下一个命令不会启动,相反该操作可能会结束或者跳过一些命令。如果一个新命令在另一个命令运行时被调度,系统CPU必须等待前一个命令或命令链完成。

当一个无线电操作命令完成时,无线电CPU向系统CPU抛出一个COMMAND_DONE中断。如果像前面解释的那样链接了许多命令,则在每个命令之后引发COMMAND_DONE中断,而在链中的最后一个命令之后引发LAST_COMMAND_DONE中断。对于一个非链式命令,LAST_COMMAND_DONE中断也会在该命令之后引发。当引发LAST_COMMAND_DONE时,COMMAND_DONE总是同时被引发。在引发COMMAND_DONE中断之前,无线电CPU会将命令结构中的状态位(status)也更新为命令完成状态。
在启动COMMAND_DONE中断后,无线电CPU不访问命令结构。

2.5.1 触发

触发可以规定命令被系统CPU发布的条件和时间,或用于特定无线电操作命令中的其他特定目的。
触发器的数据结构如下图所示:
在这里插入图片描述
下面将对触发器的结构进行介绍。

trigger type

射频操作命令支持多种触发类型,通过设置不同的触发类型,可以规定不同的命令发布的条件。
无线电操作命令支持的触发类型如下所示:
在这里插入图片描述
除了TRIG_NOW和TRIG_NEVER之外,所有触发器都使用32位的时间参数。
绝对定时使用32位的RAT值。相对计时使用RAT滴答的数量。外部触发器使用source和edge标识符。
相对计时可以相对于提交命令链的时间、命令的开始、前一个或第一个命令的开始,或者相对于命令中观察到的事件,这些事件将为每个命令定义。
需要注意的是:相对时间的用法比较特殊,相对计时可以相对于提交命令链的时间、命令的开始、前一个或第一个命令的开始,或者相对于命令中观察到的事件,其具体要求如下:

  • 对于链中的第一个命令,如果开始触发器是类型5到9中的任何一个,则立即开始。如果链中第一个命令引用的另一个触发器是类型5到9中的任何一个,则触发器时间相对于这些命令提交的时间。
  • 如果命令的启动触发器是TRIG_REL_START,则会产生错误,该类型不能用于启动触发。
  • 如果命令的起始触发器为TRIG_NEVER,且bEnaCmd为0,则会产生错误,该命令不会被触发。

对于外部触发器,无线电CPU将RAT设置为使用选定的输入事件作为一个捕获触发器;然后,无线电CPU使用这个捕获中断来触发动作。

bEnaCmd

如果bEnaCmd为1,则动作也可能由命令触发(CMD_TRIGGER命令)。

trigger No

triggerNo参数标识该命令的触发号。

pastTring

如果触发器在计算时发生在过去,则行为取决于pastTrig位。如果该位为0,则触发器不发生,或者对于启动触发器,将产生一个错误。如果pastTrig位为1,则触发器会尽快发生。
注意如果过去的触发被触发,则相对于命令开始的计时相对于程序开始运行的时间,而不是实际的开始时间。

对于外部触发器,如果事件发生在设置发生之前,则不捕获该事件,并忽略pastTrig位。

2.5.2 条件执行

当前命令是否被执行的执行可能取决于前一个命令的执行结果。
对于每个命令,可能有三种结果:

  • TURE
  • FALSE
  • ABORT
    每个命令都定义了判断。如果没有定义,则结果为TRUE,除非命令以错误结束,在这种情况下,结果为ABORT。

每一个命令结构都包含一字节条件来运行下一条命令。该条件字节的结构如下图所示:
在这里插入图片描述
其中RULE规定了下一条命令的执行条件,主要有以下几种:
在这里插入图片描述
如果执行被停止,无线电CPU将回到空闲状态,并且在通过CMDR寄存器输入新命令之前不会运行进一步的命令。LAST_COMMAND_DONE中断被抛出。

如果该规则为COND_SKIP_ON_FALSE或COND_SKIP_ON_TRUE,则在nSkip字段中显示需要跳过的命令数量。如果跳过次数为0,则重新运行相同的命令。如果跳数为1,则在链中执行下一个命令。如果跳过次数是2,则运行下一个命令之后的命令,以此类推。

如果命令以中止结果结束,则无论条件如何,执行都将结束。会引发LAST_COMMAND_DONE中断。中止结果的一个条件示例是发出一个CMD_ABORT命令。

2.5.3 无线电CPU在解析命令前处理

对于所有的无线电操作命令,在解析命令的其余部分之前,先检查启动触发器和条件代码。如果启动触发器具有非法的触发类型(包括启动触发器不允许的TRIG_REL_START,以及与没有命令触发器组合的TRIG_NEVER),无线电CPU将status字段设置为ERROR_START_TRIG。如果condition字段有一个非法的值,无线电CPU会将status字段设置为ERROR_CONDITION。如果start触发器发生在过去,并且startTrigger。pastTrig为0,无线电CPU设置status字段为ERROR_PAST_START。

2.6 命令的数据结构

经过上面的介绍,我们可以得知在一个无线电操作命令中,会存在命令状态位、下一个命令指针位、启动事件位、启动触发类型位和执行条件位。
因此我们可以得到无线电操作命令的数据结构格式:
在这里插入图片描述
可以看到,前面讲到的有关命令调度的信息都存在于该数据结构中
需要说明的是,该数据结构中,字节索引是指向该结构的指针的偏移量。多字节字段是小端序的,需要根据字段大小进行16位半字或32位字对齐。对于位编号,0是LSB。
需要注意的是命令的数据结构是由系统CPU产生的,因此R/W类型也都是针对系统CPU而言的
因此R/W列的用法可表示如下:

  • R:系统CPU可以读回返回结果;无线电CPU不读取该字段。
  • W:系统CPU写入一个值,无线电CPU只读取它,不修改它。
  • R/W:系统CPU写入一个初始值,无线电CPU可以修改它。

我们还知道,这些不同的数据位也使用了子数据结构来表示,对于该数据结构的专用子数据结构,来自父结构的字段不会重复,但是字节索引列反映了它们的存在。

所有命令的唯一必选字段是命令ID号,这是一个16位的数字,作为命令结构的前两个字节发送。

一些即时命令有附加字段,这些字段是为每个命令定义的。此外无线电操作命令也有附加的必填字段。

所有标记为“Reserved”的命令字段都应该被写入0。

2.7 数据条目的数据结构

数据条目(Data Entry)是必须存入一个射频队列中。
队列是作为无线电操作命令的命令结构的一部分设置的。
关于以命令的形式操作队列将在后面专门介绍,目前我们先来认识这个数据条目的数据结构。

2.7.1 数据条目队列

数据条目队列的结构如下图所示:
在这里插入图片描述
其中包含一个32位的队头指针,和一个32位的对尾指针。该队列的头指针一直指向当前无线电CPU正在处理的数据条目。

任何使用队列的命令都包含一个指向数据条目队列的数据结构的指针,该指针在系统CPU分配并初始化这个队列结构是被放入。

2.7.2 数据条目

数据条目队列中包含的数据条目结构如下图所示。
在这里插入图片描述
这些条目被组织在一个链表中。队列的第一个数据条目由队列结构的pCurrEntry字段指向。在数据条目中的pNextEntry字段存着指向下一个数据条目的指针,队列结构的pLastEntry字段指向队列中的最后一个条目,通过这种方式构成一个数据链表。

每个数据条目在某一时刻下一定处于以下几个状态中:

  • Pending:表示该条目未被无线电CPU使用。这是在提交条目之前系统CPU写入的状态。
  • Active:该条目是队列中当前打开的供无线电CPU写入(RX)或读取(TX)的条目。
  • Busy:正在写或读一个未完成的包。当条目处于这种状态时,某些操作是不允许的。
  • Finished:无线电CPU已完成将数据写入此条目,并可供系统CPU重用或释放内存(如果动态分配)。

对于数据条目,系统CPU在系统RAM或无线电RAM的可用部分中设置所需的数据结构。如果数据结构是动态分配的,系统CPU使用后会释放内存。

在用于接收数据的条目中,无线电CPU可以使用LenSz来表示条目元素的长度。如果config.LenSz为00,表示此指标未使用。除非当接收到的数据包的长度可以通过其他方法确定,否则LenSz位不能设置为00,必须被用来记录接收数据的长度。

length表示的是存储数据条目元素的缓冲区的大小,表示这个数据条目中可接收的所有条目元素的大小,如果是指针条目类型,则length表示所指向的数据缓冲区的大小。

2.7.3 指针条目

使用指针条目(Pointer Entry)是表明数据不包含在条目结构中,但在条目原本存放数据的位置包含了一个指向其他缓冲区的指针,该指针指向存储数据的内存地址,该地址由系统CPU分配并写入,由无线电CPU来读取。
通过设置config.type = 2来配置数据条目成为一个指针条目。指针替换数据字段,其结构如下图所示:
在这里插入图片描述
数据从pData提供的缓冲区中读取或存储,这个缓冲区的大小由length决定,此时config.lenSz可以设置为00。

2.7.4 提前读取部分接收条目

专有模式支持一中RX条目,其中数据可以在通过射频接收整个数据包之前被读取,它可以用于以下目的:

  • 在接收到整个数据包之前必须读取数据
  • 当包的长度在包的开始是未知的
  • 当包的长度太长,以致于整个有效负载不能同时保存在内存中

为了支持这一点,对普通数据条目的结构做了一个特殊变体。作为多元素条目,同一条目中可以包含多个条目元素。每个条目元素对应于通过射频接收的一个数据包,或者仅代表数据包的一部分。元素还可以包含其他字段。该类型通过设置config.type = 3。在多元素条目中,数据字段的组成如图所示:
在这里插入图片描述
该条目更新如下:

  • 当新的字节被写入缓冲区时,nextIndex字段被更新。
  • 接收报文时,射频CPU设置pktStatus.bEntryOpen =1。

当一个条目元素结束时,要么是因为包结束了,要么是因为元素到达了条目pktStatus的末尾。pktStatus.bEntryOpen被射频CPU设置为0。pktStatus.numElements递增。如果报文继续进入下一个条目,无线电CPU设置pktStatus.bLastCont =1,同是无线电CPU会将下一个条目的pktStatus.bFirstCont位也设置为1。如果没有下一项可用,状态设置为Unfinished,否则设置为Finished。

由于在条目元素开头指定的长度字段(取决于config.lenSz)指定的是条目中数据的长度,而不是整个数据包的长度。如果在打开表项时不知道长度(一个表项无法存满整个数据包),则length字段被写入数据的剩余长度,并在数据结束前由无线电CPU更新。

2.8 外部信号

无线电CPU控制4个CPEGPOx信号,可用于外部信号,例如控制外部PAs和LNAs或调试。

  • 内部LNA使能时,CPEGPO0为高电平,
  • 内部PA使能时,CPEGPO1为高电平,
  • 合成器校准时,CPEGPO2为高电平。

RAT的两个输出信号具有自动配置,可用于观察。当数据包开始传输时,信号RATGPO0为高,当传输结束时为低。观察RATGPO0可以得到数据包传输的精确时间,因为内部使用的是相同的信号。RATGPO0与CPEGPO1非常相似,但它比CPEGPO1提前了一些微秒,而且与调制解调器发出的第一个传输符号相比,计时更准确。

默认情况下,射频CPU在启动时将CPEGPO0映射为RFC_GPO0信号,CPEGPO1映射为RFC_GPO1信号,CPEGPO2映射为RFC_GPO2信号,RATGPO0映射为RFC_GPO3信号。这个映射可以通过写入rfc_bell:SYSGPOCTL寄存器来修改。

RFC_GPOx信号可以通过系统I/O控制器映射到输出管脚。

3 命令的定义

下面将介绍一组独立于使用的射频协议的命令。这些命令与无线电的低级操作有关。

3.1 独立于协议的无线电操作命令

首先对于接下里要介绍的无线电操作命令,造成操作结束的原因被列在下面表中,或者这些原因被添加到命令的额外参数中。
在这里插入图片描述

这些操作结束的原因将被记录在命令结构体的status字段中,这个命令结束的结果是TRUE、Flash或者ABORT,将被status中的rule字段表示出来(具体见2.5.2),这个结果将表明下一个命令是会继续执行,还是会返回空闲状态。

3.2 各种无线电命令的介绍

有关各种无线电命令的介绍,可以直接查阅CC1310技术参考手册的23.3.4和23.3.4两章节,在此再一一介绍

4 数据队列的用法

该章节将介绍无线电CPU是如何使用数据队列的

4.1 仅供内部无线电CPU操作的数据队列操作

在CC1310的技术参考手册中的23.3.4章节列出了用于数据队列操作的各种命令,那些命令都是由无线电CPU产生的针对于内部无线电数据队列的立即命令。但是除了那些用于维护数据队列的命令外,无线电CPU还可以实现一些内部操作。

4.1.1 PROC_ALLOCATE_TX:读取被分配的TX条目

该操作用于读取TX队列的当前条目
该操作需要指定当前操作的队列指针(提供pQueue),在执行成功后返回被读取的数据条目的指针(pEntry)。

如果指定的队列为空,或者队列的第一个条目已经忙,该过程将返回错误。否则,执行以下操作:

Set pQueue->pCurrEntry->status = Busy
Set pEntry = pQueue->pCurrEntry

首先将操作的队列的当前条目的状态设置为BUSY,表明TX队列的当前条目正在被读取,之后读取当前条目的信息。

4.1.2 PROC_FREE_DATA_ENTRY:清除已分配数据条目

该操作会激活队列的当前条目,来开始写入或读取当前条目的信息
该操作需要指定当前操作的队列指针(提供pQueue),在执行成功后返回被清除的数据条目的指针(pEntry)。

如果指定的队列为空,该过程将返回错误。否则,执行以下操作

Set  pQueue->pCurrEntry->status = Active

通过将当前条目的状态设为Active,表明该队列的当前条目可以读取或写入新的数据。

4.1.3 PROC_FINISH_DATA_ENTRY:从队列中完成第一个数据条目的使用

该操作实质是将处于Pending状态的下一个条目的信息更新到到当前条目中
该操作需要指定当前操作的队列(提供pQueue),在执行成功后返回下一个要被分配的数据条目的指针(pEntry)。

如果指定的队列为空,该过程将返回错误。否则,执行以下操作:

Set pTemp = pQueue->pCurrEntry
Set pQueue->pCurrEntry = pTemp->pNextEntry
Set pTemp->status = Finished
Set pEntry = pQueue->pCurrEntry

将当前条目中存储的下一个条目信息赋值给当前条目,并返回即将被操作的条目的信息

4.1.4 PROC_ALLOCATE_RX:为存储数据分配RX缓冲区

该操作需要指定当前操作的队列指针(pQueue)和需要存储的条目元素(数据包)的大小(size),在执行成功后返回存储数据的数据条目的指针pEntry和指向已完成的数据条目的指针(pFinishEntery),若未执行成功,则只返回存储数据的数据条目的指针(pEntry)。

如果队列的第一个条目已经繁忙,该过程将返回错误。如果没有空间容纳指定大小的条目元素,包括队列为空的情况,则返回" no space "错误。否则,执行以下操作:

If pQueue->pCurrEntry->type != 1 then
Set pTemp = pQueue->pCurrEntry
Set pQueue->pCurrEntry = pTemp->pNextEntry
Set pTemp->status = Finished
else
Increase pQueue->pCurrEntry->nextIndex by size
Increment pQueue->pCurrEntry->numElements by 1
If pQueue->pCurrEntry->nextIndex + 2 == pQueue->pCurrEntry-
>length then
Set pTemp = pQueue->pCurrEntry
Set pQueue->pCurrEntry = pTemp->pNextEntry
Set pTemp->status = Finished
Set pFinishedEntry == pTemp
else
Set pQueue->pCurrEntry->status = Active
Set pFinishedEntry == NULL
end if
end
4.1.5 PROC_FINISH_RX:提交接收到的数据到RX数据条目

该操作需要指定当前操作的队列指针(pQueue)和已存储的条目元素的大小(size),在执行成功后返回存储数据的数据条目的指针pEntry和指向已完成的数据条目的指针(pFinishEntery),若未执行成功,则只返回存储数据的数据条目的指针(pEntry)。

如果队列为空或没有空间容纳指定大小的条目元素,该过程将返回错误。否则,执行以下操作:

If pQueue->pCurrEntry->type != 1 then
Set pTemp = pQueue->pCurrEntry
Set pQueue->pCurrEntry = pTemp->pNextEntry
Set pTemp->status = Finished
else
Increase pQueue->pCurrEntry->nextIndex by size
Increment pQueue->pCurrEntry->numElements by 1
If pQueue->pCurrEntry->nextIndex + 2 == pQueue->pCurrEntry-
>length then
Set pTemp = pQueue->pCurrEntry
Set pQueue->pCurrEntry = pTemp->pNextEntry
Set pTemp->status = Finished
Set pFinishedEntry == pTemp
else
Set pQueue->pCurrEntry->status = Active
Set pFinishedEntry == NULL
end if
end

注意:这个操作是在执行PROC_ALLOCATE_RX操作并写入缓冲区中的正确位置完成后执行的,其输入参数sIze必须与PROC_ALLOCATE_RX相同。

4.2 无线电CPU使用队列操作样例

4.2.1 接收队列

当无线电CPU收到一个数据包时,它通过调用PROC_ALLOCATE_RX准备一个缓冲区来读取。如果这是成功的,分配的缓冲区将用于存储为每个协议定义的传入数据包。如果发生无空间错误,则接收到的数据无法存储,并且为每个协议定义了处理。

在接收到数据包之后,根据为每个协议定义的规则,它可以被保留或丢弃。为了保存数据包,无线电CPU调用PROC_FINISH_RX。这使得接收到的数据对系统CPU可用。为了丢弃报文,无线电CPU调用PROC_FREE_DATA_ENTRY,这意味着下一个报文可能会覆盖上一个报文接收到的数据。

4.2.2 发送队列

当无线电CPU准备从TX队列传输一个数据包时,它调用PROC_ALLOCATE_TX来获得一个指向要传输的数据的指针。报文传输时,无线电CPU调用PROC_FINISH_DATA_ENTRY或PROC_FREE_DATA_ENTRY。

如果调用PROC_FINISH_DATA_ENTRY,则通知系统CPU,当前条目的数据已经完成发送,当前条目可以被重新使用。如果无法选择重传数据包,则必须使用此调用过程。
如果调用PROC_FREE_DATA_ENTRY,传输的条目将保持在队列中的第一个,以便它可以被传输,这在期待收到一个确认信息时使用。

如果在传输的数据包上收到一个确认,然后无线电CPU调用PROC_FREE_DATA_ENTRY,无线电CPU调用PROC_ALLOCATE_TX,然后PROC_FINISH_DATA_ENTRY(这相当于CMD_REMOVE_DATA_ENTRY,参见技术手册的23.3.3.2节)。这个调用进程导致队列中的下一个条目被传输。如果没有收到确认,则重传最后一个传输的数据包。

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值