TPMS Toyota PMV-107j на модулях RFM119

Эмуляторы датчиков давления в шинах по прежнему пользуются спросом (нет проблем с заменой комплектов зима/лето, нет проблем при заломе датчиков на шиномонтаже и т.п.), но из-за COVID-19 и других событий логистика доставки компонентов улетела к чёртовой матери, теперь очень желательно выпускать эмуляторы TPMS для Toyota, Mercedes и т.п. в одном конструктиве, и на модуле RFM119 это возможно — для разных типов датчиков должна меняться только прошивка.

Спойлер: всё получилось 🙂 Неважно на какой частоте, какой полосой и каким типом модуляции эти датчики работают — теперь это одно изделие.

Прототип эмулятора TPMS Toyota PMV-107j

Ниже показан экран диагностики TPMS с «привязанным» эмулятором. В итоге эмулятор получился очень лаконичным и замечательным, далее будет коротенький рассказ про немаленькие проблемы маленького устройства 🙂

Сканер с «привязанным» эмулятором TPMS

Основная проблема изготовления эмулятора TPMS Toyota — дешёвый FSK передатчик. Можно, конечно, извращаться и пытаться менять нагрузочную ёмкость на ПАВ-резонаторе классических OOK-модулей, но этот номер часто не проходит:

1) нагрузочную ёмкость ПАВ-а надо подбирать к каждому модулю индивидуально, даже если модули из одной партии, и такая дополнительная операция сводит на нет низкую стоимость передатчика,

2) при изменении частоты на 15КГц (а реально надо больше), амплитуда выходного сигнала передатчика меняется раз в 20, а принимать такой АМ/ЧМ сигнал соглашается далеко не всякий автомобильчик. Короче, для массового производства FSK передатчик дорогой, а изготовление АМ/ЧМ передатчика в одном флаконе, переводит промышленное изделие в серию идиотских радиолюбительских поделок.

Китайская фирма HopeRF делает замечательные модули передатчиков RFM119. В продаже есть модули на 315МГц, 433.92МГц, 868.35МГц, 915МГц с выходной OOK модуляцией, и как бы чихать на это поделие (копеечных OOK передатчиков навалом). Однако, если открыть описание модуля, то выясняется, что RFM119 может работать и как FSK передатчик! А вот FSK передатчик найти сложно, модуль становится интересен!

Описание модуля RFM119

Модуль RFM119 собран микросхеме ф.CMOSTEK CMT2119A. Собственно, CMT2119A и есть модуль, больше ничего активного в модуле нет: наука достигла таких высот, что умудрилась засунуть в корпус SOT23-6 EEPROM, процессор, логику и, собственно, передатчик мощностью более 100мВт (+14dBm) при напряжении питания 3.3В. В EEPROM записывается частота передатчика, тип модуляции, полоса, мощность, полярность и т.п.; после подачи питания, данные вычитываются из EEPROM, и передатчик передаёт, казалось бы всё просто… Но… Но, китайцы используют проприетарный протокол записи EEPROM, как и что писать в микросхему — неизвестно. Хотите программировать параметры — покупайте программатор!

Программатор CMOSTEK

Ладно, программатор закажем, но хотелось бы посмотреть, как работают модули RFM119 в режиме FSK — может они не подходят для наших целей, надо ж отмакетировать изделие. Решили заказать на Алиэкспрессе модули с FSK модуляцией разной полосы и на разные частоты, и вот тут-то выяснилось, что заказать модули RFM119 с чем-то отличным от заявленных параметров капец как сложно: из полутора десятков продаванов только один согласился прислать по 10шт модулей на каждую частоту. По итогу, он нас обманул: все пришедшие модули были OOK; впрочем, это обычная практика у Поднебесной.

В это же время была сделана попытка заказать программатор в 3х разных местах: у производителя и через дилеров (Россия и Европа). Не вдаваясь в подробности, попытку мы «запили водой»: производителю мы не интересны, а дельцы из России и Европы не смогли нам его продать даже по стоимости в 7 раз(!) превышающей его стоимость на сайте производителя — мурыжили заявку 2 месяца, увеличивали стоимость, в конце концов отказались.

Надо отметить, что бороться-то было за что, схема всей линейки эмуляторов TPMS на модуле RFM119 получается лаконичная и дешёвая, аналогичного варианта передатчика как бы и нет.

Схема эмулятора TPMS, схема одинакова для разных типов датчиков давления в шинах

Как оказалось, всё, что ни делается — всё к лучшему 🙂 На просторах китайского интернета нашёлся «конфиденциальный» документ AN135 на китайском языке (слава Гугль-переводчику!), в котором есть последовательность команд, которая переводит RFM119 в режим работы с данными не из EEPROM, а из RAM! Смысловое описание команд отсутствует, но оно и не требуется, т.к. в микросхеме всё сложно — 16ти разрядная память, адресация через защёлку, старт-стоп копирования страниц памяти…

