从睡觉醒来后i2c不起作用

⚠️
大家好. .感谢来到论坛。令人兴奋的消息!我们现在正在转移到新的论坛平台的过程中,它将提供更好的功能,并包含在主对话网站。所有的帖子和账号已经迁移。我们现在只接受新论坛的流量-请发布任何新的帖子在https://www.dialog-seminile.com/support.。我们将在未来几天修复错误/优化搜索和标记。
13个员额/ 0个新员额
最后一篇
理查德莱克
离线
最后一次露面:3年10个月前
加入:2017-03-01 18:54
从睡觉醒来后i2c不起作用

我有一个工作I2C,加速度计连接到DEV板。
初始化后的通信工作。
在该单元转到Extended_sleep之后并唤醒I2C不再工作。目前只有I2C上的一个设备。电源未禁用。
日志含义task stuck at ad_i2c.c:284 OS_EVENT_WAIT(dev_config->bus_data->event, OS_EVENT_FOREVER);

中断触发一次,但我不能清除它,因为我需要读取一个地址来清除加速计侧的大头针。所以加速度计似乎还在工作。

我有一次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.

peripher_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,输出,i2c_scl,false);// i2c1 clk.
hw_gpio_configure_pin(HW_GPIO_PORT_4, HW_GPIO_PIN_3, INPUT, GPIO, false);/ / accel硬中断请求优先级别

醒来后,示例说要改变线条。在Periph_init()中是否需要在延长睡眠后缺少I2C通信的情况下进行任何其他需要完成。

谢谢你的协助。

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

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

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

嗨Richard Legault,

我不认为你提到的配置中有任何遗漏,你如何触发系统中传感器存储器等的读取?设备暂停的部分代码是因为它等待来自I2C模块的完整事件,但显然没有发生任何事情。

也请看看下面的帖子,也许这将有所帮助:

https://support.dialog-semicondiondiondum/forums/post/dialog-smartbond-bl ...

谢谢mt_dialog.

理查德莱克
离线
最后一次露面:3年10个月前
加入:2017-03-01 18:54
当它出来的睡眠

当它从休眠状态出来时,I2C状态为0(禁用)。
要使I2C再次发挥作用,仅执行hw_i2c_enable(HW_I2C1)是不够的,我还必须初始化总线并设置目标地址。
因此,I2C Periph_Init的代码现在:

=================.
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,输出,i2c_scl,false);// i2c1 clk.
hw_gpio_configure_pin(HW_GPIO_PORT_4, HW_GPIO_PIN_3, INPUT, GPIO, false);/ / accel硬中断请求优先级别

