I2c睡眠后不工作

⚠️
嗨,...感谢您来论坛。令人兴奋的消息!我们现在正在迁至我们的新论坛平台,将提供更好的功能,并包含在主对话框网站中。所有帖子和帐户都已迁移。我们现在只接受新论坛上的流量 - 请发布任何新线程https://www.dialog-seminile.com/support.。我们将在未来几天修复错误/优化搜索和标记。
13个帖子/ 0新
最后一篇
理查德Legault
离线
最后一次露面:3年8个月前
加入:2017-03-01 18:54
I2c睡眠后不工作

我有一个工作I2C,加速度计连接到DEV板。
初始化后进行通信工作。
当单元进入Extended_Sleep并唤醒后,I2C不再工作。目前在I2C上只有一个设备。电源没有被禁用。
该任务陷入ad_i2c.c:284 os_event_wait(dev_config-> bus_data->事件,os_event_forever);

中断火灾一次,但我无法清除它,因为我需要读取地址以清除来自加速度计侧的PIN。所以加速似乎仍在工作。

我有一次I2C_BUS_INIT(I2C1)和I2C_DEVICE_INIT(ACCEL_KXCJB)。
platform_devices.h包含

I2C_BUS(I2C1)

i2c_slave_device(i2c1,Accel_kxcjb,0x0e,
hw_i2c_addressing_7b,hw_i2c_speed_fast);

I2C_BUS_END.

periph_init()包含(使用HW_GPIO_PINCONFIG宏,因此名称已正确扩展)

hw_gpio_configure_pin(hw_gpio_port_3,hw_gpio_pin_0,输入,i2c_sda,false);// IC21数据
hw_gpio_configure_pin(HW_GPIO_PORT_4, HW_GPIO_PIN_7, OUTPUT, I2C_SCL, false);/ / I2C1 CLK
hw_gpio_configure_pin(hw_gpio_port_4,hw_gpio_pin_3,输入,gpio,false);// Accel Irq.

在唤醒之后,这些例子说要重新创建这些行。还有什么需要在外围init()中做的,我想念I2C通信工作后延长睡眠。

感谢你的协助。

设备:
理查德Legault
离线
最后一次露面:3年8个月前
加入:2017-03-01 18:54
我已经探测了SCL线

我已经探测了SCL线,延长睡眠后没有在线上的活动。

mt_dialog.
离线
最后一次露面:3个月2周前
职员
加入:2015-06-08 34
嗨Richard Legault,

嗨Richard Legault,

我没有看到您提到的配置中缺少的任何缺失,如何触发系统从系统读取传感器存储器等?设备停顿的代码的一部分是因为它等待来自I2C模块的完整事件,并且显然没有发生任何内容。

还请看看下面的职位,也许这将有所帮助:

https://support.dialog-semiconductor.com/forums/post/dialog-smartbond-bl..。

谢谢mt_dialog.

理查德Legault
离线
最后一次露面:3年8个月前
加入:2017-03-01 18:54
当它从睡梦中醒来

当它出来的睡眠时,I2C状态为0(禁用)。
要再次获取I2C功能,请执行HW_I2C_ENABLE(HW_I2C1)我不得不in in in in in in in in in in in in in entr设置目标地址。
因此I2C外围的代码现在是:

=================.
hw_gpio_configure_pin(hw_gpio_port_3,hw_gpio_pin_0,输入,i2c_sda,false);// IC21数据
hw_gpio_configure_pin(HW_GPIO_PORT_4, HW_GPIO_PIN_7, OUTPUT, I2C_SCL, false);/ / I2C1 CLK
hw_gpio_configure_pin(hw_gpio_port_4,hw_gpio_pin_3,输入,gpio,false);// Accel Irq.

Static const i2c_config CFG = {
.speed = hw_i2c_speed_fast,
.mode = HW_I2C_MODE_MASTER,
.ddr_mode = hw_i2c_addressing_7b,
};

hw_i2c_init(hw_i2c1,cfg);
hw_i2c_set_target_address(hw_i2c1,0x0e);/ *出现适配器在公共汽车上只有一个I2C设备时,适配器不会设置地址?* /
hw_i2c_enable(hw_i2c1);
====================

