ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
19 апреля
1163529 Топик полностью
VladislavS. (12.01.2022 16:04, просмотров: 410) ответил Costic на Серьёзно хочу спросить - для каких "разных типов" у вас код с пинами написан? У евгения1294 и @ламерка тоже шаблоны для пинов используются. Ну, не могу я осознать шаблон для пинов. Контейнеры - это понятно, max/min, но пины?... Обычно они в SDK на чип прописаны. Проверку пинов через assert делают, причём в том же SDK.
У меня написаны классы для GPIO-портов старых STM32 типа F1, новых STM32, Миландра MDR1986, Cамописного порта для Microblaze, Dummy-порта (виртуального). 

Из этих портов формируются пины. Каждый пин знает какой тип и номер порта у него, своё положение в порту, свой режим работы, умеет выполнять основные действия присущие пинам.

Из пинов можно формировать списки и шины. Их же можно как типы передавать в другие шаблоны. При всех операциях пины группируются по портам, выбирается оптимальная стратегия работы с ними в пределах порта.

Можно собрать в специальный класс, который конфигурирует все порты разом, например, при начальной инициализации. Можно учесть их cостояния по включению.

// Обзываем ноги согласно схеме
using LED_PIN = GPIO::PA_10;
using ENP = GPIO::PB_6;
using ENN = GPIO::PA_15;
using STR_TX = GPIO::PB_4;   // TIM3_CH1
using STR_RX = GPIO::PB_7;   // TIM4_CH2
using STR_SW = GPIO::PA_5;   // TIM2_CH1
using SPI3_SCK  = GPIO::PB_3;
using SPI3_MOSI = GPIO::PB_5;
using SPI3_CS1 = GPIO::PA_1;
using SPI3_CS2 = GPIO::PA_0;
using SPI1_MISO = GPIO::PA_3;
using SPI1_MOSI = GPIO::PB_0;
using SPI1_SCK  = GPIO::PA_7;
using CSB_ADAR = GPIO::PA_8;
using TXLD = GPIO::PA_4;
using RXLD = GPIO::PA_6;
using TXRXLD = GPIO::PinList<RXLD,TXLD>;
using PA_ON_ADAR = GPIO::PA_9;

// Собираем список всех ног и задаём разом всем режимы, остальные в Analog 
using SWD_CONFIG = ConfigList<PinMode::AF_PushPull_VeryHighSpeed_PullUp<0x0>, PA_13,     // PA13=SWDIO
                              PinMode::AF_PushPull_LowSpeed_PullDown<0x0>,    PA_14>;    // PA14=SWCLK

using TIMERS_CONFIG = ConfigList<PinMode::AF_PushPull_VeryHighSpeed<1>, STR_SW,          // STR_SW = TIM2_CH1
                                 PinMode::AF_PushPull_VeryHighSpeed<2>, STR_TX, STR_RX>; // STR_TX = TIM3_CH1 STR_RX = TIM4_CH2

using SPI_CONFIG = ConfigList< PinMode::AF_PushPull_VeryHighSpeed<6>, SPI3_SCK, SPI3_MOSI,
                               PinMode::PushPull_VeryHighSpeed<1>, SPI3_CS1, SPI3_CS2, CSB_ADAR,
                               PinMode::PushPull_VeryHighSpeed<0>, SPI1_SCK, SPI1_MOSI >;

ConfigList< SWD_CONFIG, SPI_CONFIG,TIMERS_CONFIG,
            //PinMode::AF_PushPull_HighSpeed<0>, PA_8,  // MCO
            PinMode::PushPull_LowSpeed<0>, LED_PIN, ENP, ENN,
            PinMode::PushPull_LowSpeed<1>, PA_ON_ADAR,
            PinMode::PushPull_VeryHighSpeed<0>, RXLD, TXLD,
            PinMode::Analog, CfgCmd::AllUnusedPins
          >::pwr_config();

Всё это проверится на дубликаты, корректность задания всех параметров, сгруппируется по портам, отсутствующим пинам задастся режим Analog. Cкомпилируется вот в такое

        MOV      R1,#+1207959552
        LDR.N    R2,??__low_level_init_0+0x30
        STR      R2,[R1, #+0]   
        MOVS     R3,#+36        
        STRB     R3,[R1, #+15]  
        MOVS     R2,#+16        
        LDR.W    R12,??__low_level_init_0+0x34
        STR      R12,[R1, #+8]  
        STRB     R2,[R1, #+34]  
        MOV      R3,#+50529027  
        STR      R3,[R1, #+24]  
        MOVW     R2,#+39613     
        STRH     R2,[R1, #+1024]
        MOVS     R3,#+0         
        STRB     R3,[R1, #+1037]
        MOVW     R2,#+53187     
        STRH     R2,[R1, #+1032]
        LDR.N    R3,??__low_level_init_0+0x38
        STR      R3,[R1, #+1056]

Тут задан режим работы 32 ног (2 порта по 16 бит). Я работаю только с именами и режимами. Ничего не знаю про тип контроллера и регистры необходимые для выполнения этого действия.


Всё это на этапе компиляции, никаких контейнеров и ассертов в рантайме.