Ниже приводится код AVR инициализации RFM119, частоты и модуляции прилагаются, пользуйтесь 🙂

; ************
; * RF SETUP *
; ************
;______________________________________________________________
; сброс TWI
rst_twi:
        push    tmp2                        ; сохранение tmp2
        clr     tmp1                        ; DATA=Lo на всё время передачи
        ldi     tmp2, 32                    ; счётчик битов
        rjmp    wrtw_txlp                   ; переход в цикл передачи битов
;______________________________________________________________
; запись регистра по TWI (tmp1 - addr, tmp2 - data)
wreg_twi:
        ori     tmp1, 0x80                  ; установка режима записи данных
        rcall   wr_twi                      ; запись адреса
        mov     tmp1, tmp2                  ; установка данных
;______________________________________________________________
; запись байта по TWI-протоколу
wr_twi:
        push    tmp2                        ; сохранение tmp2
        ldi     tmp2, 8                     ; счётчик битов
wrtw_txlp:
        sbi     CTBout, RFCpin              ;~2 CLK=Hi
        lsl     tmp1                        ;~1
        brcs    wrtw_sethi                  ;~1/2 проверка старшего бита
        cbi     CTBout, RFDpin              ;~2 DATA=Lo
        rjmp    wrtw_chwt                   ;~2 переход на тактовую задержку
wrtw_sethi:
        sbi     CTBout, RFDpin              ;~2 DATA=Hi
        nop                                 ;~1
wrtw_chwt:
        rcall   wrtw_ret                    ;~4+3(call), тактовая задержка
        cbi     CTBout, RFCpin              ;~2 CLK=Lo
        rcall   wrtw_ret                    ;~4+3(call), тактовая задержка
        dec     tmp2                        ;~1, декремент циклового счётчика
        brne    wrtw_txlp                   ;~1/2, закрытие цикла передачи
        pop     tmp2                        ; восстановление tmp2
wrtw_ret:
        ret                                 ; выход
 
;______________________________________________________________
; выключение питания CMT2119
rfm_off:
        cbi     CTBout, RFDpin              ; DATA=Lo
        cbi     CTBout, RFCpin              ; CLK=Lo
        cbi     CTBout, RFPpin              ; PWR=OFF
        ret                                 ; выход
;______________________________________________________________
; включение питания CMT2119 с последующей инициализацией
rfm_on:
        sbi     CTBout, RFPpin              ; PWR=ON
        sbi     CTBout, RFDpin              ; DATA=Hi
        sbi     CTBout, RFCpin              ; CLK=Hi
 
        rcall   rst_twi                     ; сброс шины
        ldi     tmp1, 0x8D                  ; регистр программного сброса
        ldi     tmp2, 0x00                  ; данные для сброса
        rcall   wreg_twi                    ; сброс
        ldi     tmp1, 0x3D                  ; TWI control
        ldi     tmp2, 0x01                  ; TWI ON
        rcall   wreg_twi                    ; сброс
        ldi     tmp1, 4                     ; время задержки 2ms
        rcall   del05ms                     ; задержка
 
; proprietary command preamble
        ldi     ZL, low(cmt2119_pre << 1)   ; указатель на данные 
        ldi     ZH, high(cmt2119_pre << 1)  ; преамбулы для инициализации CMT2119
        ldi     tmp3, 10                    ; счётчик пар адрес-данные
rfms_prelp:
        lpm     tmp2, Z+                    ; загрузка данных
        lpm     tmp1, Z+                    ; загрузка адреса
        rcall   wreg_twi                    ; запись адреса из tmp2
        dec     tmp3                        ; декремент цикловой переменной
        brne    rfms_prelp                  ; закрытие цикла преамбулы
 
; установка режима передатчика
        ldi     ZL, low(cmt2119_rfmo << 1)  ; указатель на таблицу регистров
        ldi     ZH, high(cmt2119_rfmo << 1) ;
        clr     tmp3                        ; сброс номера регистра
rfms_ramsetlp:
        mov     tmp2, tmp3                  ; адрес из цикловой переменной
        ldi     tmp1, 0x18                  ; регистр защёлки адреса
        rcall   wreg_twi                    ; запись адреса из tmp2
        lpm     tmp2, Z+                    ; загрузка Lo-данных
        ldi     tmp1, 0x19                  ; регистр Lo-данных
        rcall   wreg_twi                    ; запись Lo-данных
        lpm     tmp2, Z+                    ; загрузка Hi-данных
        ldi     tmp1, 0x1A                  ; регистр Hi-данных
        rcall   wreg_twi                    ; запись Hi-данных
        ldi     tmp1, 0x25                  ; регистр управления RAM
        ldi     tmp2, 0x01                  ; флаг применения защёлок к RAM
        rcall   wreg_twi                    ; установка данных в RAM
        inc     tmp3                        ; инкремент адреса RAM
        cpi     tmp3, 0x15                  ; проверка окончания записи RAM
        brne    rfms_ramsetlp               ; закрытие цикла записи в RAM
