jcxz 234 12 декабря, 2018 Опубликовано 12 декабря, 2018 · Жалоба 1 час назад, Arlleex сказал: 3. Даю больше 9 стробов по линии SCL. Если сбойнул слэйв (например - потерял клок), то это не поможет. Лучше выполнить многократное стоп-условие. Да и адрес бывает 10-битовый, так что 9 раз - маловато будет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 12 декабря, 2018 Опубликовано 12 декабря, 2018 · Жалоба 21 минуту назад, jcxz сказал: Если сбойнул слэйв (например - потерял клок), то это не поможет. Лучше выполнить многократное стоп-условие. Да и адрес бывает 10-битовый, так что 9 раз - маловато будет. Однако, просто очень странно, что сам производитель рекомендует делать >9 тактов по SCL при высоком SDA, а не формировать стоп-условия. https://www.nxp.com/docs/en/user-guide/UM10204.pdf Цитата 3.1.16 Bus clear In the unlikely event where the clock (SCL) is stuck LOW, the preferential procedure is to reset the bus using the HW reset signal if your I2C devices have HW reset inputs. If the I2C devices do not have HW reset inputs, cycle power to the devices to activate the mandatory internal Power-On Reset (POR) circuit. If the data line (SDA) is stuck LOW, the master should send nine clock pulses. The device that held the bus LOW should release it sometime within those nine clocks. If not, then use the HW reset or cycle power to clear the bus. Как я понимаю, первый случай (SCL залипла в 0) возможен только в ведомых на шине, поддерживающих технологию clock stretching-а. И тут спасет только вход сброса этой микросхемы (если он вообще имеется; как показывает практика, таких устройств меньше, чем обделенных таким входом), либо внешний перетык питания этой микросхемы (как когда-то я делал на одном из своих девайсов). Второй случай (SDA залипла в 0) спасается подачей 9 циклов синхронизации по линии SCL. И вот в течение этих клоков линия SDA должна подняться вверх. А если не поднялась - простите/извините, используйте аппаратный сброс (если есть), либо рубите канаты питание. Для 10-битной адресации логично подавать больше синхроимпульсов для получения такого же эффекта, выводящего из коматоза. В общем, никакой 100% гарантии. Так вот. Если залип SDA в 0, то стоп-условие, ИМХО, вряд ли поможет, так как при этом мы должны уметь формировать фронт на SDA. А он залип. А им надо дернуть. А он насильно притянут ведомым к 0. Вот картинка: Более того, если SCL еще можно сделать выходом типа push-pull (и то только для ведомых, не поддерживающих clock-ctretching), то SDA сделать push-pull нельзя вообще никогда, только open drain, т.к. шина данных двунаправленная, и при залипании шины в 0 (ведомый активировал нижний ключ входного/выходного драйвера) переводить драйвер мастера шины в push-pull и последующая выдача лог. 1 на этой линии может поджарить драйверы или в подчиненном, либо в мастере (МК). Тогда уж, ИМХО, совсем правильная процедура сброса будет включать сначала подачу 9 (или больше) импульсов синхронизации на SCL при отпущенном SDA, а затем, попутно проверяя состояние SDA входным регистром GPIO, поймав на SDA лог. 1, дать стоп-условие. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 12 декабря, 2018 Опубликовано 12 декабря, 2018 · Жалоба 1 hour ago, jcxz said: Если сбойнул слэйв (например - потерял клок), то это не поможет. Лучше выполнить многократное стоп-условие. Да и адрес бывает 10-битовый, так что 9 раз - маловато будет. Зависит от того, какие устройства есть на шине. Где-то видел апноту, где этот вопрос разжёвывали. Считали худший случай для разных вариантов и всё такое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 12 декабря, 2018 Опубликовано 12 декабря, 2018 · Жалоба 1 минуту назад, scifi сказал: Зависит от того, какие устройства есть на шине. Где-то видел апноту, где этот вопрос разжёвывали. Считали худший случай для разных вариантов и всё такое. Разве зависит? I2C же допускает объединение на одной шине устройств с 7-и и 10-битным адресом? Если так, то 7-битные должны как-то определять что сейчас передаётся 10-битный адрес. И соответственно пропускать его весь. Вот что сказано в википедии: Комбинация бит 11110ХХ адреса зарезервирована для 10-битной адресации. Получается похоже что можно совмещать на одной шине устройства с разной длиной адреса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 12 декабря, 2018 Опубликовано 12 декабря, 2018 · Жалоба 37 минут назад, Arlleex сказал: Так вот. Если залип SDA в 0, то стоп-условие, ИМХО, вряд ли поможет, так как при этом мы должны уметь формировать фронт на SDA. А он залип. А им надо дернуть. А он насильно притянут ведомым к 0. Вот картинка: Как может залипнуть SDA? Если клоки SCL подаются то в конце концов доберёмся до конца принимаемого байта (раз SDA был == 0, значит слэйв передавал), до бита ACK, и он по любому отлипнет. 39 минут назад, Arlleex сказал: Тогда уж, ИМХО, совсем правильная процедура сброса будет включать сначала подачу 9 (или больше) импульсов синхронизации на SCL при отпущенном SDA, а затем, попутно проверяя состояние SDA входным регистром GPIO, поймав на SDA лог. 1, дать стоп-условие. Я просто даю много раз подряд СТОП-условие. Потому что если слэйв в состоянии передачи, и даже почему-то сразу не отработает СТОП посреди байта, то по-крайней мере он его будет воспринимать как клок, дойдёт до конца байта, и на ACK-е примет СТОП. Просто у меня количество СТОП-ов == длина байта + макс.длина адреса (10 битного). Clock-stretching отрабатываю всегда. На его залипание не рассчитываю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 12 декабря, 2018 Опубликовано 12 декабря, 2018 · Жалоба 5 часов назад, Integro сказал: Как показывает практика, подвиcает не блок микроконтроллера, а один из slave'вов держит линию данных в нуле. Моя практика показывает, что I2C подвисает даже если на шине нет ни одного устройства, способного тянуть SCL к нулю.:( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться