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

STM32F407V I2C в slave тема конечно избитая

Здравствуйте, Уважаемые Друзья.

 

Есть I2C МАСТЕР который передает и принимает данные.

 

У меня реализован I2C подчиненный который принимает и отдает данные.

 

Мастер ведет себя не совсем корректно по отношению к протоколу I2C.

 

Он делает запрос чтения к моему устройству примерно так

 

СТАРТ->АДРЕСС ЗАПИСИ->ДАННЫЕ, а потом при низком SCL переводит SDA в высокий уровень.

Затем снова выдет

СТАРТ->АДРЕСС ЧТЕНИЕ-> читает данные после чего выдает СТОП.

 

Я по протоколу могу разобрать когда у меня закончится передача данных от мастера, но

вопрос как это сделать аппаратно по прерыванию.

 

Вот тут затыка.

 

В режиме I2C слайв не работает прерывание SB (было сгенерированно условие СТАРТ).

 

Есть еще флаг BERR (Bus error) но он не реагирует на что либо после передачи байта.

 

Может кто сталкивался с подобным.

 

 

 

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


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

СТАРТ->АДРЕСС ЗАПИСИ->ДАННЫЕ, а потом при низком SCL переводит SDA в высокий уровень.

В режиме передачи Master не управляет битом подтверждения ACK, а вот Вы, как Slave, его выдаете. Почему Вы NACK выдаете - это Вам надо разобраться. Master тут не при чем, он делает все правильно. Более того, Master в конце чтения последнего байта должен выставить Вам NACK перед выставлением STOP-сигнала.

Вот тут затыка.

Зачем Вам SB, если у Вас есть замечательное прерывание ADDR? Оно придет после того, как Вы Slave-ом примете свой (или альтернативный, в STM32 их несколько) физический адрес устройства.

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


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

В режиме передачи Master не управляет битом подтверждения ACK, а вот Вы, как Slave, его выдаете. Почему Вы NACK выдаете - это Вам надо разобраться. Master тут не при чем, он делает все правильно. Более того, Master в конце чтения последнего байта должен выставить Вам NACK перед выставлением STOP-сигнала.

 

Зачем Вам SB, если у Вас есть замечательное прерывание ADDR? Оно придет после того, как Вы Slave-ом примете свой (или альтернативный, в STM32 их несколько) физический адрес устройства.

 

С подтверждением там все в порядке.

Мастер передал последний байт.

Слейв ему сказал ACK.

Затем мастер делает следующее

 

SCL = 0

SDA = 1

SCL = 1

SDA = 0 - это новый старт без стопа.

 

С чтением как раз все ОК есть и NAK и СТОП.

 

Прерывание ADDR использую, но оно приходит после передачи адреса (запроса чтения).

В программе есть обработка данных их нужно успеть приготовить для мастера.

Поэтому ищу как понять что мастер окончил передавать.

Но получается что аппаратно никак.

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


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

. . .

Master в конце чтения последнего байта должен выставить Вам NACK перед выставлением STOP-сигнала.

 

. . .Мастер передал последний байт.

Слейв ему сказал ACK . . . .

Мастер, выставляя на последнем байте NACK, информирует слейва, что это - последний байт.

Возможно, что и формирование STOP или ReSTART мастером завязано на установку передачи этого бита в узле I2C.

Наличие установленного мастером NACK на позиции ACK видится слейвом и должно установить флаг прерывания.

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


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

Наличие установленного мастером NACK на позиции ACK видится слейвом и должно установить флаг прерывания.

 

Это так и происходит, но это мастер читает из слейва.

Там все ок и NACK есть и СТОП тоже генерируется.

Это чтение из слейва, проблемы при записи в слейв.

 

Как оно работает.

Мастеру нужно получить какое то количество байт из слейва.

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

По протоколу после этого мастер должен выдать СТОП и потом начать чтение.