; выключение TWI
        ldi     tmp1, 0x0D                  ; TWI control
        ldi     tmp2, 0x02                  ; значение регистра
        rcall   wreg_twi                    ; TWI OFF
; установка CLK/DATA в статическое состояние для передачи кода
        sbi     CTBout, RFCpin              ; CLK=Hi
        cbi     CTBout, RFDpin              ; DATA=Lo
        ldi     tmp1, 1                     ; время задержки 0.5ms
        rjmp    del05ms                     ; задержка
 
;______________________________________________________________
cmt2119_pre:
; проприетарная преамбула: Rnn|Dnn
        .dw     0x0278, 0x2F80, 0x35CA, 0x36EB, 0x3737
        .dw     0x3882, 0x1210, 0x1200, 0x2407, 0x1D20
 
cmt2119_rfmo:
; проприетарная установка режима передачи и частоты: Dnnnn
; 315.00MHz, OOK
;       .dw     0x007F, 0x5400, 0x0000, 0x0000, 0x0000, 0xF000
;       .dw     0x0001, 0xB13B, 0x4800, 0x0000, 0x2401, 0x01B0
;       .dw     0x8000, 0x0007, 0xFFFF, 0x0020, 0x5FD9, 0x22D6
;       .dw     0x0E13, 0x0019, 0x2000
 
; 315.00MHz, FSK-25KHz/F-inversion
        .dw     0x007F, 0x5400, 0x0000, 0x0000, 0x0000, 0xF000
        .dw     0x0001, 0xB13B, 0x4808, 0x017A, 0x6401, 0x0081
        .dw     0x8000, 0x0000, 0xFFFF, 0x0020, 0x5FD9, 0xA2D6
        .dw     0x0E13, 0x0019, 0x0000
 
; 315.00MHz, FSK-50KHz/F-inversion
;       .dw     0x007F, 0x5400, 0x0000, 0x0000, 0x0000, 0xF000
;       .dw     0x0001, 0xB13B, 0x4808, 0x02F4, 0x6401, 0x0081
;       .dw     0x8000, 0x0000, 0xFFFF, 0x0020, 0x5FD9, 0xA2D6
;       .dw     0x0E13, 0x0019, 0x0000
 
; 315.00MHz, FSK-100KHz/F-inversion
;       .dw     0x007F, 0x5400, 0x0000, 0x0000, 0x0000, 0xF000
;       .dw     0x0001, 0xB13B, 0x4808, 0x05E8, 0x6401, 0x0081
;       .dw     0x8000, 0x0000, 0xFFFF, 0x0020, 0x5FD9, 0xA2D6
;       .dw     0x0E13, 0x0019, 0x0000
 
; 433.92MHz, OOK
;       .dw     0x007F, 0x5400, 0x0000, 0x0000, 0x0000, 0xF000
;       .dw     0x0000, 0xC1C5, 0x4200, 0x0000, 0x2401, 0x01B0
;       .dw     0x8000, 0x0004, 0xFFFF, 0x0020, 0x5FE8, 0x22D6
;       .dw     0x0E13, 0x0019, 0x2000
 
; 433.92MHz, FSK-35KHz/F-inversion
;       .dw     0x007F, 0x1400, 0x0000, 0x0000, 0x0000, 0xF000
;       .dw     0x0000, 0xC1C5, 0x4208, 0x0160, 0x6401, 0x0081
;       .dw     0x8000, 0x0000, 0xFFFF, 0x0020, 0x5FE8, 0xA2D6
;       .dw     0x0E13, 0x0019, 0x0000
 
; 868.35MHz, OOK
;       .dw     0x007F, 0x5000, 0x0000, 0x0000, 0x0000, 0xF000
;       .dw     0x0000, 0xCBCE, 0x4200, 0x0000, 0x2401, 0x01B0
;       .dw     0x8000, 0x0006, 0xFFFF, 0x0020, 0x5F1E, 0x22D6
;       .dw     0x0E13, 0x0019, 0x2000
 
; 868.35MHz, FSK-35KHz/F-inversion
;       .dw     0x007F, 0x5000, 0x0000, 0x0000, 0x0000, 0xF000
;       .dw     0x0000, 0xCBCE, 0x4208, 0x00B0, 0x6401, 0x0081
;       .dw     0x8000, 0x0000, 0xFFFF, 0x0020, 0x5FF0, 0xA2D6
;       .dw     0x0E13, 0x0019, 0x0000