From 6d1a5c8f7173e264ece8cfcf0b6ba99aa44504b0 Mon Sep 17 00:00:00 2001 From: Razvalyaev Date: Fri, 7 Nov 2025 20:28:01 +0300 Subject: [PATCH] release 0.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - stm general перенесена в другой репозиторий - рефакторинг документации --- MyLibs/Inc/bench_time.h | 257 +++++++ MyLibs/Inc/bit_access.h | 2 +- .../{evolve_optimizer.h => gen_optimizer.h} | 87 ++- .../{__mylibs_config.h => mylibs_config.h} | 31 +- MyLibs/Inc/mylibs_defs.h | 31 +- .../{__mylibs_include.h => mylibs_include.h} | 33 +- MyLibs/Inc/trace.h | 1 - MyLibs/Inc/trackers.h | 1 - README.md | 54 +- ...{__SEGGER_RTT_Conf.h => SEGGER_RTT_Conf.h} | 0 RTT/SEGGER_RTT_Syscalls_KEIL.c | 394 ++++++++++ STM32_General/Inc/__general_flash.h | 44 -- STM32_General/Inc/general_gpio.h | 237 ------ STM32_General/Inc/general_spi.h | 170 ----- STM32_General/Inc/general_tim.h | 301 -------- STM32_General/Inc/general_uart.h | 156 ---- STM32_General/Src/__general_flash.c | 192 ----- STM32_General/Src/general_gpio.c | 326 -------- STM32_General/Src/general_spi.c | 284 ------- STM32_General/Src/general_tim.c | 722 ------------------ STM32_General/Src/general_uart.c | 383 ---------- mainpage.h | 98 --- 22 files changed, 790 insertions(+), 3014 deletions(-) create mode 100644 MyLibs/Inc/bench_time.h rename MyLibs/Inc/{evolve_optimizer.h => gen_optimizer.h} (81%) rename MyLibs/Inc/{__mylibs_config.h => mylibs_config.h} (77%) rename MyLibs/Inc/{__mylibs_include.h => mylibs_include.h} (82%) rename RTT/{__SEGGER_RTT_Conf.h => SEGGER_RTT_Conf.h} (100%) create mode 100644 RTT/SEGGER_RTT_Syscalls_KEIL.c delete mode 100644 STM32_General/Inc/__general_flash.h delete mode 100644 STM32_General/Inc/general_gpio.h delete mode 100644 STM32_General/Inc/general_spi.h delete mode 100644 STM32_General/Inc/general_tim.h delete mode 100644 STM32_General/Inc/general_uart.h delete mode 100644 STM32_General/Src/__general_flash.c delete mode 100644 STM32_General/Src/general_gpio.c delete mode 100644 STM32_General/Src/general_spi.c delete mode 100644 STM32_General/Src/general_tim.c delete mode 100644 STM32_General/Src/general_uart.c delete mode 100644 mainpage.h diff --git a/MyLibs/Inc/bench_time.h b/MyLibs/Inc/bench_time.h new file mode 100644 index 0000000..731ccc3 --- /dev/null +++ b/MyLibs/Inc/bench_time.h @@ -0,0 +1,257 @@ +/** +****************************************************************************** +* @file bench_time.h +* @brief Заголовочный файл для измерения времени между событиями +****************************************************************************** +* @addtogroup BENCH_TIME Time measurement +* @brief Библиотека для измерения времени/тиков между событиями +* @details +Поддерживает: +- Многоканальные измерения (несколько независимых таймеров) +- Платформонезависимый интерфейс +- Измерение в тиках или временных единицах +- Статистику измерений (мин/макс/среднее) +- Настраиваемый размер тиков для каждого канала + +Параметры для конфигурации: +- @ref BENCH_TIME_ENABLE - Включить бенч времени +- @ref BENCH_TIME_MAX_CHANNELS - Максимальное количество каналов измерения (по умолчанию 8) + +@par Пример использования: +@code +#include "bench_time.h" + +// Инициализация +BenchTime_Init(); + +// Измерение с SysTick +BenchTime_Start(0, HAL_GetTick, 0xFFFFFFFF); +some_function(); +uint32_t time = BenchTime_End(0, HAL_GetTick); + +// Измерение с TIM2 (16-бит) +BenchTime_Start(1, TIM2->CNT, 0xFFFF); +fast_function(); +uint32_t time2 = BenchTime_End(1, TIM2->CNT); + +// Измерение с DWT цикловым счетчиком +BenchTime_Start(2, DWT->CYCCNT, 0xFFFFFFFF); +critical_function(); +uint32_t cycles = BenchTime_End(2, DWT->CYCCNT); + +// Многоканальное измерение +BenchTime_Start(0, HAL_GetTick, 1000); // общее время +BenchTime_Start(1, TIM3->CNT, 500); // часть 1 + +// ... код 1 + +uint32_t part1 = BenchTime_End(1, TIM3->CNT); +BenchTime_Start(2, TIM4->CNT, 200); // часть 2 + +// ... код 2 + +uint32_t part2 = BenchTime_End(2, TIM4->CNT); +uint32_t total = BenchTime_End(0, HAL_GetTick); // общее время + +// Статистика +uint32_t min_time = BenchTime_GetMin(0); +uint32_t max_time = BenchTime_GetMax(0); +uint32_t avg_time = BenchTime_GetAverage(0); +uint32_t count = BenchTime_GetCount(0); +@endcode +* @{ +*****************************************************************************/ +#ifndef __BENCH_TIME_H_ +#define __BENCH_TIME_H_ + +#include "mylibs_defs.h" +#include + +#ifdef BENCH_TIME_ENABLE + +// Конфигурация библиотеки +#ifndef BENCH_TIME_MAX_CHANNELS +#define BENCH_TIME_MAX_CHANNELS 8 ///< Максимальное количество каналов измерения +#endif + +/** + * @brief Структура статистики измерений + */ +typedef struct { + uint32_t min_ticks; ///< Минимальное время в тиках + uint32_t max_ticks; ///< Максимальное время в тиках + uint32_t total_ticks; ///< Суммарное время в тиках + uint32_t count; ///< Количество измерений + uint32_t last_ticks; ///< Последнее измеренное время +} BenchTimeStats_t; + +/** + * @brief Структура канала измерения + */ +typedef struct { + uint32_t start_tick; ///< Время старта в тиках + uint32_t tick_period; ///< Период тиков для переполнения + uint32_t is_running; ///< Флаг активного измерения + BenchTimeStats_t stats; ///< Статистика измерений +} BenchTimeChannel_t; + +/** + * @brief Основная структура менеджера измерений + */ +typedef struct { + BenchTimeChannel_t channels[BENCH_TIME_MAX_CHANNELS]; ///< Каналы измерения +} BenchTime_t; + +static BenchTime_t hbt = {0}; ///< Внутренний экземпляр + +/** + * @brief Инициализация системы измерения времени + */ +static inline void BenchTime_Init(void) { + for (int i = 0; i < BENCH_TIME_MAX_CHANNELS; i++) { + hbt.channels[i].start_tick = 0; + hbt.channels[i].tick_period = 0xFFFFFFFF; + hbt.channels[i].is_running = 0; + hbt.channels[i].stats.min_ticks = 0xFFFFFFFF; + hbt.channels[i].stats.max_ticks = 0; + hbt.channels[i].stats.total_ticks = 0; + hbt.channels[i].stats.count = 0; + hbt.channels[i].stats.last_ticks = 0; + } +} + +/** + * @brief Начало измерения на указанном канале + * @param channel Номер канала (0..BENCH_TIME_MAX_CHANNELS-1) + * @param ticks Источник тиков (например: HAL_GetTick(), TIM2->CNT, DWT->CYCCNT) + * @param tick_period Период тиков для переполнения + * @return 1 - успех, 0 - ошибка + */ +static inline uint32_t BenchTime_Start(uint8_t channel, uint32_t ticks, uint32_t tick_period) { + if (channel >= BENCH_TIME_MAX_CHANNELS) return 0; + if (hbt.channels[channel].is_running) return 0; + + hbt.channels[channel].start_tick = ticks; + hbt.channels[channel].tick_period = tick_period; + hbt.channels[channel].is_running = 1; + return 1; +} + +/** + * @brief Окончание измерения на указанном канале + * @param channel Номер канала (0..BENCH_TIME_MAX_CHANNELS-1) + * @param ticks Источник тиков (должен быть тот же что в Start) + * @return Измеренное время в тиках, 0 - в случае ошибки + */ +static inline uint32_t BenchTime_End(uint8_t channel, uint32_t ticks) { + if (channel >= BENCH_TIME_MAX_CHANNELS) return 0; + if (!hbt.channels[channel].is_running) return 0; + + uint32_t end_tick = ticks; + uint32_t start_tick = hbt.channels[channel].start_tick; + uint32_t tick_period = hbt.channels[channel].tick_period; + uint32_t elapsed_ticks; + + if (end_tick >= start_tick) { + elapsed_ticks = end_tick - start_tick; + } else { + elapsed_ticks = (tick_period - start_tick) + end_tick + 1; + } + + if (elapsed_ticks > tick_period) { + elapsed_ticks = tick_period; + } + + hbt.channels[channel].is_running = 0; + + // Обновление статистики + BenchTimeStats_t* stats = &hbt.channels[channel].stats; + stats->last_ticks = elapsed_ticks; + + if (elapsed_ticks < stats->min_ticks) { + stats->min_ticks = elapsed_ticks; + } + + if (elapsed_ticks > stats->max_ticks) { + stats->max_ticks = elapsed_ticks; + } + + stats->total_ticks += elapsed_ticks; + stats->count++; + + return elapsed_ticks; +} + +/** + * @brief Получение минимального времени измерения + */ +static inline uint32_t BenchTime_GetMin(uint8_t channel) { + if (channel >= BENCH_TIME_MAX_CHANNELS) return 0; + return hbt.channels[channel].stats.min_ticks; +} + +/** + * @brief Получение максимального времени измерения + */ +static inline uint32_t BenchTime_GetMax(uint8_t channel) { + if (channel >= BENCH_TIME_MAX_CHANNELS) return 0; + return hbt.channels[channel].stats.max_ticks; +} + +/** + * @brief Получение среднего времени измерения + */ +static inline uint32_t BenchTime_GetAverage(uint8_t channel) { + if (channel >= BENCH_TIME_MAX_CHANNELS) return 0; + BenchTimeStats_t* stats = &hbt.channels[channel].stats; + if (stats->count == 0) return 0; + return stats->total_ticks / stats->count; +} + +/** + * @brief Получение количества измерений + */ +static inline uint32_t BenchTime_GetCount(uint8_t channel) { + if (channel >= BENCH_TIME_MAX_CHANNELS) return 0; + return hbt.channels[channel].stats.count; +} + +/** + * @brief Получение последнего измеренного времени + */ +static inline uint32_t BenchTime_GetLast(uint8_t channel) { + if (channel >= BENCH_TIME_MAX_CHANNELS) return 0; + return hbt.channels[channel].stats.last_ticks; +} + +/** + * @brief Сброс статистики для канала + */ +static inline void BenchTime_ResetStats(uint8_t channel) { + if (channel >= BENCH_TIME_MAX_CHANNELS) return; + BenchTimeStats_t* stats = &hbt.channels[channel].stats; + stats->min_ticks = 0xFFFFFFFF; + stats->max_ticks = 0; + stats->total_ticks = 0; + stats->count = 0; + stats->last_ticks = 0; +} +#else //BENCH_TIME_ENABLE + +#define BenchTime_Init() +#define BenchTime_Start(channel, ticks, tick_period) 0 +#define BenchTime_End(channel, ticks) 0 +#define BenchTime_GetMin(channel) 0 +#define BenchTime_GetMax(channel) 0 +#define BenchTime_GetAverage(channel) 0 +#define BenchTime_GetCount(channel) 0 +#define BenchTime_GetLast(channel) 0 +#define BenchTime_ResetStats(channel) + +#endif //BENCH_TIME_ENABLE + +#endif // __BENCH_TIME_H_ + +/** BENCH_TIME + * @} + */ \ No newline at end of file diff --git a/MyLibs/Inc/bit_access.h b/MyLibs/Inc/bit_access.h index fe824cd..52a6d60 100644 --- a/MyLibs/Inc/bit_access.h +++ b/MyLibs/Inc/bit_access.h @@ -4,7 +4,7 @@ * @brief Заголочный файл для дефайнов битового доступа. ************************************************************************** * @defgroup BIT_ACCESS_DEFINES Bit access defines -* @ingroup MYLIBS_DEFINES +* @ingroup MYLIBS_TOOLS * @brief Макросы и typedef'ы для работы с битами в unsigned типах. * @details В этом файле определены макросы для получения значения конкретного бита^ diff --git a/MyLibs/Inc/evolve_optimizer.h b/MyLibs/Inc/gen_optimizer.h similarity index 81% rename from MyLibs/Inc/evolve_optimizer.h rename to MyLibs/Inc/gen_optimizer.h index 7d4de0f..3a2c35f 100644 --- a/MyLibs/Inc/evolve_optimizer.h +++ b/MyLibs/Inc/gen_optimizer.h @@ -1,10 +1,9 @@ /** ****************************************************************************** -* @file evolve_optimizer.h +* @file gen_optimizer.h * @brief Заголовочный файл для адаптивного подбора параметров ****************************************************************************** -* @addtogroup EVOLVE_OPTIMIZER Evolve optimizer -* @ingroup MYLIBS_DEFINES +* @addtogroup GEN_OPTIMIZER Genetic optimizer * @brief Библиотека для эволюционного подбора параметров * @details Поддерживает: @@ -15,24 +14,24 @@ Параметры для конфигурации: -- @ref ENABLE_EVOLVE_OPTIMIZATION - Включить оптимизацию параметров - Если библиотека отключена @ref ENABLE_EVOLVE_OPTIMIZATION, то вставляются +- @ref GEN_OPTIMIZATION_ENABLE - Включить оптимизацию параметров + Если библиотека отключена @ref GEN_OPTIMIZATION_ENABLE, то вставляются заглушки, никак не влияющие на параметры и остальную программу -- @ref EVOLVE_MAX_PARAMS - Максимальное количество параметров -- @ref EVOLVE_MAX_CANDIDATES - Максимальное количество кандидатов для обучения -- (опционально) @ref EVOLVE_MUTATION_MIN_PCT - Минимальная мутация в процентах от Loss (по умолчанию 10%) -- (опционально) @ref EVOLVE_MUTATION_MAX_PCT - Максимальная мутация в процентах от Loss (по умолчанию 100%) +- @ref GEN_MAX_PARAMS - Максимальное количество параметров +- @ref GEN_MAX_CANDIDATES - Максимальное количество кандидатов для обучения +- (опционально) @ref GEN_MUTATION_MIN_PCT - Минимальная мутация в процентах от Loss (по умолчанию 10%) +- (опционально) @ref GEN_MUTATION_MAX_PCT - Максимальная мутация в процентах от Loss (по умолчанию 100%) - (опционально) @ref ELOVLE_N_ELITE_CANDIDATE - Количество кандидатов, которые проходят в поколение без изменений @par Пример использования: @code -#include "evolve_optimizer.h" +#include "gen_optimizer.h" #define N_PARAMS 4 #define N_CANDIDATES 100 #define N_BEST 10 #define MUTATION 0.1f float params[N_PARAMS]; -EvolveOptimizer_t optimizer; +GenOptimizer_t optimizer; // Формирование параметров uint16_t param_u16 = 800; @@ -45,11 +44,11 @@ params[2] = PARAM_SCALE(param_u8, 10.0f, 100.0f); params[3] = PARAM_SCALE(param_i16, 500.0f, 5000.0f); // Инициалиазция -EvolveOptimizer_Init(&optimizer, N_PARAMS, N_CANDIDATES, N_BEST, MUTATION, params); +GenOptimizer_Init(&optimizer, N_PARAMS, N_CANDIDATES, N_BEST, MUTATION, params); // Шаг эволюции float loss = calc_loss(); // расчет эффективности параметров (от 0 до 1) -EvolveOptimizer_Step(&optimizer, params, loss); +GenOptimizer_Step(&optimizer, params, loss); // Взятие следующих для эволюции параметров param_u16 = PARAM_UNSCALE(params[0], 0.0f, 1000.0f); @@ -59,14 +58,14 @@ param_i16 = PARAM_UNSCALE(params[3], 500.0f, 5000.0f); @endcode * @{ *****************************************************************************/ -#ifndef __EVOLVE_OPTIMIZER_H_ -#define __EVOLVE_OPTIMIZER_H_ +#ifndef __GEN_OPTIMIZER_H_ +#define __GEN_OPTIMIZER_H_ #include "mylibs_defs.h" #include #include -#ifdef ENABLE_EVOLVE_OPTIMIZATION +#ifdef GEN_OPTIMIZATION_ENABLE /** * @brief Линейное масштабирование x из диапазона [min_val, max_val] в диапазон [0, 1) */ @@ -85,11 +84,11 @@ param_i16 = PARAM_UNSCALE(params[3], 500.0f, 5000.0f); -#ifndef EVOLVE_MUTATION_MIN_PCT -#define EVOLVE_MUTATION_MIN_PCT 10 ///< Минимальная мутация (в процентах от Loss) +#ifndef GEN_MUTATION_MIN_PCT +#define GEN_MUTATION_MIN_PCT 10 ///< Минимальная мутация (в процентах от Loss) #endif -#ifndef EVOLVE_MUTATION_MAX_PCT -#define EVOLVE_MUTATION_MAX_PCT 100 ///< Максимальная мутация (в процентах от Loss) +#ifndef GEN_MUTATION_MAX_PCT +#define GEN_MUTATION_MAX_PCT 100 ///< Максимальная мутация (в процентах от Loss) #endif #ifndef ELOVLE_N_ELITE_CANDIDATE #define ELOVLE_N_ELITE_CANDIDATE 2 ///< Количество кандидатов, которые проходят в поколение без изменений (по умолчанию 2) @@ -107,25 +106,25 @@ typedef struct { uint16_t n_best; ///< Количество лучших, усредняемых float mutation_amp; ///< Амплитуда мутации (0..1) - uint16_t cand_index; ///< Индекс кандидата для обработки + uint16_t cand_index; ///< Индекс текущего кандидата uint16_t gen_index; ///< Индекс популяции //INTERNAL float gen_mut; ///< Амплитуда мутации у текущей популяции - float loss[EVOLVE_MAX_CANDIDATES]; ///< Loss для каждого кандидата - float candidates[EVOLVE_MAX_CANDIDATES][EVOLVE_MAX_PARAMS]; ///< Параметры кандидатов - uint16_t sorted_idx[EVOLVE_MAX_CANDIDATES]; ///< Индексы отсортированных кандидатов -} EvolveOptimizer_t; + float loss[GEN_MAX_CANDIDATES]; ///< Loss для каждого кандидата + float candidates[GEN_MAX_CANDIDATES][GEN_MAX_PARAMS]; ///< Параметры кандидатов + uint16_t sorted_idx[GEN_MAX_CANDIDATES]; ///< Индексы отсортированных кандидатов +} GenOptimizer_t; /** - * @cond EVOLVE_INTERNAL + * @cond GEN_INTERNAL */ // Вспомогательный указатель для сортировки -static EvolveOptimizer_t *g_sort_opt; // глобальный указатель на текущий оптимизатор +static GenOptimizer_t *g_sort_opt; // глобальный указатель на текущий оптимизатор // функция условия сортировки static int cmp_idx(const void *a, const void *b) { @@ -152,7 +151,7 @@ static int cmp_idx(const void *a, const void *b) { * @return 0 — если окей, * -1 — если ошибка */ -__STATIC_INLINE int EvolveOptimizer_Init(EvolveOptimizer_t* opt, +static int GenOptimizer_Init(GenOptimizer_t* opt, uint16_t n_params, uint16_t n_cand, uint16_t n_best, @@ -162,15 +161,15 @@ __STATIC_INLINE int EvolveOptimizer_Init(EvolveOptimizer_t* opt, if((opt == NULL) || (start_params == NULL)) return -1; - if(n_params > EVOLVE_MAX_PARAMS) + if(n_params > GEN_MAX_PARAMS) return -1; opt->n_params = n_params; - if(n_cand > EVOLVE_MAX_CANDIDATES) + if(n_cand > GEN_MAX_CANDIDATES) return -1; opt->n_cand = n_cand; - if(n_best > EVOLVE_MAX_CANDIDATES/2) + if(n_best > GEN_MAX_CANDIDATES/2) return -1; opt->n_best = n_best; @@ -222,7 +221,7 @@ __STATIC_INLINE int EvolveOptimizer_Init(EvolveOptimizer_t* opt, * @note Функция использует глобальную внутреннюю переменную для сортировки. * Надо убедится что только один экземпляр функции запущен в момент времени */ -__STATIC_INLINE int EvolveOptimizer_Step(EvolveOptimizer_t* opt, +static int GenOptimizer_Step(GenOptimizer_t* opt, float* params, float loss) { @@ -230,15 +229,15 @@ __STATIC_INLINE int EvolveOptimizer_Step(EvolveOptimizer_t* opt, return -1; uint16_t n_params = opt->n_params; - if(n_params > EVOLVE_MAX_PARAMS) + if(n_params > GEN_MAX_PARAMS) return -1; uint16_t n_cand = opt->n_cand; - if(n_cand > EVOLVE_MAX_CANDIDATES) + if(n_cand > GEN_MAX_CANDIDATES) return -1; uint16_t n_best = opt->n_best; - if(n_best > EVOLVE_MAX_CANDIDATES/2) + if(n_best > GEN_MAX_CANDIDATES/2) return -1; float mut = opt->mutation_amp; @@ -280,8 +279,8 @@ __STATIC_INLINE int EvolveOptimizer_Step(EvolveOptimizer_t* opt, if(opt->stability < 0.0f) opt->stability = 0.0f; if(opt->stability > 1.0f) opt->stability = 1.0f; - float mut_pct = EVOLVE_MUTATION_MIN_PCT + - (EVOLVE_MUTATION_MAX_PCT - EVOLVE_MUTATION_MIN_PCT) * loss_ratio; + float mut_pct = GEN_MUTATION_MIN_PCT + + (GEN_MUTATION_MAX_PCT - GEN_MUTATION_MIN_PCT) * loss_ratio; float adaptive_mut = mut * (mut_pct / 100.0f); if (adaptive_mut < 0.0001f) adaptive_mut = 0.0001f; opt->gen_mut = adaptive_mut; @@ -315,7 +314,7 @@ __STATIC_INLINE int EvolveOptimizer_Step(EvolveOptimizer_t* opt, return 0; } -#else // ENABLE_EVOLVE_OPTIMIZATION +#else // GEN_OPTIMIZATION_ENABLE //заглушки typedef struct { uint16_t n_params; @@ -324,15 +323,15 @@ typedef struct { float mutation_amp; float loss[0]; float candidates[0][0]; -} EvolveOptimizer_t; -#define EvolveOptimizer_Init(opt, n_params, n_cand, n_best, mutation_amp, start_params) -#define EvolveOptimizer_Step(opt, params, LossFunc) +} GenOptimizer_t; +#define GenOptimizer_Init(opt, n_params, n_cand, n_best, mutation_amp, start_params) +#define GenOptimizer_Step(opt, params, LossFunc) #define PARAM_SCALE(x, min_val, max_val) (x) #define PARAM_UNSCALE(val, min_val, max_val) (val) -#endif // ENABLE_EVOLVE_OPTIMIZATION +#endif // GEN_OPTIMIZATION_ENABLE -#endif // __EVOLVE_OPTIMIZER_H_ +#endif // __GEN_OPTIMIZER_H_ -/** EVOLVE_OPTIMIZER +/** GEN_OPTIMIZER * @} */ diff --git a/MyLibs/Inc/__mylibs_config.h b/MyLibs/Inc/mylibs_config.h similarity index 77% rename from MyLibs/Inc/__mylibs_config.h rename to MyLibs/Inc/mylibs_config.h index 68208d2..5e56f3d 100644 --- a/MyLibs/Inc/__mylibs_config.h +++ b/MyLibs/Inc/mylibs_config.h @@ -55,21 +55,38 @@ /** - * @addtogroup EVOLVE_CONFIG Evolve configs + * @addtogroup GEN_CONFIG Genetic configs * @ingroup MYLIBS_CONFIG - * @brief Конфигурация однослойного персептрона и алгоритма обучения + * @brief Конфигурация генетического алгоритма обучения * @{ */ -#define ENABLE_EVOLVE_OPTIMIZATION ///< Включить оптимизацию параметров -#define EVOLVE_MAX_PARAMS 20 ///< Максимальное количество параметров -#define EVOLVE_MAX_CANDIDATES 100 ///< Максимальное количество кандидатов для обучения +#define GEN_OPTIMIZATION_ENABLE ///< Включить оптимизацию параметров +#define GEN_MAX_PARAMS 20 ///< Максимальное количество параметров +#define GEN_MAX_CANDIDATES 100 ///< Максимальное количество кандидатов для обучения -/** EVOLVE_CONFIG +/** GEN_CONFIG * @} */ +/** + * @addtogroup GEN_CONFIG Genetic configs + * @ingroup MYLIBS_CONFIG + * @brief Конфигурация генетического алгоритма обучения + * @{ + */ + + +#define BENCH_TIME_ENABLE ///< Включить бенч времени +#define BENCH_TIME_MAX_CHANNELS 16 ///< Максимальное количество каналов измерения + +/** GEN_CONFIG + * @} + */ + + + /** * @addtogroup LIBS_CONFIG Libraries configs * @ingroup MYLIBS_CONFIG @@ -79,7 +96,7 @@ #define local_time() uwTick ///< Локальное время -#define INCLUDE_EVOLVE_OPTIMIZER ///< Подключить библиотеку для оптимизации параметров +#define INCLUDE_GEN_OPTIMIZER ///< Подключить библиотеку для оптимизации параметров #define INCLUDE_BIT_ACCESS_LIB ///< Подключить библиотеку с typedef с битовыми полями #define INCLUDE_TRACKERS_LIB ///< Подключить библиотеку с трекерами #define INCLUDE_TRACE_LIB ///< Подключить библиотеку с трейсами diff --git a/MyLibs/Inc/mylibs_defs.h b/MyLibs/Inc/mylibs_defs.h index e7e835f..8b32702 100644 --- a/MyLibs/Inc/mylibs_defs.h +++ b/MyLibs/Inc/mylibs_defs.h @@ -3,13 +3,28 @@ * @file mylibs_defs.h * @brief Заголочный файл для дефайнов библиотеки MyLibsGeneral. ************************************************************************** -* @defgroup MYLIBS_DEFINES General Tools +* @defgroup MYLIBS_TOOLS General Tools * @ingroup MYLIBS_ALL * @brief Общие макросы и typedef'ы, используемые по всему проекту * +* @defgroup MYLIBS_DEBUG_TOOLS Debug Tools +* @ingroup MYLIBS_ALL +* @brief Утилиты для тестирования программы +* +* @addtogroup BENCH_TIME +* @ingroup MYLIBS_DEBUG_TOOLS +* +* @addtogroup GEN_OPTIMIZER +* @ingroup MYLIBS_DEBUG_TOOLS +* +* @addtogroup TRACE +* @ingroup MYLIBS_DEBUG_TOOLS +* +* @addtogroup TRACKERS +* @ingroup MYLIBS_DEBUG_TOOLS *************************************************************************/ -#ifndef __MYLIBS_DEFINES_H_ -#define __MYLIBS_DEFINES_H_ +#ifndef __MYLIBS_TOOLS_H_ +#define __MYLIBS_TOOLS_H_ #include "mylibs_config.h" @@ -17,7 +32,7 @@ ******************************ERROR_HANDLER********************************/ /** * @addtogroup ERROR_HANDLER_DEFINES Error Handler defines - * @ingroup MYLIBS_DEFINES + * @ingroup MYLIBS_TOOLS * @brief Дефайны для обработки ошибок * @{ */ @@ -58,7 +73,7 @@ extern void Error_Handler(void); ******************************DELAYS_DEFINES*******************************/ /** * @addtogroup DELAYS_DEFINES Delays defines - * @ingroup MYLIBS_DEFINES + * @ingroup MYLIBS_TOOLS * @brief Макросы и определения для работы с задержками в миллисекундах. * @details * Этот блок содержит макросы для реализации задержек с использованием HAL или FreeRTOS: @@ -138,10 +153,9 @@ extern void Error_Handler(void); /*************************************************************************** *******************************UTIL_DEFINES********************************/ -static int dummy; /** * @addtogroup UTILS_DEFINES Utils defines - * @ingroup MYLIBS_DEFINES + * @ingroup MYLIBS_TOOLS * @brief Общие вспомогательные макросы * @{ */ @@ -191,6 +205,7 @@ static int dummy; * @cond LIBS_INTERNAL */ +static int dummy; // переменная которой присваиваются значения, которые некуда присвоить /** * @brief Аналог HAL макроса для привязки DMA к UART. @@ -203,4 +218,4 @@ do{ \ /** @endcond */ -#endif //__MYLIBS_DEFINES_H_ \ No newline at end of file +#endif //__MYLIBS_TOOLS_H_ \ No newline at end of file diff --git a/MyLibs/Inc/__mylibs_include.h b/MyLibs/Inc/mylibs_include.h similarity index 82% rename from MyLibs/Inc/__mylibs_include.h rename to MyLibs/Inc/mylibs_include.h index e9acba2..27fa86c 100644 --- a/MyLibs/Inc/__mylibs_include.h +++ b/MyLibs/Inc/mylibs_include.h @@ -14,13 +14,8 @@ - Сконфигурировать mylibs_config.h: - Подключить заголовочный файл HAL библиотеки конкретного МК (напр. stm32f4xx_hal.h) - Подключить другие заголовочные файлы которые общие для всего проекта и должны быть видны - - -- Подключить mylibs_include.h туда, где необходим доступ к библиотекам. + - Подключить mylibs_include.h туда, где необходим доступ к библиотекам. -* @defgroup MYLIBS_PERIPHERAL Peripheral -* @ingroup MYLIBS_ALL -* @brief Модули для управления периферией -* *************************************************************************/ #ifndef __MYLIBS_INCLUDE_H_ #define __MYLIBS_INCLUDE_H_ @@ -79,8 +74,8 @@ #define HF_HandleFault(...) #endif -#ifdef INCLUDE_EVOLVE_OPTIMIZER -#include "evolve_optimizer.h" +#ifdef INCLUDE_GEN_OPTIMIZER +#include "gen_optimizer.h" #else typedef struct { uint16_t n_params; @@ -89,13 +84,29 @@ typedef struct { uint16_t iq_mutation; int32_t loss[0]; int32_t candidates[0][0]; -} EvolveOptimizer_t; -#define EvolveOptimizer_Init(opt, n_params, n_cand, n_best, iq_mutation, start_params) -#define EvolveOptimizer_Step(opt, params, LossFunc) +} GenOptimizer_t; +#define GenOptimizer_Init(opt, n_params, n_cand, n_best, iq_mutation, start_params) +#define GenOptimizer_Step(opt, params, LossFunc) #define PARAM_SCALE_Q16(x, min_val, max_val) (x) #define PARAM_UNSCALE_Q16(q16_val, min_val, max_val) (q16_val) #endif + + +#ifdef INCLUDE_BENCH_TEST +#include "bench_time.h" +#else //BENCH_TIME_ENABLE +#define BenchTime_Init() +#define BenchTime_Start(channel, ticks, tick_period) 0 +#define BenchTime_End(channel, ticks) 0 +#define BenchTime_GetMin(channel) 0 +#define BenchTime_GetMax(channel) 0 +#define BenchTime_GetAverage(channel) 0 +#define BenchTime_GetCount(channel) 0 +#define BenchTime_GetLast(channel) 0 +#define BenchTime_ResetStats(channel) +#endif //BENCH_TIME_ENABLE + #ifdef INCLUDE_GENERAL_PERIPH_LIBS #include "__general_flash.h" diff --git a/MyLibs/Inc/trace.h b/MyLibs/Inc/trace.h index d0f5c7f..976b8d1 100644 --- a/MyLibs/Inc/trace.h +++ b/MyLibs/Inc/trace.h @@ -4,7 +4,6 @@ * @brief Заголочный файл для работы с трассировкой. ************************************************************************** * @addtogroup TRACE Trace defines -* @ingroup MYLIBS_DEFINES * @brief Дефайны для работы с трассировкой *************************************************************************/ #ifndef __TRACE_H_ diff --git a/MyLibs/Inc/trackers.h b/MyLibs/Inc/trackers.h index 9313f39..458dd00 100644 --- a/MyLibs/Inc/trackers.h +++ b/MyLibs/Inc/trackers.h @@ -4,7 +4,6 @@ * @brief Заголочный файл для работы с трекерами @ref TRACKERS. ************************************************************************** * @addtogroup TRACKERS Trackers defines -* @ingroup MYLIBS_DEFINES * @brief Дефайны для работы с трекерами * @details Есть дефайн для объявления структуры трекера: TrackerTypeDef(num_user_vars). diff --git a/README.md b/README.md index 1f0f99f..219c2b0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,22 @@ -# Инструкция по подключению релиза библиотеки `ExtendedLibs` +# Обзор `ExtendedLibs` -Данный субмодуль подключается напрямую из Git и содержит набор вспомогательных библиотек для работы МК, в частности STM32 и SEGGER RTT. +ExtendedLibs - это набор библиотек для удобной работы с STM32. Данный субмодуль подключается напрямую из Git и содержит набор вспомогательных библиотек для работы МК, в частности STM32 и SEGGER RTT. + +## Основные возможности + + +#### Общие утилиты MyLibs (@ref MYLIBS_TOOLS) +- Макросы для задержек (@ref DELAYS_DEFINES) +- Утилиты для работы с всяким (@ref UTILS_DEFINES) +- Битовый доступ к регистрам через union (@ref BIT_ACCESS_DEFINES) + +#### Отладка* (@ref MYLIBS_DEBUG_TOOLS) +- Трассировка (@ref TRACE) +- Измерение временных интервалов (@ref BENCH_TIME) +- Генетический алгоритм для оптимизации параметров (@ref GEN_OPTIMIZER) +- Трекеры для статистики и отладки (@ref TRACKERS) + +_*Модули отладки независимы от MyLibs и могут быть использованы отдельно_ ## Структура библиотеки @@ -13,29 +29,17 @@ ProjectRoot/ │ │ ├── __mylibs_config.h # Конфигурация библиотек │ │ ├── mylibs_defs.h # Общие определения и макросы │ │ ├── bit_access.h # Битовый доступ к регистрам -│ │ ├── evolve_optimizer.h # Оптимизатор (генетический алгоритм) +│ │ ├── gen_optimizer.h # Оптимизатор (генетический алгоритм) │ │ ├── trackers.h # Трекеры для отладки │ │ └── trace.h # Трассировка и логирование │ └── src/ │ -├──RTT # Библиотека RTT -│ ├── __SEGGER_RTT_Conf.h # Конфигурационный файл RTT -│ ├── SEGGER_RTT.c # Основной модуль RTT -│ ├── SEGGER_RTT.h # Основной заголовок RTT -│ ├── SEGGER_RTT_ASM_ARMv7M.S # Ассемблерная оптимизация для ARMv7M -│ └── SEGGER_RTT_printf.c # Реализация printf() через RTT -│ -└── STM32_General # Работа с периферией STM32 - ├── inc/ - │ ├── general_gpio.h # Работа с GPIO - │ ├── general_spi.h # Работа с SPI - │ ├── general_tim.h # Работа с таймерами - │ └── general_uart.h # Работа с UART - └── src/ - ├── general_gpio.c # Реализация GPIO - ├── general_spi.c # Реализация SPI - ├── general_tim.c # Реализация TIM - └── general_uart.c # Реализация UART +└──RTT # Библиотека RTT + ├── __SEGGER_RTT_Conf.h # Конфигурационный файл RTT + ├── SEGGER_RTT.c # Основной модуль RTT + ├── SEGGER_RTT.h # Основной заголовок RTT + ├── SEGGER_RTT_ASM_ARMv7M.S # Ассемблерная оптимизация для ARMv7M + └── SEGGER_RTT_printf.c # Реализация printf() через RTT ``` ## Инструкция по подключению @@ -75,10 +79,4 @@ ProjectRoot/ ```bash git submodule update --remote -``` - -## Документация - -Библиотека `MyLibs` и `STM32_General` документирована в формате Doxygen. HTML документацию можно [скачать здесь](https://git.arktika.cyou/Razvalyaev/STM32_ExtendedLibs/archive/v0.02.zip) - -Библиотека `RTT` документирована в формате [страницы википедии](https://kb.segger.com/RTT) и просто комментариями в коде. \ No newline at end of file +``` \ No newline at end of file diff --git a/RTT/__SEGGER_RTT_Conf.h b/RTT/SEGGER_RTT_Conf.h similarity index 100% rename from RTT/__SEGGER_RTT_Conf.h rename to RTT/SEGGER_RTT_Conf.h diff --git a/RTT/SEGGER_RTT_Syscalls_KEIL.c b/RTT/SEGGER_RTT_Syscalls_KEIL.c new file mode 100644 index 0000000..0ad5840 --- /dev/null +++ b/RTT/SEGGER_RTT_Syscalls_KEIL.c @@ -0,0 +1,394 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2021 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 7.54 * +* * +********************************************************************** + +---------------------------END-OF-HEADER------------------------------ +File : RTT_Syscalls_KEIL.c +Purpose : Retargeting module for KEIL MDK-CM3. + Low-level functions for using printf() via RTT +Revision: $Rev: 24316 $ +Notes : (1) https://wiki.segger.com/Keil_MDK-ARM#RTT_in_uVision +---------------------------------------------------------------------- +*/ +#if (defined __CC_ARM) || (defined __ARMCC_VERSION) + +#include +#include +#include +#include +#include + +#include "SEGGER_RTT.h" +/********************************************************************* +* +* #pragmas +* +********************************************************************** +*/ +#if __ARMCC_VERSION < 6000000 +#pragma import(__use_no_semihosting) +#endif + +#ifdef _MICROLIB + #pragma import(__use_full_stdio) +#endif + +/********************************************************************* +* +* Defines non-configurable +* +********************************************************************** +*/ + +/* Standard IO device handles - arbitrary, but any real file system handles must be + less than 0x8000. */ +#define STDIN 0x8001 // Standard Input Stream +#define STDOUT 0x8002 // Standard Output Stream +#define STDERR 0x8003 // Standard Error Stream + +/********************************************************************* +* +* Public const +* +********************************************************************** +*/ +#if __ARMCC_VERSION < 5000000 +//const char __stdin_name[] = "STDIN"; +const char __stdout_name[] = "STDOUT"; +const char __stderr_name[] = "STDERR"; +#endif + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ + +/********************************************************************* +* +* _ttywrch +* +* Function description: +* Outputs a character to the console +* +* Parameters: +* c - character to output +* +*/ +void _ttywrch(int c) { + fputc(c, stdout); // stdout + fflush(stdout); +} + +/********************************************************************* +* +* _sys_open +* +* Function description: +* Opens the device/file in order to do read/write operations +* +* Parameters: +* sName - sName of the device/file to open +* OpenMode - This parameter is currently ignored +* +* Return value: +* != 0 - Handle to the object to open, otherwise +* == 0 -"device" is not handled by this module +* +*/ +FILEHANDLE _sys_open(const char * sName, int OpenMode) { + (void)OpenMode; + // Register standard Input Output devices. + if (strcmp(sName, __stdout_name) == 0) { + return (STDOUT); + } else if (strcmp(sName, __stderr_name) == 0) { + return (STDERR); + } else + return (0); // Not implemented +} + +/********************************************************************* +* +* _sys_close +* +* Function description: +* Closes the handle to the open device/file +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* +* Return value: +* 0 - device/file closed +* +*/ +int _sys_close(FILEHANDLE hFile) { + (void)hFile; + return 0; // Not implemented +} + +/********************************************************************* +* +* _sys_write +* +* Function description: +* Writes the data to an open handle. +* Currently this function only outputs data to the console +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* pBuffer - Pointer to the data that shall be written +* NumBytes - Number of bytes to write +* Mode - The Mode that shall be used +* +* Return value: +* Number of bytes *not* written to the file/device +* +*/ +int _sys_write(FILEHANDLE hFile, const unsigned char * pBuffer, unsigned NumBytes, int Mode) { + int r = 0; + + (void)Mode; + if (hFile == STDOUT) { + SEGGER_RTT_Write(0, (const char*)pBuffer, NumBytes); + return 0; + } + return r; +} + +/********************************************************************* +* +* _sys_read +* +* Function description: +* Reads data from an open handle. +* Currently this modules does nothing. +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* pBuffer - Pointer to buffer to store the read data +* NumBytes - Number of bytes to read +* Mode - The Mode that shall be used +* +* Return value: +* Number of bytes read from the file/device +* +*/ +int _sys_read(FILEHANDLE hFile, unsigned char * pBuffer, unsigned NumBytes, int Mode) { + (void)hFile; + (void)pBuffer; + (void)NumBytes; + (void)Mode; + return (0); // Not implemented +} + +/********************************************************************* +* +* _sys_istty +* +* Function description: +* This function shall return whether the opened file +* is a console device or not. +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* +* Return value: +* 1 - Device is a console +* 0 - Device is not a console +* +*/ +int _sys_istty(FILEHANDLE hFile) { + if (hFile > 0x8000) { + return (1); + } + return (0); // Not implemented +} + +/********************************************************************* +* +* _sys_seek +* +* Function description: +* Seeks via the file to a specific position +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* Pos - +* +* Return value: +* int - +* +*/ +int _sys_seek(FILEHANDLE hFile, long Pos) { + (void)hFile; + (void)Pos; + return (0); // Not implemented +} + +/********************************************************************* +* +* _sys_ensure +* +* Function description: +* +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* +* Return value: +* int - +* +*/ +int _sys_ensure(FILEHANDLE hFile) { + (void)hFile; + return (-1); // Not implemented +} + +/********************************************************************* +* +* _sys_flen +* +* Function description: +* Returns the length of the opened file handle +* +* Parameters: +* hFile - Handle to a file opened via _sys_open +* +* Return value: +* Length of the file +* +*/ +long _sys_flen(FILEHANDLE hFile) { + (void)hFile; + return (0); // Not implemented +} + +/********************************************************************* +* +* _sys_tmpnam +* +* Function description: +* This function converts the file number fileno for a temporary +* file to a unique filename, for example, tmp0001. +* +* Parameters: +* pBuffer - Pointer to a buffer to store the name +* FileNum - file number to convert +* MaxLen - Size of the buffer +* +* Return value: +* 1 - Error +* 0 - Success +* +*/ +int _sys_tmpnam2(char * pBuffer, int FileNum, unsigned MaxLen) { + (void)pBuffer; + (void)FileNum; + (void)MaxLen; + return (1); // Not implemented +} + +/********************************************************************* +* +* _sys_command_string +* +* Function description: +* This function shall execute a system command. +* +* Parameters: +* cmd - Pointer to the command string +* len - Length of the string +* +* Return value: +* == NULL - Command was not successfully executed +* == sCmd - Command was passed successfully +* +*/ +char * _sys_command_string(char * cmd, int len) { + (void)len; + return cmd; // Not implemented +} + +/********************************************************************* +* +* _sys_exit +* +* Function description: +* This function is called when the application returns from main +* +* Parameters: +* ReturnCode - Return code from the main function +* +* +*/ +void _sys_exit(int ReturnCode) { + (void)ReturnCode; + while (1); // Not implemented +} + +#if __ARMCC_VERSION >= 5000000 +/********************************************************************* +* +* stdout_putchar +* +* Function description: +* Put a character to the stdout +* +* Parameters: +* ch - Character to output +* +* +*/ +int stdout_putchar(int ch) { + (void)ch; + return ch; // Not implemented +} +#endif + +#endif +/*************************** End of file ****************************/ \ No newline at end of file diff --git a/STM32_General/Inc/__general_flash.h b/STM32_General/Inc/__general_flash.h deleted file mode 100644 index 9a532e5..0000000 --- a/STM32_General/Inc/__general_flash.h +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************** -* @file general_flash.h -* @brief Заголовочны файл модуля работы с FLASH. -*************************************************************************/ -#ifndef __FLASH_GENERAL_H_ -#define __FLASH_GENERAL_H_ - -////////////////////////////////////////////////////////////////////// -/////////////////////////---USER SETTINGS---///////////////////////// - - -/////////////////////////---USER SETTINGS---///////////////////////// -#include "mylibs_defs.h" - - - -///////////////////////////////////////////////////////////////////// -////////////////////////////---DEFINES---//////////////////////////// - -////////////////////////////---DEFINES---//////////////////////////// - - -///////////////////////////////////////////////////////////////////// -///////////////////////---STRUCTURES & ENUMS---////////////////////// - -///////////////////////---STRUCTURES & ENUMS---////////////////////// - - -///////////////////////////////////////////////////////////////////// -///////////////////////////---FUNCTIONS---/////////////////////////// - -HAL_StatusTypeDef FLASH_Enable_DualBankMode(void); -HAL_StatusTypeDef FLASH_WriteProtection(uint32_t BankN, uint32_t WriteProtection); -/* functions for reading bytes/halswords/words */ -uint8_t FLASH_Read_Byte(uint32_t add); -uint16_t FLASH_Read_HalfWord(uint32_t add); -uint32_t FLASH_Read_Word(uint32_t add); -/* functions for writing bytes/halswords/words */ -HAL_StatusTypeDef FLASH_Write_Byte(uint32_t Address, uint8_t Data); -HAL_StatusTypeDef FLASH_Write_HalfWord(uint32_t Address, uint16_t Data); -HAL_StatusTypeDef FLASH_Write_Word(uint32_t Address, uint32_t Data); -///////////////////////////---FUNCTIONS---/////////////////////////// - -#endif // __FLASH_GENERAL_H_ \ No newline at end of file diff --git a/STM32_General/Inc/general_gpio.h b/STM32_General/Inc/general_gpio.h deleted file mode 100644 index 218a6bf..0000000 --- a/STM32_General/Inc/general_gpio.h +++ /dev/null @@ -1,237 +0,0 @@ -/** -************************************************************************** -* @file general_gpio.h -* @brief Заголовочный файл для модуля инициализации портов и работы с ними. -************************************************************************** -* @defgroup MY_LIBS_GPIO GPIO Tools -* @ingroup MYLIBS_PERIPHERAL -* @brief Функции и макросы для удобной работы с GPIO. -* @details -Модуль предоставляет универсальные инструменты для работы с GPIO): - - @ref MYLIBS_GPIO_GENERAL — инициализация и общие функции работы с портами. - - @ref MYLIBS_GPIO_SWITCH — работа с GPIO как с кнопкой: чтение состояния, - фильтрация дребезга, настройка активного уровня. - - @ref MYLIBS_GPIO_LEDS — работа с GPIO как со светодиодом: включение, - выключение, моргание и плавное затухание. - -*************************************************************************/ -#ifndef __GPIO_GENERAL_H_ -#define __GPIO_GENERAL_H_ - -#include "mylibs_defs.h" - -/** - * @addtogroup GPIO_INIT Init defines - * @ingroup MYLIBS_GPIO_GENERAL - * @brief Настройка состояний кнопок и количества тиков в периоде ШИМ - * @{ - */ - -#ifndef local_time -#define local_time() HAL_GetTick() ///< Локальное время -#endif - -#ifndef LED_PWM_TICKS -#define LED_PWM_TICKS 15 ///< Количество тиков в периоде ШИМ -#endif - -#ifndef LED_ON -#define LED_ON 1 ///< Состояние пина для включения светодиода -#endif -#ifndef LED_OFF -#define LED_OFF 0 ///< Состояние пина для выключения светодиода -#endif - -#ifndef SW_ON -#define SW_ON 1 ///< Состояние пина при нажатой кнопке -#endif -#ifndef SW_OFF -#define SW_OFF 0 ///< Состояние пина при отжатой кнопке -#endif - -/** GPIO_INIT - * @} - */ - - -/** - * @brief Режимы работы светодиода - * @ingroup MYLIBS_GPIO_LEDS - */ -typedef enum -{ - LED_IS_OFF = 0, ///< Светодиод выключен - LED_IS_ON = 1, ///< Светодиод включен - LED_IS_BLINKING = 2, ///< Моргание светодиодом - LED_IS_FADING = 3, ///< Плавное моргание светодиодом -}GPIO_LEDStateTypeDef; - -/** - * @brief Структура светодиода - * @ingroup MYLIBS_GPIO_LEDS - */ -typedef struct -{ - GPIO_LEDStateTypeDef state; ///< Текущий режим работы светодиода - - GPIO_TypeDef *LED_Port; ///< GPIO порт ножки светодиода - uint32_t LED_Pin; ///< GPIO пин ножки светодиода - - uint8_t LED_ActiveLvl; ///< Активный уровень ножки (при котором светодиод горит) - uint32_t LED_Period; ///< Период моргания светодиода - - uint32_t tickprev; -}GPIO_LEDTypeDef; - -/** - * @brief Структура кнопки - * @ingroup MYLIBS_GPIO_SWITCH - */ -typedef struct -{ - GPIO_TypeDef *Sw_Port; ///< GPIO порт ножки кнопки - uint32_t Sw_Pin; ///< GPIO пин ножки кнопки - - uint8_t Sw_ActiveLvl; ///< Активный уровень ножки (при котором кнопка нажата) - uint32_t Sw_PrevState; ///< Предыдущее состояние кнопки - uint32_t Sw_FilterDelay; ///< Фильтр от дребезга (в мс) - - uint32_t tickprev; -}GPIO_SwitchTypeDef; - - -///////////////////////////////////////////////////////////////////// -///////////////////////////---FUNCTIONS---/////////////////////////// -/** - * @addtogroup MYLIBS_GPIO_GENERAL General tools - * @ingroup MY_LIBS_GPIO - * @brief Общие функции/макросы для работы с GPIO - * @par Пример использования: - @code - // Включаем тактирование порта GPIOA - GPIO_Clock_Enable(GPIOA); - @endcode - * @{ - */ - -HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx); - -/** MYLIBS_GPIO_GENERAL - * @} - */ - -/** - * @addtogroup MYLIBS_GPIO_SWITCH Switch tools - * @ingroup MY_LIBS_GPIO - * @brief Функции для работы с GPIO, как с кнопкой - * @par Пример использования: - @code - MX_GPIO_Init(); // инициализация пина аппаратная - - // Инициализация кнопки на порте GPIOB, пин 0, активный уровень 1 - GPIO_SwitchTypeDef sw1; - GPIO_Switch_Init(&sw1, GPIOB, GPIO_PIN_0, 1); // или дефайн SW_ON/SW_OFF - - // Считываем состояние кнопки - if(GPIO_Read_Switch(&sw1)) - { - // Кнопка нажата - LED_ON(); - } - else - { - // Кнопка отжата - LED_OFF(); - } - @endcode - * @{ - */ - -/* Инициализировать кнопку (структуру кнопки) */ -HAL_StatusTypeDef GPIO_Switch_Init(GPIO_SwitchTypeDef *sw, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t SW_On_State); -/* Считать состоянии кнопки запуска */ -int GPIO_Read_Switch(GPIO_SwitchTypeDef *swstart); - -/** MYLIBS_GPIO_SWITCH - * @} - */ - - -/** - * @addtogroup MYLIBS_GPIO_LEDS LED tools - * @ingroup MY_LIBS_GPIO - * @brief Функции для работы с GPIO, для управления светодиодом - * @par Пример использования: - @code - MX_GPIO_Init(); // инициализация пина аппаратная - - // Инициализация светодиода на порте GPIOA, пин 5, активный уровень 0 - GPIO_LEDTypeDef led; - GPIO_LED_Init(&led, GPIOA, GPIO_PIN_5, 0); // или дефайн LED_ON/LED_OFF - - // Включение светодиода - GPIO_LED_On(&led); - - // Запуск моргания - GPIO_LED_Blink_Start(&led, 500); // Период 500 мс - - // В основном цикле - while (1) { - GPIO_LED_Dynamic_Handle(&led); - } - @endcode - * @{ - */ - -/* Инициализировать светодиод (структуру светодиода) */ -HAL_StatusTypeDef GPIO_LED_Init(GPIO_LEDTypeDef *led, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t LED_On_State); -/* Включить светодиод */ -HAL_StatusTypeDef GPIO_LED_On (GPIO_LEDTypeDef *led); -/* Выключить светодиод */ -HAL_StatusTypeDef GPIO_LED_Off (GPIO_LEDTypeDef *led); -/* Выставить светодиод по переменной */ -HAL_StatusTypeDef GPIO_LED_Set (GPIO_LEDTypeDef *led, uint8_t led_state); -/* Активировать моргание светодиодом */ -HAL_StatusTypeDef GPIO_LED_Blink_Start (GPIO_LEDTypeDef *led, uint32_t period); -/* Активировать моргание светодиодом */ -HAL_StatusTypeDef GPIO_LED_Fading_Start(GPIO_LEDTypeDef *led, uint32_t period); -/* Управление динамическими режимами свечения светодиода */ -void GPIO_LED_Dynamic_Handle(GPIO_LEDTypeDef *led); - -/** MYLIBS_GPIO_LEDS - * @} - */ -///////////////////////////---FUNCTIONS---/////////////////////////// - - -/** - * @cond GPIO_INTERNAL - */ - -// /** -// * @brief Маппинг альтернативной функции SPI между GPIO -// * @ingroup MYLIBS_GPIO_GENERAL -// */ -// #define SPI_Alternate_Mapping(INSTANCE) \ -// ((((INSTANCE) == TIM1) || ((INSTANCE) == TIM2))? GPIO_AF1_TIM1: \ -// (((INSTANCE) == TIM3) || ((INSTANCE) == TIM4) || ((INSTANCE) == TIM5))? GPIO_AF2_TIM3: \ -// (((INSTANCE) == TIM8) || ((INSTANCE) == TIM9) || ((INSTANCE) == TIM10) || ((INSTANCE) == TIM11))? GPIO_AF3_TIM8: \ -// (((INSTANCE) == TIM12) || ((INSTANCE) == TIM13) || ((INSTANCE) == TIM14))? GPIO_AF9_TIM12: \ -// (0)) - - -/** - * @brief Маппинг альтернативной функции TIM между GPIO - * @ingroup MYLIBS_GPIO_GENERAL - */ -#define GPIO_TIM_Alternate_Mapping(INSTANCE) \ -((((INSTANCE) == TIM1) || ((INSTANCE) == TIM2))? GPIO_AF1_TIM1: \ -(((INSTANCE) == TIM3) || ((INSTANCE) == TIM4) || ((INSTANCE) == TIM5))? GPIO_AF2_TIM3: \ -(((INSTANCE) == TIM8) || ((INSTANCE) == TIM9) || ((INSTANCE) == TIM10) || ((INSTANCE) == TIM11))? GPIO_AF3_TIM8: \ -(((INSTANCE) == TIM12) || ((INSTANCE) == TIM13) || ((INSTANCE) == TIM14))? GPIO_AF9_TIM12: \ -(0)) - - -/** @endcond */ - -#endif // __GPIO_GENERAL_H_ \ No newline at end of file diff --git a/STM32_General/Inc/general_spi.h b/STM32_General/Inc/general_spi.h deleted file mode 100644 index 239db9d..0000000 --- a/STM32_General/Inc/general_spi.h +++ /dev/null @@ -1,170 +0,0 @@ -/** -************************************************************************** -* @file general_spi.h -* @brief Заголовочный файл для модуля инициализации SPI. -************************************************************************** -* @defgroup MY_LIBS_SPI SPI Tools -* @ingroup MYLIBS_PERIPHERAL -* @brief Функции и макросы для удобной работы с SPI. -* @details -Модуль предоставляет функции для базовой инициализации SPI - - -@par Пример использования: -@code -// Структура настроек SPI -SPI_SettingsTypeDef spi1Settings; - -void SPI1_Init(void) -{ - // Настройка SPI1 как Master, 8 бит, полный дуплекс - spi1Settings.hspi.Instance = SPI1; - spi1Settings.hspi.Init.Mode = SPI_MODE_MASTER; - spi1Settings.hspi.Init.Direction = SPI_DIRECTION_2LINES; - spi1Settings.hspi.Init.DataSize = SPI_DATASIZE_8BIT; - spi1Settings.hspi.Init.CLKPolarity = SPI_POLARITY_LOW; - spi1Settings.hspi.Init.CLKPhase = SPI_PHASE_1EDGE; - spi1Settings.hspi.Init.NSS = SPI_NSS_SOFT; - spi1Settings.hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; - spi1Settings.hspi.Init.FirstBit = SPI_FIRSTBIT_MSB; - spi1Settings.hspi.Init.TIMode = SPI_TIMODE_DISABLE; - spi1Settings.hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - - // Настройка GPIO - spi1Settings.CLK_GPIOx = GPIOA; - spi1Settings.CLK_PIN = GPIO_PIN_5; - spi1Settings.CLK_GPIO_AlternageFunc = GPIO_AF5_SPI1; - - spi1Settings.MISO_GPIOx = GPIOA; - spi1Settings.MISO_PIN = GPIO_PIN_6; - spi1Settings.MISO_GPIO_AlternageFunc = GPIO_AF5_SPI1; - - spi1Settings.MOSI_GPIOx = GPIOA; - spi1Settings.MOSI_PIN = GPIO_PIN_7; - spi1Settings.MOSI_GPIO_AlternageFunc = GPIO_AF5_SPI1; - - // Инициализация SPI - if(SPI_Base_Init(&spi1Settings) != HAL_OK) - { - // Обработка ошибки - Error_Handler(); - } -} -@endcode - - - -* @note Требуется подключение модуля SPI в библиотеке HAL -@code -#define HAL_SPI_MODULE_ENABLED -@endcode -* @{ -*************************************************************************/ -#ifndef __SPI_GENERAL_H_ -#define __SPI_GENERAL_H_ - - -///////////////////////////////////////////////////////////////////// -/////////////////////////---USER SETTINGS---///////////////////////// -/** - * @addtogroup SPI_INIT Init defines - * @ingroup MY_LIBS_SPI - * @brief Настройка SPI - * @{ - */ -#define HAL_SPI_MODULE_ENABLED ///< Включение HAL SPI - -#define USE_SPI1 ///< Включить SPI1 в @ref SPI_MspInit -#define USE_SPI2 ///< Включить SPI2 в @ref SPI_MspInit -#define USE_SPI3 ///< Включить SPI3 в @ref SPI_MspInit -/** SPI_INIT - * @} - */ -/////////////////////////---USER SETTINGS---///////////////////////// -#include "mylibs_defs.h" - - - -///////////////////////////////////////////////////////////////////// -////////////////////////////---DEFINES---//////////////////////////// - - - -////////////////////////////---DEFINES---//////////////////////////// - - -///////////////////////////////////////////////////////////////////// -///////////////////////---STRUCTURES & ENUMS---////////////////////// -/** - * @brief Структура настроек SPI - * @details Содержит все необходимые параметры для инициализации SPI, - * включая GPIO и DMA. - */ -typedef struct -{ - SPI_HandleTypeDef hspi; ///< HAL handle SPI - - GPIO_TypeDef *CLK_GPIOx; ///< Порт CLK - uint32_t CLK_PIN; ///< Пин CLK - uint32_t CLK_GPIO_AlternageFunc; ///< Альтернативная функция для CLK - - GPIO_TypeDef *MISO_GPIOx; ///< Порт MISO - uint32_t MISO_PIN; ///< Пин MISO - uint32_t MISO_GPIO_AlternageFunc; ///< Альтернативная функция для MISO - - GPIO_TypeDef *MOSI_GPIOx; ///< Порт MOSI - uint32_t MOSI_PIN; ///< Пин MOSI - uint32_t MOSI_GPIO_AlternageFunc; ///< Альтернативная функция для MOSI - - DMA_Stream_TypeDef *DMAChannel; ///< Канал DMA (NULL если не нужен) - uint32_t DMA_CHANNEL_X; ///< Номер канала DMA (0 если не нужен) - -} SPI_SettingsTypeDef; -///////////////////////---STRUCTURES & ENUMS---////////////////////// - - -///////////////////////////////////////////////////////////////////// -///////////////////////////---FUNCTIONS---/////////////////////////// - -/* Инициализация SPI с использованием структуры настроек */ -HAL_StatusTypeDef SPI_Base_Init(SPI_SettingsTypeDef *sspi); - -/* Проверка корректности структуры настроек SPI */ -HAL_StatusTypeDef SPI_Check_Init_Struct(SPI_SettingsTypeDef *sspi); - -/* Инициализация тактирования и прерываний для выбранного SPI */ -void SPI_MspInit(SPI_HandleTypeDef *hspi); - -/* Деинициализация тактирования и прерываний для выбранного SPI */ -void SPI_MspDeInit(SPI_HandleTypeDef *hspi); - - -/** - * @cond SPI_INTERNAL - */ - -/* Настройка GPIO для SPI */ -void SPI_GPIO_Init(SPI_SettingsTypeDef *sspi); - -/* Настройка DMA для SPI */ -void SPI_DMA_Init(SPI_HandleTypeDef *hspi, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X); - -#ifndef __USER_LINKDMA -/** - * @brief Аналог HAL макроса для привязки DMA к UART. - * @note @ref __HAL_LINKDMA. - */ -#define __USER_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \ -do{ \ -(__HANDLE__)->__PPP_DMA_FIELD__ = (__DMA_HANDLE__); \ -(__DMA_HANDLE__)->Parent = (__HANDLE__);} while(0U) -#endif - -/** @endcond */ -///////////////////////////---FUNCTIONS---/////////////////////////// - -#endif // __SPI_GENERAL_H_ - -/** MY_LIBS_SPI - * @} - */ \ No newline at end of file diff --git a/STM32_General/Inc/general_tim.h b/STM32_General/Inc/general_tim.h deleted file mode 100644 index a45493c..0000000 --- a/STM32_General/Inc/general_tim.h +++ /dev/null @@ -1,301 +0,0 @@ -/** -************************************************************************** -* @file general_tim.h -* @brief Заголовочный файл для модуля инициализации таймеров и работы с ними. -************************************************************************** -* @defgroup MY_LIBS_TIM TIM Tools -* @ingroup MYLIBS_PERIPHERAL -* @brief Функции и макросы для удобной работы с TIM. -* @details -Модуль предоставляет универсальные инструменты для работы с TIM: - - @ref MYLIBS_TIM_GENERAL — базовая инициализация таймеров и прерываний. - - @ref MYLIBS_TIM_DELAY — функции задержки через таймеры (blocking и non-blocking). - - @ref MYLIBS_TIM_OC — настройка каналов Output Compare и PWM. - - @ref MYLIBS_TIM_ENCODER — работа с энкодерами, чтение положения и кнопки. - -* @note Требуется подключение модуля TIM в библиотеке HAL и GPIO (@ref MY_LIBS_GPIO) из MyLibs -@code -#define HAL_TIM_MODULE_ENABLED -@endcode -*************************************************************************/ -#ifndef __TIM_GENERAL_H_ -#define __TIM_GENERAL_H_ - -///////////////////////////////////////////////////////////////////// -/////////////////////////---USER SETTINGS---///////////////////////// -/** - * @addtogroup TIM_INIT Init defines - * @ingroup MYLIBS_TIM_GENERAL - * @brief Настройка таймеров - * @{ - */ -#define HAL_TIM_MODULE_ENABLED - -#define USE_TIM1 ///< Включить TIM1 в @ref TIM_Base_MspInit -#define USE_TIM2 ///< Включить TIM2 в @ref TIM_Base_MspInit -#define USE_TIM3 ///< Включить TIM3 в @ref TIM_Base_MspInit -#define USE_TIM4 ///< Включить TIM4 в @ref TIM_Base_MspInit -#define USE_TIM5 ///< Включить TIM5 в @ref TIM_Base_MspInit -#define USE_TIM6 ///< Включить TIM6 в @ref TIM_Base_MspInit -#define USE_TIM7 ///< Включить TIM7 в @ref TIM_Base_MspInit -#define USE_TIM8 ///< Включить TIM8 в @ref TIM_Base_MspInit -#define USE_TIM9 ///< Включить TIM9 в @ref TIM_Base_MspInit -#define USE_TIM10 ///< Включить TIM10 в @ref TIM_Base_MspInit -#define USE_TIM11 ///< Включить TIM11 в @ref TIM_Base_MspInit -#define USE_TIM12 ///< Включить TIM12 в @ref TIM_Base_MspInit -#define USE_TIM13 ///< Включить TIM13 в @ref TIM_Base_MspInit -#define USE_TIM14 ///< Включить TIM14 в @ref TIM_Base_MspInit -/** TIM_INIT - * @} - */ -/////////////////////////---USER SETTINGS---///////////////////////// -#include "mylibs_defs.h" -#include "general_gpio.h" - -///////////////////////////////////////////////////////////////////// -////////////////////////////---DEFINES---//////////////////////////// -#define TIM_IT_CONF_Pos 0 -//#define TIM_PWM_CONF_Pos 1 -//#define TIM_CLCK_SRC_CONF_Pos 2 -//#define TIM_SLAVE_CONF_Pos 3 -//#define TIM_MASTER_CONF_Pos 4 -//#define TIM_BDTR_CONF_Pos 5 - -#define TIM_IT_CONF (1<<(TIM_IT_CONF_Pos)) -//#define TIM_PWM_CONF (1<<(TIM_PWM_Pos)) - -////////////////////////////---DEFINES---////////////////////////////] - - - -///////////////////////////////////////////////////////////////////// -///////////////////////---STRUCTURES & ENUMS---////////////////////// -/** - * @brief Режим прерываний таймера - * @ingroup MYLIBS_TIM_GENERAL - */ -typedef enum -{ - TIM_DEFAULT = 0, ///< Прерываний отключены - TIM_IT_MODE = TIM_IT_CONF, ///< Прерываний включены -// TIM_PWM_MODE = TIM_PWM_ENABLE, -// TIM_PWM_IT_MODE = TIM_PWM_ENABLE | TIM_IT_CONF, -}TIM_ITModeTypeDef; - -/** - * @brief Длительность тика таймера (частота тактирования таймера) - * @ingroup MYLIBS_TIM_GENERAL - * @details enum дает базовые длительности, но можно выставить другие - * (напр 500 - 0.5 мс) - */ -typedef enum -{ - TIM_Base_Disable = 0, ///< Таймер отключен - TIM_TickBase_1US = 1, ///< Таймер тактируется с частотой 1 МГц - TIM_TickBase_10US = 10, ///< Таймер тактируется с частотой 100 кГц - TIM_TickBase_100US = 100, ///< Таймер тактируется с частотой 10 кГц - TIM_TickBase_1MS = 1000, ///< Таймер тактируется с частотой 1 кГц - TIM_TickBase_10MS = 10000, ///< Таймер тактируется с частотой 100 Гц - TIM_TickBase_100MS = 100000, ///< Таймер тактируется с частотой 10 Гц -}TIM_MHzTickBaseTypeDef; - -/** - * @brief Структура инициализации таймера - * @ingroup MYLIBS_TIM_GENERAL - * @details - * Содержит все базовые структуры, которые нужны для инициализации таймера. - * Если структуры настроек не заданы, то они заполнятся сами дефолтными параметрами - * - * Также высокоуровневые настройки частоты работы таймера. - * Если какая-либо высокоуровневая настройка не задана, то - * по возможности берется низкоуровневая настройка из структур - */ -typedef struct // struct with settings for custom function -{ - TIM_HandleTypeDef htim; ///< HAL handle таймера - TIM_ClockConfigTypeDef sClockSourceConfig; ///< Настройки тактирования таймера - TIM_SlaveConfigTypeDef sSlaveConfig; ///< Настройки слейв режима таймера - TIM_MasterConfigTypeDef sMasterConfig; ///< Настройки мастер режима таймера - TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig; ///< Настройки дедтаймов таймера - - TIM_ITModeTypeDef sTimMode; ///< Настройки прерывания таймера - TIM_MHzTickBaseTypeDef sTickBaseUS; ///< Длительность одного тика - uint8_t sTickBasePrescaler; ///< Дополнительный делитель, для удобного деления @ref sTickBaseUS - float sTimAHBFreqMHz; ///< Частота шины тактирования таймера - float sTimFreqHz; ///< Желаемая частота таймера - -}TIM_SettingsTypeDef; - - -/** - * @brief Структура инициализации енкодера - * @ingroup MYLIBS_TIM_ENCODER - * @details - * Содержит все базовые структуры, которые нужны для инициализации таймера. - * Если структуры настроек не заданы, то они заполнятся сами дефолтными параметрами - * - * Также высокоуровневые настройки частоты работы таймера. - * Если какая-либо высокоуровневая настройка не задана, то - * по возможности берется низкоуровневая настройка из структур - */ -typedef struct // struct with variables for encoder -{ - int16_t Encoder_Diff; ///< Считанная разница - uint16_t Encoder_Shdw; ///< Последние считанные тики - - TIM_HandleTypeDef *htim; ///< Указатель на HAL handle таймера - TIM_Encoder_InitTypeDef sConfig; ///< Указатель на структуру настройки энкодера - - GPIO_TypeDef *GPIOx; ///< Порт, куда подключается энкодер - uint32_t GPIO_PIN_TI1; ///< Пин, куда подключается канал TI1 - uint32_t GPIO_PIN_TI2; ///< Пин, куда подключается канал TI2 - uint32_t GPIO_PIN_SW; ///< Пин, куда кнопка энкодера (если есть) - - GPIO_SwitchTypeDef Sw; ///< Структура кнопки - -}TIM_EncoderTypeDef; -///////////////////////---STRUCTURES & ENUMS---////////////////////// - -///////////////////////////////////////////////////////////////////// -///////////////////////////---FUNCTIONS---/////////////////////////// -/** - * @addtogroup MYLIBS_TIM_GENERAL General tools - * @ingroup MY_LIBS_TIM - * @brief Функции для базовой инициализации таймеров - * @par Пример использования: - @code - TIM_SettingsTypeDef tim2Settings; - - void TIM2_Init(void) - { - // Настройка таймера TIM2 на 1 кГц с прерываниями с шагом таймера 10 мкс - tim2Settings.htim.Instance = TIM2; - tim2Settings.sTimMode = TIM_IT_MODE; - tim2Settings.sTickBaseUS = TIM_TickBase_10US; - tim2Settings.sTickBasePrescaler = 1; - tim2Settings.sTimFreqHz = 1000; // 1 кГц - tim2Settings.sTimAHBFreqMHz = 72000000; // Hz - - if(TIM_Base_Init(&tim2Settings) != HAL_OK) - { - Error_Handler(); - } - } - @endcode - * @{ - */ -/* Initialize TIM with TIM_SettingsTypeDef structure */ -HAL_StatusTypeDef TIM_Base_Init(TIM_SettingsTypeDef* stim); -/* Initialize TIMs clock and interrupt */ -void TIM_Base_MspInit(TIM_HandleTypeDef* htim, TIM_ITModeTypeDef it_mode); -/* DeInitialize TIMs clock and interrupt */ -void TIM_Base_MspDeInit(TIM_HandleTypeDef* htim); -/** MYLIBS_TIM_GENERAL - * @} - */ - -/** - * @addtogroup MYLIBS_TIM_DELAY Delay tools - * @ingroup MY_LIBS_TIM - * @brief Функции для формирования задержек с помощью таймеров - * @par Пример использования: - @code - TIM_HandleTypeDef htim2; - - // блокирующая задержка 500 тиков таймера - LED_ON(); - TIM_Delay(&htim2, 500); - LED_OFF(); - - - while(1) - { - // не блокирующая задержка 200 тиков таймера - if(TIM_Delay_NonBlocking(&htim2, 200) == HAL_OK) - { - TIM_Delay_Start(&htim2); - LED_TOOGLE(); - } - } - @endcode - * @{ - */ -/* Start delay via TIM */ -HAL_StatusTypeDef TIM_Delay_Start(TIM_HandleTypeDef *htim); -/* Delay via TIM */ -HAL_StatusTypeDef TIM_Delay(TIM_HandleTypeDef *htim, uint16_t delay); -/* Wait Delay via TIM without blocking app */ -HAL_StatusTypeDef TIM_Delay_NonBlocking(TIM_HandleTypeDef *htim, uint16_t delay); -/** MYLIBS_TIM_DELAY - * @} - */ - -/** - * @addtogroup MYLIBS_TIM_OC PWM/OC Channels tools - * @ingroup MY_LIBS_TIM - * @brief Функции для инициализации базовых функций каналов таймера - * @par Пример использования: - @code - void PWM_Channel_Init_Example(void) - { - TIM_HandleTypeDef htim3; - TIM_OC_InitTypeDef sConfigOC; - GPIO_TypeDef *GPIOx = GPIOB; - uint32_t PWM_PIN = GPIO_PIN_0; - - // Настройка таймера и канала PWM - TIM_Output_PWM_Init(&htim3, &sConfigOC, TIM_CHANNEL_1, GPIOx, PWM_PIN); - - // Настройка компаратора OC - TIM_OC_Comparator_Init(&htim3, TIM_CHANNEL_1); - } - @endcode - * @{ - */ -/* Initialize PWM Channel and GPIO for output */ -HAL_StatusTypeDef TIM_Output_PWM_Init(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfigOC, uint32_t TIM_CHANNEL, GPIO_TypeDef *GPIOx, uint32_t PWM_PIN); -/* Initialize OC Comparator */ -HAL_StatusTypeDef TIM_OC_Comparator_Init(TIM_HandleTypeDef *htim, uint32_t TIM_CHANNEL); -/** MYLIBS_TIM_ENCODER - * @} - */ - -/** - * @addtogroup MYLIBS_TIM_ENCODER Encoder tools - * @ingroup MY_LIBS_TIM - * @brief Функции для считывания энкодера - * @par Пример использования: - @code - TIM_EncoderTypeDef henc1; - TIM_HandleTypeDef htim4; - - // инициализация - henc1.htim = &htim4; - henc1.GPIOx = GPIOA; - henc1.GPIO_PIN_TI1 = GPIO_PIN_0; - henc1.GPIO_PIN_TI2 = GPIO_PIN_1; - TIM_Encoder_Init(&henc1, &htim4); - - // считывание энкодера и кнопки - int16_t delta = TIM_Encoder_Read(&henc1); - setpoint_tmp += delta; - if(TIM_Encoder_ReadSwitch(&henc1)) - { - setpoint = setpoint_tmp; // подтвердить новое значение - } - @endcode - * @{ - */ -/* Initialize TIM Encoder functional */ -HAL_StatusTypeDef TIM_Encoder_Init(TIM_EncoderTypeDef *henc1, TIM_HandleTypeDef *htim); -/* Считать энкодер */ -HAL_StatusTypeDef TIM_Encoder_Read(TIM_EncoderTypeDef *henc); -/* Считать кнопку энкодера */ -int TIM_Encoder_ReadSwitch(TIM_EncoderTypeDef *henc); -/** MYLIBS_TIM_ENCODER - * @} - */ -///////////////////////////---FUNCTIONS---/////////////////////////// - - -#endif // __TIM_GENERAL_H_ diff --git a/STM32_General/Inc/general_uart.h b/STM32_General/Inc/general_uart.h deleted file mode 100644 index cf0660a..0000000 --- a/STM32_General/Inc/general_uart.h +++ /dev/null @@ -1,156 +0,0 @@ -/** -************************************************************************** -* @file general_uart.h -* @brief Заголовочный файл для модуля инициализации UART. -************************************************************************** -* @defgroup MY_LIBS_UART UART Tools -* @ingroup MYLIBS_PERIPHERAL -* @brief Функции и макросы для удобной работы с UART. -* @details -Модуль предоставляет функции для базовой инициализации UART - - -@par Пример использования: -@code -// Структура настроек UART -UART_SettingsTypeDef uart2Settings; - -void UART2_Init(void) -{ - // Настройка UART2 с 115200 бод, 8 бит, 1 стоп-бит, без паритета - uart2Settings.huart.Instance = USART2; - uart2Settings.huart.Init.BaudRate = 115200; - uart2Settings.huart.Init.WordLength = UART_WORDLENGTH_8B; - uart2Settings.huart.Init.StopBits = UART_STOPBITS_1; - uart2Settings.huart.Init.Parity = UART_PARITY_NONE; - uart2Settings.huart.Init.Mode = UART_MODE_TX_RX; - uart2Settings.huart.Init.HwFlowCtl = UART_HWCONTROL_NONE; - uart2Settings.huart.Init.OverSampling = UART_OVERSAMPLING_16; - - // Настройка GPIO - uart2Settings.GPIOx = GPIOA; - uart2Settings.GPIO_PIN_TX = GPIO_PIN_2; - uart2Settings.GPIO_PIN_RX = GPIO_PIN_3; - - // DMA не используется в этом примере - uart2Settings.DMAChannel = NULL; - uart2Settings.DMA_CHANNEL_X = 0; - - // Инициализация UART - if(UART_Base_Init(&uart2Settings) != HAL_OK) - { - // Обработка ошибки - Error_Handler(); - } -} -@endcode - -* @note Требуется подключение модуля UART в библиотеке HAL -@code -#define HAL_UART_MODULE_ENABLED -@endcode -* @{ -*************************************************************************/ -#ifndef __UART_GENERAL_H_ -#define __UART_GENERAL_H_ - -///////////////////////////////////////////////////////////////////// -/////////////////////////---USER SETTINGS---///////////////////////// -/** - * @addtogroup UART_INIT Init defines - * @ingroup MY_LIBS_UART - * @brief Настройка UART - * @{ - */ -#define HAL_UART_MODULE_ENABLED ///< Включение HAL UART - -#define USE_USART1 ///< Включить USART1 в @ref UART_MspInit -#define USE_USART2 ///< Включить USART2 в @ref UART_MspInit -#define USE_USART3 ///< Включить USART3 в @ref UART_MspInit -#define USE_UART4 ///< Включить UART4 в @ref UART_MspInit -#define USE_UART5 ///< Включить UART5 в @ref UART_MspInit -#define USE_USART6 ///< Включить USART6 в @ref UART_MspInit -/** UART_INIT - * @} - */ -/////////////////////////---USER SETTINGS---///////////////////////// -#include "mylibs_defs.h" - - - -///////////////////////////////////////////////////////////////////// -////////////////////////////---DEFINES---//////////////////////////// - - - -////////////////////////////---DEFINES---//////////////////////////// - - -///////////////////////////////////////////////////////////////////// -///////////////////////---STRUCTURES & ENUMS---////////////////////// -/** - * @brief Структура настроек UART - * @details Содержит все необходимые параметры для инициализации UART, - * включая GPIO и DMA. - */ -typedef struct -{ - UART_HandleTypeDef huart; ///< HAL handle UART - - GPIO_TypeDef *GPIOx; ///< Порт для UART - uint16_t GPIO_PIN_RX; ///< Пин приема - uint16_t GPIO_PIN_TX; ///< Пин передачи - - DMA_Stream_TypeDef *DMAChannel; ///< Канал DMA (NULL если не нужен) - uint32_t DMA_CHANNEL_X; ///< Номер канала DMA (0 если не нужен) - -} UART_SettingsTypeDef; - -///////////////////////---STRUCTURES & ENUMS---////////////////////// - - -///////////////////////////////////////////////////////////////////// -///////////////////////////---FUNCTIONS---/////////////////////////// - -/* Инициализация UART с использованием структуры настроек */ -HAL_StatusTypeDef UART_Base_Init(UART_SettingsTypeDef *suart); - -/* Проверка корректности структуры настроек UART */ -HAL_StatusTypeDef UART_Check_Init_Struct(UART_SettingsTypeDef *suart); - -/* Инициализация тактирования и прерываний для выбранного UART */ -void UART_MspInit(UART_HandleTypeDef *huart); - -/* Деинициализация тактирования и прерываний для выбранного UART */ -void UART_MspDeInit(UART_HandleTypeDef *huart); - - -/** - * @cond UART_INTERNAL - */ - -/* Настройка GPIO для UART */ -void UART_GPIO_Init(GPIO_TypeDef *GPIOx, uint16_t GPIO_PIN_RX, uint16_t GPIO_PIN_TX); - -/* Настройка DMA для UART */ -void UART_DMA_Init(UART_HandleTypeDef *huart, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X); - -#ifndef __USER_LINKDMA -/** - * @brief Аналог HAL макроса для привязки DMA к UART. - * @note @ref __HAL_LINKDMA. - */ -#define __USER_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \ -do{ \ -(__HANDLE__)->__PPP_DMA_FIELD__ = (__DMA_HANDLE__); \ -(__DMA_HANDLE__)->Parent = (__HANDLE__);} while(0U) -#endif - -/** @endcond */ -///////////////////////////---FUNCTIONS---/////////////////////////// - -#endif // __UART_GENERAL_H_ - -/** MY_LIBS_UART - * @} - */ \ No newline at end of file diff --git a/STM32_General/Src/__general_flash.c b/STM32_General/Src/__general_flash.c deleted file mode 100644 index f7c5e7c..0000000 --- a/STM32_General/Src/__general_flash.c +++ /dev/null @@ -1,192 +0,0 @@ -#include "__general_flash.h" -FLASH_EraseInitTypeDef EraseInitStruct; -extern HAL_StatusTypeDef res_hal; -unsigned CRC_Update; -//uint32_t PAGE_OFFSET = ((uint32_t)((4-1) * 0x0400)); -uint32_t PAGE_NUMB = 127; - - -/* Записать в память данные, произвольного размера */ -HAL_StatusTypeDef FLASH_Write_Data(uint32_t* Address, uint8_t* Data, int Data_size) -{ - HAL_StatusTypeDef res_hal; - - int data_cnt = 0; - uint32_t adr; - uint32_t word_data; - - - res_hal = HAL_FLASH_Unlock(); - if (res_hal != HAL_OK) return res_hal; - - for (adr = *Address; adr < *Address + Data_size; adr = adr + 4) - { - - - word_data = ( - Data[data_cnt] | - Data[data_cnt + 1] << 8 | - Data[data_cnt + 2] << 16 | - Data[data_cnt + 3] << 24); - - res_hal = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, adr, word_data); - - if (res_hal != HAL_OK) return res_hal; - - data_cnt += 4; - } - - *Address += Data_size; - res_hal = HAL_FLASH_Lock(); - - return res_hal; -} - - - -HAL_StatusTypeDef FLASH_Enable_DualBankMode(void) -{ - HAL_StatusTypeDef res_hal; - FLASH_AdvOBProgramInitTypeDef OB_DualBank; - - - res_hal = HAL_FLASH_Unlock(); - if (res_hal != HAL_OK) - return res_hal; - - res_hal = HAL_FLASH_OB_Unlock(); - if (res_hal != HAL_OK) - return res_hal; - - - FLASH->OPTCR |= FLASH_OPTCR_DB1M; - - res_hal = HAL_FLASH_OB_Launch(); - if (res_hal != HAL_OK) - return res_hal; - - res_hal = HAL_FLASH_OB_Lock(); - if (res_hal != HAL_OK) - return res_hal; - - res_hal = HAL_FLASH_Lock(); - if (res_hal != HAL_OK) - return res_hal; - - - return res_hal; -} - - - -/* Убрать защиту */ -HAL_StatusTypeDef FLASH_WriteProtection(uint32_t BankN, uint32_t WriteProtection) -{ - HAL_StatusTypeDef res_hal; - FLASH_OBProgramInitTypeDef OBInit; - - // Очистка всех возможных ошибок - FLASH->SR |= FLASH_FLAG_WRPERR // Write Protection Error - | FLASH_FLAG_PGSERR // Programming Sequence Error - | FLASH_FLAG_PGAERR // Programming Alignment Error - | FLASH_FLAG_OPERR; // Operation Error - - res_hal = HAL_FLASH_Unlock(); - if (res_hal != HAL_OK) - return res_hal; - - res_hal = HAL_FLASH_OB_Unlock(); // Разблокировка Option Bytes - if (res_hal != HAL_OK) - return res_hal; - - // Считываем текущую конфигурацию Option Bytes - HAL_FLASHEx_OBGetConfig(&OBInit); - - // Отключаем защиту на всех секторах второго банка - OBInit.OptionType = OPTIONBYTE_WRP; - OBInit.WRPState = WriteProtection; // Снять защиту - OBInit.WRPSector = OB_WRP_SECTOR_12; // Снять защиту - OBInit.Banks = BankN; // Указываем второй банк - res_hal = HAL_FLASHEx_OBProgram(&OBInit); - if (res_hal != HAL_OK) - return res_hal; - - // Записываем изменения и перезагружаем чип - res_hal = HAL_FLASH_OB_Launch(); - if (res_hal != HAL_OK) - return res_hal; - - // Считываем текущую конфигурацию Option Bytes - HAL_FLASHEx_OBGetConfig(&OBInit); - -// Блокировка Option Bytes - res_hal = HAL_FLASH_OB_Lock(); - if (res_hal != HAL_OK) - return res_hal; - - res_hal = HAL_FLASH_Lock(); - if (res_hal != HAL_OK) - return res_hal; - - return res_hal; -} -//-----------------ELEMENTARY FUNCTIONS--------------------- -/* functions for reading bytes/halswords/words */ -uint8_t FLASH_Read_Byte(uint32_t add) -{ - return (*(__IO uint8_t*)(add)); -} -uint16_t FLASH_Read_HalfWord(uint32_t add) -{ - return (*(__IO uint16_t*)(add)); -} -uint32_t FLASH_Read_Word(uint32_t add) -{ - return (*(__IO uint32_t*)(add)); -} -/* functions for writing bytes/halswords/words */ -HAL_StatusTypeDef FLASH_Write_Byte(uint32_t Address, uint8_t Data) -{ - HAL_StatusTypeDef res_hal; - - res_hal = HAL_FLASH_Unlock(); - - if (res_hal != HAL_OK) return res_hal; - - res_hal = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, (uint8_t)(Data)); - - if (res_hal != HAL_OK) return res_hal; - - res_hal = HAL_FLASH_Lock(); - return res_hal; -} -HAL_StatusTypeDef FLASH_Write_HalfWord(uint32_t Address, uint16_t Data) -{ - HAL_StatusTypeDef res_hal; - - res_hal = HAL_FLASH_Unlock(); - - if (res_hal != HAL_OK) return res_hal; - - res_hal = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, (uint16_t)(Data)); - - if (res_hal != HAL_OK) return res_hal; - - res_hal = HAL_FLASH_Lock(); - return res_hal; -} -HAL_StatusTypeDef FLASH_Write_Word(uint32_t Address, uint32_t Data) -{ - HAL_StatusTypeDef res_hal; - - res_hal = HAL_FLASH_Unlock(); - if (res_hal != HAL_OK) return res_hal; - - res_hal = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, (uint32_t)(Data)); - if (res_hal != HAL_OK) return res_hal; - - res_hal = HAL_FLASH_Lock(); - return res_hal; -} -//---------------------------------------------------------- - diff --git a/STM32_General/Src/general_gpio.c b/STM32_General/Src/general_gpio.c deleted file mode 100644 index 6839d51..0000000 --- a/STM32_General/Src/general_gpio.c +++ /dev/null @@ -1,326 +0,0 @@ -/** -************************************************************************** -* @file general_gpio.c -* @brief Модуль для инициализации портов и работы с ними. -************************************************************************** -* @details -Реализация функций для работы с GPIO: - - Включение тактирования портов - - Инициализация светодиодов и кнопок - - Управление светодиодами: включение, выключение, моргание, плавное затухание - - Чтение состояния кнопок с фильтром от дребезга -***************************************************************************/ -#include "general_gpio.h" - -//------------------------------------------------------------------- -//------------------------GPIO INIT FUNCTIONS------------------------ - - -/** - * @brief Включить тактирование порта GPIO - */ -HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx) -{ - if(check_null_ptr_1(GPIOx)) - return HAL_ERROR; - - HAL_StatusTypeDef status = HAL_OK; - // choose port for enable clock - if (GPIOx==GPIOA) - __HAL_RCC_GPIOA_CLK_ENABLE(); - else if (GPIOx==GPIOB) - __HAL_RCC_GPIOB_CLK_ENABLE(); -#ifdef GPIOC - else if (GPIOx==GPIOC) - __HAL_RCC_GPIOC_CLK_ENABLE(); -#endif -#ifdef GPIOD - else if (GPIOx==GPIOD) - __HAL_RCC_GPIOD_CLK_ENABLE(); -#endif -#ifdef GPIOE - else if (GPIOx==GPIOE) - __HAL_RCC_GPIOE_CLK_ENABLE(); -#endif -#ifdef GPIOF - else if (GPIOx==GPIOF) - __HAL_RCC_GPIOF_CLK_ENABLE(); -#endif -#ifdef GPIOH - else if (GPIOx==GPIOF) - __HAL_RCC_GPIOH_CLK_ENABLE(); -#endif - else - status = HAL_ERROR; - - return status; -} - -//------------------------GPIO INIT FUNCTIONS------------------------ -//------------------------------------------------------------------- - - -//------------------------------------------------------------------- -//------------------------GPIO LED FUNCTIONS------------------------- - -/** - * @brief Инициализировать светодиод (структуру светодиода) - * @param led Указатель на структуру светодиода - * @param GPIOx Указатель на структуру порта для светодиода - * @param GPIO_PIN_X Пин для светодиода - * @param LED_ActiveLevel Состояния пина, при котором светодиод будет включен - */ -HAL_StatusTypeDef GPIO_LED_Init(GPIO_LEDTypeDef *led, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t LED_ActiveLevel) -{ - if(check_null_ptr_3(led, GPIOx, GPIO_PIN_X)) - return HAL_ERROR; - - led->LED_Port = GPIOx; - led->LED_Pin = GPIO_PIN_X; - led->LED_ActiveLvl = LED_ActiveLevel; - - GPIO_LED_Off(led); - return HAL_OK; -} - -/** - * @brief Включить светодиод - * @param led Указатель на структуру светодиода - * @return HAL Status - */ -HAL_StatusTypeDef GPIO_LED_On(GPIO_LEDTypeDef *led) -{ - if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin)) - return HAL_ERROR; - - led->state = LED_IS_ON; - HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, led->LED_ActiveLvl); - - - return HAL_OK; -} -/** - * @brief Выключить светодиод - * @param led Указатель на структуру светодиода - * @return HAL Status - */ -HAL_StatusTypeDef GPIO_LED_Off(GPIO_LEDTypeDef *led) -{ - if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin)) - return HAL_ERROR; - - led->state = LED_IS_OFF; - HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, !led->LED_ActiveLvl); - - - - return HAL_OK; -} -/** - * @brief Выставить светодиод по переменной - * @param led Указатель на структуру светодиода - * @param led_state Состояние светодиода - * @return HAL Status - */ -HAL_StatusTypeDef GPIO_LED_Set(GPIO_LEDTypeDef *led, uint8_t led_state) -{ - if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin)) - return HAL_ERROR; - - if(led_state) - { - return GPIO_LED_On(led); - } - else - { - return GPIO_LED_Off(led); - } -} -/** - * @brief Активировать моргание светодиодом - * @param led Указатель на структуру светодиода - * @param period Период плавного моргания светодиода - * @return HAL Status - * @details Функция ставит режим моргания, который после управляется в @ref GPIO_LED_Dynamic_Handle - */ -HAL_StatusTypeDef GPIO_LED_Blink_Start(GPIO_LEDTypeDef *led, uint32_t period) -{ - if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin)) - return HAL_ERROR; - - led->state = LED_IS_BLINKING; - led->LED_Period = period; - - return HAL_OK; -} - -/** - * @brief Активировать моргание светодиодом - * @param led Указатель на структуру светодиода - * @param period Период плавного моргания светодиода - * @return HAL Status - * @details Функция ставит режим моргания, который после управляется в @ref GPIO_LED_Dynamic_Handle - */ -HAL_StatusTypeDef GPIO_LED_Fading_Start(GPIO_LEDTypeDef *led, uint32_t period) -{ - if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin)) - return HAL_ERROR; - - led->state = LED_IS_FADING; - led->LED_Period = period; - - - return HAL_OK; -} - -//uint8_t LED_PWM_FADING_DUTYS[LED_PWM_TICKS] = {0 1 2 3 4 5 6 7 8 9 10 11 12 } -/** - * @brief Управление динамическими режимами свечения светодиода - * @param Указатель на структуру светодиода - * @details Функция моргает/плавно моргает светодиодом в неблокирующем режиме - * Т.е. функцию надо вызывать постоянно, чтобы она мониторила тики - * и в нужный момент переключала светодиод - */ -void GPIO_LED_Dynamic_Handle(GPIO_LEDTypeDef *led) -{ - if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin)) - return; - - /* Режим моргания светодиода */ - if(led->state == LED_IS_BLINKING) - { - uint32_t tickcurrent = local_time(); - /* Ожидание истечения периода моргания */ - if((tickcurrent - led->tickprev) > led->LED_Period) - { - /* Моргание */ - HAL_GPIO_TogglePin(led->LED_Port, led->LED_Pin); - - led->tickprev = tickcurrent; - } - } - /* Режим плавного моргания светодиода */ - else if(led->state == LED_IS_FADING) - { - static unsigned direction = 0; - static int duty = 0; - uint32_t tickcurrent = local_time(); - /* Ожидание момента изменения яркости */ - /* Период ШИМ 20 мс, поэтому менять яроксть надо 40 раз за период (туда обратно) */ - if((tickcurrent - led->tickprev) > led->LED_Period/(LED_PWM_TICKS*2)) - { - /* Формирование разтухания */ - if(direction == 0) - { - if(++duty >= LED_PWM_TICKS) - { - direction = 1; - duty = LED_PWM_TICKS; - } - } - /* Формирование затухания */ - else - { - if(--duty <= 0) - { - direction = 0; - duty = 0; - } - } - led->tickprev = tickcurrent; - } - /* Формирование ШИМ для изменения яркости */ - int duty_crt = (duty*duty/LED_PWM_TICKS); - if(tickcurrent%LED_PWM_TICKS < duty_crt) - { - HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, led->LED_ActiveLvl); - } - else - { - HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, !led->LED_ActiveLvl); - } - } -} -//------------------------GPIO LED FUNCTIONS------------------------- -//------------------------------------------------------------------- - -//------------------------------------------------------------------- -//------------------------GPIO SW FUNCTIONS------------------------- - -/** -* @brief Инициализировать кнопку (структуру кнопки) - * @param sw Указатель на структуру кнопки - * @param GPIOx Указатель на структуру порта для кнопки - * @param GPIO_PIN_X Пин для кнопки - * @param SW_ActiveLevel Состояния пина, когда кнопка нажата - * @return HAL Status - */ -HAL_StatusTypeDef GPIO_Switch_Init(GPIO_SwitchTypeDef *sw, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t SW_ActiveLevel) -{ - if(check_null_ptr_3(sw, GPIOx, GPIO_PIN_X)) - return HAL_ERROR; - - sw->Sw_Port = GPIOx; - sw->Sw_Pin = GPIO_PIN_X; - sw->Sw_ActiveLvl = SW_ActiveLevel; - return HAL_OK; -} - -/** - * @brief Считать состоянии кнопки - * @param sw Указатель на структуру кнопки - * @return 1 - если кнопка нажата, - * 0 - если отжата, - * -1 - если ошибка - * @details Функция включает в себя неблокирующую проверку на дребезг - * Т.е. функцию надо вызывать постоянно, чтобы она мониторила состояние кнопки - */ -int GPIO_Read_Switch(GPIO_SwitchTypeDef *sw) -{ - if(check_null_ptr_3(sw, sw->Sw_Port, sw->Sw_Pin)) - return -1; - - if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl) - { - sw->Sw_PrevState = 1; - - - if(sw->Sw_FilterDelay) // если включена защита от дребезга - { - if(sw->tickprev == 0) - sw->tickprev = local_time(); - - if((local_time() - sw->tickprev) >= sw->Sw_FilterDelay) - { - if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl) - { - return 1; - } - else - { - sw->tickprev = 0; - return 0; - } - } - } - else // если нет защиты от дребезга - { - if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl) - { - return 1; - } - else - { - sw->tickprev = 0; - return 0; - } - } - } - else - { - sw->Sw_PrevState = 0; - } - return 0; -} -//------------------------GPIO SW FUNCTIONS------------------------- -//------------------------------------------------------------------- \ No newline at end of file diff --git a/STM32_General/Src/general_spi.c b/STM32_General/Src/general_spi.c deleted file mode 100644 index d81ba7d..0000000 --- a/STM32_General/Src/general_spi.c +++ /dev/null @@ -1,284 +0,0 @@ -/** -************************************************************************** -* @file general_spi.c -* @brief Модуль для инициализации SPI. -************************************************************************** -Реализация функций для работы с SPI: - - Инициализация SPI и его линий CLK/MISO/MOSI - - Настройка GPIO для SPI - - Настройка NVIC и тактирования SPI -**************************************************************************/ -#include "general_spi.h" -#include "general_gpio.h" - -//------------------------------------------------------------------- -//------------------------SPI INIT FUNCTIONS------------------------ -/** - * @brief Инициализация SPI с помощью структуры SPI_SettingsTypeDef. - * @param sspi Указатель на структуру с настройками SPI. - * @return HAL status. - * @details - * Инициализирует SPI и его GPIO. - * Настройка аналогична HAL_SPI_Init - * @code - * suart.hspi.Init... - * @endcode - * но дополнительно надо прописать пины CLK/MISO/MOSI @ref SPI_SettingsTypeDef - */ -HAL_StatusTypeDef SPI_Base_Init(SPI_SettingsTypeDef *sspi) -{ // function takes setting structure for init - - // check is settings are valid - if(SPI_Check_Init_Struct(sspi) != HAL_OK) - return HAL_ERROR; - - SPI_MspInit(&sspi->hspi); - - if (HAL_SPI_Init(&sspi->hspi) != HAL_OK) - { - MyLibs_Error_Handler(); - return HAL_ERROR; - } - - // init gpio from SPISettings structure - SPI_GPIO_Init(sspi); - -// // init dma from SPISettings structure if need -// if (sspi->DMAChannel != 0) -// SPI_DMA_Init(&sspi->hspi, sspi->hspi.hdmarx, sspi->DMAChannel, sspi->DMA_CHANNEL_X); - - return HAL_OK; -} - - -/** - * @brief Инициализация GPIO для SPI. - * @param sspi Указатель на структуру с настройками SPI. - */ -void SPI_GPIO_Init(SPI_SettingsTypeDef *sspi) -{ - GPIO_InitTypeDef GPIO_InitStruct = {0}; - // GPIO INIT - GPIO_Clock_Enable(sspi->CLK_GPIOx); - GPIO_Clock_Enable(sspi->MISO_GPIOx); - GPIO_Clock_Enable(sspi->MOSI_GPIOx); - // CLK PIN INIT - GPIO_InitStruct.Pin = sspi->CLK_PIN; - GPIO_InitStruct.Alternate = sspi->CLK_GPIO_AlternageFunc; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - HAL_GPIO_Init(sspi->CLK_GPIOx, &GPIO_InitStruct); - // MISO PIN INIT - GPIO_InitStruct.Pin = sspi->MISO_PIN; - GPIO_InitStruct.Alternate = sspi->MISO_GPIO_AlternageFunc; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - HAL_GPIO_Init(sspi->MISO_GPIOx, &GPIO_InitStruct); - // MOSI PIN INIT - GPIO_InitStruct.Pin = sspi->MOSI_PIN; - GPIO_InitStruct.Alternate = sspi->MOSI_GPIO_AlternageFunc; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - HAL_GPIO_Init(sspi->MOSI_GPIOx, &GPIO_InitStruct); -} - - -void SPI_DMA_Init(SPI_HandleTypeDef *hspi, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X) -{ // function takes spi and dma handlers and dmachannel for spi -// // for now only dma rx is supported, tx maybe later if needed -// // calc defines on boot_project_setup.h - -// /* SPI3 DMA Init */ -// /* SPI3_RX Init */ -// -// hdma_rx->Instance = DMAChannel; -//#if defined(STM32F4xx) // dma channel choose for 407 -// hdma_rx->Init.Channel = DMA_CHANNEL_X; -//#endif -// hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY; -// hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE; -// hdma_rx->Init.MemInc = DMA_MINC_ENABLE; -// hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; -// hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; -// hdma_rx->Init.Mode = DMA_CIRCULAR; -// hdma_rx->Init.Priority = DMA_PRIORITY_LOW; -// if (HAL_DMA_Init(hdma_rx) != HAL_OK) -// { -// MyLibs_Error_Handler(); -// } - -// __USER_LINKDMA(hspi,hdmarx,hdma_rx); -// - -// // __USER_LINKDMA is need because __HAL_LINKDMA is written for global defined hdma_rx -// // so you get error because hal uses . insted of -> -} - - -/** - * @brief Настройка тактирования и прерываний SPI. - * @param hspi Указатель на хендл SPI. - * @note Чтобы не генерировать функцию с иницилизацией неиспользуемых SPI, - дефайнами @ref SPI_INIT в @ref general_spi.h определяются используемые SPI. - */ -void SPI_MspInit(SPI_HandleTypeDef *hspi) // analog for hal function -{ - // rcc, dma and interrupt init for SPIs - // GPIO init was moved to own functions SPI_GPIO_Init - if(0); -#ifdef USE_SPI1 - else if(hspi->Instance==SPI1) - { - -// /* DMA2 clock enable */ -// __HAL_RCC_DMA2_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); - - /* SPI1 clock enable */ - __HAL_RCC_SPI1_CLK_ENABLE(); - - /* SPI1 interrupt Init */ - HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(SPI1_IRQn); - } -#endif // USE_SPI1 -#ifdef USE_SPI2 - else if(hspi->Instance==SPI2) - { -// /* DMA1 clock enable */ -// __HAL_RCC_DMA1_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn); - - /* SPI2 clock enable */ - __HAL_RCC_SPI2_CLK_ENABLE(); - - /* SPI2 interrupt Init */ - HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(SPI2_IRQn); - } -#endif // USE_SPI2 -#ifdef USE_SPI3 - else if(hspi->Instance==SPI3) - { -// /* DMA1 clock enable */ -// __HAL_RCC_DMA1_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn); - - /* SPI3 clock enable */ - __HAL_RCC_SPI3_CLK_ENABLE(); - /* SPI3 interrupt Init */ - HAL_NVIC_SetPriority(SPI3_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(SPI3_IRQn); - } -#endif // USE_SPI3 -} - -/** - * @brief Деинициализация тактирования и прерываний SPI. - * @param hspi Указатель на хендл SPI. - * @note Чтобы не генерировать функцию с иницилизацией неиспользуемых SPI, - дефайнами @ref SPI_INIT в @ref general_spi.h определяются используемые SPI. - */ -void SPI_MspDeInit(SPI_HandleTypeDef *hspi) // analog for hal function -{ - // rcc, dma and interrupt init for SPIs - // GPIO init was moved to own functions SPI_GPIO_Init - if(0); -#ifdef USE_SPI1 - else if(hspi->Instance==SPI1) - { - -// /* DMA2 clock enable */ -// __HAL_RCC_DMA2_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); - - /* SPI1 clock reset */ - __HAL_RCC_SPI1_FORCE_RESET(); - __HAL_RCC_SPI1_RELEASE_RESET(); - } -#endif // USE_SPI1 -#ifdef USE_SPI2 - else if(hspi->Instance==SPI2) - { -// /* DMA1 clock enable */ -// __HAL_RCC_DMA1_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn); - - /* SPI2 clock reset */ - __HAL_RCC_SPI2_FORCE_RESET(); - __HAL_RCC_SPI2_RELEASE_RESET(); - } -#endif // USE_SPI2 -#ifdef USE_SPI3 - else if(hspi->Instance==SPI3) - { -// /* DMA1 clock enable */ -// __HAL_RCC_DMA1_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn); - - /* SPI3 clock reset */ - __HAL_RCC_SPI3_FORCE_RESET(); - __HAL_RCC_SPI3_RELEASE_RESET(); - } -#endif // USE_SPI3 -} - -/** - * @brief Проверка корректности структуры инициализации SPI. - * @param sspi Указатель на структуру с настройками SPI. - * @return HAL status. - */ -HAL_StatusTypeDef SPI_Check_Init_Struct(SPI_SettingsTypeDef *sspi) -{ - // check is settings are valid - if (!IS_SPI_ALL_INSTANCE(sspi->hspi.Instance)) - return HAL_ERROR; - - // check init settings - if (!IS_SPI_MODE(sspi->hspi.Init.Mode)) - return HAL_ERROR; - if (!IS_SPI_DIRECTION(sspi->hspi.Init.Direction)) - return HAL_ERROR; - if (!IS_SPI_DATASIZE(sspi->hspi.Init.DataSize)) - return HAL_ERROR; - if (!IS_SPI_BAUDRATE_PRESCALER(sspi->hspi.Init.BaudRatePrescaler)) - return HAL_ERROR; - if (!IS_SPI_CPOL(sspi->hspi.Init.CLKPolarity)) - return HAL_ERROR; - if (!IS_SPI_CPHA(sspi->hspi.Init.CLKPhase)) - return HAL_ERROR; - if (!IS_SPI_NSS(sspi->hspi.Init.NSS)) - return HAL_ERROR; - if (!IS_SPI_FIRST_BIT(sspi->hspi.Init.FirstBit)) - return HAL_ERROR; - if (!IS_SPI_CRC_CALCULATION(sspi->hspi.Init.CRCCalculation)) - return HAL_ERROR; - if (!IS_SPI_CRC_POLYNOMIAL(sspi->hspi.Init.NSS) && - (sspi->hspi.Init.CRCCalculation != SPI_CRCCALCULATION_DISABLE)) - return HAL_ERROR; - if (!IS_SPI_TIMODE(sspi->hspi.Init.TIMode)) - return HAL_ERROR; - - // check gpio - if (!IS_GPIO_ALL_INSTANCE(sspi->CLK_GPIOx) || !IS_GPIO_ALL_INSTANCE(sspi->MISO_GPIOx) || !IS_GPIO_ALL_INSTANCE(sspi->MOSI_GPIOx)) - return HAL_ERROR; - if (!IS_GPIO_PIN(sspi->CLK_PIN) && !IS_GPIO_PIN(sspi->MISO_PIN) && !IS_GPIO_PIN(sspi->MOSI_PIN)) // if both pins arent set up - return HAL_ERROR; - - return HAL_OK; -} \ No newline at end of file diff --git a/STM32_General/Src/general_tim.c b/STM32_General/Src/general_tim.c deleted file mode 100644 index ca3367a..0000000 --- a/STM32_General/Src/general_tim.c +++ /dev/null @@ -1,722 +0,0 @@ -/** -************************************************************************** -* @file general_tim.c -* @brief Модуль для инициализации таймеров и работы с ними. -************************************************************************** -Реализация функций для работы с TIM: - - Инициализация таймера и его каналов - - Формирование задержек через таймеры - - Считывание энкодера -*************************************************************************/ -#include "general_tim.h" - -//------------------------------------------------------------------- -//-------------------------TIM INIT FUNCTIONS------------------------ -/** - * @brief Инициализация таймера. - * @param stim Указатель на структуру с настройками таймера. - * @return HAL status. - * @details - * Инициализирует таймер исходя из настроек верхнего уровня: - * - Длительность одного тика @ref TIM_MHzTickBaseTypeDef - * - Частота таймера (в Гц, float) - * - Частота тактирования таймера от шины (в Гц, float) - * - * При невозможности выставления частоты при заданой длительности тика - * длительность тика увеличивается до тех пор, пока частота не будет достигнута. - * - * При выставлении дефайна @ref UPDATE_TIM_PARAMS_AFTER_INITIALIZATION - * новая длительность тика записывается в структуру. - * - * Также остается возможность низкоуровневой настройки по структурам @ref TIM_SettingsTypeDef. - * Для этого надо высокоуровневые настройки приравнять к нулю - */ -HAL_StatusTypeDef TIM_Base_Init(TIM_SettingsTypeDef *stim) -{ // function takes structure for init - // check that htim is defined - if(check_null_ptr_2(stim, stim->htim.Instance)) - return HAL_ERROR; - - - - if(stim->sTickBaseUS) // if tickbase isnt disable - { - if(stim->sTimAHBFreqMHz == NULL) - return HAL_ERROR; - stim->htim.Init.Prescaler = (stim->sTimAHBFreqMHz*stim->sTickBaseUS) - 1; - - if ((stim->sTimFreqHz != NULL)) - stim->htim.Init.Period = ((1000000/stim->sTickBaseUS) / stim->sTimFreqHz) - 1; - else if (stim->htim.Init.Period == NULL) - stim->htim.Init.Period = 0xFFFF; - - if(stim->sTickBasePrescaler) - { - stim->htim.Init.Prescaler = (stim->htim.Init.Prescaler + 1)/stim->sTickBasePrescaler - 1; - stim->htim.Init.Period = (stim->htim.Init.Period + 1)*stim->sTickBasePrescaler - 1; - } - else - stim->sTickBasePrescaler = 1; - } - - // fix overflow of presc and period if need - for(int i = 0; (stim->htim.Init.Prescaler > 0xFFFF) || (stim->htim.Init.Period > 0xFFFF); i++) - { - if (i>10) // if it isnt fixed after 10 itteration - return HAL_ERRPOR - { - return HAL_ERROR; - } - - // if timbase is too big (prescaller too big for choosen base from MHZ) - if(stim->htim.Init.Prescaler > 0xFFFF) - { - // переносим часть пресскалера в период - stim->htim.Init.Prescaler = ((stim->htim.Init.Prescaler + 1)/2) - 1; - stim->htim.Init.Period = ((stim->htim.Init.Period + 1)*2) - 1; - // обновляем TickBase, если есть куда обновлять - if(stim->sTickBaseUS > 1) - stim->sTickBaseUS /= 2; - // обновляем sTickBasePrescaler, если sTickBaseUS - уже в минимуме - else if (stim->sTickBaseUS == 1) - stim->sTickBasePrescaler *= 2; - else // if TickBase = 0 - return error - return HAL_ERROR; - } - // if freq is too low (period too big for choosen base) - if(stim->htim.Init.Period > 0xFFFF) - { - // переносим часть периода в прескалер - stim->htim.Init.Period = ((stim->htim.Init.Period + 1)/2) - 1; - stim->htim.Init.Prescaler = ((stim->htim.Init.Prescaler + 1)*2) - 1; - // обновляем TickBase - stim->sTickBaseUS *= 2; - } - } - - //-------------TIM BASE INIT---------------- - // tim base init - TIM_Base_MspInit(&stim->htim, stim->sTimMode); - if (HAL_TIM_Base_Init(&stim->htim) != HAL_OK) - { - MyLibs_Error_Handler(); - return HAL_ERROR; - } - - //-------------CLOCK SRC INIT--------------- - // fill sClockSourceConfig if its NULL - if (stim->sClockSourceConfig.ClockSource == NULL) - stim->sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; - // clock source init - if (HAL_TIM_ConfigClockSource(&stim->htim, &stim->sClockSourceConfig) != HAL_OK) - { - MyLibs_Error_Handler(); - return HAL_ERROR; - } - - //--------------SLAVE INIT------------------ - // if slave mode enables - config it - if (stim->sSlaveConfig.SlaveMode) - { - // slave mode init - if (HAL_TIM_SlaveConfigSynchro(&stim->htim, &stim->sSlaveConfig) != HAL_OK) - { - MyLibs_Error_Handler(); - return HAL_ERROR; - } - } - //--------------MASTER INIT----------------- - // master mode init - if (HAL_TIMEx_MasterConfigSynchronization(&stim->htim, &stim->sMasterConfig) != HAL_OK) - { - MyLibs_Error_Handler(); - return HAL_ERROR; - } - - //--------------BDTR INIT----------------- - if (HAL_TIMEx_ConfigBreakDeadTime(&stim->htim, &stim->sBreakDeadTimeConfig) != HAL_OK) - { - MyLibs_Error_Handler(); - return HAL_ERROR; - } - - //----------------IT CLEAR------------------- - __HAL_TIM_CLEAR_IT(&stim->htim, TIM_IT_UPDATE); - - - // обновляем TickBase - #ifdef UPDATE_TIM_PARAMS_AFTER_INITIALIZATION - stim->sTickBaseUS = (stim->htim.Instance->PSC+1)*stim->sTickBasePrescaler/(stim->sTimAHBFreqMHz); - if(stim->sTickBaseUS == 0) // if prescaler is too high - { // recalc what is prescaler irl - stim->sTickBaseUS = 1; - stim->sTickBasePrescaler = stim->sTimAHBFreqMHz/(stim->htim.Instance->PSC+1); - } - #endif - stim->htim.Instance->CNT = 0; - return HAL_OK; -} - - - -/** - * @brief Инициализация режима энкодер у таймера. - * @param henc Указатель на хендл энкодера. - * @param htim Указатель на хендл таймера. - * @return HAL status. - * @note Предварительно надо инициализировать таймер @ref TIM_Base_Init. - */ -HAL_StatusTypeDef TIM_Encoder_Init(TIM_EncoderTypeDef *henc, TIM_HandleTypeDef *htim) -{ - if(check_null_ptr_3(henc, htim, htim->Instance)) - return HAL_ERROR; - if(check_null_ptr_3(henc->GPIOx, henc->GPIO_PIN_TI1, henc->GPIO_PIN_TI2)) - return HAL_ERROR; - - GPIO_InitTypeDef GPIO_InitStruct = {0}; - HAL_StatusTypeDef RES = HAL_ERROR; - henc->htim = htim; - - // setup channel for pwm - RES = HAL_TIM_Encoder_Init(henc->htim, &henc->sConfig); - if (RES != HAL_OK) - { - MyLibs_Error_Handler(); - return RES; - } - // choose port for enable clock - RES = GPIO_Clock_Enable(henc->GPIOx); - if(RES != HAL_OK) - { - MyLibs_Error_Handler(); - return RES; - } - - GPIO_InitStruct.Pin = henc->GPIO_PIN_TI1|henc->GPIO_PIN_TI2; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_TIM_Alternate_Mapping(henc->htim->Instance); - if(GPIO_InitStruct.Alternate) - HAL_GPIO_Init(henc->GPIOx, &GPIO_InitStruct); - - if(henc->GPIO_PIN_SW) - { - /*Configure switch pin */ - GPIO_InitStruct.Pin = henc->GPIO_PIN_SW; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_PULLUP; - HAL_GPIO_Init(henc->GPIOx, &GPIO_InitStruct); - - GPIO_Switch_Init(&henc->Sw, henc->GPIOx, henc->GPIO_PIN_SW, 0); - } - - return HAL_OK; -} - -/** - * @brief Инициализация выхода ШИМ таймера. - * @param htim Указатель на хендл таймера. - * @param sConfigOC Указатель на настрйоки канала таймера. - * @param TIM_CHANNEL Канал таймера для настройки. - * @param GPIOx Порт для вывода ШИМ. - * @param GPIO_PIN Пин для вывода ШИМ. - * @return HAL status. - * @note Предварительно надо инициализировать таймер @ref TIM_Base_Init. - */ -HAL_StatusTypeDef TIM_Output_PWM_Init(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfigOC, uint32_t TIM_CHANNEL, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN) -{ - if(check_null_ptr_3(htim, htim->Instance, sConfigOC)) - return HAL_ERROR; - if(check_null_ptr_2(GPIOx, GPIO_PIN)) - return HAL_ERROR; - - GPIO_InitTypeDef GPIO_InitStruct = {0}; - HAL_StatusTypeDef RES = HAL_ERROR; - - // setup channel for pwm - RES = HAL_TIM_PWM_ConfigChannel(htim, sConfigOC, TIM_CHANNEL); - if (RES != HAL_OK) - { - MyLibs_Error_Handler(); - return RES; - } - // choose port for enable clock - RES = GPIO_Clock_Enable(GPIOx); - if(RES != HAL_OK) - { - MyLibs_Error_Handler(); - return RES; - } - - GPIO_InitStruct.Pin = GPIO_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - if(sConfigOC->OCPolarity == TIM_OCNPOLARITY_HIGH) - GPIO_InitStruct.Pull = GPIO_PULLDOWN; - else - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_TIM_Alternate_Mapping(htim->Instance); - if(GPIO_InitStruct.Alternate) - HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); - - return HAL_OK; -} - -/** - * @brief Инициализация OC компаратора таймера. - * @param htim Указатель на хендл таймера. - * @param TIM_CHANNEL Канал таймера для настройки. - * @return HAL status. - * @note Предварительно надо инициализировать таймер @ref TIM_Base_Init. - */ -HAL_StatusTypeDef TIM_OC_Comparator_Init(TIM_HandleTypeDef *htim, uint32_t TIM_CHANNEL) -{ - if(check_null_ptr_2(htim, htim->Instance)) - return HAL_ERROR; - - TIM_OC_InitTypeDef sConfigOC = {0}; - HAL_StatusTypeDef RES = HAL_ERROR; - - sConfigOC.OCMode = TIM_OCMODE_ACTIVE; - sConfigOC.Pulse = 0; - sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; - - RES = HAL_TIM_OC_ConfigChannel(htim, &sConfigOC, TIM_CHANNEL); - if (RES != HAL_OK) - { - MyLibs_Error_Handler(); - return RES; - } - return RES; -} - - -//------------------------------------------------------------------- -//-------------------------TIM USER FUNCTIONS------------------------ -/** - * @brief Считать энкодер. - * @param henc Указатель на хендл энкодера. - * @return HAL status. - * @details Читает разницу энкодера, которую он накопил после - * предыдущего вызова этой функции. - */ -HAL_StatusTypeDef TIM_Encoder_Read(TIM_EncoderTypeDef *henc) -{ - if(check_null_ptr_3(henc, henc->htim, henc->htim->Instance)) - return HAL_ERROR; - - uint16_t cnt_now = (uint16_t)henc->htim->Instance->CNT; - int16_t diff = (int16_t)(cnt_now - henc->Encoder_Shdw); // переполнение корректно обрабатывается - henc->Encoder_Diff = diff; - henc->Encoder_Shdw = cnt_now; - - return HAL_OK; -} -/** - * @brief Считать кнопку энкодера. - * @param henc Указатель на хендл энкодера. - * @return 1 - если кнопка нажата, - * 0 - если отжата, - * -1 - если ошибка - */ -int TIM_Encoder_ReadSwitch(TIM_EncoderTypeDef *henc) -{ - if(check_null_ptr_1(henc)) - return -1; - - return GPIO_Read_Switch(&henc->Sw); -} - -/** - * @brief Задержка в тиках таймера (блокирующая). - * @param htim Указатель на хендл таймера. - * @param delay Задержка в тиках таймера. - * @return HAL status. - * @details Формирует задержку с блокировкой программы. - */ -HAL_StatusTypeDef TIM_Delay(TIM_HandleTypeDef *htim, uint16_t delay) -{ - if(check_null_ptr_2(htim, htim->Instance)) - return HAL_ERROR; - - if(delay >= htim->Instance->ARR) - { - return HAL_ERROR; - } - htim->Instance->CNT = 0; - while(1) - { - if(htim->Instance->CNT > delay) - { - return HAL_OK; - } - } -} - -/** - * @brief Начать отсчет неблокирующей задержки. - * @param htim Указатель на хендл таймера. - * @return HAL status. - * @details Сбрасывает счетчик для начала отсчета неблокирующей задержки. - * @ref TIM_Delay_NonBlocking для проверки статуса задержки - */ -HAL_StatusTypeDef TIM_Delay_Start(TIM_HandleTypeDef *htim) -{ - if(check_null_ptr_2(htim, htim->Instance)) - return HAL_ERROR; - - htim->Instance->CNT = 0; - - return HAL_OK; -} - -/** - * @brief Задержка в тиках таймера (неблокирующая). - * @param htim Указатель на хендл таймера. - * @param delay Задержка в тиках таймера. - * @return HAL status. - * @details Формирует задержку с блокировкой программы. - * Перед ожиданием задержки надо запутстить таймер @ref TIM_Delay_Start - * @note Таймер не должен использоваться на время этой задержки - */ -HAL_StatusTypeDef TIM_Delay_NonBlocking(TIM_HandleTypeDef *htim, uint16_t delay) -{ - if(check_null_ptr_2(htim, htim->Instance)) - return HAL_ERROR; - - if(delay >= htim->Instance->ARR) - { - return HAL_ERROR; - } - - if(htim->Instance->CNT <= delay) - { - return HAL_BUSY; - } - else - { - return HAL_OK; - } -} - -/** - * @brief Инициализация CLK и NVIC таймеров. - * @param htim Указатель на хендл таймера. - * @note Чтобы не генерировать функцию с иницилизацией неиспользуемых таймеров, - дефайнами @ref TIM_INIT в @ref general_tim.h определяются используемые таймеры. - */ -void TIM_Base_MspInit(TIM_HandleTypeDef* htim, TIM_ITModeTypeDef it_mode) -{ - if(check_null_ptr_2(htim, htim->Instance)) - return; - - it_mode = it_mode&TIM_IT_CONF; -#ifdef USE_TIM1 - if(htim->Instance==TIM1) - { - /* TIM2 clock enable */ - __HAL_RCC_TIM1_CLK_ENABLE(); - - /* TIM2 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn); - } - } -#endif -#ifdef USE_TIM2 - if(htim->Instance==TIM2) - { - /* TIM2 clock enable */ - __HAL_RCC_TIM2_CLK_ENABLE(); - - /* TIM2 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM2_IRQn); - } - } -#endif -#ifdef USE_TIM3 - if(htim->Instance==TIM3) - { - /* TIM3 clock enable */ - __HAL_RCC_TIM3_CLK_ENABLE(); - - /* TIM3 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM3_IRQn); - } - } -#endif -#ifdef USE_TIM4 - if(htim->Instance==TIM4) - { - /* TIM4 clock enable */ - __HAL_RCC_TIM4_CLK_ENABLE(); - - /* TIM4 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM4_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM4_IRQn); - } - } -#endif -#ifdef USE_TIM5 - if(htim->Instance==TIM5) - { - /* TIM5 clock enable */ - __HAL_RCC_TIM5_CLK_ENABLE(); - - /* TIM5 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM5_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM5_IRQn); - } - } -#endif -#ifdef USE_TIM6 - if(htim->Instance==TIM6) - { - /* TIM6 clock enable */ - __HAL_RCC_TIM6_CLK_ENABLE(); - - /* TIM6 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn); - } - } -#endif -#ifdef USE_TIM7 - if(htim->Instance==TIM7) - { - /* TIM7 clock enable */ - __HAL_RCC_TIM7_CLK_ENABLE(); - - /* TIM7 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM7_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM7_IRQn); - } - } -#endif -#ifdef USE_TIM8 - if(htim->Instance==TIM8) - { - /* TIM8 clock enable */ - __HAL_RCC_TIM8_CLK_ENABLE(); - - /* TIM8 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn); - } - } -#endif -#ifdef USE_TIM9 - if(htim->Instance==TIM9) - { - /* TIM9 clock enable */ - __HAL_RCC_TIM9_CLK_ENABLE(); - - /* TIM9 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM1_BRK_TIM9_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn); - } - } -#endif -#ifdef USE_TIM10 - if(htim->Instance==TIM10) - { - /* TIM10 clock enable */ - __HAL_RCC_TIM10_CLK_ENABLE(); - - /* TIM10 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn); - } - } -#endif -#ifdef USE_TIM11 - if(htim->Instance==TIM11) - { - /* TIM11 clock enable */ - __HAL_RCC_TIM11_CLK_ENABLE(); - - /* TIM11 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM11_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM11_IRQn); - } - } -#endif -#ifdef USE_TIM12 - if(htim->Instance==TIM12) - { - /* TIM12 clock enable */ - __HAL_RCC_TIM12_CLK_ENABLE(); - - /* TIM12 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM8_BRK_TIM12_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn); - } - } -#endif -#ifdef USE_TIM13 - if(htim->Instance==TIM13) - { - /* TIM13 clock enable */ - __HAL_RCC_TIM13_CLK_ENABLE(); - - /* TIM13 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn); - } - } -#endif -#ifdef USE_TIM14 - if(htim->Instance==TIM14) - { - /* TIM14 clock enable */ - __HAL_RCC_TIM14_CLK_ENABLE(); - - /* TIM14 interrupt Init */ - if(it_mode) - { - HAL_NVIC_SetPriority(TIM8_TRG_COM_TIM14_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM8_TRG_COM_TIM14_IRQn); - } - } -#endif -} -/** - * @brief Деинициализация CLK и NVIC таймеров. - * @param htim Указатель на хендл таймера. - * @note Чтобы не генерировать функцию с деиницилизацией неиспользуемых таймеров, - дефайнами @ref TIM_INIT в @ref general_tim.h определяются используемые таймеры. - */ -void TIM_Base_MspDeInit(TIM_HandleTypeDef* htim) -{ - if(check_null_ptr_2(htim, htim->Instance)) - return; - -#ifdef USE_TIM1 - if(htim->Instance==TIM1) - { - __HAL_RCC_TIM1_FORCE_RESET(); - __HAL_RCC_TIM1_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM2 - if(htim->Instance==TIM2) - { - __HAL_RCC_TIM2_FORCE_RESET(); - __HAL_RCC_TIM2_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM3 - if(htim->Instance==TIM3) - { - __HAL_RCC_TIM3_FORCE_RESET(); - __HAL_RCC_TIM3_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM4 - if(htim->Instance==TIM4) - { - __HAL_RCC_TIM4_FORCE_RESET(); - __HAL_RCC_TIM4_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM5 - if(htim->Instance==TIM5) - { - __HAL_RCC_TIM5_FORCE_RESET(); - __HAL_RCC_TIM5_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM6 - if(htim->Instance==TIM6) - { - __HAL_RCC_TIM6_FORCE_RESET(); - __HAL_RCC_TIM6_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM7 - if(htim->Instance==TIM7) - { - __HAL_RCC_TIM7_FORCE_RESET(); - __HAL_RCC_TIM7_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM8 - if(htim->Instance==TIM8) - { - __HAL_RCC_TIM8_FORCE_RESET(); - __HAL_RCC_TIM8_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM9 - if(htim->Instance==TIM9) - { - __HAL_RCC_TIM9_FORCE_RESET(); - __HAL_RCC_TIM9_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM10 - if(htim->Instance==TIM10) - { - __HAL_RCC_TIM10_FORCE_RESET(); - __HAL_RCC_TIM10_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM11 - if(htim->Instance==TIM11) - { - __HAL_RCC_TIM11_FORCE_RESET(); - __HAL_RCC_TIM11_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM12 - if(htim->Instance==TIM12) - { - __HAL_RCC_TIM12_FORCE_RESET(); - __HAL_RCC_TIM12_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM13 - if(htim->Instance==TIM13) - { - __HAL_RCC_TIM13_FORCE_RESET(); - __HAL_RCC_TIM13_RELEASE_RESET(); - } -#endif -#ifdef USE_TIM14 - if(htim->Instance==TIM14) - { - __HAL_RCC_TIM14_FORCE_RESET(); - __HAL_RCC_TIM14_RELEASE_RESET(); - } -#endif -} -//-------------------------TIM INIT FUNCTIONS------------------------ -//------------------------------------------------------------------- diff --git a/STM32_General/Src/general_uart.c b/STM32_General/Src/general_uart.c deleted file mode 100644 index a5fcc1b..0000000 --- a/STM32_General/Src/general_uart.c +++ /dev/null @@ -1,383 +0,0 @@ -/** -************************************************************************** -* @file general_uart.c -* @brief Модуль для инициализации UART. -************************************************************************** -Реализация функций для работы с UART: - - Инициализация UART и его линий RX/TX - - Настройка DMA для UART - - Настройка GPIO для UART - - Настройка NVIC и тактирования UART -**************************************************************************/ -#include "general_uart.h" -#include "general_gpio.h" - -//------------------------------------------------------------------- -//------------------------UART INIT FUNCTIONS------------------------ -/** - * @brief Инициализация UART с помощью структуры UART_SettingsTypeDef. - * @param suart Указатель на структуру с настройками UART. - * @return HAL status. - * @details - * Инициализирует UART и его GPIO и при необходимости DMA. - * Настройка аналогична HAL_UART_Init - * @code - * suart.huart.Init... - * @endcode - * но дополнительно надо прописать пины RX/TX @ref UART_SettingsTypeDef - * @code - * suart->GPIOx, suart->GPIO_PIN_RX, suart->GPIO_PIN_TX - * @endcode - */ -HAL_StatusTypeDef UART_Base_Init(UART_SettingsTypeDef *suart) -{ // function takes setting structure for init - - // check is settings are valid - if(UART_Check_Init_Struct(suart) != HAL_OK) - return HAL_ERROR; - - suart->huart.Init.Mode = UART_MODE_TX_RX; - - UART_MspInit(&suart->huart); - - - if (HAL_UART_Init(&suart->huart) != HAL_OK) - { - MyLibs_Error_Handler(); - return HAL_ERROR; - } - - // init gpio from UARTSettings structure - UART_GPIO_Init(suart->GPIOx, suart->GPIO_PIN_RX, suart->GPIO_PIN_TX); - - __HAL_UART_ENABLE_IT(&suart->huart, UART_IT_IDLE); - // init dma from UARTSettings structure if need - if (suart->DMAChannel != 0) - UART_DMA_Init(&suart->huart, suart->huart.hdmarx, suart->DMAChannel, suart->DMA_CHANNEL_X); - - - return HAL_OK; -} - - -/** - * @brief Инициализация GPIO для UART. - * @param GPIOx Порт для настройки. - * @param GPIO_PIN_RX Пин для приема. - * @param GPIO_PIN_TX Пин для передачи. - */ -void UART_GPIO_Init(GPIO_TypeDef *GPIOx, uint16_t GPIO_PIN_RX, uint16_t GPIO_PIN_TX) -{ // function takes port and pins (for rx and tx) - GPIO_InitTypeDef GPIO_InitStruct = {0}; - - // choose port for enable clock - GPIO_Clock_Enable(GPIOx); - - //USART3 GPIO Configuration - //GPIO_PIN_TX ------> USART_TX - //GPIO_PIN_RX ------> USART_RX - -#if defined(STM32F4xx) // gpio init for 407 - GPIO_InitStruct.Pin = GPIO_PIN_TX|GPIO_PIN_RX; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF7_USART3; - HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); -#elif defined(STM32F1xx) // gpio init for atm403/stm103 - //GPIO_PIN_TX ------> USART_TX - GPIO_InitStruct.Pin = GPIO_PIN_TX; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); - -// GPIO_PIN_RX ------> USART_RX - GPIO_InitStruct.Pin = GPIO_PIN_RX; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); -#endif -} - -/** - * @brief Инициализация DMA для UART. - * @param huart Указатель на хендл UART. - * @param hdma_rx Указатель на хендл DMA для линии приема UART. - * @param DMAChannel Указатель на канал DMA/поток DMA в STM32F407. - * @param DMA_CHANNEL_X Канал DMA. - */ -void UART_DMA_Init(UART_HandleTypeDef *huart, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X) -{ // function takes uart and dma handlers and dmachannel for uart - // for now only dma rx is supported, tx maybe later if needed - // calc defines on boot_project_setup.h - - /* USART3 DMA Init */ - /* USART3_RX Init */ - - hdma_rx->Instance = DMAChannel; -#if defined(STM32F4xx) // dma channel choose for 407 - hdma_rx->Init.Channel = DMA_CHANNEL_X; -#endif - hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY; - hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE; - hdma_rx->Init.MemInc = DMA_MINC_ENABLE; - hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - hdma_rx->Init.Mode = DMA_CIRCULAR; - hdma_rx->Init.Priority = DMA_PRIORITY_LOW; - if (HAL_DMA_Init(hdma_rx) != HAL_OK) - { - MyLibs_Error_Handler(); - } - - __USER_LINKDMA(huart,hdmarx,hdma_rx); - - - // __USER_LINKDMA is need because __HAL_LINKDMA is written for global defined hdma_rx - // so you get error because hal uses . insted of -> -} - -/** - * @brief Настройка тактирования и прерываний UART. - * @param huart Указатель на хендл UART. - * @note Чтобы не генерировать функцию с иницилизацией неиспользуемых UART, - дефайнами @ref UART_INIT в @ref general_uart.h определяются используемые UART. - */ -void UART_MspInit(UART_HandleTypeDef *huart) // analog for hal function -{ -// __RCC_DMA_UART_CLK_ENABLE(); -// /* DMA interrupt init */ -// /* DMA1_Stream1_IRQn interrupt configuration */ -// HAL_NVIC_SetPriority(DMA_UART_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA_UART_IRQn); - - // rcc, dma and interrupt init for USARTs - // GPIO init was moved to own functions UART_GPIO_Init - if(0); -#ifdef USE_USART1 - else if(huart->Instance==USART1) - { - - /* DMA2 clock enable */ - __HAL_RCC_DMA2_CLK_ENABLE(); - /* DMA interrupt init */ - HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); - - /* USART1 clock enable */ - __HAL_RCC_USART1_CLK_ENABLE(); - - /* USART1 interrupt Init */ - HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(USART1_IRQn); - } -#endif // USE_USART1 -#ifdef USE_USART2 - else if(huart->Instance==USART2) - { - /* DMA1 clock enable */ - __HAL_RCC_DMA1_CLK_ENABLE(); - /* DMA interrupt init */ - HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn); - - /* USART2 clock enable */ - __HAL_RCC_USART2_CLK_ENABLE(); - - /* USART2 interrupt Init */ - HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(USART2_IRQn); - } -#endif // USE_USART2 -#ifdef USE_USART3 - else if(huart->Instance==USART3) - { - /* DMA1 clock enable */ - __HAL_RCC_DMA1_CLK_ENABLE(); - /* DMA interrupt init */ - HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn); - - /* USART3 clock enable */ - __HAL_RCC_USART3_CLK_ENABLE(); - /* USART3 interrupt Init */ - HAL_NVIC_SetPriority(USART3_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(USART3_IRQn); - } -#endif // USE_USART3 -#ifdef USE_UART4 - else if(huart->Instance==UART4) - { - /* DMA1 clock enable */ - __HAL_RCC_DMA1_CLK_ENABLE(); - /* DMA interrupt init */ - HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn); - - /* UART4 clock enable */ - __HAL_RCC_UART4_CLK_ENABLE(); - - /* UART4 interrupt Init */ - HAL_NVIC_SetPriority(UART4_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(UART4_IRQn); - } -#endif // USE_UART4 -#ifdef USE_UART5 - else if(huart->Instance==UART5) - { - /* DMA1 clock enable */ - __HAL_RCC_DMA1_CLK_ENABLE(); - /* DMA interrupt init */ - HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn); - - /* UART5 clock enable */ - __HAL_RCC_DMA1_CLK_ENABLE(); - - /* UART5 interrupt Init */ - HAL_NVIC_SetPriority(UART5_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(UART5_IRQn); - } -#endif // USE_UART5 -#ifdef USE_USART6 - else if(huart->Instance==USART6) - { - /* DMA2 clock enable */ - __HAL_RCC_DMA2_CLK_ENABLE(); - /* DMA interrupt init */ - HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn); - - /* USART6 clock enable */ - __HAL_RCC_USART6_CLK_ENABLE(); - - /* USART6 interrupt Init */ - HAL_NVIC_SetPriority(USART6_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(USART6_IRQn); - } -#endif // USE_USART6 -} - -/** - * @brief Деинициализация тактирования и прерываний UART. - * @param huart Указатель на хендл UART. - * @note Чтобы не генерировать функцию с деиницилизацией неиспользуемых UART, - дефайнами @ref UART_INIT в @ref general_uart.h определяются используемые UART. - */ -void UART_MspDeInit(UART_HandleTypeDef *huart) // analog for hal function -{ - // rcc, dma and interrupt init for USARTs - // GPIO init was moved to own functions UART_GPIO_Init - if(0); -#ifdef USE_USART1 - else if(huart->Instance==USART1) - { - -// /* DMA2 clock enable */ -// __HAL_RCC_DMA2_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); - - /* USART1 clock reset */ - __HAL_RCC_USART1_FORCE_RESET(); - __HAL_RCC_USART1_RELEASE_RESET(); - } -#endif // USE_USART1 -#ifdef USE_USART2 - else if(huart->Instance==USART2) - { -// /* DMA1 clock enable */ -// __HAL_RCC_DMA1_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn); - - /* USART2 clock reset */ - __HAL_RCC_USART2_FORCE_RESET(); - __HAL_RCC_USART2_RELEASE_RESET(); - } -#endif // USE_USART2 -#ifdef USE_USART3 - else if(huart->Instance==USART3) - { -// /* DMA1 clock enable */ -// __HAL_RCC_DMA1_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn); - - /* USART3 clock reset */ - __HAL_RCC_USART3_FORCE_RESET(); - __HAL_RCC_USART3_RELEASE_RESET(); - } -#endif // USE_USART3 -#ifdef USE_UART4 - else if(huart->Instance==UART4) - { -// /* DMA1 clock enable */ -// __HAL_RCC_DMA1_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn); - - /* UART4 clock reset */ - __HAL_RCC_UART4_FORCE_RESET(); - __HAL_RCC_UART4_RELEASE_RESET(); - } -#endif // USE_UART4 -#ifdef USE_UART5 - else if(huart->Instance==UART5) - { -// /* DMA1 clock enable */ -// __HAL_RCC_DMA1_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn); - - /* UART5 clock reset */ - __HAL_RCC_UART5_FORCE_RESET(); - __HAL_RCC_UART5_RELEASE_RESET(); - } -#endif // USE_UART5 -#ifdef USE_USART6 - else if(huart->Instance==USART6) - { -// /* DMA2 clock enable */ -// __HAL_RCC_DMA2_CLK_ENABLE(); -// /* DMA interrupt init */ -// HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn); - - /* USART6 clock reset */ - __HAL_RCC_USART6_FORCE_RESET(); - __HAL_RCC_USART6_RELEASE_RESET(); - } -#endif // USE_USART6 -} - -/** - * @brief Проверка корректности структуры инициализации UART. - * @param suart Указатель на структуру с настройками UART. - * @return HAL status. - */ -HAL_StatusTypeDef UART_Check_Init_Struct(UART_SettingsTypeDef *suart) -{ - // check is settings are valid - if (!IS_UART_INSTANCE(suart->huart.Instance)) - return HAL_ERROR; - - if (!IS_UART_BAUDRATE(suart->huart.Init.BaudRate) || (suart->huart.Init.BaudRate == NULL)) - return HAL_ERROR; - - if (!IS_GPIO_ALL_INSTANCE(suart->GPIOx)) - return HAL_ERROR; - - if (!IS_GPIO_PIN(suart->GPIO_PIN_RX) && !IS_GPIO_PIN(suart->GPIO_PIN_TX)) // if both pins arent set up - return HAL_ERROR; - - return HAL_OK; -} - -//------------------------UART INIT FUNCTIONS------------------------ -//------------------------------------------------------------------- diff --git a/mainpage.h b/mainpage.h deleted file mode 100644 index 3d88555..0000000 --- a/mainpage.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Скачать HTML документацию можно здесь: - * https://git.arktika.cyou/Razvalyaev/STM32_ExtendedLibs/archive/v0.02.zip - */ -/** -@mainpage - - -@section overview Обзор -MyLibs - это набор библиотек для удобной работы с STM32. - -\htmlonly -Актуальная версия -\endhtmlonly - -@subsection features Основные возможности - -@subsubsection utils_module Общие утилиты (@ref MYLIBS_DEFINES) -- Макросы для задержек и утилит (@ref DELAYS_DEFINES и @ref UTILS_DEFINES) -- Трекеры для статистики и отладки (@ref TRACKERS и @ref TRACE) -- Эволюционный алгоритм для оптимизации параметров (@ref EVOLVE_OPTIMIZER) -- Битовый доступ к регистрам через union (@ref BIT_ACCESS_DEFINES) - -@subsubsection trace_module Трассировка @ref TRACE -- Serial трассировка через SWO и RTT (@ref TRACE_SERIAL) -- GPIO трассировка для отладки (@ref TRACE_GPIO) -- Сохранение логов в Flash память (@ref TRACE_RTT_FLASH) -- Обработка HardFault с сохранением контекста (@ref TRACE_HARDFAULT) - -@subsubsection gpio_module Модуль GPIO @ref MY_LIBS_GPIO -- Инициализация портов и тактирования (@ref MYLIBS_GPIO_GENERAL) -- Управление светодиодами (включение/выключение, моргание, плавное затухание) (@ref MYLIBS_GPIO_LEDS) -- Работа с кнопками (чтение состояния, фильтрация дребезга) (@ref MYLIBS_GPIO_SWITCH) - -@subsubsection tim_module Модуль таймеров @ref MY_LIBS_TIM -- Базовая инициализация таймеров (@ref MYLIBS_TIM_GENERAL) -- Формирование задержек (блокирующие и неблокирующие) (@ref MYLIBS_TIM_DELAY) -- Работа с энкодерами (чтение положения, обработка кнопок) (@ref MYLIBS_TIM_ENCODER) -- Настройка ШИМ и Output Compare (@ref MYLIBS_TIM_OC) - -@subsubsection uart_module Модуль UART @ref MY_LIBS_UART -- Базовая инициализация UART и его пинов одной функцией (@ref UART_Base_Init) - -@subsubsection spi_module Модуль SPI @ref MY_LIBS_SPI -- Базовая инициализация SPI и пинов одной функцией (@ref SPI_Base_Init) - -@subsection structure Структура проекта - -@code -ProjectRoot/ -├── MyLibs/ # Общие библиотеки, независимые от платформы (или почти) -│ ├── inc/ -│ │ ├── mylibs_include.h # Главный include файл -│ │ ├── mylibs_config.h # Конфигурация библиотек -│ │ ├── mylibs_defs.h # Общие определения и макросы -│ │ ├── bit_access.h # Битовый доступ к регистрам -│ │ ├── evolve_optimizer.h # Оптимизатор (генетический алгоритм) -│ │ ├── trackers.h # Трекеры для отладки -│ │ └── trace.h # Трассировка и логирование -│ └── src/ -│ -├──RTT # Библиотека RTT -│ ├── __SEGGER_RTT_Conf.h # Конфигурационный файл RTT -│ ├── SEGGER_RTT.c # Основной модуль RTT -│ ├── SEGGER_RTT.h # Основной заголовок RTT -│ ├── SEGGER_RTT_ASM_ARMv7M.S # Ассемблерная оптимизация для ARMv7M -│ └── SEGGER_RTT_printf.c # Реализация printf() через RTT -│ -└── STM32_General # Работа с периферией STM32 - ├── inc/ - │ ├── general_gpio.h # Работа с GPIO - │ ├── general_spi.h # Работа с SPI - │ ├── general_tim.h # Работа с таймерами - │ └── general_uart.h # Работа с UART - └── src/ - ├── general_gpio.c # Реализация GPIO - ├── general_spi.c # Реализация SPI - ├── general_tim.c # Реализация TIM - └── general_uart.c # Реализация UART -@endcode - - - - -@subsection usage_basic Использование - -Инструкция по подключению: - -1. Настройте конфигурацию @ref MYLIBS_CONFIG в @ref mylibs_config.h - -2. Подключите главный заголовочный файл: -@code -#include "mylibs_include.h" -@endcode - -3. Используйте нужные модули в своем коде. Примеры использования приведены в соответствующей теме - -*/ \ No newline at end of file