Увлекся я микроконтроллерами в качестве хобби давно. И тогда они не валялись на дороге. Ошибка установки битов-предохранителей в AVR (так я себе представлял fuse-bits) непременно вели на Колхозную площадь города Смоленска в радиолюбительские ряды за новенькой микросхемой в обмен на деньги. Но мир изменился.

После доставки находки в радиолюбительское логово, предстояла разборка устройства методом декомпозиции с соблюдением требований безопасности. Отделив всё вредное для здоровья (и избавившись от лишнего согласно правилам сортировки мусора), предо мной предстало это.

Зёрна отделены от плевел
Зёрна отделены от плевел

Рассмотрим детали. LP4068 - контроллер зарядки аккумуляторов Li-Po Li-Ion на 800 мА, G1808 - судя по расположению транзистор (я так и не опознал деталь по маркировке), через который управляется нагреватель, символьный светодиодный индикатор с шестью выводами и микроконтроллер PUYA py32f002a, плюс модный Type-C разъем для зарядки. Ну чем не девборда для разработки поделки выходного дня? Быстрый поиск по маркировке черного квадратика привел к листу технической информации, в котором было указано что это 32-bit Arm Cortex-M0+ @ 24 MHz с таймерами, АЦП, различными периферийными интерфейсами, портами ввода-вывода общего назначения. А ножки SWD и SWC намекали на то что, программы в него можно прошивать при помощи распространенного ST-Link V2.

Цоколёвка
Цоколёвка

Но, как оказалось, работать с этим контроллером через этот программатор невозможно. Нужен J-Link. По запросам Puya programmer находились какие-то программаторы по заоблачным ценам. С виду клоны J-Link'а. В сети мне попадались инструкции по переделке ST-Link V2 в J-Link. На ближайшем к дому маркетплейсе за 250 р был заказан "свисток" (свой основной, с оригинальным STM32, добытый на хакатоне по Флипперу было жалко). А пока покупка шла к покупателю, я не спешно (аж целых два дня) изучал тему. Оказывается, еще контроллеры Puya можно шить при помощи DAP-Link, который можно получить из blue pill. Забегая вперед, у меня сработал первый вариант.

Изучая просторы сети, я наткнулся на репозиторий замечательного человека IOSettings, который уже прошел этот путь и создал шаблон. Еще он подробно расписал все шаги для таких как я, привыкших к GUI и плохо знакомым с цепочками инструментов, компиляторами, make-файлами. Далее идем по шагам.

1. Подготовка ПО

 Первым делом нам нужен Python. Устанавливаем с официального сайта с обязательным включением пути к исполняемым файлам в системную переменную Path (поставить галочку в мастере установки). В последнее время мне нравится такой способ получения доступа к этой настройке: Нажимаем "Win+R", вводим sysdm.cpl и получаем окно системных настроек. Проверяем доступность Python из командной строки.

C:\Users\xxx>python --version
Python 3.11.1

Для загрузки программы в контроллер будем использовать pyocd (инструмент для отладки, программирования и исследования Arm Cortex микроконтроллеров). Чтобы его установить нужен менеджер пакетов pip. Если менеджер не установлен, нужно загрузить специальный скрипт get-pip.py с официального сайта и выполнить его. Так же проверяем.

C:\Users\xxx>pip --version
pip 23.0.1 from C:\python\Lib\site-packages\pip (python 3.11)

Теперь можно установить pyocd выполнив pip install pyocd.

Для компиляции исходного кода и последующей компоновки исполняемых файлов нужна утилита make. Я использовал её из состава набора инструментов разработки ПО mingw64. В поисковике ищем бинарники (исполняемые файлы), скачиваем, копируем, прописываем в Path.

Пути к исполняемым файлам
Пути к исполняемым файлам

Проверяем доступность.

C:\Users\xxx>make -v
GNU Make 4.4.1
Built for x86_64-w64-mingw32
Copyright (C) 1988-2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

В моем комплекте mingw утилита называлась mingw64-make.exe, и вызов этой утилиты не пройдет с таким именем. Я не знаю есть ли в windows механизм трансляции имен файлов (cast), вопрос решил простым переименованием.

Настало время воспользоваться шаблоном от IOSettings. По ссылке из его руководства загружаем GNU Arm Embedded Toolchain для Windows, распаковываем, добавляем в path (вторая выделенная строка на снимке экрана выше). Так же клонируем/загружаем репозиторий с шаблоном.

