STM32WL 系列中的 Sub-GHz 无线电中断

STM32WL系列单片机包括基于Semtech SX1261和SX1262收发器的嵌入式Sub-GHz无线电。与SX126x器件一样,Sub-GHz无线电系统由SPI接口、BUSY线和三根中断(IRQ)线控制。唯一的区别在于,由于无线电集成在STM32WL器件中,因此这些信号(在图1中突出显示)会在内部连接到SoC的其他部分。


1 Sub-GHz无线电系统接口信号(源自RM0453中的图9)

因此,STM32WL Sub-GHz无线电系统的中断线路与Semtech SX126x收发器相同。也就是说,有十个可启用/禁用并映射到任意三个IRQ线路的中断源。下表描述了这些中断源。

1 Sub-GHz无线电系统中断源(源自RM0453中的表37)

描述 数据包类型 操作
0 TxDone 数据包传输已完成 LoRa和GFSK TX
1 RxDone 数据包接收已完成 LoRa和GFSK RX
2 PreambleDetected 前导码已检测 LoRa和GFSK RX
3 SyncDetected 同步字有效 GFSK RX
4 HeaderValid 标头有效 LoRa RX
5 HeaderErr 标头CRC错误 LoRa RX
6 Err 前导码、同步字、地址、CRC或长度错误 GFSK RX
6 CrcErr CRC错误 LoRa RX
7 CadDone 频道活动检测已完成 LoRa CAD

本文将使用Sub-GHz PhyMiddleware的低级驱动程序与STM32WL进行接口连接。提供的代码也可以应用于使用完整Middleware(包括高级驱动程序)的应用,但这样做可能并不必需,因为大部分实现细节已经被上层抽象化。有关在STM32WL项目中使用低级Sub-GHz驱动程序的更多信息,请参阅使用STM32WL系列的初级Sub-GHz无线电驱动程序

以下代码片段演示了利用STM32WL无线电中断的基本过程。第一步(列表1中显示)是将回调函数的指针作为参数传递给驱动程序的初始化例程。每当Sub-GHz无线电系统发出中断时,系统都会执行此回调函数。为了确定中断源(参见表1),此函数必须包含一个RadioIrqMasks_t类型的单个参数,从而允许使用switch语句(或其他条件逻辑)来处理每个单独的中断源。

列表 1 设置和实施Sub-GHz无线电回调函数的模板

// Initialize the hardware (SPI bus, TCXO control, RF switch)
SUBGRF_Init(RadioOnDioIrq);

.
.
.

// Callback function - executed once for each (enabled) interrupt issued from sub-GHz radio
void RadioOnDioIrq(RadioIrqMasks_t radioIrq)
{
  switch (radioIrq)
  {
    case IRQ_TX_DONE:
      // do something
      break;
    case IRQ_RX_DONE:
      // do something
      break;
    case IRQ_RX_TX_TIMEOUT:
      // do something
      break;
    case IRQ_CRC_ERROR:
      // do something
      break;
    default:
      break;
  }
}

为了使Sub-GHz无线电子系统生成中断请求,必须全局启用一个或多个中断源,并将其映射到任一IRQ线路中。如列表2所示,这可以通过调用SUBGRF_SetDioIrqParams() 函数来实现。该函数的第一个参数是全局中断使能掩码,用于启用/禁用指定的中断源。后三个参数是用于单个IRQ线路的掩码,可将中断源映射到相应的线路上。例如,在列表2中,第一个参数全局启用了TxDone、Timeout和RxDone中断。第二个参数用于指示,当TxDone或Timeout中断发生时,IRQ1线路应从低电平变为高电平。类似地,当RxDone中断发生时,IRQ2线路应从低电平变为高电平。在此示例中,没有将中断源映射到IRQ3线路。

列表 2 :启用Sub-GHz无线电系统的中断

SUBGRF_SetDioIrqParams( IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_RX_DONE,
                      IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT,
                      IRQ_RX_DONE,
                      IRQ_RADIO_NONE );

备注:如果同时触发了映射到同一IRQ线路上的多个中断源,则回调函数将被多次调用以处理每个源事件。

然而,除非直接修改Sub-GHz Phy Middleware,否则无法为单个IRQ线路分配单独的回调函数。也就是说,无论触发的中断映射到哪个IRQ线路,系统都会执行相同的回调函数。因此,大多数应用通常只使用IRQ1线路。如果应用必须确定被触发的是哪个IRQ线路,可以使用列表3中提供的代码。该代码采用了一种解决方法,即,将内部IRQ线路变成外部线路,从而允许轮询GPIO IDR(输入数据寄存器)来获取每个线路的状态。有关将内部Sub-GHz无线电信号变成外部线路的详细信息,请参阅将内部STM32WLSub-GHz无线电接口信号映射到GPIO引脚

列表 3 将IRQ[0:2]线路由到GPIO引脚并查看它们的当前状态。

#define GPIO_PIN_RF_IRQ1 GPIO_PIN_3
#define GPIO_PIN_RF_IRQ2 GPIO_PIN_5
#define GPIO_PIN_RF_IRQ3 GPIO_PIN_8

/**************************** Initialization Code *****************************/
// Enable GPIOB Clock
__HAL_RCC_GPIOB_CLK_ENABLE();

// Configure RF_{IRQ0, IRQ1, IRQ2} pins
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_RF_IRQ1 | GPIO_PIN_RF_IRQ2 | GPIO_PIN_RF_IRQ3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_RF_BUSY;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


/************ Conditional logic to be placed in callback function *************/
// Check status of each IRQ line
if (READ_BIT(GPIOB->IDR, GPIO_PIN_RF_IRQ1))
{
  // IRQ1 line triggered
}
else if (READ_BIT(GPIOB->IDR, GPIO_PIN_RF_IRQ2))
{
  // IRQ2 line triggered
}
else if (READ_BIT(GPIOB->IDR, GPIO_PIN_RF_IRQ3))
{
  // IRQ3 line triggered
}

在大多数情况下,管理STM32WL系列器件上的Sub-GHz无线电系统中断和与外部射频收发器进行接口连接完全相同。只不过由于无线电控制信号的内部化,略微影响了灵活性。STM32CubeWL MCU封装中提供了几个利用无线电中断的完整示例应用。

1 个赞