Обратное проектирование сигнала i2c

i2c

У меня есть устройство i2c, которое я хотел бы переделать инженером. Используя орингальный мастер устройства, вот снимок из логического анализатора

Я хотел бы заменить оригинальный мастер устройства на arduino, у устройства есть вывод прерывания, который при обнаружении выполнит описанную выше операцию.

До сих пор я выяснил, что адрес 0x53 (первый байт). Я также выяснил,взаимодействуя с устройством, что второй, третий и последний байт-это данные с ведомого устройства.

Как мне написать код arduino для имитации этой транзакции? Вот код, который я написал, и ответ, который я получил, не совсем такой же

#include <Wire.h>

void setup() {
  Wire.begin();        // присоединиться к шине i2c (адрес необязательно для master)
  Wire. setClock(100000)
  Serial.begin(9600);  // начало serial для вывода
}

void loop() {
  Wire.requestFrom(0x53, 6);    // запрос 6 байт с ведомого устройства #8

  while (Wire.available()) { // ведомый может отправить меньше запрошенного
    char c = Wire.read(); // получить байт в качестве символа
    Serial.print(c);         // печать символа
  }

  delay(500);
}

, 👍2

Обсуждение

Вы уверены, что должны получать один и тот же ответ каждый раз, когда запрашиваете данные с устройства? И что происходит с настоящим мастером перед этой транзакцией чтения? Часто устройства I2C работают как "мастер-запись, чтобы сообщить устройству, какие данные вы хотите иметь - > мастер-чтение, чтобы фактически получить эти данные". Поэтому, если перед транзакцией чтения существует основной цикл записи, это может быть важно. Прежде чем пытаться воссоздать мастер с помощью Arduino, я бы попытался понять протокол. Нет простого способа обойти это. В зависимости от того, что вы ожидаете от устройства, ищите шаблоны в потоке данных., @chrisl

@chrisl я могу заверить, что цикла записи нет ни перед каждой транзакцией, ни даже перед самой первой транзакцией во время включения питания. Это нетрудно проверить в логическом анализаторе. И да, я записал все возможные опции устройства( их 11). Он просто продолжает пожинать плоды,единственное отличие-это второй, третий и последний байт в зависимости от того, как вы взаимодействуете с устройством. Как добавить небольшую задержку между каждым байтом?, @DrakeJest

Для введения задержки вам потребуется изменить библиотеку "Провод". Хотя я сомневаюсь, что это помогло бы. Задержка вводится ведущим устройством (так как, если бы ведомый выполнял тактовую настройку, Arduino не смог бы преодолеть это). Зачем это понадобилось рабу? Это прекрасно работает в общении. В I2C, когда ведомое устройство работает слишком медленно для ведущего, связь обычно полностью прерывается, что в основном приводит к блокировке шины I2C. Также вы можете видеть на первом рисунке, что ведомое устройство освобождает линию SDA сразу после импульса подтверждения. Это говорит о том, что он не слишком медленный., @chrisl


1 ответ


1

Индивидуальный протокол

Как уже упоминалось в комментариях, возможно, контроллер и цель обмениваются данными с использованием настраиваемого протокола, для которого вам потребуется изменить библиотеку проводов и/или библиотеку TWI.

Изменить библиотеку TWI непросто, потому что в ней используется очень запутанная смесь кода ISR и кода опроса, отличного от ISR.

Я переписал библиотеку TWI, чтобы вы могли использовать стандартные протоколы пакетного чтения и пакетной записи либо в режиме ISR, либо в режиме опроса, либо создавать свой собственный протокол с использованием функций строительного блока. Он использует сторожевой таймер для обнаружения тайм-аутов, когда шина зависает из-за ошибки.

Терминология

Терминология моей библиотеки TWI соответствует недавно выпущенному NXP Semiconductors v7 спецификации шины I2C, которая имеет:

Обновил термины "ведущий/ведомый" до "контроллер/цель", чтобы привести их в соответствие со спецификацией MIPI I3C и проектом инклюзивного языка NXP

UM10204, I2C-bus specification and user manual, v7, 2021-10-01, Table 1, Revision history

,