Но мастер СТОП не генерит, а тихонько поднимает SDA SCL в 1 и выдает повторный СТАРТ.

 

Дальше при чтение все как и положено в последнем байте NACK и СТОП.

 

NACK я отлавливаю в прерывании тут все нормально работает.

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


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

По протоколу после этого мастер должен выдать СТОП и потом начать чтение.

По какому протоколу? По протоколу I2C? Если так, то ничего он не должен. Для этого и существует понятие повторного старта, чтобы лишний раз не останавливать транзакцию. А STM32 прекрасно ловит после повторного старта и передачи физического адреса прерывание по ADDR, вот его и используйте. И времени там в прерывании раздуплиться да понять что произошло - вагон :rolleyes: Это ж I2C.

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


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

По какому протоколу? По протоколу I2C? Если так, то ничего он не должен.

 

Хм что то не встречал такого поведения МАСТЕРА на I2C.

Обычно СТАРТ СТОП всегда дублируют друг друга.

 

Перечитал еще раз описание I2C кое где есть упоминание что может быть повторный СТАРТ.

Ну да ладно пусть будет так, но моя проблема решается только флагом ADDR.

 

Можно так же извратиться с использованием прерываний по EXTI фиксируя СТАРТ.

 

Вот интересно почему в контроллере не реализовали прерывание на СТАРТ в slave.

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


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

Хм что то не встречал такого поведения МАСТЕРА на I2C.

Обычно СТАРТ СТОП всегда дублируют друг друга.

А Вы посмотрите описание любой микросхемы I2C EEPROM-памяти, там практически в 100% случаев чтение с повторным стартом.

 

Вот интересно почему в контроллере не реализовали прерывание на СТАРТ в slave.

Да ровно по той же причине, по которой весь модуль I2C в STM32 - сплошной костыль. Потому что криворукие инженеры там сидят, вот почему.

Написать полноценный хороший контроллер I2C Master или Slave на STM32 можно, даже со всеми обработками ошибок и т.д., и DMA прикрутить, но это все выйдет в денек-другой сплошного копания Reference Manual, что не всегда позволительно.

 

Ну да ладно пусть будет так, но моя проблема решается только флагом ADDR.

 

Можно так же извратиться с использованием прерываний по EXTI фиксируя СТАРТ.

Я вот реально не понимаю, в чем Ваше недоверие, если это можно так назвать, к прерыванию по ADDR? :biggrin:

Зачем извращаться с EXTI, огребая от него еще кучу лишнего геммороя набора особенностей, если по SCL/SDA пронесется лишний clock...

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


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

. . . По протоколу после этого мастер должен выдать СТОП и потом начать чтение. . . .
По-логике, для "два-в-одном" пакетов-комнад, которые предусматривают двойную функцию запись+чтение

используется ReSTART вместо стоп+старт. К тому что "прописал" Arlleex добавить нечего.

Посмотрите описание фреймов запрос-ответ для EEPROM повышенной емкости, где адрес задается 2 байтами.

(в первой часте фрейма идет запись адреса в слейв, во второй - чтение из слейва).

 

. . . Вот интересно почему в контроллере не реализовали прерывание на СТАРТ в slave.
Состояние "старт" отслеживается автоматом переферийного узла (аппаратно), и генерировать по нему прерывание, IMHO, смысла нет.

(байт еще не пришел, придет ли вообще - неизвестно, а если придет - то об этом будет выставлен другой флаг - что есть инф. в приемном буфере)

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

 

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


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

Я вот реально не понимаю, в чем Ваше недоверие, если это можно так назвать, к прерыванию по ADDR? :biggrin:

 

Много предварительных расчетов данных которые отдаю мастеру.

Мастер не терпит растяжку линии SCL и тд.

 

Софтверно все решил.

Но хотел убедится что аппаратно не получится, вы и подтвердили мои изыскания.

Ладно тему можно закрывать.

 

Спасибо всем за участие.

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


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

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

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

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

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

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

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

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

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

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