Nordic SoC 内部集成了无线射频收发器,它不仅支持能BLE协议,还支持其他2.4GHz协议比如ANT+,Zigbee,Thread等等,用户甚至可以直接控制寄存器定制属于自己的私有2.4GHz通信协议。它使用GFSK的调制方式,支持空中速率有250kbps,1Mbps,2Mbps等。并且nRF52811/nRF52820/nRF52833/nRF52840等型号还支持802.15.4 协议。下图是nRF52832射频寄存器的框架图。

上图黄色箭头标注的是接收的主要流程,蓝色箭头标志的是发送的主要流程。我们可以发现,虽然Radio收发器有接收和发射两个模块,但其依然是半双工的,即无法同时接收与发送数据,并配有1个发送通道和8个接收通道。EasyDMA、自动拆装包、CRC模块组合在一起之后,大大简化了Radio的配置。


EasyDMA可以射频模块可以直接从RAM读写数据而不需要CPU的参与,但用户需要在开启START任务收发无线数据之前,将内存的地址和长度填入Radio的PACKETPTR寄存器和PCNF1.MAXLEN寄存器中。RAM中的数据结构包括S0,LENGTH,S1,PAYLOAD,static-add-on四个部分。static-add-on是额外字段,发送的时候紧跟在PAYLOAD后面,一般的使用中我们将它省略了PAYLOAD的长度由RAM中的LENGTH决定,static-add-on的长度由PCNF1.STATLEN决定。它们中有些部分是按位定义的,但它们都占用整数个字节。比如设置3bit的LENGTH,但它在RAM中占用1个字节;设置9bit的LENGTH,但它在RAM中占用2个字节。


空中包还带有PREAMBLE,ADDRESS,CRC这三项,下图是nRF52832 SoC空中包的格式。

空中包里,ADDRESS 和 PAYLOAD部分总是LSB;CRC部分总是MSB;S0,LENTH,S1的大小端受PCN1.ENDIAN寄存器控制。


PREAMBLE是前导码,除了在BLE模式2Mbps情况下是2个字节,其他情况通常是用1个字节。当ADDRESS的第一个bit是0时PREAMBLE会被设为0xAA,否则它将被设为0x55。


ADDRESS是无线的收发地址,它由BASE 和 PREFIX 两部分组成。只有接收机与发射机的地址匹配,才能成功通信。BASE部分的长度由FCNF1.BALEN控制,内容由BASE0和BASE1两个寄存器控制;PREFIX的内容由PREFIX0和PREFIX1两个寄存器控制。通过这两个部分的排列搭配,可以搭配出8种逻辑地址。用户在配置发送的地址时从这8个逻辑地址中挑选一个,由TXADDRESS寄存器控制;设置接收地址的时候根据需要将这写逻辑地址配置给8个接收通道,由RXADDRESSES寄存器控制,用户可以根据需要打开接收地址通道的个数。


[S0+LENGTH+S1+PAYLOAD+static-add-on] 它们是存储在RAM中的数据包。

S0,LENGTH,S1是可选部分,它们的长度分别由PCNF0.S0LEN,PCNF0.LFLEN ,PCNF0.S1LEN决定,大小端由PCNF1.ENDIAN控制。

PAYLOAD的长度由LENGTH决定;Static-add-on的长度由PCNF1.STATLEN决定。

PCNF1.MAXLEN定义了Radio收发数据包最大字节数,限制了PAYLOAD加上static-add-on的总长度,它可以防止其他区域的RAM(超出EasyDMA定义的RAM范围)被读写。

所以当 PCNF1.STATLEN 加 LENGTH大于 PCNF1.MAXLEN时,PAYLOAD加static-add-on的长度将被减为PCNF1.MAXLEN,并且LENGTH定义的长度不会被截短,超出的部分不会被Radio收发,不会参与CRC的计算。 


CRC是校验字段,紧跟在PAYLOAD后面,MSB格式。CRC可以校验除了PREAMBLE之外的整个数据包。CRC校验的配置通过CRCCNF,CRCPOLY,CRCINIT三个寄存器完成。


Radio工作状态机


发送时序

下图是Radio的发送时序图。第一行是状态机进度条,第二行是对应的空中包结构,第三行是用户触发的任务。第二行和第三行中间如READY,ADDRESS等是Radio产生的事件。图中框出了单次发送和连续发送时使用的shortcut,不难发现shortcut减少了Radio发送过程中的一些步骤,提高了效率。


接收时序

下图是Radio的接收时序图。同样的,图中框出了单次接收和连续接收时使用的shortcut,不难发现shortcut减少了Radio发送过程中的一些步骤,提高了效率。


 

 

 

 

静态固定长度 收发例程代码(带ACK):

网盘链接:https://pan.baidu.com/s/1mz7F0IlDMp58Ciz1pvMGSA

提取码: e9ll

动态长度 收发例程代码(带ACK):

网盘链接:https://pan.baidu.com/s/17-aPYhWXzAZE_8CPqLV98g

提取码: 5577

6 对 “NORDIC BLE SoC 2.4GHz通信简介”的想法;

        1. NRF_ERROR_RESOURCES 是因为协议栈的缓存不够了,等到下一个连接间隔,数据被底层发送出去之后,就可以填充新的数据了。
          这个部分是BLE的协议栈控制的,其实跟2.4G的寄存器设置没有直接关系。

          1. 感谢博主解答。我还想请教一个问题,串口透传发送函数:ble_uarts_data_send()发出的数据是先存在协议栈的缓存,然后,一个个送到EasyDMA使用的内存里面,最后发射出去;还是说ble_uarts_data_send()发出的数据直接送到EasyDMA使用的内存。查了网上的资料,NRF_ERROR_RESOURCES因为收发器FIFO满了,这收发器FIFO指的是EasyDMA使用的内存还是协议栈创建的缓存。还有我把连接间隔和连接事件长度都设置为100ms,10ms发送一次数据,链路为2Mbit/s,还是出现NRF_ERROR_RESOURCES

          2. 这个地方的FIFO,已经不是DMA的了,可以理解是纯软件层面的缓存,如上面的回答,跟RF的寄存器没有直接关系。协议栈自身的缓存满了之后,等到下一个连接间隔来了,数据成功发送出去之后,才能继续在应用层调用API发送。

发表评论