Кремень FMZ Реклама
Kremen FMHM Реклама

Marlin, Robin, два сопла

jmz
Идет загрузка
Загрузка
17.12.2018
8119
93
Техничка

Подпишитесь на автора

Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.

Отписаться от уведомлений вы всегда сможете в профиле автора.

38
Marlin, Robin, два сопла
Запуск Marlin на MKS Robin без потери встроенного загрузчика.

Вторая серия закончилась на создании полного набора инструментов, необходимых для подготовки прошивки для MKS Robin. Настало время применить их для чего-то более существенного, чем мигание светодиодом, и продолжить картографирование щедро усеянного граблями поля чудес.

Сборка прошивки для MKS Robin отличается от сборки под обычную отладочную плату, поэтому в platformio.ini был добавлен новый вариант сборки [env:mks_robin] с ‘extra_scripts’, отвечающим за нестандартное расположение прошивки в памяти и шифрование.

MKS Robin - серийно выпускаемая плата, поэтому начинать надо было с создания для нее собственного описания. Новая плата добавляется в Marlin в три простых шага - уникальный идентификатор платы добавляется в Marlinsrccoreoards.h, файл с описанием ног микроконтроллера добавляется в Marlinsrcpins, в файле Marlinsrcpinspins.h прописывается соответствие второго первому.

Для первого запуска много периферии не требовалось, достаточно было COM порта и диода, поэтому для ускорения процесса pins_MKS_ROBIN.h был с минимальными изменениями скопирован с другой STM32F1 платы. В MarlinsrcHALHAL_STM32F1HAL.cpp я добавил код включения светодиода при инициализации платы - экрана нет, а так хоть какой-то контроль работоспособности.

В Configuration.h прописал ‘#define MOTHERBOARD BOARD_MKS_ROBIN’ и ‘#define SERIAL_PORT 3’ и запустил компиляцию. Но чуда не случилось. Или наоборот, случилось, но совсем не то, что ожидалось. PlatformIO наотрез отказался что-либо компилировать под STM32F103ZET6, мотивируя свой отказ отсутствием описания для genericSTM32F103ZE в platformsststm32oards.

В Marlin предусмотрено место для складирования описаний неизвестных плат (boards_dir = buildroot/share/PlatformIO/boards), но в этот нашлось более простое решение. После удаления platformsststm32 и запуска компиляции, PlatformIO заного скачал данные для работы с STM32, где, среди прочего, было и описание genericSTM32F103ZE.

Компиляция прошла успешно. Начало файла выглядело немного непривычно, но без криминала. Для успокоения внутреннего параноика отключил черную магию extra_scripts, скомпилировал заново и сравнил вектора прерываний. В сборке для Robin все вектора были сдвинуты на 0x7000, в полном соответствии с модифицированными параметрами линковки.

После записи прошивки на SD карту и обновления Robin, произошло традиционное ничего. Поскольку для чистоты эксперимента микроконтроллер я не разблокировал и доступа к какой-либо отладочной информации не было, эксперимент был повторен на отладочной плате. Проблема успешно воспроизвелась, но показания ST-Link были, мягко говоря, странными - адрес текущей команды находился в области загрузчика, а не прошивки. Сделал контрольную сборку с отключенным extra_scripts для прошивки без загрузчика, с ней Marlin успешно загрузился.

Скрипт, модифицирующий прошивку для работы с загрузчиком MKS Robin был проверен для фреймворка stm32cube (он же CubeMX, он же HAL) и работал. Marlin использовал stm32duino и не работал. Главное правило настройки чего угодно гласит: “не крути две ручки сразу”, поэтому отложил в сторону Marlin и взял код попроще - arduino-blink из подборки примеров проектов PlatformIO. Без загрузчика blink заработал, с загрузчиком - нет. Отладчик показал адрес текущей команды из области загрузчика. Marlin был оправдан.

Начал разбираться с stm32duino, довольно быстро нашел в начале инициализации вызов функции, меняющий указатель на таблицу векторов прерываний на адрес VECT_TAB_ADDR. В коде значение этой константы нигде не задается, PlatformIO динамически подставляет его в параметры сборки, используя скрипт platformsststm32uilderframeworksarduinomaplestm32f1.py. Добавил в extra_scripts еще немного магии, для замены значения VECT_TAB_ADDR в параметрах сборки, и пересобранный blink начал работать и с загрузчиком.

