Задача такая. Микроконтроллер STM32F1. На шине i2c две микросхемы датчиков, нужно опрашивать их 16 раз в секунду в фоне, не мешая основной задаче.
Для этого реализовал работу с i2c целиком через прерывания и DMA. На вход подаётся набор опкодов, которые управляют последовательностью действий на шине I2C (START, записать 7-битный адрес, читать N байт и так далее, в конце опкод STOP который на шине выставляет состояние STOP).
В конце последовательности должна вызываться указанная мной подпрограмма чтобы решить что дальше делатть.
Далее написал подпрограммы для работы с датчиками. На один датчик просто идёт последовательность чтения/записи регистров, в конце STOP. На второй датчик обмен идёт в два этапа, сначала читаем один регистр, потом STOP, анализируем что получили и в зависимости от этого генерируем новую последовательность опкодов, которую снова запускаем на выполнение.
И так 16 раз в секунду.
По отдельности каждая подпрограмма работает нормально. Проблемы начинаются когда начинаешь их вызывать сразу друг после друга.
Иногда это работает, иногда нет. Причина в том, что последнее прерывание (по которому выполняется опкод STOP и, соответственно, вызов моей подпрограммы) вызывается ДО того, как на шине выставилось состояние STOP. И если я прямо во время этого прерывания "заряжаю" автомат на выполнение следующей последовательности, то периферийный контроллер I2C сбивается с ритма и часто подвисает. То есть, в идеале, после выставления бита STOP в регистре CR1 нужно прождать какое-то время, пока этот STOP реально выполнится, и только после этого начинать следующий обмен по шине.
К сожалению, даташит меня огорчает.
Вложение:
1.jpg [137.33 KiB]
Скачиваний: 386
Как видно, событие (прерывание) EV8_2 вызывается до выставления STOP, а после сигнала STOP никаких событий уже не возникает.
А мне бы хотелось выставить STOP, подождать какое-то время, затем начать следующий цикл обмена. Но такой аппаратной возможности, без тупого ожидания в цикле, я не нашёл. Можно припахать для этого один из таймеров, но хочется обойтись только I2C (библиотека работы с I2C общего плана, не заточенная под конкретный проект).
Кто-нибудь встречался с такой ситуацией?