DA14581有两条GPIO线配置为输出,并在固件初始化时设置为高电平。这些线路上的负脉冲触发主机控制器上的电平中断。
我发现,大约每500次中就有1次,当DA14581刚刚通电并与主机控制器握手,然后开始发布广告时,这两条GPIO线路同时在主机控制器上触发意外中断。DA14581子卡由外部电源供电。我确保当时没有固件代码会更改GPIO线路状态。
DA14581配置了扩展的睡眠模式。当它连接或断电时,从未发现此问题。
非常感谢您的任何见解。
你好
当使用扩展睡眠时,您将看到以下行为:每次唤醒时,在user_peripher_setup .c (peripher_init()函数)中重新初始化gpio。这个函数将重新锁存所有输出锁存,并完全按照您描述的那样操作,并将所有gpio设置为相同文件的set_pad_functions()中定义的状态。
/ MHv
间歇性不必要的中断并不是从睡眠中唤醒的系统造成的。相反,他们是在第一次打开收音机做广告之后。我将启动\u SLEEP\u DELAY\u默认值更改为3秒,这样广告总是在睡眠仍处于禁用状态时启动,但我仍然看到不必要的中断。
此外,我从未见过这一点,而Ble连接并启用延长睡眠。
嗨,哲深,
你能告诉我们你正在使用哪些销钉和问题?您确定这些引脚是否不受581的任何外围设备,因此它们可以接管特定引脚的控制,也许是SPI接口的引脚?你还能让我们知道你使用的最初的例子,以便开发您的申请吗?也许这是电源相关的,所以请您检查电源并监控事件发生时的状态吗?您是否确定外部设备上发生的中断是因为GPIO的切换(您是否使用分析仪监视引脚?)。事实上,您注意到设备将您在无线电活动活动之前切换为输出的引脚,可能是由于您启用了诊断引脚,您是否在项目上有这种功能性?
谢谢mt_dialog.
mt_dialog:
请参阅下面的代码。RF_WAKE和RF_RDYN都配置为端口1的GPIO线(DA14581输出和主机输入),并且在应用程序启动后预计处于高空闲状态。在意外的DA14581复位时,RF_唤醒线将在短时间内处于低电平,这将触发主机控制器上的中断,作为响应,该中断将关闭DA14581电源并打开DA14581电源。射频同步器用于SPI同步信号。在此之前,DA14581与主机之间的握手涉及SPI数据传输(主机作为SPI主机)和RF_RDYN信令,未发现任何问题。
spi_slave_init在设置_pad_函数和通电uart2后在periph_init中调用。函数deassert_rf_wake()将rf_wake设置为高在periph_init中调用,因此在系统初始化和从睡眠中唤醒时调用。函数assert_rf_wake()将rf_wake设置为低,但在固件代码中的任何地方都没有调用。
所有SPI信号都从端口0配置GPIO线。本项目基于SDK 5.0,没有使用特定的示例。我无法捕捉到RF_WAKE或RF_RDYN上导致这个问题的确切脉冲,因为DA14581每隔几秒钟就会启动电源,这个问题可能在几个小时内都不会出现。我确实在主机端有执行跟踪,显示RF_WAKE和RF_RDYN上的中断同时被引发。
我不知道你说的诊断针是什么。set_pad_functions函数定义了我使用的所有引脚。
#定义GPIO\U UART2\U端口GPIO\U端口\U 0
#定义GPIO\U UART2\U TX\U引脚GPIO\U引脚0#定义GPIO_UART2_RX_PIN GPIO_PIN_1
#define gpio_spi_port gpio_port_0.
#定义GPIO_SPI_CS_引脚GPIO_引脚4#define gpio_spi_clk_pin gpio_pin_5.#define 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_引脚GPIO_引脚1
void set\u pad\u函数(void)//设置gpio端口函数模式{// UART引脚配置GPIO_配置引脚(GPIO_UART2_端口,GPIO_UART2_发送引脚,输出,PID_UART2_发送,错误);GPIO_ConfigurePin(GPIO_UART2_PORT, GPIO_UART2_RX_PIN, INPUT_PULLDOWN, PID_UART2_RX, false);
//未使用的引脚配置GPIO_配置引脚(GPIO_未使用的端口、GPIO_未使用的OTP_引脚、输入_下拉、PID_GPIO、false);GPIO_配置引脚(GPIO_未使用的端口、GPIO_未使用的3引脚、输入_下拉列表、PID_GPIO、false);
// SPI引脚配置GPIO_配置引脚(GPIO_SPI_端口、GPIO_SPI_时钟引脚、输入、PID_SPI_时钟、假);GPIO_ConfigurePin(GPIO_SPI_PORT, GPIO_SPI_CS_PIN, INPUT, PID_SPI_EN, true);//活动低电平GPIO_配置引脚(GPIO_SPI_端口、GPIO_SPI_DO_引脚、输入_下拉、PID_GPIO、false);//最初设置为下拉,在断言CS时将设置为输出。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,输出,pid_gpio,true);//活动低电平}
/******************************************************************************************* @brief assert rf_wake信号。*****************************************************************************************/__inline void aser_rf_wake(void){//拉出rf_wake gpio线路低(assert rf_wake line)SetWord16 (RF_WAKE_RESET_DATA_REG RF_WAKE_MASK);
//轮询以确保RF_ATTN行断言而(!rf_wake_是_断言的()){SetWord16 (RF_WAKE_RESET_DATA_REG RF_WAKE_MASK);}}
/******************************************************************************************* @brief取消断言RF_WAKE信号。*****************************************************************************************/__INLINE空白deassert_rf_wake(空白){//拉出rf_wake gpio line高(deassert rf_wake line)SetWord16(RF_WAKE_SET_DATA_REG,RF_WAKE_MASK);
//轮询以确保RF_唤醒线已解除断言/ /当(rf_wake_is_asserted ())// {//SetWord16(RF_WAKE_SET_DATA_REG,RF_WAKE_MASK);//}}
空白spi_slave_init(空白){// peripherla时钟寄存器clk_per_regsetbits16(clk_per_reg,spi_div,spi_freq_div_2);//将SPI内部时钟分频器设置为2,//这允许16M/2 = 8M SPI采样频率// SPI采样频率至少需要4x> SPI时钟频率设置16(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设置16(SPI控制寄存器、SPI POL、SPI CLK空闲POL低);//模式0:SPI_CLK_IDLE_POL_LOWsetbits16(spi_ctrl_reg,spi_pha,spi_pha_mode_0);//和spi_pha_mode_0.设置16(SPI控制、SPI控制、SPI控制启用);//对CPU启用SPI可屏蔽中断setbits16(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空闲时,强制SPI_DO为0
// SPI控制寄存器1 SPI_CTRL_REG1SetBits16 (SPI_CTRL_REG1 SPI_FIFO_MODE 0 x00);//启用SPI RX和TX fifo
设置16(SPI_CTRL_REG,SPI_ON,1);//启用SPI模块
/ /设置中断NVIC设置优先级(SPI IRQn,20);//将中断优先级设置为20,现在待定,0为最高NVIC_EnableIRQ (SPI_IRQn);
//如果BLE FW准备好与居里交谈如果(readyForSPITraffic){//取消断言RF_ATTN和RF_WAKE行deassert_rf_rdyn();deassert_rf_wake();}}
void 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);
// rom补丁patch_func ();
//初始焊盘set_pad_functions ();
//(重新)初始化外围设备//即。/ / uart_init (UART_BAUDRATE_115K2 3);
#if(已定义(启用打印)已定义(测试总线已启用UART2))setBits16(CLK_PER_REG,UART2_ENABLE,1);uart2_init(UART_波特率_115K2,3);#万一
//将SPI初始化为从设备spi_slave_init ();
//启用padsSetBits16(系统控制寄存器、焊盘锁存器、1);}
我将重点讨论您提到的“在意外重置时,设备将使线路变低”这一点,当设备重置时,58x遵循的过程取决于代码所在的位置(OTP或从外部设备引导)。从外部设备引导时,端口0通过设备的外围设备(UART/SPI/I2C)使用。所有其他端口都处于输入下拉状态,即引脚的复位状态。在OTP情况下,所有端口都处于输入下拉状态,一旦设备将OTP镜像到系统内存,它们将保持该状态,直到fw最终运行并执行periph_init()函数。因此,如果58x侧出现意外重置,则线路的切换是意料之中的。
我尝试了各种对话框重置(NMI/Assertion/Hard),并且每次RF_WAKE都会在主机控制器上触发一个中断。这就是为什么我使用它作为“对话重置检测线”。然而,这一次在....上没有对话框重置时触发了这一行只是不知道是怎么回事,为什么....
对不起,我有点困惑,在你上一篇文章中你提到了这个问题发生在设备出现意外重置时,你看到线条变低了,现在你看到当没有从设备重置时发生的事件?
您提到在设备上重置重置的处理程序,显然,由于外部原因(例如,电源问题)而言,设备将重置为原因,这就是为什么由于内存不足导致的平台_RESET通过平台_RESET,或者某些东西触发了580本身上的复位引脚(是连接到地面的复位引脚)。
对不起,如果我在早期的帖子中没有做这一点。我配置了rf_wake以检测意外的对话框重置,这是工作。但是,我的问题是某些时候(大约500个时间上电和断电对话框),在电源对话框后命令无线电开始广告,我看到了一个RF_Wake中断,而对话框处于正常状态串行Printf输出显示的条件。所以基本上我看到了对话重置的“误报”,我希望了解如何发生这种情况。
所以你可能是那个情况下的581没有重置或命中任何断言,以便导致重置但仍然rf_wake引脚切换并导致侧面的中断?这是唯一一个发生的引脚,我的意思是,如果存在一个真正的重置,其他引脚应该展示相同的行为(你检查了另一个引脚发生在rf_wake的情况下发生什么吗?)。我没有看到销钉的任何明显原因只是为了每500重新切换一次,而端口/引脚10没有任何特殊行为(我的意思是与XTAL或任何类似的串扰),并且没有观察到您呈现的行为通过对话框。您是否可以提供任何测试FW,也许可以分享以检查我们是否可以在独立设备上复制此行为?
你好
当使用扩展睡眠时,您将看到以下行为:每次唤醒时,在user_peripher_setup .c (peripher_init()函数)中重新初始化gpio。这个函数将重新锁存所有输出锁存,并完全按照您描述的那样操作,并将所有gpio设置为相同文件的set_pad_functions()中定义的状态。
/ MHv
间歇性不必要的中断并不是从睡眠中唤醒的系统造成的。相反,他们是在第一次打开收音机做广告之后。我将启动\u SLEEP\u DELAY\u默认值更改为3秒,这样广告总是在睡眠仍处于禁用状态时启动,但我仍然看到不必要的中断。
此外,我从未见过这一点,而Ble连接并启用延长睡眠。
嗨,哲深,
你能告诉我们你正在使用哪些销钉和问题?您确定这些引脚是否不受581的任何外围设备,因此它们可以接管特定引脚的控制,也许是SPI接口的引脚?你还能让我们知道你使用的最初的例子,以便开发您的申请吗?也许这是电源相关的,所以请您检查电源并监控事件发生时的状态吗?您是否确定外部设备上发生的中断是因为GPIO的切换(您是否使用分析仪监视引脚?)。事实上,您注意到设备将您在无线电活动活动之前切换为输出的引脚,可能是由于您启用了诊断引脚,您是否在项目上有这种功能性?
谢谢mt_dialog.
mt_dialog:
请参阅下面的代码。RF_WAKE和RF_RDYN都配置为端口1的GPIO线(DA14581输出和主机输入),并且在应用程序启动后预计处于高空闲状态。在意外的DA14581复位时,RF_唤醒线将在短时间内处于低电平,这将触发主机控制器上的中断,作为响应,该中断将关闭DA14581电源并打开DA14581电源。射频同步器用于SPI同步信号。在此之前,DA14581与主机之间的握手涉及SPI数据传输(主机作为SPI主机)和RF_RDYN信令,未发现任何问题。
spi_slave_init在设置_pad_函数和通电uart2后在periph_init中调用。函数deassert_rf_wake()将rf_wake设置为高在periph_init中调用,因此在系统初始化和从睡眠中唤醒时调用。函数assert_rf_wake()将rf_wake设置为低,但在固件代码中的任何地方都没有调用。
所有SPI信号都从端口0配置GPIO线。本项目基于SDK 5.0,没有使用特定的示例。我无法捕捉到RF_WAKE或RF_RDYN上导致这个问题的确切脉冲,因为DA14581每隔几秒钟就会启动电源,这个问题可能在几个小时内都不会出现。我确实在主机端有执行跟踪,显示RF_WAKE和RF_RDYN上的中断同时被引发。
我不知道你说的诊断针是什么。set_pad_functions函数定义了我使用的所有引脚。
#定义GPIO\U UART2\U端口GPIO\U端口\U 0
#定义GPIO\U UART2\U TX\U引脚GPIO\U引脚0
#定义GPIO_UART2_RX_PIN GPIO_PIN_1
#define gpio_spi_port gpio_port_0.
#定义GPIO_SPI_CS_引脚GPIO_引脚4
#define gpio_spi_clk_pin gpio_pin_5.
#define 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_引脚GPIO_引脚1
void set\u pad\u函数(void)//设置gpio端口函数模式
{
// UART引脚配置
GPIO_配置引脚(GPIO_UART2_端口,GPIO_UART2_发送引脚,输出,PID_UART2_发送,错误);
GPIO_ConfigurePin(GPIO_UART2_PORT, GPIO_UART2_RX_PIN, INPUT_PULLDOWN, PID_UART2_RX, false);
//未使用的引脚配置
GPIO_配置引脚(GPIO_未使用的端口、GPIO_未使用的OTP_引脚、输入_下拉、PID_GPIO、false);
GPIO_配置引脚(GPIO_未使用的端口、GPIO_未使用的3引脚、输入_下拉列表、PID_GPIO、false);
// SPI引脚配置
GPIO_配置引脚(GPIO_SPI_端口、GPIO_SPI_时钟引脚、输入、PID_SPI_时钟、假);
GPIO_ConfigurePin(GPIO_SPI_PORT, GPIO_SPI_CS_PIN, INPUT, PID_SPI_EN, true);//活动低电平
GPIO_配置引脚(GPIO_SPI_端口、GPIO_SPI_DO_引脚、输入_下拉、PID_GPIO、false);//最初设置为下拉,在断言CS时将设置为输出。
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,输出,pid_gpio,true);//活动低电平
}
/**
****************************************************************************************
* @brief assert rf_wake信号。
****************************************************************************************
*/
__inline void aser_rf_wake(void)
{
//拉出rf_wake gpio线路低(assert rf_wake line)
SetWord16 (RF_WAKE_RESET_DATA_REG RF_WAKE_MASK);
//轮询以确保RF_ATTN行断言
而(!rf_wake_是_断言的())
{
SetWord16 (RF_WAKE_RESET_DATA_REG RF_WAKE_MASK);
}
}
/**
****************************************************************************************
* @brief取消断言RF_WAKE信号。
****************************************************************************************
*/
__INLINE空白deassert_rf_wake(空白)
{
//拉出rf_wake gpio line高(deassert rf_wake line)
SetWord16(RF_WAKE_SET_DATA_REG,RF_WAKE_MASK);
//轮询以确保RF_唤醒线已解除断言
/ /当(rf_wake_is_asserted ())
// {
//SetWord16(RF_WAKE_SET_DATA_REG,RF_WAKE_MASK);
//}
}
空白spi_slave_init(空白)
{
// peripherla时钟寄存器clk_per_reg
setbits16(clk_per_reg,spi_div,spi_freq_div_2);//将SPI内部时钟分频器设置为2,
//这允许16M/2 = 8M SPI采样频率
// SPI采样频率至少需要4x> SPI时钟频率
设置16(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
设置16(SPI控制寄存器、SPI POL、SPI CLK空闲POL低);//模式0:SPI_CLK_IDLE_POL_LOW
setbits16(spi_ctrl_reg,spi_pha,spi_pha_mode_0);//和spi_pha_mode_0.
设置16(SPI控制、SPI控制、SPI控制启用);//对CPU启用SPI可屏蔽中断
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空闲时,强制SPI_DO为0
// SPI控制寄存器1 SPI_CTRL_REG1
SetBits16 (SPI_CTRL_REG1 SPI_FIFO_MODE 0 x00);//启用SPI RX和TX fifo
设置16(SPI_CTRL_REG,SPI_ON,1);//启用SPI模块
/ /设置中断
NVIC设置优先级(SPI IRQn,20);//将中断优先级设置为20,现在待定,0为最高
NVIC_EnableIRQ (SPI_IRQn);
//如果BLE FW准备好与居里交谈
如果(readyForSPITraffic)
{
//取消断言RF_ATTN和RF_WAKE行
deassert_rf_rdyn();
deassert_rf_wake();
}
}
void 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);
// rom补丁
patch_func ();
//初始焊盘
set_pad_functions ();
//(重新)初始化外围设备
//即。
/ / uart_init (UART_BAUDRATE_115K2 3);
#if(已定义(启用打印)已定义(测试总线已启用UART2))
setBits16(CLK_PER_REG,UART2_ENABLE,1);
uart2_init(UART_波特率_115K2,3);
#万一
//将SPI初始化为从设备
spi_slave_init ();
//启用pads
SetBits16(系统控制寄存器、焊盘锁存器、1);
}
嗨,哲深,
我将重点讨论您提到的“在意外重置时,设备将使线路变低”这一点,当设备重置时,58x遵循的过程取决于代码所在的位置(OTP或从外部设备引导)。从外部设备引导时,端口0通过设备的外围设备(UART/SPI/I2C)使用。所有其他端口都处于输入下拉状态,即引脚的复位状态。在OTP情况下,所有端口都处于输入下拉状态,一旦设备将OTP镜像到系统内存,它们将保持该状态,直到fw最终运行并执行periph_init()函数。因此,如果58x侧出现意外重置,则线路的切换是意料之中的。
谢谢mt_dialog.
我尝试了各种对话框重置(NMI/Assertion/Hard),并且每次RF_WAKE都会在主机控制器上触发一个中断。这就是为什么我使用它作为“对话重置检测线”。然而,这一次在....上没有对话框重置时触发了这一行只是不知道是怎么回事,为什么....
嗨,哲深,
对不起,我有点困惑,在你上一篇文章中你提到了这个问题发生在设备出现意外重置时,你看到线条变低了,现在你看到当没有从设备重置时发生的事件?
您提到在设备上重置重置的处理程序,显然,由于外部原因(例如,电源问题)而言,设备将重置为原因,这就是为什么由于内存不足导致的平台_RESET通过平台_RESET,或者某些东西触发了580本身上的复位引脚(是连接到地面的复位引脚)。
谢谢mt_dialog.
对不起,如果我在早期的帖子中没有做这一点。我配置了rf_wake以检测意外的对话框重置,这是工作。但是,我的问题是某些时候(大约500个时间上电和断电对话框),在电源对话框后命令无线电开始广告,我看到了一个RF_Wake中断,而对话框处于正常状态串行Printf输出显示的条件。所以基本上我看到了对话重置的“误报”,我希望了解如何发生这种情况。
嗨,哲深,
所以你可能是那个情况下的581没有重置或命中任何断言,以便导致重置但仍然rf_wake引脚切换并导致侧面的中断?这是唯一一个发生的引脚,我的意思是,如果存在一个真正的重置,其他引脚应该展示相同的行为(你检查了另一个引脚发生在rf_wake的情况下发生什么吗?)。我没有看到销钉的任何明显原因只是为了每500重新切换一次,而端口/引脚10没有任何特殊行为(我的意思是与XTAL或任何类似的串扰),并且没有观察到您呈现的行为通过对话框。您是否可以提供任何测试FW,也许可以分享以检查我们是否可以在独立设备上复制此行为?
谢谢mt_dialog.