Для редактирования кода предлагается использовать MSVS Code. Скачиваем и устанавливаем, запускаем из консоли C:\Users\xxx>code (в этом случаи подтянутся значения из переменной Path). Добавляем в MSVS Сode папку с шаблоном. Третий пункт из инструкции IOSettings по настройке pyocd пропускаем и переходим к редактированию make файла. Тут прописываем свой микроконтроллер и путь к инструментам GNU Arm Embedded Toolchain. Сохраняем изменения.

# MCU types: 
MCU_TYPE		= PY32F002Ax5
##### Toolchains #######
ARM_TOOCHAIN	?= /opt/arm-gnu-toolchain-13.2.Rel1-mingw-w64-i686-arm-none-eabi/bin

В каталоге User находится тот код, который будет компилироваться. Открываем main.c (классический Blink) и немного правим его под реалии нашей платы. Нужно удалить все, что касается вывода по UART и использовать выводы 8 и 12 порта A.

Важное замечание! В первых экспериментах не используйте PA13 и PA14! Если вы сконфигурируете их под свои задачи, у вас пропадет интерфейс SWD. Я таким образом окирпичил один контроллер (благо он был добыт бесплатно путем древнего навыка собирательства). Причем мои попытки использовать вывод NRST, чтобы как-то стереть память до загрузки программы, не к чему не привели.

#include "py32f0xx_bsp_printf.h"
static void APP_LedConfig(void);

int main(void)
{
  HAL_Init();                                 
  APP_LedConfig();

  while (1)
  {
    HAL_Delay(500);                            
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8); //переключем состояние анода одного сегмента
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12,0); //катод постоянно подключен к минусу
    
  }
}

static void APP_LedConfig(void) //тут конфигурируем порты
{
  GPIO_InitTypeDef GPIO_InitStruct;

  __HAL_RCC_GPIOA_CLK_ENABLE();

  GPIO_InitStruct.Pin = GPIO_PIN_8; //заполняем структуру конфигурации для 8 выхода
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); //передаем структуру
 
  GPIO_InitStruct.Pin = GPIO_PIN_12; //заполняем структуру конфигурации для 12 выхода
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); //передаем структуру
}

void APP_ErrorHandler(void)
{
  while (1);
}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)
{
  while (1)
  {
  }
}
#endif /* USE_FULL_ASSERT */

Настало время ввести команду make в терминале VS Code. И эта утилита возьмет все, что нужно, подставит куда надо и сделает всю работу (прямо магия какая-то). Но у меня выпал ряд ошибок. Как оказалось make файл написан для *nix системы, и для запуска нужен терминал bash.

На этом этапе наша цепочка инструментов работает!
На этом этапе наша цепочка инструментов работает!

2. Подготовка ST Link V2

Тем временем прибыл программатор. Приступим к его конверсии в J Link. Для преобразования ищем и скачиваем утилиту STLinkReflash.exe. Тут вроде все понятно, но читая материалы по этим преобразованиям я наткнулся на вероятность сбоя при прошивке и отказе работы с микроконтроллерами, отличными от STM. Утилиту STLinkReflash нужно слегка доработать. Приведу цитату человека с ником Miragui:

If you have tried to flash a clone ST-Link V2 to J-Link you must have encountered the following message;

"Unsupported ST-LINK hardware variant"

The solution is to change the following offsets in STLinkReflash.exe
I used the HxD hex editor. But you can use any other you like.

offset 2566 3C > 38
offset 2567 40 > C0
offset 26B2 3C > 38
offset 26B3 4A > C0

Я пошел его путем, только смещения 26B2 и 26B3 у меня не совпали. Они были сдвинуты на 16 байт выше. Тем не менее, после изменений и сохранения копии все получилось с первого раза.

Тут надо отметить, что у меня уже была установлена STM32CubeIDE и в процессе экспериментов операционная система никакие драйвера не запрашивала (они были установлены ранее). Возможно, вам отдельно будет нужно установить драйверы на программатор.

Проверяем наличие программатора командой pyocd list .

Вывод списка программаторов
Вывод списка программаторов

Добавим поддержку микроконтроллеров puya в pyocd. Командой pyocd pack find PY32 обновим индекс и командой pyocd pack install PY32 добавим поддержку Puya. Проверить установку пакета можно командой pyocd list --targets .

3. Первая загрузка

Припаиваем к заботливо оставленным пятачкам мой любимый МГТФ. Кстати, SWD и SWC выведены на Type-С разъем. Думаю на заводе изделие прошивается через него.

Пациент готов к жизни в новых качествах
Пациент готов к жизни в новых качествах

