Миландр. Неожиданное поведение CAN.

У контроллеров Миландр 1986ВЕ9х довольно много небольших проблем, описанных в errata, но так же есть и не описанные. Об одной из таких проблем и поговорим. Здесь не будет кода, только поток мыслей.

Cover Image
  • Из чего состоит проблема?
  • Проблема ли это?
  • Как решить этот вопрос?

Проблема проявляется следующим образом.

Несколько буферов настроены на отправку ответа на запрос RTR. Несколько буферов на приём. Из одного буфера периодически отправляется пакет (обычный пакет данных).

Имеет несколько ситуаций:

  1. Если мы получали RTR запрос и после него решили отправить какие-то данные в простом пакете, то замечаем такую картину - отправляется пакет данных, а за ним отправляется ответ на RTR запрос (хотя никакого запроса сейчас небыло).
  2. Если мы не получали RTR запросов или получили после них просто пакеты данных (в нём не установлен флаг RTR), то при отправке лишнего пакета не наблюдается.

Из-за чего это происходит?

Помимо буферов для приёма и отправки в контроллере CAN если ещё нескаолько теневых регистров для принятого пакета и отправленного Рассмотрим регистры для принятого пакета, для отправленного нам не интересны:

  • MDR_CANx->RXID
  • MDR_CANx->RXDLC
  • MDR_CANx->RXDATAL
  • MDR_CANx->RXDATAH

Проблема кроется в том, что по какой-то причине после отправки пакета задействуется приёмный теневой буфер. И если в регистре RXDLC установлен флаг RTR, то контроллер отправлет ответ.

Проблема ли это?

Могие скажут что нет, другие скажу да, и те и другие правы. Всё зависит от конкретного проекта.

Для меня это явилось проблемой по нескольким причинам, одна из которых самомисный протокол самоопределяющейся сети, в которой одно устройство головное и несколько управляемых. Далее в подробности вдаваться не буду, скажу лишь то, что это портило логику программы и вносило дополнительные сложности, да ещё и увеличивало энергопотребление устройства.

Как решить этот вопрос?

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

Для полноценного решения проблемы необходимо разрешить приём своих пакетов. Получится так, что мы своим пакетом данных (не ответом на RTR) перезапишем регистры теневого буфера и тем самым обойдём данную проблему. Если это не устроит ищите свои способы решения в дополнение к этому. Например можно перевести контроллер в Self Test Mode и чтение с подтверждением своих пакетов, отправить самому себе пакет данных, а после получения вернуть всё обратно, но есть шанс пропустить в это время на линии что-то важное.

В любом случае никому не навязываю своё мнение, выбор исключительно за вами.

PS

Этой проблеме уже 6 лет и она нигде не описана, но несколько раз поднималась на форуме Миландра.

Как всегда - хорошего и безбажного кодинга.