Перейти к содержанию
    

Что-то не совсем адекватно работает модуль I2C2. Или я что-то не учел.

Кто-нить с ним работал. Есть какие-нить дополнительные грабли, кроме описанных в errat'е?

Симптомы: идет постоянный обмен с 8 устройствами. STM32 мастер. В какой-то момент общение со всеми устройствами выпадает на Ack Failed в момент передачи адреса. Отваливаются сразу все. Через некоторое время обмен восстанавливается.

 

З.Ы. на первом i2c висят часы и с ними никаких проблем не обнаружено.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Покопался на форуме ST. Вообщем, хотели как лучше, получилось как всегда.

 

З.Ы. ни у кого нет bit bang реализации i2c? И вообще, как на "быстром" проце делать привязку к времени? Не висеть же все время в процедуре обмена. С другой стороны вешать на прерывание таймера - больно часто выходит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрите здесь свежак: STM32F10xxx devices: advanced I²C examples, если ещё не видели.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрите здесь свежак: STM32F10xxx devices: advanced I²C examples, если ещё не видели.

 

Спасибо. Глядел диагонально. Еще пару месяцев назад этот пример содержал реализации на основе прерываний и полинга. Теперь только ДМА. У меня же основная засада в том, что заранее неизвестно, сколько данных отдаст периферийное устройство. Количество данных идет в первом байте. Т.е. ДМА не мой вариант.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня тоже он че-то не идет. Работает некоторое время, потом виснет. помогает только полный рестарт i2c + передергивание вручную SCL.

прерывания забустил.

Также есть несколько веток (типа https://my.st.com/public/STe2ecommunities/m...urrentviews=304 ) на их форуме, тоже без решений по сути.

Сделал софтовый I2C, благо, шина не сильно нагружена

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще вопрос

 

Пытаюсь запустить обмен по шине на прерываниях. Так вот не пойму, у них прерывание по Start bit send работает в принципе?

То есть выставляю в I2C1->CR1 бит I2C_CR_START. По идее, после генерации старта на шине я должен попасть в прерывание I2C1_EV_IRQHandler() и там увидеть выставленный фдаг SB в SR1, однако, в прерывание не попадаю. Или я что то не так понял?

 

Другие прерывания вроде работают (например ADDR TxE).

Прерывания разрешены, переферия затактирована...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще вопрос

 

Пытаюсь запустить обмен по шине на прерываниях. Так вот не пойму, у них прерывание по Start bit send работает в принципе?

То есть выставляю в I2C1->CR1 бит I2C_CR_START. По идее, после генерации старта на шине я должен попасть в прерывание I2C1_EV_IRQHandler() и там увидеть выставленный фдаг SB в SR1, однако, в прерывание не попадаю. Или я что то не так понял?

 

Другие прерывания вроде работают (например ADDR TxE).

Прерывания разрешены, переферия затактирована...

 

Резисторы подтягивающие в наличии?

Линии SDA и SCL в норме?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Рекомендации ST по поводу I2C:

Это периферийное устройство в STM32 - сложное с кучей диагностических флагов и множеством режимов работы. Кроме того, оно чувствительно к таймингам, оттого инженеры саппорта ST обещают наложить проклятие на каждого, кто будет работать с этим модулем напрямую (и потом будет жаловаться на глюки). Вместо этого строго рекомендуется применять библиотеку CPAL, она доступна с сайта st.com. Не факт, что это ваш случай, но вероятность далеко не нулевая.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Теперь только ДМА. У меня же основная засада в том, что заранее неизвестно, сколько данных отдаст периферийное устройство. Количество данных идет в первом байте. Т.е. ДМА не мой вариант.

Это как так? Мастер не знает, сколько спрашивает? Протокол I2C весьма детерминированный. Мастер определяет, сколько читать/писать. Если у ведомого запросить больше, чем он может дать, он выставит NACK. Это ловится в прерывании, обмен завершается, DMA останавливается. Все чисто. Не глядел еще примеры от ST: в свое время написал свою поддержку, работающую по прерываниям и с использованием DMA, работает стабильно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если у ведомого запросить больше, чем он может дать, он выставит NACK.

 

Не, 24LC можно читать до посинения по кругу, только оно никому не надо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прошу прощения, разобрался, напутал в чтении.

Изменено пользователем sls_

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем доброго времени суток!

Помогите разобраться с опросом MS5611, никак не могу прочитать два байта при опросе, читается старший и все... Может кто сталкивался уже?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем доброго времени суток!

Помогите разобраться с опросом MS5611, никак не могу прочитать два байта при опросе, читается старший и все... Может кто сталкивался уже?

Что значит "читается старший и все"? Что значит "всё", то есть, как это проявляется: выставляется NACK, либо I2C виснет вообще, либо младший байт неправильный по содержанию?

 

Как можно вообще так пространно вопросы ставить и потом на ответы надеяться?...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Доброго времени суток. Юзаю i2c на STM32F4DISCOVERY для опроса датчика. Использую библиотеку CPAL. Появилась проблема, которая вот уже много времени гложет мозг. Суть в следующем.

 

CPAL проверяет таймауты, для чего на CPAL у меня выделен TIM3, по прерыванию раз в мс вызывается библиотечная функция CPAL_I2C_TIMEOUT_Manager(). И все вроде хорошо. НО! Возникают моменты, когда программа затыкается на __CPAL_I2C_TIMEOUT(). Это дефайн, который представляет из себя цикл, выход из которого возможен по одному из двух условий: 1) наступило ожидаемое событие (например, скинулся бит BUSY статусного регистра); 2) превышен лимит ожидания. То есть, если щелкает таймер, то рано или поздно цикл будет покинут. НО! При зависании в __CPAL_I2C_TIMEOUT() таймер хоть и работает, и выставлены нужные флаги, но прерывание, и соответственно, подсчет таймингов, не вызываются.

 

Привожу рисунок, на нем - собственно место затыка во время отладки, а также регистры 3-го таймера. Ниже по коду в комментах - определение самой __CPAL_I2C_TIMEOUT()

post-77447-1373446754_thumb.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Так определите, кто (где, почему) запретил прерывание, если оно не вызывается.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...