Все готово к выполнению команды make flash. Но тут есть нюанс (с). После подачи питания, изделие выдает количество оставшихся использований, заряд аккумулятора и уходит в глубокий сон делая недоступным SWD. Я пробовал различные комбинации reset из Eclipse IDE, добавлял кнопку... но ничего не вышло. Получилось тогда, когда устройство только включилось и ему сразу же была стерта заводская прошивка командой pyocd erase -t py32f002ax5 --chip --config ./Misc/pyocd.yaml (соединил общий провод платы с общим проводом программатора и нажал ввод). После этого процесс прошивки проходит как обычно.

3. Хитрый экранчик

Символьный светодиодный экран имеет 6 ножек и 19 сегментов, символы капли и молнии двухцветные. Так как управлять? Конкретно на этот индикатор я документацию не нашел, но нашел на похожий. Там два диода для двух сегментов включены параллельно и разнонаправленно. Подавая напряжение в одну сторону зажигаем один, меняем полярность - горит второй. Я сконфигурировал порты PA12, PB1, PA8, PB0, PA7, PA6 как выходы и установил их в ноль. Потом на один из портов подавал единицу, и у меня загоралось сразу три сегмента. Явно ещё что-то соединено. Выпаяв индикатор, попробовал подавать на выводы 3 В с ограничением по току. Ожидаемо загорался один сегмент. Тут стало ясно, что при работе с одним сегментом, все остальные порты должны "висеть в воздухе" - так называемый вход Hi-Z. Для зажигания нужного сегмента нужно динамически конфигурировать GPIO. Для этого была написана некрасивая switch-case функция (показывать её тут не будем). Красиво можно сделать через библиотеку LL, управляя регистрами. Но я пока этого не умею. И да, на плате нет никаких токоограничивающих резисторов - только динамическая индикация. При помощи этой функции, (на входе порт, пин и направление) я нашел комбинации для включения нужных сегментов и создал анимацию "вечной" загрузки.

В качестве заключения хочется сказать следующее. Да, сейчас есть дешевые платы для разработки, удобные IDE. Да, 20 кБ много, для того, чтобы помигать светодиодами (в конфигурационном файле подключено много лишнего). Однако, мне понравилось разбираться с тем, с чем я вроде знаком, но как так сделать чтобы оно заработало я не знаю. И решая микрозадачи по достижению цели, получаешь удовольствие от результата. Наверное это часть DIY движения. Поздравляю с наступающими праздниками!

Hidden text

Приветствуются замечания по статье с целью увеличения её технической ценности