否在示例或文档中没有提及睡眠时需要完成这些初始步骤。我只发现了之前的响应中的链接。

问题是:在深度睡眠后正确行为或在I2C适配器或HW_I2C代码中是一个错误所需的初始化。即使仅具有一个设备的总线,适配器也更新设备地址。

为什么我必须设置TargetAddress时,适配器应该为我做这个?如果我没有在init中设置地址,那么对于从设备的所有寄存器读取,我将得到一个值0x07。这是一件藏物吗因为车上只有一个装置。

mt_dialog.
离线
最后一次露面:3个月2周前
职员
加入:2015-06-08 34
嗨Richard Legault,

嗨Richard Legault,

如上所述,由于之前的帖子上的直接答案不需要,因为您正在使用适配器才能与传感器进行交互,因此适配器将重新启用并为您配置I2C总线,您只需要放置PERIPH_SETUP()函数中的PIN配置。因此,如果您使用的适配器,您将只需使用ad_i2c_open()中声明的I2C设备“和”AD_I2C_TRANSACT()或AD_I2C_WRITE(),AD_I2C_READ()“开始”将打开“已声明的I2C设备”。等等,你如何触发交易?

谢谢mt_dialog.

理查德Legault
离线
最后一次露面:3年8个月前
加入:2017-03-01 18:54
是的,这是预期的

是的,这是预期的行为,但观察到的行为是,我确实需要做这3步,否则I2C在从长时间睡眠中醒来时不会有反应。

mt_dialog.
离线
最后一次露面:3个月2周前
职员
加入:2015-06-08 34
嗨理查德

嗨理查德

它的预期和系统的表现性实际上,如果您调用上面提到的功能,以便启动I2C模块的交互,则
调用ad_i2c_bus_aquire()函数,ad_i2c_bus_apply_config()将为当前事务配置I2C模块(hw_i2c_init() / hw_i2c_enable())
将为当前事务执行主目标地址,也将从HW_I2C_INIT()设置)。所以,如果这是你可以实现的唯一方式
I2C通信也许您不使用适配器才能触发I2C交互。例如,我从RTOS计时器定期读取传感器的值,所以
系统唤醒,使用以下功能,我可以读取传感器的名称。

/*从传感器读取独立的读写事务*/
空白read_mpu_reg_rw (uint8_t reg_addr)
{
静态uint8_t who_i_am_rw = 0;
uint8_t addr = reg_addr;
MPU6050 = AD_I2C_OPEN(MPU_6050);
AD_I2C_WRITE(MPU6050,&REG_ADDR,1);
ad_i2c_read(mpu6050,&who_i_am_rw,1);
printf(“%02x \ n \ r”,who_i_am_rw);
}

谢谢mt_dialog.

理查德Legault
离线
最后一次露面:3年8个月前
加入:2017-03-01 18:54
是的,我有一个空位。的

是的,我有一个空位。事务调用永远不会返回,因为它在等待I2C完成。我用写和读替换了事务,但是我观察到的行为仍然是相同的。DA14681的SDK是1.0.8.1050.1

谢谢你一直这么做。我很困惑,为什么在长时间睡眠后,我没有看到预期的行为。

顺便说一下,当我做hw_i2c_get_enable_status()它返回0后,延长睡眠,除非我有3个不必要的步骤,在迂回init。

在I2C_Handler()调用i2c->时,intr_cb的值是NULL。

我没有改变任何保留设置,但它看起来像I2C的内存(状态)在延长睡眠期间丢失。

可以在那里造成这种行为吗?请注意,我们已将8Mbit Winbond替换为64Mbit Winbond闪存部分。我们已经为它创建了新的合适的头文件。

#define proj_configoptimal_retram(0)

