单开一篇,介绍sx1278的FIFO工作流程和应用设置,分析下出的一些小问题,毕竟也困扰了我几天。亦或是我比较愚钝。总之,记下来吧!
/******************************************************************************************************************************************************************************/
SX1278的FIFO介绍:
先贴一段datasheet的定义: SX1276/77/78配备了256字节的RAM数据缓存,该缓存仅能通过LoRa模式进行访问。 RAM区(以下称为“FIFO数据缓存”)可以完全由用户定制,用于访问接收的或发送的数据。LoRaTMFIFO数据缓存只能通过SPI接口访问。
这些FIFO数据缓存保存与最后接收操作相关的数据,除睡眠模式之外,在其他操作模式下 均可读。在切换到新的接收模式时,它会自动清除旧内容。
这段介绍是说,在睡眠模式下,会清空FIFO数据缓存区的数据。在其他模式都是可以读的。另外,在datasheet的其他地方有提到,FIFO数据缓存区仅在待机模式可写。
话不多说,先贴张图:
这张图可以说是很详细,一眼看过去就全清楚了。首先,在LoRa模式下,SX1278芯片接收到的数据和要发送的数据,都是存放在这个256byte的FIFO数据缓冲区中,其次,发送缓存区指针RegFifoTxBaseAddr 和接受缓冲区指针RegFifoRxBaseAddr
分别指向缓冲区的某一个位置,这个位置可以由用户自己设置,即要用多大的空间由用户自己说了算,如果一次性收发的数据量很大(小于256byte),可以把整个FIFO缓冲区当作接收或者发送缓冲区,是不是很棒呢。官方原话是这么说的(FIFO数据缓存拥有双端口配置,因此可以在缓存内同时存储将要发送和接收的信息。寄存器RegFifoTxBaseAddr明确规定了存储将要发送信息的起始位置。同样的,针对接收操作,寄存器RegFifoRxBaseAddr也显示了接收操作中写入缓存的起始位置。)
两个基地址RegFifoTxBaseAddr 和RegFifoRxBaseAddr 默认值是0x80和0x00,即各128byte。
再看一遍图,发现还有两个指针RegFifoRxCurrentAddr 和 RegFifoAddrPtr 。下面着重讲这两个指针(为什么?因为官方讲的太隐晦了,导致我只能猜,然后找证据):
RegFifoRxCurrentAddr 用于连续接受模式,图中它也指向接收缓冲区FIFO,作用是记录本次接收数据的起始地址,用户在这个地方开始读取本次接受到的数据。--------为什么要用这货(RegFifoRxCurrentAddr)?由于连续接受模式,新数据包的第一个字节会在上一个数据包的最后一个字节之后立即写入,这个时候,接受指针(RegFifoRxByteAddr就是这货)已经随着接收到的数据,在FIFO中移动到了数据地址的最尾端,如果要读取RegFifoRxBaseAddr处的数据,是读不到的,因为这个地址后面没有数据,RegFifoRxCurrentAddr实质上是保存的上一个数据接受完成后RegFifoRxBaseAddr的地址值,即本次接收数据的起始地址。(应该说清楚了吧?没说清楚?下面补充!)。
RegFifoAddrPtr用于用户读取FIFO中的数据,它指向FIFO的哪里,便从哪里开始读,读多少数据也是用户自己来定。--------那读多少数据呢?在显式报头的情况下,收到的数据包中包含了本次有效数据的长度(RegRxNbBytes ),在取得数据前,可以先获得本次数据的长度,这样就可以读出这次发送的全部数据了。
由于datasheet关于指针的描述很隐晦,这里进行说明和举证:
Q1、datasheet中的接收指针(The RX modem address pointer )是啥?
A1:接收指针是这货RegFifoRxByteAddr,上面已经提到了这点,那为什么是这货,举证:
datasheet描述:可以手动将RegFifoAddrPtr设置为RegFifoRxByteAddr减去RegRxNbBytes的值,使该指针从当前数据包开始,一直指向最后接收的数据包的存储位置。可以通过RegRxNbBytes次读取寄存器RegFifo中的地址,以提取数据包的有效负载字节。(英文:it is possible to manually point to the location of the last packet received, from the start of the currentpacket, by setting RegFifoAddrPtr to RegFifoRxByteAddr minus RegRxNbBytes. The payload bytes can then be read from the FIFO by reading the RegFifo address RegRxNbBytes times. )
这句话的意思是在连续接受模式读取FIFO中数据的另外一种方式:用RegFifoRxCurrentAddr = RegFifoRxByteAddr - RegRxNbBytes。这就说明了接收指针就是RegFifoRxByteAddr,接收数据前,它被用户指定指向FIFO中的某一个地址(缺省值为0x00),接收到数据后,它会指向接受到的数据的末尾地址。
Q2、单次接收模式下,一次接收数据结束后,RegFifoRxByteAddr会重置为基地址0x00(或者用户设定的某一个地址)吗?
A2、会,datasheet中有单次接收流程:用户从FIFO的基地址0x00处(如果你把基地址设置为其他值,则从你设置的值处)开始读取数据,一次读取数据结束,下次读取时,需要将再次从基地址0x00处(如果你把基地址设置为其他值,则从你设置的值处)读取,那么就是说完成每次的单次接收后,都会RegFifoRxByteAddr都会重置。(datasheet没有说明,就只能这样猜测了,没有直接证据)
Q3、连续接收模式下,需要判断接收缓冲区满的情况吗?
A3、需要的,datasheet中也明确说明:关联微控制器MCU必须对地址指针进行处理,以保证FIFO数据缓存不会溢出。这种情况下,就要视情况来对接收指针RegFifoRxByteAddr进行设置,只要在FIFO没有满的情况下,将接收指针RegFifoRxByteAddr指向基地址就行,当然,RegFifoRxCurrentAddr也要同时指向基地址。
补充一下,MCU通过SPI读取接受到的数据是发送寄存器RegFifo地址(0x00)来读取寄存器中的值。