Поиск ошибки FDCAN, которой нет

Всегда работа с CAN была простой, но что-то пошло не так (в устройстве на КДПВ)…
image
В последнее время мне часто удается использовать микроконтроллер STM32H750VB, и вот в одном устройстве понадобилось задействовать шину CAN, но первая же попытка, которую я предпринял показала всю мою самоуверенность дала странный результат. Ниже описана история

Итак, сначала о схемотехнике. На КДПВ зеленым обведен, понятно дело, сам виновник — микроконтроллер, тут ничего сложного с CAN нет — он подключен согласно

image

В качестве физического уровня применен MAX3051 (ну нравится он мне…), вот примерно так:

image

Ранее вместо STM32H750VB в такой же системе был STM32F107, но старичок не справился с задачами и было решено заменить его на модный и молодежный более современный.

Но вот незадача — у старого микроконтроллера был bxCAN, а в новом уже FDCAN. Хотя отличия и есть, но с точки зрения кода (да и работы — устойства-то на шине старые): замена — это очень просто. Для желающих можно сравнить:

В общем, косметические различия. И мне казалось, что и заработает все сразу и правильно.

Однако, сразу не заработало…

Контроллер CAN не мог выставить доминантный уровень и переходил в отказ состояние Bus-Off, также никаких данных с шины не принималось (притом, что другое устройство на шине стабильно посылало пакеты два раза в секунду).

Что ж, подумал я, пришла очередь отладки, и припаял проводки на линии CAN-RX и CAN-TX (собственно просмотр самой шины выглядел логично — устройство молчало, а подключенное другое устройство посылало пакеты, как договаривались).

После этого вначале был включен режим FDCAN_MODE_BUS_MONITORING. И, о чудо, сразу увиделись пакеты от шины! (В этом режиме контроллер CAN только слушает данные, но ничего не передает). Так, замечательно…

Далее был включен режим FDCAN_MODE_EXTERNAL_LOOPBACK (в этом режиме, наоборот, слушаем только себя, но зато все передаем в шину). И на линиях CAN_RX и CAN_TX появились все пакеты данных — как отправляемые самим устройством, так и принимаемые с шины, вот на 
рисунке ниже (серым данные TX от микроконтроллера, оранжевым данные линии RX) они видны как пики:

image

Итак, после этого эксперимента стало понятно, что схема работает верно, контроллер CAN в микропроцессоре может как принимать, так и передавать данные.

Однако при попытке одновременно как принимать, так и передавать данные все равно система становилась Bus-Off c ошибкой в регистре контроля ошибок (FDCAN protocol status register (FDCAN_PSR)) LEC[2:0] = 5 —, а это означает из даташита Bit0Error: During the transmission of a message (or acknowledge bit, or active error
flag, or overload flag), the device wanted to send a dominant level (data or identifier bit
logical value 0), but the monitored bus value was recessive…

После двух дней мучений (понятно, в чем ошибка, но не понятно, как исправить) и вдумчивого исследования даташита, errata и кучи стороннего кода и мануалов пришло просветление понимание — все я делаю правильно, но не работает!

Что же, подумал я, может дело в технике, и… заменил сам микроконтроллер (на другой из той же партии). И… оно заработало! Ну то есть вот вообще без плясок с бубном проблем, с исходным кодом и как положено с первого раза.

Краткие итоги

Видимо, попался такой вот хитробракованный экземпляр. Но зато удалось сильно глубже вникнуть в работу FDCAN вообще, что можно отнести к плюсам. А к минусам… А к ним можно отнести потерянное время (контроллер удалось пристроить в другой проект) и понимание того, что современные контроллеры глючат со страшной силой тоже по-современному (или это тоже плюс?).

© Habrahabr.ru