Комментарии (43)


  1. udik_chudik
    26.12.2023 19:11

    Круто! Повезло что на вашем была маркировка) у меня полно таких пациентов со стертой(


    1. avtopolet Автор
      26.12.2023 19:11
      +1

      Из четырёх "намайненных" у меня три Puya и один "CM180". И вот он уже отличается по разводке, хотя корпус такой-же.


  1. NutsUnderline
    26.12.2023 19:11

    для начинающихa arm'щиков - но материал с плюсиком.

    pyocd конечно интересно будет глянуть. для j-link существует родной софт под все платформы. одна, правда тонкость - .ftm файлы надо либо найти готовые либо сочинить свои - а это уже задача ен для начинающих


  1. osmanpasha
    26.12.2023 19:11
    +3

    Есть ещё проект black magic probe - опенсорсная прошивка программатора-отладчика arm-ядер. В него можно перепрошить китайский stlink или blue pill, и общаться с ним через gdb


  1. LordCarCar
    26.12.2023 19:11
    +11

    После доставки находки

    А что нашли-то и где?


    1. 200sx_Pilot
      26.12.2023 19:11

      Вступление - в ленте.

      к автору - а как можно использовать прилагаемый датчик?


      1. avtopolet Автор
        26.12.2023 19:11

        Фактически это не датчик а маленький компьютер. Измеряет напряжение аккумулятора, считает эм.. использования. Мне попалась такая одноразовая, в которой два нагревателя. Контроллер там ещё их переключает при достижении ресурса. Делать можно всё то, что и с распространённым МК. В шаблоне есть примеры и либы для датчиков, OLED экранов. Например в цепь нагревателя поставить микро моторчик. С одного порта ШИМом управлять сервой. На вход другого порта поставить IR приёмник. Уместить это все в машинке Hotwheels :))


    1. Soren
      26.12.2023 19:11
      +2

      Скорее всего, это плата от одноразовой электронной сигареты. Валяется у меня такая же (пока еще) не разобранная, дисплей соответствует.


      1. Zara6502
        26.12.2023 19:11

        плата от одноразовой электронной сигареты

        народу в Новосибе ими пользуется вроде бы немало, но ни разу не находил такое, в мусорках не копаюсь XD а вам откуда достаётся? покупаете или сами (знакомые) курите?


        1. avtopolet Автор
          26.12.2023 19:11

          Специально не копаюсь. Но если буду идти один и сверху увижу - возьму. Видел как дети копаются. Типа хаха, давай ты возьмешь, нет ты...


      1. avtopolet Автор
        26.12.2023 19:11
        +1

        Вот в таких скорее всего ничего интересного. Ну максимум контроллер заряда.


      1. zurabob
        26.12.2023 19:11
        +2

        Спасибо, добрый человек. А то статья очень интересная, проц копеечный на lcsc, но откуда эта радость непонятно. Прям как на пикабу: "зеленый банк", "полосатый оператор", только еще более зашифровано. А разве сигареты одноразовые, никогда не видел валяющихся?


    1. avtopolet Автор
      26.12.2023 19:11
      +1

      Вот прям как на картинке :) Кто то докурил и оставил в стаканчике. Я их все собираю. Просто не раз видел как их дети докуривают. Простые в утиль. Эти разбираю :)


      1. sim2q
        26.12.2023 19:11
        +2

        Мне кажется не лишним будет добавить об опасности жижи. Как то разбирал одну простенькую без МК, старался очень аккуратно но всё же задел - пришлось стирать всё подряд т.к. даже не смог локализовать источник. Страшная штука.


        1. SergeyMax
          26.12.2023 19:11

          А опасность в чëм


          1. isden
            26.12.2023 19:11
            +1

            В запахе.


            1. SergeyMax
              26.12.2023 19:11

              А в чем опасность запаха


              1. HardWrMan
                26.12.2023 19:11
                +3

                Родители заругают!


              1. isden
                26.12.2023 19:11
                +1

                Я забыл добавить /s.

                А серьезно - пару раз попадались какие-то адские жидкости, следовых количеств которых достаточно для долгого, неудаляемого, и достаточно противного запаха.


        1. zuek
          26.12.2023 19:11

          Ну, Вы преувеличиваете - запах "жижи" выдыхается за пару дней, да и смывается она, даже просто струёй воды, практически бесследно. Я первый раз, когда "обляпался", тоже переживал, а сейчас курочу эти девайсы один за одним - главное, оперативно утилизировать все источники жижи, и качественно прополоскать сохраняемые детали, т.к. они тоже зачастую "запачканы".


          1. sim2q
            26.12.2023 19:11
            +1

            она уже просто в вас навсегда...)


            1. HardWrMan
              26.12.2023 19:11

              Угу, человек адаптируется. Я, например, как некурящий, всегда 100% знаю курит человек или нет - от него тупо соответствующий запах идёт. А он уже не чувствует этого просто.


          1. isden
            26.12.2023 19:11

            Я выше писал - мне пару раз попадалось что-то адское. Немного измазал руки, помыл с мылом. Запах (причем не самой жидкости, а чего-то такого - вероятно одного из компонентов жидкости) остался, усиленно протер кожу спиртом - остался. Помыл еще раз с мылом и губкой - стало чуть получше, но все равно остался. Прошел сам через несколько дней.


      1. zuek
        26.12.2023 19:11

        Простые в утиль. Эти разбираю

        Я их не подбираю, но коллеги, кто пользуется, исправно несут мне их нескончаемой чередой, и разбираю я все, даже те, что без порта подзарядки - для извлечения литиевых аккумуляторов - в основном, использую в фонариках вместо батареек (некоторые типоразмеры идеально заменяют сборку из трёх aaa, нередко встречающуюся в самых дешёвых вариантах; некоторые заменяют сборку из трёх "таблеток").

        А вот про то, что рядом с экранчиком находится полноценный микроконтроллер - не знал, хотя и подозревал, т.к. "счётчик жижи" на простой элементной базе - несколько нетривиальная задача.


        1. isden
          26.12.2023 19:11

          т.к. "счётчик жижи" на простой элементной базе - несколько нетривиальная задача.

          Там обычно считается просто количество затяжек - с этим сильно проще.


    1. avtopolet Автор
      26.12.2023 19:11

      Вот максимально вуалировал, чтобы не пропагандировать :)


    1. iliasam
      26.12.2023 19:11

      Отвечу за автора - "обнаружил в пустом стаканчике рядом с кофейней хайп-вейп девайс. Да не простой, а с экранчиком"


  1. HardWrMan
    26.12.2023 19:11
    +1

    Важное замечание! В первых экспериментах не используйте PA13 и PA14! Если вы сконфигурируете их под свои задачи, у вас пропадет интерфейс SWD. Я таким образом окирпичил один контроллер (благо он был добыт бесплатно путем древнего навыка собирательства). Причем мои попытки использовать вывод NRST, чтобы как-то стереть память до загрузки программы, не к чему не привели.

    А у STшек с этим полный порядок. Делаешь "Connect Under Reset" и делаешь стирание. ни разу не окирпичил безвозвратно простым использованием ног SWD. У STшек единственная дорога в один конец это установка OB_RDP_LEVEL_2.


    1. avtopolet Автор
      26.12.2023 19:11

      Да, это пытался делать. В документации есть пункт про некую задержку перед стартом программы. Что то типа "фильтр 20 мс". Но пока не понял как это использовать.


      1. HardWrMan
        26.12.2023 19:11

        Главное - нельзя отлаживать. Надо сразу стирать. Я, кстати, встречал проекты, где ноги SWD настраивались на выход в статике как раз для исключения варианта "Attach to running device". Например, это позволяет сделать "MikroProg Suit": просто жмём "Erase" и дело сделано.


    1. 0xdead926e
      26.12.2023 19:11

      У STшек единственная дорога в один конец это установка OB_RDP_LEVEL_2.

      не совсем в один. если есть чем паверглитчить- оным сбрасывается до level 1, из которого чип можно просто стереть. по крайней мере работает на F0 и F4.


      1. HardWrMan
        26.12.2023 19:11

        Согласен, есть такой хакерский вариант. Однако, он не стабильный. Но на безрыбье вполне себе вариант, если нет других контроллеров и есть много времени.


  1. Simonov77
    26.12.2023 19:11
    +1

    Объясните, пожалуйста, зачем pyton? Не проще и удобнее использовать IDE. Тот же STM32CubeIDE бесплатно лежит на сайте производителя.


    1. avtopolet Автор
      26.12.2023 19:11
      +2

      Перед конфигугированием проца вы в IDE выбираете таргет. А в этом случаи что выбирать?


      1. SuperTEHb
        26.12.2023 19:11
        +2

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


      1. Simonov77
        26.12.2023 19:11
        +2

        Да, тут я немножко в лужу сел!) Просто сам я пользуюсь IAR (с j-link+) и там этот камень, вроде, есть. В keill тоже пишет, что есть. Поэтому и не сразу понял для чего шаманский танец с питоном.


      1. FlatlineMax
        26.12.2023 19:11
        +1

        А в случае неизвестного/неподдерживаемого камня начинается мини-квест "напиши device support pack". Но если планируется долгое занятие с новым камушком, то оно того стоит. Плюс потом пак можно выложить на гитхаб, пусть народ порадуется.. я конечно dsp не пишу, но для разных периферийных устройств на работе не один раз делал паки с библиотеками. Очень полезно если предполагается повторное использование в других устройствах в будущем


  1. VT100
    26.12.2023 19:11
    +5

    Символьный светодиодный экран имеет 6 ножек и 19 сегментов, символы капли и молнии двухцветные. Так как управлять?

    Charlieplex.


  1. NekitGeek
    26.12.2023 19:11

    Я думал, там будет что-то с OTP памятью или масочным ПЗУ. А так находил одноразку где RGB подсветка управлялась неизвестным 6-пиновым контроллером.


    1. isden
      26.12.2023 19:11

      А они очень разные бывают. У меня валялись несколько штук - один производитель и одна модель, но внутри разные платы. К сожалению, вся маркировка затерта, и из полезного там только аккумуляторы были (хотя тоже валяются с тех пор, не придумал куда приспособить :)).


    1. Ex01Ex01
      26.12.2023 19:11

      Есть и с ОТР памятью. Вот пример: CSU32P10 12-bit ADC 8 RISC OTP MCU. И не поиграться с этим микроконтроллером.


  1. engine9
    26.12.2023 19:11
    +1

    Я разбирал электросигу, которую отдала знакомая, там в ней вся электроника (включая силовой транзистор!) была всунута в корпус микрофонного капсюля, который являлся и датчиком потока воздуха.


  1. rooffall
    26.12.2023 19:11
    +1

    О, такой приятный и образованный человек из родного города, аж гордость берёт