DA14581有两条GPIO线配置为输出,并在固件初始化时设置为高。这些线路上的负脉冲触发主控制器上的级中断。
我发现,大约每500次中有1次,当DA14581刚刚通电,并与主控制器进行了一些握手,然后开始宣传,这两条GPIO线同时触发了主控制器上的意外中断。DA14581子卡由外置电源供电。我确保那时没有固件代码会改变GPIO线状态。
DA14581配置了扩展睡眠模式。当连接到BLE或关闭电源时,从未发现此问题。
任何洞见都将不胜感激。
你好,
当使用延长睡眠时,您将看到以下行为:在每次唤醒时,在user_peri_setup .c (peri_init()函数)中重新初始化gpio。这个函数将重新锁存所有输出锁存,并完全按照您描述的那样操作,并将所有gpio设置为同一文件的set_pad_functions()中定义的状态。
/ MHv
间歇性的不想要的中断并没有出现在系统从睡眠中唤醒时。相反,他们在第一次打开收音机播放广告后是正确的。我将STARTUP_SLEEP_DELAY_DEFAULT更改为3秒,这样当睡眠仍然被禁用时,广告总是启动,但我仍然看到不必要的中断。
此外,我从来没有看到这种情况发生时,BLE连接和延长睡眠启用。
嗨zheshen,
你能告诉我们你使用的是哪个引脚,问题发生了吗?你确定那些引脚没有被581的任何外设使用,所以它们可以接管特定引脚的控制,也许是SPI接口的引脚?您还可以告诉我们您在开发您的应用程序时使用的初始示例吗?也许这也和电源有关,所以当事故发生时,你能检查一下电源并监控电源状态吗?您确定发生在外部设备上的中断是由于GPIO的切换(您使用分析器监控引脚了吗?)事实上,您已经注意到设备在无线电活动活动之前切换作为输出的引脚,可能是由于您启用了诊断引脚,您在项目中有这种功能吗?
由于MT_dialog
MT_dialog:
请参阅下面的代码。RF_WAKE和RF_RDYN都从端口1配置为GPIO线(DA14581输出和Host输入),并且在应用程序启动后预期为空闲高。在意外重置DA14581时,RF_WAKE线将在短时间内处于低电平,这将触发主机控制器上的中断,作为响应,主机控制器将断电并上电DA14581。RF_RDYN用于SPI同步信号。在此问题之前,DA14581与主机之间的握手涉及SPI数据传输(主机作为SPI master)和RF_RDYN信令,未发现问题。
Spi_slave_init在set_pad_functions和powerup uart2之后被调用。函数deassert_rf_wake()设置RF_WAKE高在外围init中被调用,因此在系统初始化和从睡眠中唤醒时被调用。函数assert_rf_wake()将RF_WAKE设置为低值,但不会在固件代码的任何地方调用。
所有SPI信号配置GPIO线从端口0。该项目基于SDK 5.0,没有使用特定的示例。我无法捕获导致问题的RF_WAKE或RF_RDYN上的确切脉冲,因为DA14581每隔几秒就会上电一次,这个问题可能几个小时后才会出现。我在主机端的执行跟踪显示了RF_WAKE和RF_RDYN上的中断同时被引发。
我不确定你说的诊断针是什么。set_pad_functions函数定义了我正在使用的所有引脚。
#定义GPIO_UART2_PORT GPIO_PORT_0
#定义GPIO_UART2_TX_PIN GPIO_PIN_0#定义GPIO_UART2_RX_PIN GPIO_PIN_1
#定义GPIO_SPI_PORT GPIO_PORT_0
#定义GPIO_SPI_CS_PIN GPIO_PIN_4#定义GPIO_SPI_CLK_PIN GPIO_PIN_5#定义GPIO_SPI_DI_PIN GPIO_PIN_6#定义GPIO_SPI_DO_PIN GPIO_PIN_7
#定义GPIO_RF_PORT GPIO_PORT_1
#定义GPIO_RF_WAKE_PIN GPIO_PIN_0#定义GPIO_RF_RDYN_PIN GPIO_PIN_1
Void set_pad_functions(Void) //设置gpio端口功能模式{// UART引脚配置GPIO_ConfigurePin(GPIO_UART2_PORT, GPIO_UART2_TX_PIN, OUTPUT, PID_UART2_TX, false);GPIO_ConfigurePin(GPIO_UART2_PORT, GPIO_UART2_RX_PIN, INPUT_PULLDOWN, PID_UART2_RX, false);
//未使用引脚配置GPIO_ConfigurePin(GPIO_UNUSED_PORT, GPIO_UNUSED_OTP_PIN, INPUT_PULLDOWN, PID_GPIO, false);GPIO_ConfigurePin(GPIO_UNUSED_PORT, GPIO_UNUSED3_PIN, INPUT_PULLDOWN, PID_GPIO, false);
// SPI引脚配置GPIO_ConfigurePin(GPIO_SPI_PORT, GPIO_SPI_CLK_PIN, INPUT, PID_SPI_CLK, false);GPIO_ConfigurePin(GPIO_SPI_PORT, GPIO_SPI_CS_PIN, INPUT, PID_SPI_EN, true);/ /活性低GPIO_ConfigurePin(GPIO_SPI_PORT, GPIO_SPI_DO_PIN, INPUT_PULLDOWN, PID_GPIO, false);//初始设置为PULLDOWN,当CS断言时将设置为OUTPUT。GPIO_ConfigurePin(GPIO_SPI_PORT, GPIO_SPI_DI_PIN, INPUT, PID_SPI_DI, false);
// RF_WAKE和RF_RDYN引脚配置GPIO_ConfigurePin(GPIO_RF_PORT, GPIO_RF_WAKE_PIN, OUTPUT, PID_GPIO, true);/ /活性低GPIO_ConfigurePin(GPIO_RF_PORT, GPIO_RF_RDYN_PIN, OUTPUT, PID_GPIO, true);/ /活性低}
/ * ****************************************************************************************** @brief断言RF_WAKE信号。***************************************************************************************** /__INLINE空白assert_rf_wake(空白){//拉RF_WAKE GPIO line low (assert RF_WAKE line)SetWord16 (RF_WAKE_RESET_DATA_REG RF_WAKE_MASK);
//轮询以确保RF_ATTN行被断言而(! rf_wake_is_asserted ()){SetWord16 (RF_WAKE_RESET_DATA_REG RF_WAKE_MASK);}}
/ * *****************************************************************************************取消断言RF_WAKE信号。***************************************************************************************** /__INLINE空白deassert_rf_wake(空白){//拉RF_WAKE GPIO line high (deassert RF_WAKE line)SetWord16 (RF_WAKE_SET_DATA_REG RF_WAKE_MASK);
//轮询以确保RF_WAKE线路被取消/ /当(rf_wake_is_asserted ())/ / {/ / SetWord16 (RF_WAKE_SET_DATA_REG RF_WAKE_MASK);//}}
空白spi_slave_init(空白){//外围时钟寄存器CLK_PER_REGSetBits16 (CLK_PER_REG SPI_DIV SPI_FREQ_DIV_2);//设置SPI内部时钟分频器为2,//允许16M/2 = 8M的SPI采样频率// SPI采样频率至少需要4X > SPI时钟频率SetBits16 (CLK_PER_REG SPI_ENABLE 1);// SPI时钟使能
// SPI控制寄存器SPI_CTRL_REGSetBits16 (SPI_CTRL_REG SPI_ON 0);//关闭SPI模块,如果打开SetBits16 (SPI_CTRL_REG SPI_WORD SPI_MODE_32BIT);// 32位模式SetBits16 (SPI_CTRL_REG SPI_SMN SPI_ROLE_SLAVE);//设置SPI为SLAVE模式SetBits16 (SPI_CTRL_REG SPI_POL SPI_CLK_IDLE_POL_LOW);//模式0:SPI_CLK_IDLE_POL_LOWSetBits16 (SPI_CTRL_REG SPI_PHA SPI_PHA_MODE_0);/ /和SPI_PHA_MODE_0SetBits16 (SPI_CTRL_REG SPI_MINT SPI_MINT_ENABLE);//开启SPI Maskable Interrupt to CPUSetBits16 (SPI_CTRL_REG SPI_CLK SPI_XTAL_DIV_8);// SPI时钟频率为SPI采样频率/8 = 1MSetBits16 (SPI_CTRL_REG SPI_EN_CTRL 1);//启用从模式的SPI EN引脚SetBits16 (SPI_CTRL_REG SPI_DO 0);//当SPO空闲时,强制sp_do为0
// SPI控制寄存器1 SPI_CTRL_REG1SetBits16 (SPI_CTRL_REG1 SPI_FIFO_MODE 0 x00);//启用SPI RX和TX FIFOs
SetBits16 (SPI_CTRL_REG SPI_ON 1);//启用SPI模块
/ /设置中断NVIC_SetPriority (SPI_IRQn 20);//设置中断优先级为20现在TBD, 0是最高的NVIC_EnableIRQ (SPI_IRQn);
//如果BLE FW准备好与居里交谈如果(readyForSPITraffic){//取消RF_ATTN和RF_WAKE线路deassert_rf_rdyn ();deassert_rf_wake ();}}
空白periph_init(空白){//打开外设的电源域SetBits16 (PMU_CTRL_REG PERIPH_SLEEP 0);while (GetWord16(SYS_STAT_REG) & PER_IS_UP));
SetBits16 (CLK_16M_REG XTAL16_BIAS_SH_ENABLE 1);
/ /罗补丁patch_func ();
/ /初始化垫set_pad_functions ();
/ /(重新)外围设备进行初始化/ /。/ / uart_init (UART_BAUDRATE_115K2 3);
#if (defined(ENABLE_PRINTF) || defined(TEST_BUS_ENABLED_UART2))SetBits16 (CLK_PER_REG UART2_ENABLE 1);uart2_init (UART_BAUDRATE_115K2 3);# endif
//初始化SPI为从设备spi_slave_init ();
//启用padsSetBits16 (SYS_CTRL_REG PAD_LATCH_EN 1);}
我将重点放在你提到的“在意外重置设备将驱动线低”,当设备重置时,58x遵循的过程是由代码的位置决定的(要么是OTP或从外部设备启动)。当从外部设备启动时,PORT0正在通过设备的外设(UART/SPI/I2C)使用,所有其他端口都处于INPUT PULL DOWN状态,这是引脚的复位状态。在OTP情况下,所有端口都处于INPUT PULLDOWN状态,一旦设备将OTP镜像到sysram,它们就会一直处于该状态,直到fw最终运行并执行外围_init()函数。因此,如果有一个意外的重置从58x侧线切换是相当预期的。
我尝试了各种对话框重置(NMI/Assertion/Hard),每次RF_WAKE都会在主机控制器上触发一个中断。这就是为什么我使用它作为“对话框重置检测线”。然而,这一次这条线路被触发,而没有对话框重置正在....上进行只是不知道如何和为什么....
抱歉,我有点困惑,在你之前的帖子中,你提到了当设备得到意外重置时发生的问题,你看到线变低了,现在你看到了事件发生时没有从设备复位?
你提到的处理程序强制对设备进行重置,显然设备由于外部原因(例如电源问题)而重置,这就是为什么你看到的线越来越低,或者可能因为内存不足而通过platform_reset,或者是什么触发了580本身的重置引脚(重置引脚连接到地了吗?)
如果我在之前的文章中没有把这一点讲清楚,请原谅。我配置了RF_WAKE来检测意外的对话框重置,这是有效的。然而,我的问题是,一些时间(约500次的启动和关闭对话框),启动对话框后,吩咐收音机广告开始,我看到RF_WAKE中断,当对话框在正常状态如图所示从串行printf输出。所以基本上我看到了对话框重置的“假阳性”,我想知道这是怎么发生的。
因此,您确定在这种情况下,581不重置或按任何断言,以导致重置,但RF_WAKE引脚切换并导致中断在您的一边?这是唯一发生的引脚,我的意思是,如果有一个真正的重置其他引脚应该演示相同的行为(你检查过发生在RF_WAKE时其他引脚发生了什么吗?)我没有看到任何明显的原因,一个引脚只是切换一次每500,端口/引脚10没有任何特殊的行为(我的意思是交叉与XTAL或任何类似的)和行为,您所呈现的是没有观察到的对话框。你们能否提供任何可以共享的测试fw,以检查我们是否可以在独立设备上复制这种行为?
你好,
当使用延长睡眠时,您将看到以下行为:在每次唤醒时,在user_peri_setup .c (peri_init()函数)中重新初始化gpio。这个函数将重新锁存所有输出锁存,并完全按照您描述的那样操作,并将所有gpio设置为同一文件的set_pad_functions()中定义的状态。
/ MHv
间歇性的不想要的中断并没有出现在系统从睡眠中唤醒时。相反,他们在第一次打开收音机播放广告后是正确的。我将STARTUP_SLEEP_DELAY_DEFAULT更改为3秒,这样当睡眠仍然被禁用时,广告总是启动,但我仍然看到不必要的中断。
此外,我从来没有看到这种情况发生时,BLE连接和延长睡眠启用。
嗨zheshen,
你能告诉我们你使用的是哪个引脚,问题发生了吗?你确定那些引脚没有被581的任何外设使用,所以它们可以接管特定引脚的控制,也许是SPI接口的引脚?您还可以告诉我们您在开发您的应用程序时使用的初始示例吗?也许这也和电源有关,所以当事故发生时,你能检查一下电源并监控电源状态吗?您确定发生在外部设备上的中断是由于GPIO的切换(您使用分析器监控引脚了吗?)事实上,您已经注意到设备在无线电活动活动之前切换作为输出的引脚,可能是由于您启用了诊断引脚,您在项目中有这种功能吗?
由于MT_dialog
MT_dialog:
请参阅下面的代码。RF_WAKE和RF_RDYN都从端口1配置为GPIO线(DA14581输出和Host输入),并且在应用程序启动后预期为空闲高。在意外重置DA14581时,RF_WAKE线将在短时间内处于低电平,这将触发主机控制器上的中断,作为响应,主机控制器将断电并上电DA14581。RF_RDYN用于SPI同步信号。在此问题之前,DA14581与主机之间的握手涉及SPI数据传输(主机作为SPI master)和RF_RDYN信令,未发现问题。
Spi_slave_init在set_pad_functions和powerup uart2之后被调用。函数deassert_rf_wake()设置RF_WAKE高在外围init中被调用,因此在系统初始化和从睡眠中唤醒时被调用。函数assert_rf_wake()将RF_WAKE设置为低值,但不会在固件代码的任何地方调用。
所有SPI信号配置GPIO线从端口0。该项目基于SDK 5.0,没有使用特定的示例。我无法捕获导致问题的RF_WAKE或RF_RDYN上的确切脉冲,因为DA14581每隔几秒就会上电一次,这个问题可能几个小时后才会出现。我在主机端的执行跟踪显示了RF_WAKE和RF_RDYN上的中断同时被引发。
我不确定你说的诊断针是什么。set_pad_functions函数定义了我正在使用的所有引脚。
#定义GPIO_UART2_PORT GPIO_PORT_0
#定义GPIO_UART2_TX_PIN GPIO_PIN_0
#定义GPIO_UART2_RX_PIN GPIO_PIN_1
#定义GPIO_SPI_PORT GPIO_PORT_0
#定义GPIO_SPI_CS_PIN GPIO_PIN_4
#定义GPIO_SPI_CLK_PIN GPIO_PIN_5
#定义GPIO_SPI_DI_PIN GPIO_PIN_6
#定义GPIO_SPI_DO_PIN GPIO_PIN_7
#定义GPIO_RF_PORT GPIO_PORT_1
#定义GPIO_RF_WAKE_PIN GPIO_PIN_0
#定义GPIO_RF_RDYN_PIN GPIO_PIN_1
Void set_pad_functions(Void) //设置gpio端口功能模式
{
// UART引脚配置
GPIO_ConfigurePin(GPIO_UART2_PORT, GPIO_UART2_TX_PIN, OUTPUT, PID_UART2_TX, false);
GPIO_ConfigurePin(GPIO_UART2_PORT, GPIO_UART2_RX_PIN, INPUT_PULLDOWN, PID_UART2_RX, false);
//未使用引脚配置
GPIO_ConfigurePin(GPIO_UNUSED_PORT, GPIO_UNUSED_OTP_PIN, INPUT_PULLDOWN, PID_GPIO, false);
GPIO_ConfigurePin(GPIO_UNUSED_PORT, GPIO_UNUSED3_PIN, INPUT_PULLDOWN, PID_GPIO, false);
// SPI引脚配置
GPIO_ConfigurePin(GPIO_SPI_PORT, GPIO_SPI_CLK_PIN, INPUT, PID_SPI_CLK, false);
GPIO_ConfigurePin(GPIO_SPI_PORT, GPIO_SPI_CS_PIN, INPUT, PID_SPI_EN, true);/ /活性低
GPIO_ConfigurePin(GPIO_SPI_PORT, GPIO_SPI_DO_PIN, INPUT_PULLDOWN, PID_GPIO, false);//初始设置为PULLDOWN,当CS断言时将设置为OUTPUT。
GPIO_ConfigurePin(GPIO_SPI_PORT, GPIO_SPI_DI_PIN, INPUT, PID_SPI_DI, false);
// RF_WAKE和RF_RDYN引脚配置
GPIO_ConfigurePin(GPIO_RF_PORT, GPIO_RF_WAKE_PIN, OUTPUT, PID_GPIO, true);/ /活性低
GPIO_ConfigurePin(GPIO_RF_PORT, GPIO_RF_RDYN_PIN, OUTPUT, PID_GPIO, true);/ /活性低
}
/ * *
****************************************************************************************
* @brief断言RF_WAKE信号。
****************************************************************************************
* /
__INLINE空白assert_rf_wake(空白)
{
//拉RF_WAKE GPIO line low (assert RF_WAKE line)
SetWord16 (RF_WAKE_RESET_DATA_REG RF_WAKE_MASK);
//轮询以确保RF_ATTN行被断言
而(! rf_wake_is_asserted ())
{
SetWord16 (RF_WAKE_RESET_DATA_REG RF_WAKE_MASK);
}
}
/ * *
****************************************************************************************
取消断言RF_WAKE信号。
****************************************************************************************
* /
__INLINE空白deassert_rf_wake(空白)
{
//拉RF_WAKE GPIO line high (deassert RF_WAKE line)
SetWord16 (RF_WAKE_SET_DATA_REG RF_WAKE_MASK);
//轮询以确保RF_WAKE线路被取消
/ /当(rf_wake_is_asserted ())
/ / {
/ / SetWord16 (RF_WAKE_SET_DATA_REG RF_WAKE_MASK);
//}
}
空白spi_slave_init(空白)
{
//外围时钟寄存器CLK_PER_REG
SetBits16 (CLK_PER_REG SPI_DIV SPI_FREQ_DIV_2);//设置SPI内部时钟分频器为2,
//允许16M/2 = 8M的SPI采样频率
// SPI采样频率至少需要4X > SPI时钟频率
SetBits16 (CLK_PER_REG SPI_ENABLE 1);// SPI时钟使能
// SPI控制寄存器SPI_CTRL_REG
SetBits16 (SPI_CTRL_REG SPI_ON 0);//关闭SPI模块,如果打开
SetBits16 (SPI_CTRL_REG SPI_WORD SPI_MODE_32BIT);// 32位模式
SetBits16 (SPI_CTRL_REG SPI_SMN SPI_ROLE_SLAVE);//设置SPI为SLAVE模式
SetBits16 (SPI_CTRL_REG SPI_POL SPI_CLK_IDLE_POL_LOW);//模式0:SPI_CLK_IDLE_POL_LOW
SetBits16 (SPI_CTRL_REG SPI_PHA SPI_PHA_MODE_0);/ /和SPI_PHA_MODE_0
SetBits16 (SPI_CTRL_REG SPI_MINT SPI_MINT_ENABLE);//开启SPI Maskable Interrupt to CPU
SetBits16 (SPI_CTRL_REG SPI_CLK SPI_XTAL_DIV_8);// SPI时钟频率为SPI采样频率/8 = 1M
SetBits16 (SPI_CTRL_REG SPI_EN_CTRL 1);//启用从模式的SPI EN引脚
SetBits16 (SPI_CTRL_REG SPI_DO 0);//当SPO空闲时,强制sp_do为0
// SPI控制寄存器1 SPI_CTRL_REG1
SetBits16 (SPI_CTRL_REG1 SPI_FIFO_MODE 0 x00);//启用SPI RX和TX FIFOs
SetBits16 (SPI_CTRL_REG SPI_ON 1);//启用SPI模块
/ /设置中断
NVIC_SetPriority (SPI_IRQn 20);//设置中断优先级为20现在TBD, 0是最高的
NVIC_EnableIRQ (SPI_IRQn);
//如果BLE FW准备好与居里交谈
如果(readyForSPITraffic)
{
//取消RF_ATTN和RF_WAKE线路
deassert_rf_rdyn ();
deassert_rf_wake ();
}
}
空白periph_init(空白)
{
//打开外设的电源域
SetBits16 (PMU_CTRL_REG PERIPH_SLEEP 0);
while (GetWord16(SYS_STAT_REG) & PER_IS_UP));
SetBits16 (CLK_16M_REG XTAL16_BIAS_SH_ENABLE 1);
/ /罗补丁
patch_func ();
/ /初始化垫
set_pad_functions ();
/ /(重新)外围设备进行初始化
/ /。
/ / uart_init (UART_BAUDRATE_115K2 3);
#if (defined(ENABLE_PRINTF) || defined(TEST_BUS_ENABLED_UART2))
SetBits16 (CLK_PER_REG UART2_ENABLE 1);
uart2_init (UART_BAUDRATE_115K2 3);
# endif
//初始化SPI为从设备
spi_slave_init ();
//启用pads
SetBits16 (SYS_CTRL_REG PAD_LATCH_EN 1);
}
嗨zheshen,
我将重点放在你提到的“在意外重置设备将驱动线低”,当设备重置时,58x遵循的过程是由代码的位置决定的(要么是OTP或从外部设备启动)。当从外部设备启动时,PORT0正在通过设备的外设(UART/SPI/I2C)使用,所有其他端口都处于INPUT PULL DOWN状态,这是引脚的复位状态。在OTP情况下,所有端口都处于INPUT PULLDOWN状态,一旦设备将OTP镜像到sysram,它们就会一直处于该状态,直到fw最终运行并执行外围_init()函数。因此,如果有一个意外的重置从58x侧线切换是相当预期的。
由于MT_dialog
我尝试了各种对话框重置(NMI/Assertion/Hard),每次RF_WAKE都会在主机控制器上触发一个中断。这就是为什么我使用它作为“对话框重置检测线”。然而,这一次这条线路被触发,而没有对话框重置正在....上进行只是不知道如何和为什么....
嗨zheshen,
抱歉,我有点困惑,在你之前的帖子中,你提到了当设备得到意外重置时发生的问题,你看到线变低了,现在你看到了事件发生时没有从设备复位?
你提到的处理程序强制对设备进行重置,显然设备由于外部原因(例如电源问题)而重置,这就是为什么你看到的线越来越低,或者可能因为内存不足而通过platform_reset,或者是什么触发了580本身的重置引脚(重置引脚连接到地了吗?)
由于MT_dialog
如果我在之前的文章中没有把这一点讲清楚,请原谅。我配置了RF_WAKE来检测意外的对话框重置,这是有效的。然而,我的问题是,一些时间(约500次的启动和关闭对话框),启动对话框后,吩咐收音机广告开始,我看到RF_WAKE中断,当对话框在正常状态如图所示从串行printf输出。所以基本上我看到了对话框重置的“假阳性”,我想知道这是怎么发生的。
嗨zheshen,
因此,您确定在这种情况下,581不重置或按任何断言,以导致重置,但RF_WAKE引脚切换并导致中断在您的一边?这是唯一发生的引脚,我的意思是,如果有一个真正的重置其他引脚应该演示相同的行为(你检查过发生在RF_WAKE时其他引脚发生了什么吗?)我没有看到任何明显的原因,一个引脚只是切换一次每500,端口/引脚10没有任何特殊的行为(我的意思是交叉与XTAL或任何类似的)和行为,您所呈现的是没有观察到的对话框。你们能否提供任何可以共享的测试fw,以检查我们是否可以在独立设备上复制这种行为?
由于MT_dialog