Драйвер EEPROM I2C завис во время теста ESD?

В нашем прототипе у нас есть EEPROM на основе I2C. Во время теста ESD (искра с высоким потенциалом вводится в систему на очень короткое время) драйверы зависают в коде I2C.

В основном существуют циклы while, в которых мы проверяем, занят ли флаг, установлен флаг передачи или нет, подтверждение получено или нет, используя соответствующие регистры. Итак, если какой-либо из параметров не соответствует, то код будет зависать в самом этом цикле.

Этот драйвер нормально работает в нормальных условиях.

Но при искровом впрыске зависает в одном из шлейфов.

И даже после теста ESD он остается в том же состоянии, он не восстанавливается, пока мы не перезапустим устройство.

Что может пойти не так с контроллером (шина I2c MSP430F6438) или ведомым устройством (EEPROM на базе I2c), из-за чего код зависает в одном из циклов, который проверяет занятость шины, флаг передачи, флаг подтверждения получения?

Вы говорите об испытаниях на электростатический разряд или электромагнитную совместимость? Испытание на электростатический разряд обычно означает применение импульсов статического разряда к различным частям системы, а не постоянное воздействие.
Его тестирование на электростатический разряд, к сожалению, я дал описание тестирования на электромагнитную совместимость в вопросе. Любые предложения, почему он может зависнуть? или отказ I2C.

Ответы (4)

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

Импульс электростатического разряда может вызвать непреднамеренный переход на цифровые сигналы. В системе I2C, если ESD вызывает появление импульса на SDA, когда шина простаивает, это будет интерпретироваться как условие запуска. В зависимости от того, как реализованы uC и периферийные контроллеры I2C, они могут неопределенно долго ждать завершения запущенной транзакции, прежде чем они будут готовы выполнить новую транзакцию (например, сгенерированную вашим кодом).

Конечно, дополнительный импульс на SCL или SDA во время выполнения транзакции I2C (возможно, обнаруженный только одним из двух задействованных чипов) также может привести к тому, что два чипа потеряют отслеживание состояния транзакции и вызовут проблемы.

Поэтому, если вы ищете, где можно улучшить ваше оборудование, чтобы избежать этой ошибки, убедитесь, что ваши линии SDA и SCL проложены по сплошным заземляющим слоям, избегайте чрезмерного расстояния маршрутизации и, возможно, уменьшите значения подтягивающих резисторов. Также убедитесь, что uC и периферийные устройства имеют соответствующие шунтирующие конденсаторы.

Если вы ищете программные обходные пути для этой ошибки, если вы можете обнаружить состояние зависания, вы можете попробовать сбросить блок I2C UC или отправить импульсы SCL (8, 10 или 16?) с выходом SDA на высокий уровень, чтобы очистить I2C. конечный автомат на периферии. Это может потребовать сброса ввода-вывода uC, чтобы он был GPIO, и битового удара, если блок uC I2C также застрял.

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

Попробуйте установить тайм-аут для циклов, чтобы обнаружить сбой; если произойдет сбой, сбросьте оборудование и драйверы I2C.

Простейшим тайм-аутом для реализации будет подсчет количества раз, когда вы тестировали различные флаги, и когда этот счетчик истечет, выход с кодом ошибки.

Более сложным (т.е. полезным) подходом было бы отслеживание аппаратного таймера, работающего в фоновом режиме. При запуске цикла запишите текущее значение таймера плюс желаемое время ожидания; проверьте таймер в начале каждого цикла и, если он превышает предварительно рассчитанное значение, выйдите с кодом ошибки.

Что может пойти не так с контроллером (шина I2c MSP430F6438) или ведомым устройством (EEPROM на основе I2c), что приводит к зависанию кода в одном из циклов, который проверяет наличие занятой шины, флаг передачи, флаг подтверждения приема?

Трудно сказать, что вызывает зависание вашей системы. Но вы можете сделать что-то, чтобы выяснить, где ваш код висит. Если возможно, вы можете вывести сообщение об отладке на экран или на свой компьютер с помощью USART или другого интерфейса. Вы можете добавить некоторый «зонд» в свой код, когда вводите функцию или входите в цикл, вы печатаете какое-то сообщение на свой компьютер, тогда вы можете знать, где зависает ваш код.

Однако добавление тайм-аута к циклу может быть хорошей привычкой.

Разберитесь с ненадежным кодом. Если код зависает из-за непредвиденных обстоятельств, измените код, чтобы учесть непредвиденные обстоятельства. В крайнем случае попробуйте аппаратный сторожевой таймер - хотя это будет работать только (без изменения кода), если есть некоторые внешние строки, которые могут быть декодированы, которые указывают на проблему. Вы также можете подумать о некоторой защите / фильтрации электромагнитных помех на внутренней проводке и, возможно, даже взглянуть на заземляющий слой вокруг микро и EEPROM.