Контрольная сборка - Marlin загрузился и подал синий свисток в воздух, COM порт заработал, Repetier Host подключился. Для закрепления успеха подцепил на свободные ноги LCD 2004, стало возможным делать фотографии поинтереснее чем “одинокий синий диод”.
Marlin, Robin, два сопла
Оставалось только наполнить глубоким внутренним смыслом pins_MKS_ROBIN.h и проверить периферию на работоспособность. В этот момент неожиданно обнаружилось отсутствие в результатах трассировки данных по подключению полевых транзисторов. Несколько минут спустя выяснилась и причина этого упущения - прозвон напрямую ничего не дает, т.к. между затвором транзистора и микроконтроллером стоит токоограничивающий резистор. Немного странно, что не поставили буферный элемент, как это сделали ST Microelectronics на своей STEVAL-3DP001V1, но раз работает - пусть будет. Прозвон в два этапа дал все четыре управляющий выхода, после чего все они успешно побывали в роли управляющих вентилятором обдува модели.

Теперь глубина внутреннего смысла pins_MKS_ROBIN.h вмещала в себя пять шаговых двигателей, шесть концевиков, вентилятор обдува модели, три нагревателя и датчики температуры, тоже три. Практическое занятие по спортивной ходьбе по граблям показало, что кроме ранее проверенных нагревателей и вентилятора, работают все концевики, все датчики температуры и три из пяти шаговых двигателей. Двигатели Y и E1 не переходили даже в режим удержания и свободно прокручивались рукой. Проверка розовым светодиодом показала, что на линии Enable присутствовало логическое “может быть” - диод светился, но не так ярко, как от полноценного высокого уровня. Для драйвера шагового двигателя это “может быть” являлось законным основанием ничего не делать, чему он самозабвенно и предавался.

Линия Enable для Y - нога PB4, одна из функция которой NRST для JTAG отладчика. Аналогичная проблема была недавно описана в статье 3dmaniack.

Для решения этой проблемы в pins_MKS_ROBIN.h была добавлена строчка ‘#define DISABLE_DEBUG’, обеспечивающая вызов функции JTAG_DISABLE().

Для HAL_STM32F1 JTAG_DISABLE() определена как afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY) и ее вызов полностью снимает все претензии отладчика к ноге PB4, превращая скучный 2D принтер в 3D, с которым, как известно, не соскучишься.

С E1 история вышла похожей - линии Enable и Step забрал себе USB порт, не обращая внимания на такой пустяк, что в настройках Marlin USBSerial нигде не использовался.

Просмотр кода stm32duino показал, что USB всегда инициализируется, если в параметрах компиляции есть -DSERIAL_USB, любезно подставленный уже знакомым мне PlatformIO скриптом stm32f1.py. Еще немного черной магии в extra_scripts для удаления ‘-DSERIAL_USB’ из параметров командной строки привело двигатель E1 в рабочее состояние.

Следующим пунктом программы стоял второй COM порт, выведенный в разъем для ESP8266. Поддержка двух COM портов в Marlin присутствует, поэтому решение этой задачи сводилось в добавлению двух строк в Configuration.h ‘#define SERIAL_PORT_2 0’ и ‘#define NUM_SERIAL 2’.

На этом месте контроллер наглухо завис. Завис не сразу - контрольный диод успел загореться, но до инициализации экрана дело не дошло. Экспериментальным путем было выяснено, что виснет только при использовании USART1 (для WiFi), в то время как USART3(USB-COM) и USART2 (не разведен) проблем не вызывают. Для полноты эксперимента включил USBSerial и получил совсем неожиданный результат - все COM порты работали в любых сочетаниях. Убираю из командной строки ‘-DSERIAL_USB’, и USART1 снова вызывает зависание.

Побочный эффект от использования черной магии драйвера E1 мне не понравился, поэтому ‘-DSERIAL_USB’ вернулся в командную строку и второй COM порт перестал вешать микроконтроллер. Нужно было искать новый способ отобрать две ноги у USB порта и я опять погрузился в чтение stm32duino.

