Повесили же, сволочи, управление DE/!RE преобразователя 485-го на пин PA14 (который SWCLK). Вот уже второй час мучаюсь (заодно нашел несколько опечаток у себя в коде): хоть и делаю AFIO_MAPR_SWJ_CFG_DISABLE (да, тактирование AFIO включить не забыл), и настраиваю пин в режим PPOUT, и пишу ему в ODR нуль, все равно на этой ноге 4.5В! При подтяжке резистором к 3.3В получаю 0.2 - явно преобразователь уровней чудит и подтягивает, чтобы в воздухе не болтались. Однако, взял другую плату (с еще нестертой прошивкой), и там - о чудо - нуль (и, соответственно, режим Rx)!
В итоге передавать данные получается, а чтобы принимать, нужно закоротить PA14 на землю.
Думал, прокосячил с полярностью - ан нет, все проверил, как надо: в единичку устанавливаю для передачи, сбрасываю в нуль для приема. Подключил к PA14 осциллограф - вообще никакого шевеления, когда передаю. Однако, отладка работает! Вот только, к сожалению, в режиме отладки через SWD невозможно отключить эти пины (да и если отключишь, что будешь дальше делать?)…
Хрен знает что творится! Как вот у китайцев работает, а у меня - нет?
Надеялся, что где-то протупил, и вместо |= написал строгое равно для AFIO->MAPR, ан нет:
grep MAPR *.c
can.c: AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_REMAP3;
hardware.c: AFIO->MAPR = AFIO_MAPR_SWJ_CFG_DISABLE;
UPD: я уж вообще воткнул листинг нужных регистров во время смена режима (Rx/Tx). И таки что я вижу? MAPR=0x6000! Т.е. какого-то хрена строчка AFIO->MAPR = AFIO_MAPR_SWJ_CFG_DISABLE; не сработала!!!
Засунул AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_DISABLE; в эту функцию в конце. И, о чудо! На второй ее вызов (когда после передачи обратно в прием вернулась линия) я увидел на осциллографе НУЛЬ! И у меня стали передаваться данные (ну и значение уже было правильным: MAPR=0x08006000).
Вот что это за беспредел? Почему в gpio_setup, которую я вначале вызываю, регистр не меняется? Как я выше писал, явно в коде я в его значение вмешиваюсь только когда CAN настраиваю, но и там пишу |= … Неужто оно где-то неявно сбрасывается? Что за ē-мoē?
В общем, фантастика какая-то: даже если я 5 раз в разных местах gpio_setup(); разбросаю AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_DISABLE; (или даже со строгим равенством), ничего не будет! А вот сделав так:
AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_REMAP3;
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_DISABLE; // I don't know why, but without this string JTAG works (despite on turning it off in hardware.c)!
в функции CAN_setup - заработало! НО КАК??? Как, Карл?
Если что, функции настройки в такой последовательности вызываются:
StartHSE();
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
SysTick_Config(72000);
flashstorage_init();
gpio_setup(); // should be run before other peripherial setup
adc_setup();
usart_setup(the_conf.usartspeed);
CAN_setup(the_conf.CANspeed);
modbus_setup(the_conf.modbusspeed);
Код, как обычно,
здесь лежит.