【LoRa】SetTx和SetRx的几种模式的用法

1 前言

本章介绍SetTx和SetRx的使用方法,以及在使用时需要注意的点。Semtech的各个系列的transceiver使用大体相同,本章以SX126x为例展开介绍。
根据datasheet介绍,TX有两种模式,一种是TX single mode,一种是TX timeout mode。而RX有三种模式,有RX single mode、RX timeout mode和RX continuous mode。

注:有需要datasheet的可以去Semtech官网搜索即可,如SX1268。

2 TX mode

TX mode即是radio的发射模式,此寄存器的作用就是发包,下图为datasheet的截图。
SetTx寄存器
SetTx的timeout值
其中timeout的值是指SX126x内部RC时钟的tick值,SX126x内部RC使用的是64kHz,而LR11xx内部RC使用的是32.768kHz,SX128x稍有不同,有兴趣的可以看看手册,在手册中也称为RTC。
但在写代码的时候并不需要自己去计算,因为官方driver已经封装好函数,使用者只需要传入毫秒(ms)值,函数会自己计算所需的tick值,如下图,为SX126x官方driver的函数封装。

#define SX126X_RTC_FREQ_IN_HZ 64000UL
uint32_t sx126x_convert_timeout_in_ms_to_rtc_step( uint32_t timeout_in_ms )
{
    return ( uint32_t )( timeout_in_ms * ( SX126X_RTC_FREQ_IN_HZ / 1000 ) );
}
sx126x_status_t sx126x_set_tx( const void* context, const uint32_t timeout_in_ms )
{
    if( timeout_in_ms > SX126X_MAX_TIMEOUT_IN_MS )
    {
        return SX126X_STATUS_UNKNOWN_VALUE;
    }

    const uint32_t timeout_in_rtc_step = sx126x_convert_timeout_in_ms_to_rtc_step( timeout_in_ms );

    return sx126x_set_tx_with_timeout_in_rtc_step( context, timeout_in_rtc_step );
}

sx126x_status_t sx126x_set_tx_with_timeout_in_rtc_step( const void* context, const uint32_t timeout_in_rtc_step )
{
    const uint8_t buf[SX126X_SIZE_SET_TX] = {
        SX126X_SET_TX,
        ( uint8_t )( timeout_in_rtc_step >> 16 ),
        ( uint8_t )( timeout_in_rtc_step >> 8 ),
        ( uint8_t )( timeout_in_rtc_step >> 0 ),
    };

    return ( sx126x_status_t ) sx126x_hal_write( context, buf, SX126X_SIZE_SET_TX, 0, 0 );
}

2.1 SetTx的single mode

single mode也就是单次发送模式,从执行SetTx指令开始一直在TX模式,直到本包发送完,退回到STBY_RC模式,产生TX_DONE中断。那TX模式到底会持续多久呢?基本上就是本次发包的TOA(Time of arrive)时间。
设置single模式也很简单,将timeout的值设置为0即可,这种模式是最常用的也是推荐的。

sx126x_set_tx( context, 0 );

2.2 SetTx的Timeout模式

datasheet上解释使用timeout模式是为了更安全,如下图,但我认为只要代码逻辑上不出问题就不用使用timeout模式,而且官方的各个SDK代码的example中也没有使用。
SetTx的timeout解释
如果想用这个模式,设置的timeout的值需要大于本包所用的TOA时间(经实验,timeout值等于TOA时间也行,但为了安全起见,稍微大几毫秒为好)。如果是小于,则会出现在发包过程中产生timeout中断,让radio从TX回到STBT_RC模式,导致本包发送失败。

3 RX mode

RX mode是指接收模式,下图为datasheet的截图。
SX126x的发包指令
RX的三种模式解释如下图:
SetRx的三种工作模式
以下为SX126x driver中的程序片段。

sx126x_status_t sx126x_set_rx( const void* context, const uint32_t timeout_in_ms )
{
    if( timeout_in_ms > SX126X_MAX_TIMEOUT_IN_MS )
    {
        return SX126X_STATUS_UNKNOWN_VALUE;
    }

    const uint32_t timeout_in_rtc_step = sx126x_convert_timeout_in_ms_to_rtc_step( timeout_in_ms );

    return sx126x_set_rx_with_timeout_in_rtc_step( context, timeout_in_rtc_step );
}

sx126x_status_t sx126x_set_rx_with_timeout_in_rtc_step( const void* context, const uint32_t timeout_in_rtc_step )
{
    const uint8_t buf[SX126X_SIZE_SET_RX] = {
        SX126X_SET_RX,
        ( uint8_t )( timeout_in_rtc_step >> 16 ),
        ( uint8_t )( timeout_in_rtc_step >> 8 ),
        ( uint8_t )( timeout_in_rtc_step >> 0 ),
    };

    return ( sx126x_status_t ) sx126x_hal_write( context, buf, SX126X_SIZE_SET_RX, 0, 0 );
}

3.1 SetRx的single mode

根据datasheet的解释,single mode会一直让radio处于RX模式,直到接收到一个包,产生RX Done,然后自动回到STBY_RC模式。将timeout值设置为0即可设置为single mode。

sx126x_set_rx( context, 0 );

3.2 SetRx的Timeout模式

同样,timeuot模式就是设定一个时间值,时间到仍然没有接收到包就退出RX回到STBY_RC模式,并产生timeout中断。Timeout的解释与TX一样,driver里同样已经封装成毫秒(ms)单位。比如要设置一个100ms的timeout:

sx126x_set_rx( context, 100 );

3.3 SetRx的continuous模式

continuous模式,也就是持续接收模式,radio会一直待在RX模式,直到host主动发送命令改变radio模式。与其他两种模式的区别是,continuous模式下,radio收到包后不会退出RX回到STBY_RC,它会一直在RX模式。
设置RX的continuous模式,需要将timeout的tick值设置为0xFFFFFF,但由上边的sx126x_set_rx()函数封装可知,此函数传入的参数是毫秒值,并非tick值。所以需要使用函数sx126x_convert_timeout_in_ms_to_rtc_step()进行设置。
正确的方式如下程序所示:

#define SX126X_RX_CONTINUOUS 0x00FFFFFF
sx126x_set_rx_with_timeout_in_rtc_step( context, SX126X_RX_CONTINUOUS );

另外一点需要注意的是在continuous模式下,读取payload buffer时,地址是自增长的,而single和timeout模式地址指针每次都会自动回到0,如下图手册解释:
RX continuous的data buffer指针
所以应该先使用GetRxBufferStatus寄存器读出上一包的data起始地址,使用寄存器如下图:
GetRxBufferStatus寄存器
程序说明如下:

sx126x_rx_buffer_status_t rx_buffer_status;
sx126x_get_rx_buffer_status( context, &rx_buffer_status );
//sx126x_read_buffer( context, 0, buffer, rx_buffer_status.pld_len_in_bytes );
sx126x_read_buffer( context, rx_buffer_status.buffer_start_pointer, buffer, rx_buffer_status.pld_len_in_bytes );

当然,这种写法同样对single和timeout模式有效,只不过是每次读出rx_buffer_status.buffer_start_pointer的值都是0而已。

4 小结

  1. 如没有特殊需求,SetTx只使用single模式即可。
  2. RX的三种模式都很常用,但使用continuous模式时需要注意上边提到的特殊用法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Victor随笔集

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值