Плата посудомийки Bosch SWS4118: що вміє прошивка і яка з неї користь (частина 3)
Зміст статті 8
Третя частина про плату посудомийки Bosch 702168823.01GA / SWS4118 Rev.4. У першій частині — що стоїть на платі й копія EEPROM, у другій — як ми прочитали прошивку STM32. Тут — що в цій прошивці:
- що це за плата в посудомийці і з ким вона спілкується;
- з чого складається прошивка: завантажувач і основна програма;
- які блоки мікроконтролера вона вмикає — прочитано з живої плати, лише читанням;
- два трифазні інвертори, захист від перевантаження струмом, таблиці датчиків температури, самоперевірка;
- як плата спілкується з панеллю — шина D-Bus;
- яка нам із цього користь і що робимо далі.
чернетка — перший розбір, дописуємо
⚠ Усе тут прочитано без жодного запису. Прошивку розбирали на комп'ютері з копії, а налаштування блоків мікроконтролера — читанням регістрів, коли плату живив ST-Link від USB (3,3 В, без мережі).
Що це за плата
Проєкт hn/bsh-home-appliances описує силові модулі посудомийок Bosch серії EPG700xx: той самий мікроконтролер STM32F301VCT6 у корпусі на 100 виводів, на частині плат — той самий інвертор FSB50550AB, налагоджувальний роз'єм X20. Схоже, наша плата з цієї родини. (Сам кристал за ідентифікатором — STM32F302/F303, див. другу частину; а за блоками, які вмикає прошивка, — TIM8, шість компараторів, чотири підсилювачі — найімовірніше, саме STM32F303xC: у F302 таймера TIM8 немає.)
За тим описом це головний блок керування мийкою (адреса 1 на шині): саме він виконує програму миття, керує ТЕНом, насосами й клапанами. Панель із кнопками — окремий вузол (адреса 2), вона лише надсилає йому команди: яку програму вибрано, які опції. Спілкуються вони через внутрішню шину D-Bus — про неї нижче.
Для нас це важливо: команда «крути насос» народжується не в панелі, а в самій цій прошивці, коли вона виконує програму миття.
Як ми розбирали
| Що | Чим | Навіщо |
|---|---|---|
| копія прошивки (256 КБ) | дизасемблер Capstone (бібліотека для Python) — для першого погляду | побачити структуру, таблиці, звертання до блоків |
| налаштування блоків мікроконтролера | STM32_Programmer_CLI з ключем -r32 — читання регістрів на живій платі | дізнатися, що прошивка насправді ввімкнула |
| глибший розбір (далі) | Ghidra: ARM Cortex, little endian, база 0x08000000 | обробники команд, логіка програми |
Регістри читали так (кожна команда лише читає; вивід — шістнадцяткові слова). GPIO читали для кожного порту з кроком 0x400, тут показано один — GPIOE:
STM32_Programmer_CLI -c port=SWD mode=HOTPLUG freq=100 -r32 0x40021000 0x20
STM32_Programmer_CLI -c port=SWD mode=HOTPLUG freq=100 -r32 0x48001000 0x28
STM32_Programmer_CLI -c port=SWD mode=HOTPLUG freq=100 -r32 0x40012C00 0x50
STM32_Programmer_CLI -c port=SWD mode=HOTPLUG freq=100 -r32 0x40013400 0x50
STM32_Programmer_CLI -c port=SWD mode=HOTPLUG freq=100 -r32 0x40013800 0x14
| Адреса | Що там |
|---|---|
0x40021000 | RCC — тактування |
0x48000000…0x48001400 | GPIOA…GPIOF — режим кожного виводу (крок 0x400) |
0x40012C00, 0x40013400 | таймери TIM1 і TIM8 — ШІМ інверторів |
0x40013800 | USART1 — лише регістри налаштувань, до 0x10 включно |
0x4001001C…0x40010044 | компаратори й операційні підсилювачі |
0x40007400 | ЦАП |
⚠ Регістри даних послідовних портів (у USART1 — з 0x24) не читаємо: саме читання скидає в них прапорці й може загубити байт, який плата якраз приймає.
З чого складається прошивка
| Ділянка флеш-пам'яті | Розмір | Що там |
|---|---|---|
0x08000000–0x08000433 | ≈ 1 КБ | завантажувач (займає першу сторінку 2 КБ) |
0x08000800–≈0x0801E000 | ≈ 118 КБ | основна програма: таблиця переривань, код, таблиці |
0x0802C000–0x08034000 | 32 КБ | дані: налаштування, зокрема заводська копія блоку 1 EEPROM |
від 0x08038000 | ≈ 200 байт | ще трохи даних |
| решта | ≈ 100 КБ | порожньо (FF) |
Завантажувач
На самому початку стоїть рядок EDS_ST_STM32F3_02_210313 — схоже на назву й дату збірки (13.03.2021). Що робить завантажувач після ввімкнення:
- Вмикає кварцовий генератор і множник частоти ×3. Якщо кварц на 8 МГц (зовні ще не перевірили), це 24 МГц.
- Налаштовує послідовний порт USART1 на виводах PE0/PE1 (виводи 97 і 98): 9600 бод, 8 біт з парністю (на 24 МГц дільник 2500 дає рівно 9600 — ще один аргумент за кварц 8 МГц).
- Надсилає байт
0x54і ≈ 30 мс чекає відповіді (до 1 с, якщо попередній запуск попросив довше). - Якщо відповіді немає — ставить в оперативній пам'яті позначку
55 AAі перезапускає кристал сторожовим таймером. Наступний запуск бачить позначку й одразу передає керування основній програмі. - Якщо відповідь є — приймає команди:
| Байт команди | Що робить (за нашим розбором) |
|---|---|
0x0A | перевірка зв'язку — відповідає 0x8A |
0x5B | віддає рядок версії (EDS_ST_…, 32 байти) |
0x77 | задає адресу (найімовірніше, куди приймати дані) |
0x04 | змінює швидкість порту |
0x1A | запускає код із заданої адреси |
Сам завантажувач у флеш-пам'ять не пише: схоже, оновлення працює так — у оперативну пам'ять приймається програма-записувач, і вже вона переписує основну програму. Тобто прошивку можна оновити через той самий послідовний порт, яким плата спілкується з панеллю (лише формат інший: завантажувач — з парністю, 8E1, основна програма — без неї, 8N1). Ми цього не робимо, але це пояснює, звідки завантажувач на платі.
Основна програма
Таблиця переривань починається з 0x08000800. Крім стандартних, у ній задіяно лише сім обробників — вони одразу показують, що головне в програмі:
| Переривання | Що це, найімовірніше |
|---|---|
| ADC1_2 | готові виміри АЦП: струми фаз і напруга шини — серце керування двигуном |
| TIM1_UP | кожен період ШІМ першого інвертора |
| TIM1_BRK, TIM8_BRK | аварійне вимкнення інверторів |
| USART1 | прийом і передавання по шині D-Bus |
| UART5 | ще один послідовний порт (див. нижче) |
| EXTI9_5 | подія на одному з виводів 5–9 будь-якого порту — що саме, ще не з'ясовано |
Програма вміє сама писати у власну флеш-пам'ять (у ній є послідовність розблокування запису) — найімовірніше, саме так вона зберігає налаштування в ділянці 0x0802C000.
Що прошивка вмикає на кристалі
Це прочитано з регістрів живої плати, коли програма вже працювала (плата на 3,3 В від ST-Link, двигуни не під'єднані).
| Блок | Що прочитали | Що це означає |
|---|---|---|
| тактування | кварц × 9, шина APB2 — без дільника, APB1 — /2 | з кварцом 8 МГц — 72 МГц, найбільша частота цього кристала |
| USART1 (PE0, PE1) | дільник 7500, 8 біт без парності, прийом за перериванням | 9600 бод, 8N1 — рівно як D-Bus |
| TIM1 (PE8–PE13) | три пари доповняльних виходів, центроване ШІМ, період 1562, мертвий час 2 мкс | трифазний інвертор, ШІМ ≈ 23 кГц |
| TIM8 (PC6–PC8, PC10–PC12) | те саме, період 3446 | другий трифазний інвертор, ШІМ ≈ 10,4 кГц |
| виходи обох таймерів | загальний дозвіл виходів вимкнений | двигуни зараз стоять — так і має бути без мережі |
| компаратори COMP1–COMP6 | усі шість увімкнено, виходи заведено на аварійні входи таймерів | захист від перевантаження струмом: по три на кожен інвертор, по одному на фазу |
| підсилювачі OPAMP1–OPAMP4 | увімкнено | підсилюють сигнал зі шунтів струму для АЦП |
| ЦАП, обидва канали | значення 1806 з 4095 (≈ 1,46 В) | найімовірніше, поріг для компараторів |
| АЦП 1–4 | ≈ 25 виводів в аналоговому режимі | струми, напруги, температури, рівні |
| TIM2 (PA9, PA10), TIM3 (PB5), TIM4 (PD13, PD15) | виводи в режимі таймера | вимір імпульсів чи частоти (датчики) або ШІМ — ще не з'ясовано |
| UART5 | лише передавання, ≈ 900 бод; на виводи не виведено | призначення невідоме |
| сторожові таймери | незалежний і віконний | програма зависла — кристал перезапускається |
| блок CRC | рахує контрольну суму ділянок флеш-пам'яті під час роботи | самоперевірка (див. нижче) |
Номери виводів у корпусі на 100 виводів:
| Сигнали | Виводи мікроконтролера |
|---|---|
| TIM1: PE8–PE13 | 39–44 |
| TIM8: PC6, PC7, PC8 | 63, 64, 65 |
| TIM8: PC10, PC11, PC12 | 78, 79, 80 |
| USART1 (D-Bus): PE0, PE1 | 97, 98 |
Два інвертори, а силовий модуль один
Прошивка готова керувати двома трифазними двигунами: обидва таймери налаштовано однаково, в обох — свій захист. На нашій платі стоїть один силовий модуль FSB50550AB. Варіантів два: або другий двигун керується інакше (на іншій платі чи на іншій версії цієї), або ця прошивка — спільна для кількох версій плати. Який таймер іде на FSB50550AB, перевіримо прозвонкою: його входи мають дзвонитися або на виводи 39–44 (TIM1), або на 63–65 і 78–80 (TIM8).
У посудомийках Bosch трифазними безщітковими бувають і циркуляційний насос, і зливний; за описом hn на частині плат FSB50550AB крутить вентилятор сушіння. Що саме крутить наш — з'ясуємо тією ж прозвонкою і роз'ємом, до якого йдуть його виходи.
Векторне керування двигуном
У програмі є таблиця синуса на 256 значень (від −32767 до 32767). Разом із доповняльними виходами ШІМ, вимірюванням струмів через підсилювачі й АЦП і компараторами захисту це типовий набір для векторного керування (FOC) безщітковим двигуном без датчиків положення — так само будує керування й бібліотека двигунів від ST. Двигун при цьому крутиться плавно й тихо, а положення ротора прошивка, найімовірніше, обчислює за струмами.
Датчики температури
У прошивці є дві таблиці перерахунку показів 12-бітного АЦП (0–4095) у градуси. Обидві йдуть від 0 до 125 °C — це терморезистори (NTC), найімовірніше, у воді й на нагрівачі чи силовому модулі.
| °C | Таблиця 1, АЦП | Таблиця 2, АЦП |
|---|---|---|
| 0 | 3147 | 3492 |
| 10 | 2810 | 3244 |
| 20 | 2439 | 2948 |
| 30 | 2062 | 2616 |
| 40 | 1702 | 2268 |
| 50 | 1378 | 1923 |
| 60 | 1101 | 1600 |
| 70 | 875 | 1317 |
| 82 | 661 | 1029 |
| 90 | 548 | 870 |
| 100 | 435 | 703 |
| 125 | 249 | 416 |
Чим гарячіше, тим менше число: терморезистор стоїть у нижньому плечі дільника. Між точками прошивка, найімовірніше, рахує лінійно. Для нашого водонагрівача це готова градуювальна таблиця: вимірявши напругу на вході АЦП (за тієї самої схеми дільника), одразу маємо температуру. Точка 82 °C замість 80 — так у таблиці прошивки.
Самоперевірка флеш-пам'яті
Під час роботи програма рахує апаратним блоком CRC контрольну суму ділянок своєї флеш-пам'яті за таблицею діапазонів. Так зазвичай роблять у побутовій техніці, щоб пошкоджена пам'ять не керувала ТЕНом і двигуном.
Наслідок для нас: підправити в оригінальній прошивці навіть один байт не вийде просто так — самоперевірка це помітить. Тож варіантів два: рідна прошивка без змін або цілком своя.
Як плата спілкується з панеллю: D-Bus
Що відомо з опису hn і що збігається з нашим розбором:
| Що | Опис hn | У нашій прошивці |
|---|---|---|
| дроти | три: GND, DATA, VBUS; у посудомийках VBUS ≈ 13,5 В, DATA — логіка 5 В | USART1 на PE0/PE1 — ще знайти, куди йде |
| швидкість і формат | 9600 бод, 8N1 | так: дільник 7500 на 72 МГц, без парності |
| кадр | довжина, адреса й підсистема, команда (2 байти), дані, CRC16 (XMODEM) | ще розбираємо |
| підтвердження | одним байтом одразу після кадру | ще розбираємо |
Адреси вузлів за hn: 1 — блок керування мийкою (наша плата), 2 — панель керування, 0x6 — проєктор часу на підлогу, 0xA/0xB — модулі інтернету. Відомі команди: 17.10-10 xx — вибрати програму миття xx, 17.10-00 — опції, 24.20-06 — індикатори ополіскувача й солі, 25.20-08 — залишок часу.
За hn, деякі вузли вміють віддавати вміст своєї пам'яті прямо через D-Bus. Ми цього не перевіряли — нам уже не потрібно: копія є.
⚠ Усе це описано для плат hn; для нашої ще треба записати справжній обмін між панеллю й платою.
Яка нам із цього користь
| Що дізналися | Що це дає |
|---|---|
| захисту немає, копія збережена | плату завжди можна повернути до заводського стану — можна сміливо пробувати |
| завантажувач на послідовному порту | прошивку можна оновлювати без розбирання, тими самими трьома дротами |
| D-Bus: 9600 8N1, відомий формат кадру | можна слухати й надсилати команди з ESP32, не змінюючи прошивки |
| виводи ШІМ, частота, мертвий час, захист | усе, що потрібно для своєї прошивки, вже відомо з оригінальної |
| таблиці NTC | готове перерахування температури для водонагрівача |
| самоперевірка CRC | правки в оригінальній прошивці — погана ідея: або вона без змін, або цілком своя |
| два інвертори в прошивці | треба з'ясувати, який із них іде на наш FSB50550AB |
Наш план тепер такий:
- Спершу — оригінальна прошивка й D-Bus. Панель у нас є: під'єднуємо плату й панель, слухаємо лінію DATA логічним аналізатором або ESP32 (у проєкті hn є готовий компонент для ESPHome) і записуємо, що надсилає панель, коли вмикаємо програму. Потім пробуємо надсилати ці команди самі. Нічого не стираємо.
- Обмеження цього шляху: оригінальна прошивка виконує всю програму миття — чекатиме датчиків рівня й води, клапанів, замка дверцят. Без них вона, найімовірніше, зупиниться з помилкою. Можливо, допоможе сервісний тест — його теж шукатимемо в обміні й у прошивці.
- Якщо оригінальна не дасть просто крутити насос — своя прошивка. Залізо вже відоме до виводу; заводська копія лежить поруч, тож повернутись можна будь-коли.
Що далі
- Прозвонити входи FSB50550AB: TIM1 (виводи 39–44) чи TIM8 (63–65, 78–80).
- Знайти, на який роз'єм ідуть PE0/PE1 (виводи 97, 98) — це лінія D-Bus; виміряти на ньому VBUS.
- Знайти кварц і перевірити, що він на 8 МГц: від цього залежать усі частоти вище.
- Записати обмін панель ↔ плата.
- Ghidra: обробник USART1 (
0x0800BA3D) і таблиця команд D-Bus. - З'ясувати, що на виводах таймерів TIM2–TIM4 і на перериванні EXTI9_5 — датчики потоку, рівня, двигуна.
🔒 Ідентифікатори й оригінальні копії: приховано, це бачить лише автор.
Журнал змін статті
- 2026-11-10 — перша чернетка: будова прошивки, завантажувач, блоки кристала з живої плати, два інвертори, таблиці NTC, самоперевірка, D-Bus, користь і план.