======Настройки Config======
В текущей библиотеке файл //MDR32F9Qx_config.h// содержит настройки библиотеки и он един для всех микроконтроллеров.С помощью условной компиляции в этом файле задаются параметры по умолчанию, необходимые для работы библиотеки. В частности, задаются частоты внешних генераторов, которые подключены к конкретной плате. Пользователь должен сам модифицировать этот файл под свою плату. В нашей версии этот файл назван MDR_Config.h и лишь подключает Config_ХХ.h файлы для каждого конкретного МК. Это избавляет от необходимости парсить в уме условную компиляцию //MDR32F9Qx_config.h// и понимать какие настройки активны для данного МК, а какие нет. В Config_ХХ.h содержаться настройки валидные только для конкретного микроконтроллера.
#if defined (USE_MDR1986VE1)
#include
#elif defined (USE_MDR1986VE3)
#include
#elif defined (USE_MDR1986VE9x)
#include
...
...
#endif
Определения типа USE_MDR1986VE1 автоматически подключаются из Пака при выборе того или иного микроконтроллера в закладке Target опций проекта. При этом Config_ХХ.h файл, например MDR_ConfigVE9x.h, копируется в директорию RTE\Device\MDR1986VE91. Этот файл содержит настройки:
====Debug Uart====
//============= Debug Uart printf settings ==================
#define UART_DEBUG_IND 1
#define UART_DEBUG_SHOW_WELLCOME 1
#define UART_DEBUG_BAUD_DEF 9600
* UART_DEBUG_IND - Индекс UART через который работает printf через драйвер MDRB_UART_Debug.с
* UART_DEBUG_SHOW_WELLCOME - Показывать ли приветствие при подключении MDRB_UART_Debug по UART в программу терминал, происходит пи вызове MDR_UART_DBG_Init(). Это полезно для того, чтобы понять что подключение состоялось успешно.
* UART_DEBUG_BAUD_DEF - Скорость соединения драйвера MDRB_UART_Debug.с.
====Защита пинов Jtag====
//============= Защита пинов совмещенных с Jtag ==================
// Писать в пины порта совмещенные с Jtag можно только 0.
// Иначе отладчик потеряет соединение. Активным может быть только один.
//#define USE_JTAG_A
#define USE_JTAG_B
//#define USE_SWD_A
//#define USE_SWD_B
Активный USE_JTAG_B не позволяет функциям драйвера MDR_GPIO испортить обмен по JtagB. Подробнее об этом тут - [[https://startmilandr.ru/doku.php/prog:debug:reanimation|"Как вернуть кирпич в рабочее состояние"]]. В отличие от текущей библиотеки здесь добавлены варианты для защиты только выводов SWD. Использовать SWD удобнее поскольку он занимает только 2 пина, вместо 5-ти при отладке по Jtag.
====Тактирование====
//================ Параметры источников частоты ================
// Internal Generators
#define HSI_FREQ_HZ 8000000UL
#define HSI_FREQ_TRIM MDR_BKP_HSI_TRIM_8M0Hz
#define HSI_TIMEOUT 0x0600UL
#define HSI_LOW_SRI MDR_LOWRI_le40MHz
#define HSI_DELAY_EEPROM EEPROM_Delay_le25MHz
#define HSE_FREQ_HZ 8000000UL
#define HSE_TIMEOUT 0x0600UL
#define HSE_LOW_SRI MDR_LOWRI_le40MHz
#define HSE_DELAY_EEPROM EEPROM_Delay_le25MHz
... тоже самое для LSI, LSE
Это параметры по умолчанию для функций драйвера MDR_RST_Clock:
* _FREQ_HZ - Частота генератора, используется в расчете текущей частоты. Например, в CMSIS-функции SystemCoreClockUpdate() файл system_MDR1986VE9x.c.
* _FREQ_TRIM - Внутренние RC-генераторы HSI и LSI имеют большой разброс частоты, чтобы ее подстроить есть параметр HSI_FREQ_TRIM, MDR_BKP_HSI_TRIM_8M0Hz - типовое значение, но лучше подбирать под конкретный экземпляр.
* _TIMEOUT - Время ожидания готовности при включении генератора.
* _LOW_SRI и _DELAY_EEPROM - При выборе рабочей частоты МК необходимо в зависимости от частоты выставлять настройки LDO и задержку доступа к EEPROM.
====DMA====
// ========================= DMA ================================
// Для экономии памяти можно прописать 0, если альтернативные структуры DMA не используются
#define USE_DMA_ALTER_STRUCT 1
// Можно завести собственную управляющую структуру каналов вместо глобальной (по умолчанию).
#define USE_DMA_USER_CNTLS_CTRL_TABLE 0
В драйвере MDR_DMA.c выделен массив структур основных и альтернативных для всех 32-х каналов DMA. Это 64 структуры по 4-ре 32-разрядных слова. Возможно в целях экономии памяти кому-то потребуется освободить эту память. Для этого необходимо выставить в 0 значение USE_DMA_ALTER_STRUCT. Если выставить USE_DMA_USER_CNTLS_CTRL_TABLE в 1, то можно завести свою структуру возможно меньшего размера и без альтернативных структур. При этом важно помнить, что своя структура должна быть выровнена необходимым образом по адресу!
====Таймеры====
// ========================= Timer Bugfixes ================================
// Прерывание возникает раньше, чем обновляются регистры CCR и CCR1
#define USE_TIM_CAP_FIX 0
Флаг использования обхода ошибки с захватом в канале таймера. Используется в драйвере MDR_Timer.c. Демопроект показывающий ошибку - [[https://github.com/StartMilandr/Bugs/tree/master/Timer_CapSyncChannels|CAPSyncChannels]].
====Блок Power====
// ========================= POWER Bugfixes ================================
// Флаги событий не стираются с первого раза
#define USE_PWR_CLR_FIX 1
Флаг реализует двойной сброс флагов PVD в драйвере блока детектора питания POWER. Раньше считалось что это ошибка, позднее вышло уточнение что так и должно быть. Первая запись в регистр разрешает доступ к сбросу, вторая запись непосредственно сбрасывает флаг события. Подробнее - [[https://startmilandr.ru/doku.php/prog:bug:pvd_test|Особенности детектора питания, блок Power]]. //В последствии, если изменений не будет, то флаг будет удален, а двойной сброс будет выполняться без условной компиляции.//
====MDR_Delay====
// ========================= MDR_Delay ===========================
// Выбор реализации для MDR_Delay:
// По умолчанию используется ассемблерный вариант, универсальный
// Вариант на Си сильно зависит от опций компилятора
// Вариант на DWT есть только в Cortex-M3/M4 и требует предварительное включение вызовом MDR_Delay_Init().
#define USE_MDR_DELAY_ASM
//#define USE_MDR_DELAY_C
//#define USE_MDR_DELAY_DWT
// Исполнение функции задержки из ОЗУ / EEPROM происходит за разное количество тактов CPU.
// Данными параметрами можно уточнить сколько тактов CPU занимает один цикл задержки в MDR_Funcs, для повышения точности.
#define DELAY_LOOP_CYCLES_ASM 3
#define DELAY_LOOP_CYCLES_ASM_RAM 9
#define DELAY_LOOP_CYCLES_C 6
#define DELAY_LOOP_CYCLES_C_RAM 12
#define DELAY_LOOP_CYCLES_DWT 1
#ifdef USE_MDR_DELAY_C
#define DELAY_LOOP_CYCLES DELAY_LOOP_CYCLES_C
#define DELAY_LOOP_CYCLES_RAM DELAY_LOOP_CYCLES_C_RAM
#elif defined USE_MDR_DELAY_DWT
#define DELAY_LOOP_CYCLES DELAY_LOOP_CYCLES_DWT
#define DELAY_LOOP_CYCLES_RAM DELAY_LOOP_CYCLES_WDT_RAM
#else
#define DELAY_LOOP_CYCLES DELAY_LOOP_CYCLES_ASM
#define DELAY_LOOP_CYCLES_RAM DELAY_LOOP_CYCLES_ASM
#endif
В данном разделе необходимо оставить активным один из вариантов реализации функции MDR_Delay(). В данном примере при USE_MDR_DELAY_ASM функция MDR_Delay() будет иметь ассемблерную реализацию. Плюс такой реализации в том, что она не зависит от опций компилятора и один цикл задержки занимает одно количество тактов, которое определено ниже в DELAY_LOOP_CYCLES_ASM. Это количество тактов CPU_Clock на цикл задержки при исполнении кода из флеш памяти. Если же задержка исполняется из ОЗУ, то шины работают немного по другому и количество тактов на исполнение тех-же ассемблерных инструкций занимает большее количество тактов - DELAY_LOOP_CYCLES_ASM_RAM.
Вариант на ассемблере самый универсальный, работает на всех микроконтроллерах. Вариант на Си сильно зависит от опций компилятора. Для Cortex-M3 //(1986ВЕ9х)// и Cortex-M4 //(1986ВЕ8Т, "Электросила")// доступна реализация задержки на основе отладочного блока трассировки - WDT. Здесь такты CPU_Clock считаются напрямую и с кодом никак не связаны, поэтому данный вариант самый точный и независимый. Но к сожалению есть не во всех микроконтроллерах.
Подробнее обо всем этом - [[https://startmilandr.ru/doku.php/prog:pack_v6:delayasm|MDR_Delay - Функция задержки и особенности её реализации в ассемблере]].