Инициализация USBSerial происходит в функции board_setup_usb() и случается это всегда, когда определена константа SERIAL_USB. Параметров, отключающих этот функционал нет, но сама функция объявлена как __weak. В терминах С++ это означает, что можно написать свою реализацию этой функции и новая функция заменит собой исходную. Marlin использует USB только как COM порт, поэтому в HAL_STM32F1HAL.cpp я добавил проверку используемых COM портов. Если ни SERIAL_PORT ни SERIAL_PORT_2 не ссылаются на USB, то функция board_setup_usb() заменяется заглушкой, оставляя ноги PA11 и PA12 свободными.

Подключение энкодера и SD карты

На плате есть два разъема для подключения SPI модуля преобразования сигнала термопары, но китайские инженеры не развели в них линию MOSI. На работу с термопарой это никак не влияет, так как передача данных идет только в сторону микроконтроллера, а вот использовать их для подключения SD карты уже не получится.

На плате есть только один разъем, где шина SPI представлена в полнофункциональном виде - разъем подключения модуля экрана. Для подключения к шине SPI из желудей, палок и заранее купленного FPC разъема (32 контакта с шагом 1мм) был собран RepRap адаптер.
Marlin, Robin, два сопла
По-умолчанию stm32duino использует шину SPI1, а на MKS Robin все подключено в SPI2.

Для использования SPI2 в коде stm32duino в файле STM32F1librariesSPIsrcSPI.cpp библиотеки SPI нужно заменить

[CODE]SPIClass SPI(1);[/CODE]

на

[CODE]SPIClass SPI(2);[/CODE]

Параметры подключения RepRapDiscount Smart Controller

[CODE]#define LCD_PINS_RS PD14

#define LCD_PINS_ENABLE PD15

#define LCD_PINS_D4 PD1

#define LCD_PINS_D5 PD0

#define LCD_PINS_D6 PE8

#define LCD_PINS_D7 PE7

#define BTN_EN1 PE10

#define BTN_EN2 PE12

#define BTN_ENC PE9

#define SDSS PC13

#define SD_DETECT_PIN PG11

[/CODE]В файле MarlinsrcHALHAL_STM32F1spi_pins.h так же поменял сигнальные линии с SPI1 на SPI2

[CODE]#define SCK_PIN PB13

#define MISO_PIN PB14

#define MOSI_PIN PB15

#define SS_PIN PC13

[/CODE]

В результате заработало все, кроме SD_DETECT_PIN. После отключения SD_DETECT_PIN SD карта успешно инициализировалась и читалась. Позже выяснилось, что причиной неработающего SD_DETECT_PIN был погнутый контакт в столе под карту, но работу с исправленным контактом я не проверял.

TL;DR

Marlin на MKS Robin работает и обновляется с SD карты через штатный загрузчик.

Запрос на включение кода в основной репозиторий отправлен и ожидает рассмотрения.

Пока код не принят, можно использовать https://github.com/jmz52/Marlin/tree/mks-robin Конфигурационные файлы лежат в MarlinsrcconfigexamplesMksRobin

Дополнительная информация
  • SDIO шина не поддерживается, разъем SD карты на плате используется только для обновления прошивки.
  • TFT экран не поддерживается.
  • Распиновка MKS Robin
  • FPC разъем для RedRap адаптера (32 контакта с шагом 1мм)
  • FFC кабель (32 контакта с шагом 1мм)
  • На шине I2C есть микросхема EEPROM. Marlin ее поддерживает, но я ее не тестировал и адрес не проверял.
  • Сервоприводы и плавная регулировка оборотов вентилятора не проверялись на конфликт с используемыми по умолчанию таймерами.
  • В конфигурации Marlin для COM порта указана скорость 250000. Для оригинальнального WiFi модуля скорее всего потребуется снизить скорость COM порта до 115200, используемого оригинальной прошивкой. Неоригинальный WiFi модуль успешно подключился на скорости 250000.

Подпишитесь на автора

Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.

Отписаться от уведомлений вы всегда сможете в профиле автора.

38
Комментарии к статье