静态const i2c_config cfg = {
.speed = hw_i2c_speed_fast,
.mode = hw_i2c_mode_master,
.addr_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代码中的一个错误。适配器是否为只有一个设备的总线更新设备地址。

为什么当适配器假设为我这样做时,我必须设置目标Address?如果我没有在init中设置地址,那么我可以为设备读取所有寄存器的值0x07。这是仅在总线上具有一个设备的工件。

mt_dialog.
离线
最后一次露面:5个月2个星期前
职员
加入:2015-06-08 11: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.

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

是的,这是预期的行为,但观察到的行为是我确实需要做那些3个步骤,否则I2C在延长睡眠时醒来时没有响应。

mt_dialog.
离线
最后一次露面:5个月2个星期前
职员
加入:2015-06-08 11:34
你好,理查德。

你好,理查德。

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

/ *从传感器读取单独的阅读和写交易* /
void read_mpu_reg_rw(uint8_t reg_addr)
{
Static uint8_t who_i_am_rw = 0;
Uint8_t addr = reg_addr;
MPU6050 = AD_I2C_OPEN(MPU_6050);
ad_i2c_write (mpu6050 ®_addr 1);
ad_i2c_read (mpu6050 &who_i_am_rw 1);
printf(“%02x \ n \ r”,who_i_am_rw);
}

谢谢mt_dialog.

理查德莱克
离线
最后一次露面:3年10个月前
加入:2017-03-01 18:54
是的,我开了一个开放。这

是的,我开了一个开放。交易呼叫永远不会返回,因为它正在等待I2C完成。我用书写和读数替换了交易,但观察到的行为仍然是相同的。SDK为DA14681为1.0.8.1050.1

谢谢你与此保持一致。我很困惑为什么我在延长睡眠后没有看到预期的行为。

顺便说一下,当我执行HW_I2C_GET_ENABLE_STATUS_STATUS_STATUS()后,延长睡眠后返回0,除非我在PERIPH_INIT中有3个不必要的步骤。

在I2C_Handler()调用I2C-> Intr_CB的值为null。

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

会不会有什么东西导致了这种行为?请注意,我们已经将8MBit winbond替换为64MBit winbond Flash部件。我们为此创建了新的适当标题文件。

#define proj_configoptimal_retram(0)

#if!定义(Reford_Build)&&(proj_configoptimal_retram == 1)
/ *警告:在调试版本中禁用了鼠尾优化!* /
#undef proj_configoptimal_retram.
#define proj_configoptimal_retram(0)
#elif(dg_configexec_mode!= mode_is_cached)
/ *警告:对镜像模式不适用于逆流优化!* /
#undef proj_configoptimal_retram.
#define proj_configoptimal_retram(0)
#万一

#if (proj_configOPTIMAL_RETRAM == 0) / /重新开始
#定义dg_configMEM_RETENTION_MODE (0 x1f)
#定义dg_configSHUFFLING_MODE段(0 x3)

mt_dialog.
离线
最后一次露面:5个月2个星期前
职员
加入:2015-06-08 11:34
你好理查德,

你好理查德,

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

谢谢mt_dialog.

理查德莱克
离线
最后一次露面:3年10个月前
加入:2017-03-01 18:54
它是一项任务

它是在一个被中断唤醒的任务中。我在前面的响应中显示了对kxcjbDevRegisterGet的调用链。

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

这是中断处理程序(HW GPIO的清除由我写的WKUP处理程序完成。任务在检测到某个端口/引脚中断时,使用WKUP寄存器。

//这个想法是,这是中断的顶部,即它向稍后的时间运行的下半部分(任务)的信号。
静态void kxcjbtapeventintr>(void * enceData)
{
// tp_interrupteventdata p_eventdata =(tp_interrupteventdata)eventData;
baseType_t xhigherprioritytaskwoken = pdfalse;

xtasknotifyfromisr(AccelIntractTaskHandle,Accel_Intr_Notify,Esetbits,
&xHigherPriorityTaskWoken);
portyield_from_isr(xhigherprioritytaskwoken);
返回;
}

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

static void accelTaskHL(void *pvParameters)
{
/*将变量定义为static,将其从堆栈中移除*/
静态uint8_t accelSource [2];
t_errorcode错误码;
bool圣;

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, ¬ifyValue, portMAX_DELAY);//等待下一个信号:中断,超时,或控制消息

kxcjbDevRegisterGet (NULL, WHOAMI_ADDR、平差);//在这个函数中我执行ad_i2c_transact()
如果(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 == errercode_ok);
ad_i2c_close(dev);

}
else 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 == errercode_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;
}
/* else we are ignored the timer interrupt, should not happen */
打破;
案例ACCEL_STATE_1:

if(notifyValue&Accel_Intr_Notify){
kxcjbInterruptSrc (NULL, &accelSource [ACCEL_STATE_1]);
printf (" 0 = 0 x % 02 \ n \ r1 = 0 x % 02 r \ n \”,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))

){
xTimerStop (accelTimer 0);
if(Accel_Task_disable_on_tap_detect){
g_accelstate = Accel_State_disable;
kxcjbinterruptdisable();
}
别的 {
g_accelstate = Accel_State_0;
}

if(gfp_tapeventcb){
gfp_tapeventcb(g_appinfo);
}
}
别的 {
printf("交流:\ n \ r ");
fflush(stdout);

Xtimerreset(Acceltimer,0);
Accelsource [Accel_State_0] = Accelsource [Accel_State_1];
g_accelstate = Accel_State_1;/ *重新输入相同的状态* /
}
}
else if (notifyValue & ACCEL_TIMER_NOTIFY) {
g_accelState = ACCEL_STATE_0;
}
别的 {
断言(0 == 1);
}
}
}
}
}

//这是创建任务的代码,

uint32_t status = OS_TASK_CREATE("AccelInterruptHL", /*分配给任务的文本名称,for
只调试;内核不使用。* /
acceltaskkhl, /*系统初始化任务。* /
(void *) 0, /*传递给任务的参数。* /
configminimal_stack_size * os_stack_word_size * 2,
/ *分配给的字节数
任务堆栈。* /
OS_TASK_PRIORITY_HIGHEST,/ *分配给任务的优先级。* /
AccelInterractTaskHandle);/ *任务句柄* /

mt_dialog.
离线
最后一次露面:5个月2个星期前
职员
加入:2015-06-08 11: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.

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

它似乎是由于使用gcc-arm-none-eabi-6-2017-q1-update(使用这个刀具链,我必须使用额外的步骤来获得I2c工作)。
随着提供的GCC工具链:4_9-2015Q3 I2C为广告工作。

感谢您的帮助和坚持不懈。
希望这可以节省他人的时间,知道工具链会影响文档的行为。

mt_dialog.
离线
最后一次露面:5个月2个星期前
职员
加入:2015-06-08 11:34
你好理查德,

你好理查德,

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

MT_dialog问好