LIS3DH Accelerometer Software ResetLinux

Ответить
Anonymous
 LIS3DH Accelerometer Software Reset

Сообщение Anonymous »

У меня есть печатная плата с акселерометром LIS3DH, и у меня возникли проблемы с тем, чтобы заставить его работать последовательно.
Я написал драйвер I2C для него, где я устанавливал реестр управления Chip, чтобы соответствовать своей цели на этой печатной плате, но, похоже, не работает каждый раз после сброса мощности. У меня есть две проблемы:
1 - у меня есть функция инициирования с сбросом памяти программного обеспечения:

Код: Выделить всё

 static int lis3dh_init_device(void) {
int ret;
u8 reg_value;

// Memory reset
ret = lis3dh_write_reg(LIS3DH_CTRL_REG5, 0x80);
if (ret) {
return ret;
}

// 100 ms register check timeout
int timeout = 100;
while (timeout > 0) {
mdelay(10);
timeout -= 20;

ret = lis3dh_read_reg(LIS3DH_CTRL_REG5, &reg_value);
if (!ret && !(reg_value & 0x80)) {
break;
}
}

if (timeout dev, "Reset timeout");
return -ETIMEDOUT;
}
mdelay(20);

// ... registers setup

// Read int1 to clear pending interruption
lis3dh_read_reg(LIS3DH_INT1_SRC, &reg_value);

mdelay(20);
return 0;
}
< /code>
Иногда я получаю эту ошибку тайм -аута и уходит драйвер.  Разве 100 мс недостаточно для сброса памяти Чипа? Функции чтения-записи: < /p>
static int lis3dh_read_reg(u8 reg, u8 * value) {
struct i2c_msg msgs[2] = {
{
.addr  = lis3dh.client->addr,
.flags = 0,
.len   = 1,
.buf   = &reg,
},
{
.addr  = lis3dh.client->addr,
.flags = I2C_M_RD,
.len   = 1,
.buf   = value,
},
};

int ret = i2c_transfer(lis3dh.client->adapter, msgs, 2);
if (ret != 2) {
dev_err(&lis3dh.client->dev, "I2C read failed (reg 0x%02x)\n", reg);
return (ret < 0) ? ret : -EIO;
}

return 0;
}

static int lis3dh_write_reg(u8 reg, u8 value) {
u8 buf[2] = {reg, value};
struct i2c_msg msg = {
.addr  = lis3dh.client->addr,
.flags = 0,
.len   = 2,
.buf   = buf,
};

int ret = i2c_transfer(lis3dh.client->adapter, &msg, 1);
if (ret != 1) {
dev_err(&lis3dh.client->dev, "I2C write failed (reg 0x%02x)\n", reg);
return (ret < 0) ? ret : -EIO;
}

return 0;
}
Это шина I2C, обрабатываемая контроллером ЦП.

Код: Выделить всё

static ssize_t active_low_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) {
unsigned long val;
u8 new_value;
int ret;

ret = kstrtoul(buf, 10, &val);
if (ret) {
return ret;
}

new_value = val ? LIS3DH_INT_POLARITY_ACTIVE_LOW : LIS3DH_INT_POLARITY_ACTIVE_HIGH;
ret = lis3dh_verify_reg(LIS3DH_CTRL_REG6, new_value);
if (ret != 0) {
dev_err(&lis3dh.client->dev, "Couldn't set LIS3DH INT1 Active Level");
return ret;
}

mdelay(50);
return count;
}
< /code>
где: < /p>
static int lis3dh_verify_reg(u8 reg, u8 expected_value) {
u8 read_value;
int ret;
int attempts = 5;
int delay_ms = 5;

while (attempts--) {
ret = lis3dh_read_reg(reg, &read_value);
if (ret) {
// progress the delay on error
mdelay(delay_ms);
delay_ms *= 2;
continue;
}

// Quit is the register value is correct
if (read_value == expected_value) {
return 0;
}
else {
ret = lis3dh_write_reg(reg, expected_value);
if (ret) {
mdelay(delay_ms);
delay_ms *= 2;
continue;
}
}
}

dev_err(&lis3dh.client->dev, "Failed to verify reg 0x%02x (expected 0x%02x, got 0x%02x)",
reg, expected_value, read_value);
return -EIO;
}
Chip имеет линии I2C и PIN-подтягивания INT1, это не проблема HW, потому что, когда я управлял чипом полностью из пространства пользователя, используя ioctl , настройка регистрации и полярность сработали просто отлично. Я также не получаю никаких ошибок водителя во время написания новой значения полярности.
Может быть>

Подробнее здесь: https://stackoverflow.com/questions/796 ... ware-reset
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»