release 0.2

- stm general перенесена в другой репозиторий
- рефакторинг документации
This commit is contained in:
Razvalyaev 2025-11-07 20:28:01 +03:00
parent f46fa9b4ac
commit 6d1a5c8f71
22 changed files with 790 additions and 3014 deletions

257
MyLibs/Inc/bench_time.h Normal file
View File

@ -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 <stdint.h>
#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
* @}
*/

View File

@ -4,7 +4,7 @@
* @brief Заголочный файл для дефайнов битового доступа. * @brief Заголочный файл для дефайнов битового доступа.
************************************************************************** **************************************************************************
* @defgroup BIT_ACCESS_DEFINES Bit access defines * @defgroup BIT_ACCESS_DEFINES Bit access defines
* @ingroup MYLIBS_DEFINES * @ingroup MYLIBS_TOOLS
* @brief Макросы и typedef'ы для работы с битами в unsigned типах. * @brief Макросы и typedef'ы для работы с битами в unsigned типах.
* @details * @details
В этом файле определены макросы для получения значения конкретного бита^ В этом файле определены макросы для получения значения конкретного бита^

View File

@ -1,10 +1,9 @@
/** /**
****************************************************************************** ******************************************************************************
* @file evolve_optimizer.h * @file gen_optimizer.h
* @brief Заголовочный файл для адаптивного подбора параметров * @brief Заголовочный файл для адаптивного подбора параметров
****************************************************************************** ******************************************************************************
* @addtogroup EVOLVE_OPTIMIZER Evolve optimizer * @addtogroup GEN_OPTIMIZER Genetic optimizer
* @ingroup MYLIBS_DEFINES
* @brief Библиотека для эволюционного подбора параметров * @brief Библиотека для эволюционного подбора параметров
* @details * @details
Поддерживает: Поддерживает:
@ -15,24 +14,24 @@
Параметры для конфигурации: Параметры для конфигурации:
- @ref ENABLE_EVOLVE_OPTIMIZATION - Включить оптимизацию параметров - @ref GEN_OPTIMIZATION_ENABLE - Включить оптимизацию параметров
Если библиотека отключена @ref ENABLE_EVOLVE_OPTIMIZATION, то вставляются Если библиотека отключена @ref GEN_OPTIMIZATION_ENABLE, то вставляются
заглушки, никак не влияющие на параметры и остальную программу заглушки, никак не влияющие на параметры и остальную программу
- @ref EVOLVE_MAX_PARAMS - Максимальное количество параметров - @ref GEN_MAX_PARAMS - Максимальное количество параметров
- @ref EVOLVE_MAX_CANDIDATES - Максимальное количество кандидатов для обучения - @ref GEN_MAX_CANDIDATES - Максимальное количество кандидатов для обучения
- (опционально) @ref EVOLVE_MUTATION_MIN_PCT - Минимальная мутация в процентах от Loss (по умолчанию 10%) - (опционально) @ref GEN_MUTATION_MIN_PCT - Минимальная мутация в процентах от Loss (по умолчанию 10%)
- (опционально) @ref EVOLVE_MUTATION_MAX_PCT - Максимальная мутация в процентах от Loss (по умолчанию 100%) - (опционально) @ref GEN_MUTATION_MAX_PCT - Максимальная мутация в процентах от Loss (по умолчанию 100%)
- (опционально) @ref ELOVLE_N_ELITE_CANDIDATE - Количество кандидатов, которые проходят в поколение без изменений - (опционально) @ref ELOVLE_N_ELITE_CANDIDATE - Количество кандидатов, которые проходят в поколение без изменений
@par Пример использования: @par Пример использования:
@code @code
#include "evolve_optimizer.h" #include "gen_optimizer.h"
#define N_PARAMS 4 #define N_PARAMS 4
#define N_CANDIDATES 100 #define N_CANDIDATES 100
#define N_BEST 10 #define N_BEST 10
#define MUTATION 0.1f #define MUTATION 0.1f
float params[N_PARAMS]; float params[N_PARAMS];
EvolveOptimizer_t optimizer; GenOptimizer_t optimizer;
// Формирование параметров // Формирование параметров
uint16_t param_u16 = 800; 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); 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) 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); 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 @endcode
* @{ * @{
*****************************************************************************/ *****************************************************************************/
#ifndef __EVOLVE_OPTIMIZER_H_ #ifndef __GEN_OPTIMIZER_H_
#define __EVOLVE_OPTIMIZER_H_ #define __GEN_OPTIMIZER_H_
#include "mylibs_defs.h" #include "mylibs_defs.h"
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef ENABLE_EVOLVE_OPTIMIZATION #ifdef GEN_OPTIMIZATION_ENABLE
/** /**
* @brief Линейное масштабирование x из диапазона [min_val, max_val] в диапазон [0, 1) * @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 #ifndef GEN_MUTATION_MIN_PCT
#define EVOLVE_MUTATION_MIN_PCT 10 ///< Минимальная мутация (в процентах от Loss) #define GEN_MUTATION_MIN_PCT 10 ///< Минимальная мутация (в процентах от Loss)
#endif #endif
#ifndef EVOLVE_MUTATION_MAX_PCT #ifndef GEN_MUTATION_MAX_PCT
#define EVOLVE_MUTATION_MAX_PCT 100 ///< Максимальная мутация (в процентах от Loss) #define GEN_MUTATION_MAX_PCT 100 ///< Максимальная мутация (в процентах от Loss)
#endif #endif
#ifndef ELOVLE_N_ELITE_CANDIDATE #ifndef ELOVLE_N_ELITE_CANDIDATE
#define ELOVLE_N_ELITE_CANDIDATE 2 ///< Количество кандидатов, которые проходят в поколение без изменений (по умолчанию 2) #define ELOVLE_N_ELITE_CANDIDATE 2 ///< Количество кандидатов, которые проходят в поколение без изменений (по умолчанию 2)
@ -107,25 +106,25 @@ typedef struct {
uint16_t n_best; ///< Количество лучших, усредняемых uint16_t n_best; ///< Количество лучших, усредняемых
float mutation_amp; ///< Амплитуда мутации (0..1) float mutation_amp; ///< Амплитуда мутации (0..1)
uint16_t cand_index; ///< Индекс кандидата для обработки uint16_t cand_index; ///< Индекс текущего кандидата
uint16_t gen_index; ///< Индекс популяции uint16_t gen_index; ///< Индекс популяции
//INTERNAL //INTERNAL
float gen_mut; ///< Амплитуда мутации у текущей популяции float gen_mut; ///< Амплитуда мутации у текущей популяции
float loss[EVOLVE_MAX_CANDIDATES]; ///< Loss для каждого кандидата float loss[GEN_MAX_CANDIDATES]; ///< Loss для каждого кандидата
float candidates[EVOLVE_MAX_CANDIDATES][EVOLVE_MAX_PARAMS]; ///< Параметры кандидатов float candidates[GEN_MAX_CANDIDATES][GEN_MAX_PARAMS]; ///< Параметры кандидатов
uint16_t sorted_idx[EVOLVE_MAX_CANDIDATES]; ///< Индексы отсортированных кандидатов uint16_t sorted_idx[GEN_MAX_CANDIDATES]; ///< Индексы отсортированных кандидатов
} EvolveOptimizer_t; } 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) { 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 если окей, * @return 0 если окей,
* -1 если ошибка * -1 если ошибка
*/ */
__STATIC_INLINE int EvolveOptimizer_Init(EvolveOptimizer_t* opt, static int GenOptimizer_Init(GenOptimizer_t* opt,
uint16_t n_params, uint16_t n_params,
uint16_t n_cand, uint16_t n_cand,
uint16_t n_best, uint16_t n_best,
@ -162,15 +161,15 @@ __STATIC_INLINE int EvolveOptimizer_Init(EvolveOptimizer_t* opt,
if((opt == NULL) || (start_params == NULL)) if((opt == NULL) || (start_params == NULL))
return -1; return -1;
if(n_params > EVOLVE_MAX_PARAMS) if(n_params > GEN_MAX_PARAMS)
return -1; return -1;
opt->n_params = n_params; opt->n_params = n_params;
if(n_cand > EVOLVE_MAX_CANDIDATES) if(n_cand > GEN_MAX_CANDIDATES)
return -1; return -1;
opt->n_cand = n_cand; opt->n_cand = n_cand;
if(n_best > EVOLVE_MAX_CANDIDATES/2) if(n_best > GEN_MAX_CANDIDATES/2)
return -1; return -1;
opt->n_best = n_best; opt->n_best = n_best;
@ -222,7 +221,7 @@ __STATIC_INLINE int EvolveOptimizer_Init(EvolveOptimizer_t* opt,
* @note Функция использует глобальную внутреннюю переменную для сортировки. * @note Функция использует глобальную внутреннюю переменную для сортировки.
* Надо убедится что только один экземпляр функции запущен в момент времени * Надо убедится что только один экземпляр функции запущен в момент времени
*/ */
__STATIC_INLINE int EvolveOptimizer_Step(EvolveOptimizer_t* opt, static int GenOptimizer_Step(GenOptimizer_t* opt,
float* params, float* params,
float loss) float loss)
{ {
@ -230,15 +229,15 @@ __STATIC_INLINE int EvolveOptimizer_Step(EvolveOptimizer_t* opt,
return -1; return -1;
uint16_t n_params = opt->n_params; uint16_t n_params = opt->n_params;
if(n_params > EVOLVE_MAX_PARAMS) if(n_params > GEN_MAX_PARAMS)
return -1; return -1;
uint16_t n_cand = opt->n_cand; uint16_t n_cand = opt->n_cand;
if(n_cand > EVOLVE_MAX_CANDIDATES) if(n_cand > GEN_MAX_CANDIDATES)
return -1; return -1;
uint16_t n_best = opt->n_best; uint16_t n_best = opt->n_best;
if(n_best > EVOLVE_MAX_CANDIDATES/2) if(n_best > GEN_MAX_CANDIDATES/2)
return -1; return -1;
float mut = opt->mutation_amp; 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 < 0.0f) opt->stability = 0.0f;
if(opt->stability > 1.0f) opt->stability = 1.0f; if(opt->stability > 1.0f) opt->stability = 1.0f;
float mut_pct = EVOLVE_MUTATION_MIN_PCT + float mut_pct = GEN_MUTATION_MIN_PCT +
(EVOLVE_MUTATION_MAX_PCT - EVOLVE_MUTATION_MIN_PCT) * loss_ratio; (GEN_MUTATION_MAX_PCT - GEN_MUTATION_MIN_PCT) * loss_ratio;
float adaptive_mut = mut * (mut_pct / 100.0f); float adaptive_mut = mut * (mut_pct / 100.0f);
if (adaptive_mut < 0.0001f) adaptive_mut = 0.0001f; if (adaptive_mut < 0.0001f) adaptive_mut = 0.0001f;
opt->gen_mut = adaptive_mut; opt->gen_mut = adaptive_mut;
@ -315,7 +314,7 @@ __STATIC_INLINE int EvolveOptimizer_Step(EvolveOptimizer_t* opt,
return 0; return 0;
} }
#else // ENABLE_EVOLVE_OPTIMIZATION #else // GEN_OPTIMIZATION_ENABLE
//заглушки //заглушки
typedef struct { typedef struct {
uint16_t n_params; uint16_t n_params;
@ -324,15 +323,15 @@ typedef struct {
float mutation_amp; float mutation_amp;
float loss[0]; float loss[0];
float candidates[0][0]; float candidates[0][0];
} EvolveOptimizer_t; } GenOptimizer_t;
#define EvolveOptimizer_Init(opt, n_params, n_cand, n_best, mutation_amp, start_params) #define GenOptimizer_Init(opt, n_params, n_cand, n_best, mutation_amp, start_params)
#define EvolveOptimizer_Step(opt, params, LossFunc) #define GenOptimizer_Step(opt, params, LossFunc)
#define PARAM_SCALE(x, min_val, max_val) (x) #define PARAM_SCALE(x, min_val, max_val) (x)
#define PARAM_UNSCALE(val, min_val, max_val) (val) #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
* @} * @}
*/ */

View File

@ -55,21 +55,38 @@
/** /**
* @addtogroup EVOLVE_CONFIG Evolve configs * @addtogroup GEN_CONFIG Genetic configs
* @ingroup MYLIBS_CONFIG * @ingroup MYLIBS_CONFIG
* @brief Конфигурация однослойного персептрона и алгоритма обучения * @brief Конфигурация генетического алгоритма обучения
* @{ * @{
*/ */
#define ENABLE_EVOLVE_OPTIMIZATION ///< Включить оптимизацию параметров #define GEN_OPTIMIZATION_ENABLE ///< Включить оптимизацию параметров
#define EVOLVE_MAX_PARAMS 20 ///< Максимальное количество параметров #define GEN_MAX_PARAMS 20 ///< Максимальное количество параметров
#define EVOLVE_MAX_CANDIDATES 100 ///< Максимальное количество кандидатов для обучения #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 * @addtogroup LIBS_CONFIG Libraries configs
* @ingroup MYLIBS_CONFIG * @ingroup MYLIBS_CONFIG
@ -79,7 +96,7 @@
#define local_time() uwTick ///< Локальное время #define local_time() uwTick ///< Локальное время
#define INCLUDE_EVOLVE_OPTIMIZER ///< Подключить библиотеку для оптимизации параметров #define INCLUDE_GEN_OPTIMIZER ///< Подключить библиотеку для оптимизации параметров
#define INCLUDE_BIT_ACCESS_LIB ///< Подключить библиотеку с typedef с битовыми полями #define INCLUDE_BIT_ACCESS_LIB ///< Подключить библиотеку с typedef с битовыми полями
#define INCLUDE_TRACKERS_LIB ///< Подключить библиотеку с трекерами #define INCLUDE_TRACKERS_LIB ///< Подключить библиотеку с трекерами
#define INCLUDE_TRACE_LIB ///< Подключить библиотеку с трейсами #define INCLUDE_TRACE_LIB ///< Подключить библиотеку с трейсами

View File

@ -3,13 +3,28 @@
* @file mylibs_defs.h * @file mylibs_defs.h
* @brief Заголочный файл для дефайнов библиотеки MyLibsGeneral. * @brief Заголочный файл для дефайнов библиотеки MyLibsGeneral.
************************************************************************** **************************************************************************
* @defgroup MYLIBS_DEFINES General Tools * @defgroup MYLIBS_TOOLS General Tools
* @ingroup MYLIBS_ALL * @ingroup MYLIBS_ALL
* @brief Общие макросы и typedef'ы, используемые по всему проекту * @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_ #ifndef __MYLIBS_TOOLS_H_
#define __MYLIBS_DEFINES_H_ #define __MYLIBS_TOOLS_H_
#include "mylibs_config.h" #include "mylibs_config.h"
@ -17,7 +32,7 @@
******************************ERROR_HANDLER********************************/ ******************************ERROR_HANDLER********************************/
/** /**
* @addtogroup ERROR_HANDLER_DEFINES Error Handler defines * @addtogroup ERROR_HANDLER_DEFINES Error Handler defines
* @ingroup MYLIBS_DEFINES * @ingroup MYLIBS_TOOLS
* @brief Дефайны для обработки ошибок * @brief Дефайны для обработки ошибок
* @{ * @{
*/ */
@ -58,7 +73,7 @@ extern void Error_Handler(void);
******************************DELAYS_DEFINES*******************************/ ******************************DELAYS_DEFINES*******************************/
/** /**
* @addtogroup DELAYS_DEFINES Delays defines * @addtogroup DELAYS_DEFINES Delays defines
* @ingroup MYLIBS_DEFINES * @ingroup MYLIBS_TOOLS
* @brief Макросы и определения для работы с задержками в миллисекундах. * @brief Макросы и определения для работы с задержками в миллисекундах.
* @details * @details
* Этот блок содержит макросы для реализации задержек с использованием HAL или FreeRTOS: * Этот блок содержит макросы для реализации задержек с использованием HAL или FreeRTOS:
@ -138,10 +153,9 @@ extern void Error_Handler(void);
/*************************************************************************** /***************************************************************************
*******************************UTIL_DEFINES********************************/ *******************************UTIL_DEFINES********************************/
static int dummy;
/** /**
* @addtogroup UTILS_DEFINES Utils defines * @addtogroup UTILS_DEFINES Utils defines
* @ingroup MYLIBS_DEFINES * @ingroup MYLIBS_TOOLS
* @brief Общие вспомогательные макросы * @brief Общие вспомогательные макросы
* @{ * @{
*/ */
@ -191,6 +205,7 @@ static int dummy;
* @cond LIBS_INTERNAL * @cond LIBS_INTERNAL
*/ */
static int dummy; // переменная которой присваиваются значения, которые некуда присвоить
/** /**
* @brief Аналог HAL макроса для привязки DMA к UART. * @brief Аналог HAL макроса для привязки DMA к UART.
@ -203,4 +218,4 @@ do{ \
/** @endcond */ /** @endcond */
#endif //__MYLIBS_DEFINES_H_ #endif //__MYLIBS_TOOLS_H_

View File

@ -14,13 +14,8 @@
- Сконфигурировать mylibs_config.h: - Сконфигурировать mylibs_config.h:
- Подключить заголовочный файл HAL библиотеки конкретного МК (напр. stm32f4xx_hal.h) - Подключить заголовочный файл HAL библиотеки конкретного МК (напр. stm32f4xx_hal.h)
- Подключить другие заголовочные файлы которые общие для всего проекта и должны быть видны - Подключить другие заголовочные файлы которые общие для всего проекта и должны быть видны
- - Подключить mylibs_include.h туда, где необходим доступ к библиотекам.
- Подключить mylibs_include.h туда, где необходим доступ к библиотекам.
* @defgroup MYLIBS_PERIPHERAL Peripheral
* @ingroup MYLIBS_ALL
* @brief Модули для управления периферией
*
*************************************************************************/ *************************************************************************/
#ifndef __MYLIBS_INCLUDE_H_ #ifndef __MYLIBS_INCLUDE_H_
#define __MYLIBS_INCLUDE_H_ #define __MYLIBS_INCLUDE_H_
@ -79,8 +74,8 @@
#define HF_HandleFault(...) #define HF_HandleFault(...)
#endif #endif
#ifdef INCLUDE_EVOLVE_OPTIMIZER #ifdef INCLUDE_GEN_OPTIMIZER
#include "evolve_optimizer.h" #include "gen_optimizer.h"
#else #else
typedef struct { typedef struct {
uint16_t n_params; uint16_t n_params;
@ -89,13 +84,29 @@ typedef struct {
uint16_t iq_mutation; uint16_t iq_mutation;
int32_t loss[0]; int32_t loss[0];
int32_t candidates[0][0]; int32_t candidates[0][0];
} EvolveOptimizer_t; } GenOptimizer_t;
#define EvolveOptimizer_Init(opt, n_params, n_cand, n_best, iq_mutation, start_params) #define GenOptimizer_Init(opt, n_params, n_cand, n_best, iq_mutation, start_params)
#define EvolveOptimizer_Step(opt, params, LossFunc) #define GenOptimizer_Step(opt, params, LossFunc)
#define PARAM_SCALE_Q16(x, min_val, max_val) (x) #define PARAM_SCALE_Q16(x, min_val, max_val) (x)
#define PARAM_UNSCALE_Q16(q16_val, min_val, max_val) (q16_val) #define PARAM_UNSCALE_Q16(q16_val, min_val, max_val) (q16_val)
#endif #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 #ifdef INCLUDE_GENERAL_PERIPH_LIBS
#include "__general_flash.h" #include "__general_flash.h"

View File

@ -4,7 +4,6 @@
* @brief Заголочный файл для работы с трассировкой. * @brief Заголочный файл для работы с трассировкой.
************************************************************************** **************************************************************************
* @addtogroup TRACE Trace defines * @addtogroup TRACE Trace defines
* @ingroup MYLIBS_DEFINES
* @brief Дефайны для работы с трассировкой * @brief Дефайны для работы с трассировкой
*************************************************************************/ *************************************************************************/
#ifndef __TRACE_H_ #ifndef __TRACE_H_

View File

@ -4,7 +4,6 @@
* @brief Заголочный файл для работы с трекерами @ref TRACKERS. * @brief Заголочный файл для работы с трекерами @ref TRACKERS.
************************************************************************** **************************************************************************
* @addtogroup TRACKERS Trackers defines * @addtogroup TRACKERS Trackers defines
* @ingroup MYLIBS_DEFINES
* @brief Дефайны для работы с трекерами * @brief Дефайны для работы с трекерами
* @details * @details
Есть дефайн для объявления структуры трекера: TrackerTypeDef(num_user_vars). Есть дефайн для объявления структуры трекера: TrackerTypeDef(num_user_vars).

View File

@ -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_config.h # Конфигурация библиотек
│ │ ├── mylibs_defs.h # Общие определения и макросы │ │ ├── mylibs_defs.h # Общие определения и макросы
│ │ ├── bit_access.h # Битовый доступ к регистрам │ │ ├── bit_access.h # Битовый доступ к регистрам
│ │ ├── evolve_optimizer.h # Оптимизатор (генетический алгоритм) │ │ ├── gen_optimizer.h # Оптимизатор (генетический алгоритм)
│ │ ├── trackers.h # Трекеры для отладки │ │ ├── trackers.h # Трекеры для отладки
│ │ └── trace.h # Трассировка и логирование │ │ └── trace.h # Трассировка и логирование
│ └── src/ │ └── src/
├──RTT # Библиотека RTT └──RTT # Библиотека RTT
│ ├── __SEGGER_RTT_Conf.h # Конфигурационный файл RTT ├── __SEGGER_RTT_Conf.h # Конфигурационный файл RTT
│ ├── SEGGER_RTT.c # Основной модуль RTT ├── SEGGER_RTT.c # Основной модуль RTT
│ ├── SEGGER_RTT.h # Основной заголовок RTT ├── SEGGER_RTT.h # Основной заголовок RTT
│ ├── SEGGER_RTT_ASM_ARMv7M.S # Ассемблерная оптимизация для ARMv7M ├── SEGGER_RTT_ASM_ARMv7M.S # Ассемблерная оптимизация для ARMv7M
│ └── SEGGER_RTT_printf.c # Реализация printf() через RTT └── 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
``` ```
## Инструкция по подключению ## Инструкция по подключению
@ -76,9 +80,3 @@ ProjectRoot/
```bash ```bash
git submodule update --remote 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) и просто комментариями в коде.

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rt_sys.h>
#include <rt_misc.h>
#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 ****************************/

View File

@ -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_

View File

@ -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_

View File

@ -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
* @}
*/

View File

@ -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_

View File

@ -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
* @}
*/

View File

@ -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;
}
//----------------------------------------------------------

View File

@ -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-------------------------
//-------------------------------------------------------------------

View File

@ -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;
}

View File

@ -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------------------------
//-------------------------------------------------------------------

View File

@ -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------------------------
//-------------------------------------------------------------------

View File

@ -1,98 +0,0 @@
/*
* Скачать HTML документацию можно здесь:
* https://git.arktika.cyou/Razvalyaev/STM32_ExtendedLibs/archive/v0.02.zip
*/
/**
@mainpage
@section overview Обзор
MyLibs - это набор библиотек для удобной работы с STM32.
\htmlonly
<a href="https://git.arktika.cyou/Razvalyaev/STM32_ExtendedLibs/src/branch/release">Актуальная версия</a>
\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. Используйте нужные модули в своем коде. Примеры использования приведены в соответствующей теме
*/