#if!定义(Reford_Build)&&(proj_configoptimal_retram == 1)
/* WARNING: ream优化在DEBUG构建中被禁用!* /
# undef proj_configOPTIMAL_RETRAM
#define proj_configoptimal_retram(0)
#elif (dg_configEXEC_MODE != MODE_IS_CACHED)
/* WARNING: ream optimization are not applicable in MIRRORED mode!* /
# undef proj_configOPTIMAL_RETRAM
#define proj_configoptimal_retram(0)
# endif

#if(proj_configoptimal_retram == 0)
#define dg_configmem_retention_mode(0x1f)
#define dg_configshuffling_mode(0x3)

mt_dialog.
离线
最后一次露面:3个月2周前
职员
加入:2015-06-08 34
嗨理查德,

嗨理查德,

你能告诉我,如何在代码中触发i2c事务的方式,您在哪里放置代码,以便设备启动交互?

谢谢mt_dialog.

理查德Legault
离线
最后一次露面:3年8个月前
加入:2017-03-01 18:54
它是在一个任务中

它是一个由中断醒来的任务。我在以前的响应中向KXCJBDevRegistergitter展示了呼叫链。

由于中断不能使用适配器来与I2C交互,所以任务必须在通过I2C读取中断清除寄存器时清除中断。

下面是中断处理程序(清除HW GPIO是由我编写的WKUP处理程序完成的。任务向WKUP注册,以便在检测到某个端口/PIN中断时调用它们的处理程序。

//这个想法是,这是中断的顶部,即它向稍后的时间运行的下半部分(任务)的信号。
static kxcjbTapEventInterrupt(void* eventData)
{
//tp_interruptEventData p_eventData = (tp_interruptEventData) eventData;
baseType_t xhigherprioritytaskwoken = pdfalse;

xTaskNotifyFromISR(accelInterruptTaskHandle, ACCEL_INTR_NOTIFY, eSetBits,
&xhigherprioritytaskwoken);
portYIELD_FROM_ISR (xHigherPriorityTaskWoken);
返回;
}

//以下是任务//
//这个想法是,这是中断的下半部分计划以稍后的时间运行。

静态void acceltaskhl(空白* pvparameters)
{
/ *定义变量静态以使其从堆栈中获取* /
静态UINT8_T Accelsource [2];
t_errorcode错误码;
BOOL ST;

bool datavalid = false;
UINT32_T NotifyValue;
uint8_t数据;
const TimerHandle_t accelTimer = xTimerCreate("accelTaskTimer",
pdms_to_ticks(750),
pdFALSE,
(void *) 0,
accelTimerCallback);

而(1)
{
XTaskNotifyWait(0x00,Ulong_max,&NotifyValue,portmax_delay);//在这里等待下一个信号:中断,超时或控制消息

kxcjbdevregistergett - null,whoami_addr和数据);//在此函数中,我执行ad_i2c_transact()
if(notifyvalue&Accel_enable_notify){
g_accelstate = Accel_State_0;
kxcjbInterruptEnable ();
i2c_device dev = ad_i2c_open(ACCEL_KXCJB);
errcode = kxcjbbitsset(dev,ctrl_reg1_addr,ctrl_reg1_pc1_en);
断言(errCode = = ERRORCODE_OK);
ad_i2c_close(dev);

}
否则if(notifyValue&Accel_disable_notify){
kxcjbInterruptDisable ();
i2c_device dev = ad_i2c_open(ACCEL_KXCJB);
errcode = kxcjbbitleclear(dev,ctrl_reg1_addr,ctrl_reg1_pc1_en);
断言(errCode = = ERRORCODE_OK);
ad_i2c_close(dev);

g_accelstate = Accel_State_disable;
}
别的
{
切换(G_accelstate){
案例Accel_State_disable:
/* 没做什么 */
休息;
案例Accel_State_0:
if(notifyValue&Accel_Intr_Notify){
kxcjbInterruptSrc (NULL, &accelSource [ACCEL_STATE_0]);

/ *将处理计时器已经运行的情况,
*不应该发生
* /
xTimerReset (accelTimer 0);

g_accelstate = Accel_State_1;
}
/ *我们忽略了定时器中断,不应该发生* /
休息;
案例Accel_State_1:

if(notifyValue&Accel_Intr_Notify){
kxcjbinterruptsrc(null,&accelsource [Accel_State_1]);
printf(“0 = 0x%02x \ n \ r1 = 0x%02x \ n \ r”,Accelsource [0],Accelsource [1]);
。fflush (stdout);
/ *测试是否在同一轴上有源中断
*正如以前的中断发生
* /
if(((Accelsource [Accel_State_0]&(int_source2_xpwu | Int_source2_xnwu))
&&(Accelsource [Accel_State_1]&(int_source2_xpwu | Int_source2_xnwu))
)||
((accelSource (ACCEL_STATE_0) & (INT_SOURCE2_YPWU | INT_SOURCE2_YNWU))
& & (accelSource (ACCEL_STATE_1) & (INT_SOURCE2_YPWU | INT_SOURCE2_YNWU))
)||
((accelSource (ACCEL_STATE_0) & (INT_SOURCE2_ZPWU | INT_SOURCE2_ZNWU))
& & (accelSource (ACCEL_STATE_1) & (INT_SOURCE2_ZPWU | INT_SOURCE2_ZNWU))

){
Xtimstrimer(Accellimer,0);
如果(ACCEL_TASK_DISABLE_ON_TAP_DETECT) {
g_accelState = ACCEL_STATE_DISABLE;
kxcjbInterruptDisable ();
}
其他{
g_accelstate = Accel_State_0;
}

如果(gfp_tapEventCb) {
gfp_tapeventcb(g_appinfo);
}
}
其他{
printf(“ac:to \ n \ r”);
。fflush (stdout);

xTimerReset (accelTimer 0);
Accelsource [Accel_State_0] = Accelsource [Accel_State_1];
g_accelState = ACCEL_STATE_1;/*重新进入相同的状态*/
}
}
否则if(notifyValue&Accel_timer_Notify){
g_accelstate = Accel_State_0;
}
其他{
断言(0 == 1);
}
}
}
}
}

//以下是创建任务的代码,

UINT32_T Status = OS_TASK_CREATE(“AccelIntErrupthl”,/ *分配给任务的文本名称,
调试;不被内核使用。* /
Acceltaskhl,/ *系统初始化任务。* /
(void *)0,/ *传递给任务的参数。* /
configMINIMAL_STACK_SIZE * OS_STACK_WORD_SIZE * 2,
/*分配给
堆栈的任务。* /
OS_TASK_PRIORITY_HIGHEST,/ *分配给任务的优先级。* /
accelInterruptTaskHandle);/*任务句柄*/

mt_dialog.
离线
最后一次露面:3个月2周前
职员
加入:2015-06-08 34
嗨Richard Legault,

嗨Richard Legault,

因此,您已经配置了唤醒定时器,以便从附加的传感器触发传感器读数,每次传感器发出中断时,您通知触发读数的任务,并且您执行读取数据并清除中断清除。似乎好的,我不太得到的是唤醒中断的中断处理程序(我想这是KxcjbtapeventInterrupt,我是正确的),为什么处理程序有一个事件参数?此外,不建议调用portyield_from_isr(虽然我在睡眠模式下测试了它,并且至少在我的侧面时,它不会影响I2C交互),并且您不应该以最高优先级运行任务,因为这可能会影响其他任务(BLE任务,Power Manager任务等)。无论如何,我不认为那些会对I2C造成任何问题,所以我的推荐将调试它并检查代码是否通过I2C交互功能,我的意思是AD_I2C_READ / WRITE等,也,您提到的是配置的配置睡眠为零,一旦I2C交互功能被调用AD_I2C_READ / WRITE等,也可以应用I2C模块的配置。此外,您还可以编写更简单的代码,以测试与I2C中更简单的项目(您可以进行交互)通过简单的计时器或通过唤醒定时器使用传感器 - 从GPIO触发中断)并检查其在您的自定义设备上工作,然后与您现在的那个相比。最后一件事我注意到,您正在使用的I2C引脚的端口是Port4和Port 3,请注意,如果您使用的是WCSP包,则这些端口不可用。

谢谢mt_dialog.

理查德Legault
离线
最后一次露面:3年8个月前
加入:2017-03-01 18:54
它似乎是由于使用

这似乎是由于使用gcc-arm-none-eabi-6-2017-q1-update(在这个工具链中,我必须使用额外的步骤来让I2C工作)。
与提供的gcc工具链:4_9-2015q3 I2C工作的广告。

感谢您的帮助和坚持。
希望这能节省其他人的时间,因为知道工具链会影响记录的行为。

mt_dialog.
离线
最后一次露面:3个月2周前
职员
加入:2015-06-08 34
嗨理查德,

嗨理查德,

感谢您的表明,很高兴您解决了您的问题。

最好的问候mt_dialog.