forked from Elron_dev/elbear_arduino_bsp
ready to alpha
подготовка к альфа-тестированию
This commit is contained in:
commit
e36b851783
164 files changed
+27352
No files matched your search
@@ -0,0 +1 @@
|
||||
.vscode
|
||||
@@ -0,0 +1 @@
|
||||
# mcu32-hal
|
||||
@@ -0,0 +1,105 @@
|
||||
#ifndef MIK32_HAL_SCR1_TIMER
|
||||
#define MIK32_HAL_SCR1_TIMER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mcu32_memory_map.h"
|
||||
#include "power_manager.h"
|
||||
#include "inttypes.h"
|
||||
|
||||
// #include "csr.h"
|
||||
// #include "scr1_csr_encoding.h"
|
||||
#include "scr1_timer.h"
|
||||
|
||||
|
||||
|
||||
#define MIK32_FREQ 32000000 /* Входная частота, Гц */
|
||||
#define MIK32_FREQ_MHZ 32 /* Входная частота, МГц */
|
||||
|
||||
/* Источник тактированя */
|
||||
#define SCR1_TIMER_CLKSRC_INTERNAL 0 /* Тактирование от ядра */
|
||||
#define SCR1_TIMER_CLKSRC_EXTERNAL_RTC 1 /* Тактирование от внешнего RTC */
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SCR1_TIMER_TypeDef *Instance; /* Базовый адрес регистров SCR1_TIMER */
|
||||
|
||||
uint8_t ClockSource; /* Источник тактирования */
|
||||
uint16_t Divider; /* Делитель частоты 10-битное число */
|
||||
|
||||
} SCR1_TIMER_HandleTypeDef;
|
||||
|
||||
|
||||
void HAL_SCR1_Timer_Enable(SCR1_TIMER_HandleTypeDef *hscr1_timer);
|
||||
void HAL_SCR1_Timer_Disable(SCR1_TIMER_HandleTypeDef *hscr1_timer);
|
||||
void HAL_SCR1_Timer_SetClockSource(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint8_t ClockSource);
|
||||
void HAL_SCR1_Timer_SetDivider(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint16_t Divider);
|
||||
void HAL_SCR1_Timer_Init(SCR1_TIMER_HandleTypeDef *hscr1_timer);
|
||||
void HAL_SCR1_Timer_Start(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds);
|
||||
int HAL_SCR1_Timer_GetFlagCMP(SCR1_TIMER_HandleTypeDef *hscr1_timer);
|
||||
|
||||
uint64_t HAL_SCR1_Timer_Get_Ticks(SCR1_TIMER_HandleTypeDef *hscr1_timer);
|
||||
|
||||
/* Время задержки должено быть не больше 134217 мс */
|
||||
void HAL_DelayMs(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* uint32_t TIMER_CTRL;
|
||||
* uint32_t TIMER_DIV;
|
||||
* uint32_t MTIME;
|
||||
* uint32_t MTIMEH;
|
||||
* uint32_t MTIMECMP;
|
||||
* uint32_t MTIMECMPH;
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Регистр TIMER_CTRL
|
||||
------------------------------------------------------------------------------------------------
|
||||
Обозначение | Биты | По умолчанию | Описание | Доступ
|
||||
------------------------------------------------------------------------------------------------
|
||||
ENABLE | 0 | X | Включение таймера | RW
|
||||
------------------------------------------------------------------------------------------------
|
||||
CLKSRC | 1 | 0x0 | Источник тактирования | RW
|
||||
| | | 0 - Тактирования ядра |
|
||||
| | | 1 - Внешний RTC |
|
||||
------------------------------------------------------------------------------------------------
|
||||
Reserved | 31:2 | | RZ
|
||||
------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Регистр TIMER_DIV
|
||||
------------------------------------------------------------------------------------------------
|
||||
Обозначение | Биты | По умолчанию | Описание | Доступ
|
||||
------------------------------------------------------------------------------------------------
|
||||
DIV | 9:0 | X | Делитель | RW
|
||||
| Счет идет каждые DIV+1 |
|
||||
| такта частоты |
|
||||
------------------------------------------------------------------------------------------------
|
||||
Reserved | 31:10 | X | RZ
|
||||
------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
По умолчанию, MTIME и MTIMEH равны нулю после перезагрузки ядра (которая также
|
||||
начинает подсчет). Другим вариантом начала счета для MTIME/MTIMEH является запись некоторого значения в
|
||||
MTIME/MTIMEH.
|
||||
|
||||
MTIME - Счетчик таймера. 64-битне число. MTIMEH - старшее слово, MTIME - младшее слово.
|
||||
MTIMECMP - Регистр сравнения. 64-битное число. MTIMECMPH - старшее слово, MTIMECMP - младшее слово.
|
||||
|
||||
Прерывание машинного таймера становится ожидающим всякий раз, когда mtime содержит значение, большее или равное mtimecmp,
|
||||
обрабатывая значения как целые числа без знака. Прерывание сохраняется до тех пор, пока mtimecmp не станет больше
|
||||
mtime (обычно в результате записи mtimecmp). Прерывание будет принято только в том случае, если
|
||||
включены прерывания и бит MTIE установлен в регистре mie.
|
||||
|
||||
*/
|
||||
Whitespace-only changes.
@@ -0,0 +1,125 @@
|
||||
#include "mik32_hal_scr1_timer.h"
|
||||
#include "mik32_hal.h"
|
||||
|
||||
|
||||
void HAL_SCR1_Timer_Enable(SCR1_TIMER_HandleTypeDef *hscr1_timer)
|
||||
{
|
||||
hscr1_timer->Instance->TIMER_CTRL |= SCR1_TIMER_CTRL_ENABLE_M;
|
||||
}
|
||||
|
||||
void HAL_SCR1_Timer_Disable(SCR1_TIMER_HandleTypeDef *hscr1_timer)
|
||||
{
|
||||
hscr1_timer->Instance->TIMER_CTRL &= ~SCR1_TIMER_CTRL_ENABLE_M;
|
||||
|
||||
hscr1_timer->Instance->MTIME = 0;
|
||||
hscr1_timer->Instance->MTIMEH = 0;
|
||||
}
|
||||
|
||||
void HAL_SCR1_Timer_SetClockSource(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint8_t ClockSource)
|
||||
{
|
||||
hscr1_timer->ClockSource = ClockSource;
|
||||
|
||||
switch (ClockSource)
|
||||
{
|
||||
case SCR1_TIMER_CLKSRC_INTERNAL:
|
||||
hscr1_timer->Instance->TIMER_CTRL &= SCR1_TIMER_CTRL_CLKSRC_INTERNAL_M;
|
||||
break;
|
||||
|
||||
case SCR1_TIMER_CLKSRC_EXTERNAL_RTC:
|
||||
hscr1_timer->Instance->TIMER_CTRL |= SCR1_TIMER_CTRL_CLKSRC_RTC_M;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_SCR1_Timer_SetDivider(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint16_t Divider)
|
||||
{
|
||||
/* Divider 10-битное число */
|
||||
if(Divider > 1023)
|
||||
{
|
||||
Divider = 1023;
|
||||
}
|
||||
hscr1_timer->Divider = Divider;
|
||||
hscr1_timer->Instance->TIMER_DIV = Divider;
|
||||
}
|
||||
|
||||
void HAL_SCR1_Timer_Init(SCR1_TIMER_HandleTypeDef *hscr1_timer)
|
||||
{
|
||||
hscr1_timer->Instance->TIMER_CTRL = 0;
|
||||
|
||||
/* Настройка источника тактирования */
|
||||
HAL_SCR1_Timer_SetClockSource(hscr1_timer, hscr1_timer->ClockSource);
|
||||
|
||||
/* Настройка делителя */
|
||||
HAL_SCR1_Timer_SetDivider(hscr1_timer, hscr1_timer->Divider);
|
||||
|
||||
HAL_SCR1_Timer_Start(hscr1_timer, 134217);
|
||||
|
||||
}
|
||||
|
||||
void HAL_SCR1_Timer_Start(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds)
|
||||
{
|
||||
uint8_t AHBMDivider = PM->DIV_AHB; /* Делитель частоты */
|
||||
uint32_t Milliseconds_max_32bit = 134217; /* 134217 - максимальное число миллисекунд для того чтобы при расчете количества тактов не превысить 32 бита */
|
||||
|
||||
if (Milliseconds > Milliseconds_max_32bit)
|
||||
{
|
||||
Milliseconds = Milliseconds_max_32bit; /* Задержка равна предельному значению 134217, мс */
|
||||
}
|
||||
|
||||
uint32_t Ticks = Milliseconds * (MIK32_FREQ/1000); /* Количество тактов системного таймера для достижения значения Milliseconds */
|
||||
Ticks = Ticks / (AHBMDivider + 1);
|
||||
Ticks = Ticks / (hscr1_timer->Divider + 1);
|
||||
|
||||
#ifdef MIK32_SCR1_TIMER_DEBUG
|
||||
xprintf("Milliseconds = %u\n", Milliseconds);
|
||||
xprintf("Ticks = %u\n", Ticks);
|
||||
#endif
|
||||
|
||||
|
||||
hscr1_timer->Instance->MTIME = 0;
|
||||
hscr1_timer->Instance->MTIMEH = 0;
|
||||
|
||||
hscr1_timer->Instance->MTIMECMP = Ticks;
|
||||
hscr1_timer->Instance->MTIMECMPH = 0;
|
||||
|
||||
HAL_SCR1_Timer_Enable(hscr1_timer);
|
||||
}
|
||||
|
||||
uint64_t HAL_SCR1_Timer_Get_Ticks(SCR1_TIMER_HandleTypeDef *hscr1_timer)
|
||||
{
|
||||
return ((uint64_t)hscr1_timer->Instance->MTIMEH)<<32 | hscr1_timer->Instance->MTIME;
|
||||
}
|
||||
|
||||
|
||||
int HAL_SCR1_Timer_GetFlagCMP(SCR1_TIMER_HandleTypeDef *hscr1_timer)
|
||||
{
|
||||
uint32_t MTIME = hscr1_timer->Instance->MTIME;
|
||||
uint32_t MTIMEH = hscr1_timer->Instance->MTIMEH;
|
||||
uint32_t MTIMECMP = hscr1_timer->Instance->MTIMECMP;
|
||||
uint32_t MTIMECMPH = hscr1_timer->Instance->MTIMECMPH;
|
||||
|
||||
if( ((MTIMEH == MTIMECMPH) && (MTIME > MTIMECMP)) || (MTIMEH > MTIMECMPH) )
|
||||
{
|
||||
HAL_SCR1_Timer_Disable(hscr1_timer);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HAL_DelayMs(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds)
|
||||
{
|
||||
|
||||
HAL_SCR1_Timer_Start(hscr1_timer, Milliseconds);
|
||||
|
||||
while (HAL_SCR1_Timer_GetFlagCMP(hscr1_timer) == 0);
|
||||
|
||||
HAL_SCR1_Timer_Disable(hscr1_timer);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Whitespace-only changes.
@@ -0,0 +1,34 @@
|
||||
#ifndef MIK32_HAL
|
||||
#define MIK32_HAL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_def.h"
|
||||
#include "mik32_hal_pcc.h"
|
||||
|
||||
#ifndef OSC_SYSTEM_VALUE
|
||||
#define OSC_SYSTEM_VALUE ((uint32_t)32000000U) // Значение частоты основного внешнего источника по умолчанию.
|
||||
#endif
|
||||
|
||||
#ifndef OSC_CLOCK_VALUE
|
||||
#define OSC_CLOCK_VALUE ((uint32_t)32768U) // Значение частоты часового внешнего источника по умолчанию.
|
||||
#endif
|
||||
|
||||
#ifndef HSI_VALUE
|
||||
#define HSI_VALUE ((uint32_t)32000000U) // Значение частоты основного внутреннего источника по умолчанию.
|
||||
#endif
|
||||
|
||||
#ifndef LSI_VALUE
|
||||
#define LSI_VALUE ((uint32_t)32768U) // Значение частоты часового внутреннего источника по умолчанию.
|
||||
#endif
|
||||
|
||||
void HAL_MspInit();
|
||||
HAL_StatusTypeDef HAL_Init();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,360 @@
|
||||
#ifndef MIK32_HAL_ADC
|
||||
#define MIK32_HAL_ADC
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "analog_reg.h"
|
||||
#include "pad_config.h"
|
||||
#include "stdbool.h"
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "mik32_hal_gpio.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
|
||||
|
||||
/* Title: Макросы */
|
||||
|
||||
/*
|
||||
* Defines: Каналы АЦП
|
||||
*
|
||||
* ADC_CHANNEL0 - Канал АЦП0 (PORT_1_5)
|
||||
* ADC_CHANNEL1 - Канал АЦП1 (PORT_1_7)
|
||||
* ADC_CHANNEL2 - Канал АЦП2 (PORT_0_2)
|
||||
* ADC_CHANNEL3 - Канал АЦП3 (PORT_0_4)
|
||||
* ADC_CHANNEL4 - Канал АЦП4 (PORT_0_7)
|
||||
* ADC_CHANNEL5 - Канал АЦП5 (PORT_0_9)
|
||||
* ADC_CHANNEL6 - Канал АЦП6 (PORT_0_11)
|
||||
* ADC_CHANNEL7 - Канал АЦП7 (PORT_0_13)
|
||||
*
|
||||
*/
|
||||
#define ADC_CHANNEL0 0 /* Канал АЦП0 - PORT_1_5 */
|
||||
#define ADC_CHANNEL1 1 /* Канал АЦП1 - PORT_1_7 */
|
||||
#define ADC_CHANNEL2 2 /* Канал АЦП2 - PORT_0_2 */
|
||||
#define ADC_CHANNEL3 3 /* Канал АЦП3 - PORT_0_4 */
|
||||
#define ADC_CHANNEL4 4 /* Канал АЦП4 - PORT_0_7 */
|
||||
#define ADC_CHANNEL5 5 /* Канал АЦП5 - PORT_0_9 */
|
||||
#define ADC_CHANNEL6 6 /* Канал АЦП6 - PORT_0_11 */
|
||||
#define ADC_CHANNEL7 7 /* Канал АЦП7 - PORT_0_13 */
|
||||
|
||||
/*
|
||||
* Defines: Выбор ИОН
|
||||
*
|
||||
* Выбор источника опорного напряжения.
|
||||
*
|
||||
* ADC_EXTREF_OFF - Встроенный источник опорного напряжения 1,2 В
|
||||
* ADC_EXTREF_ON - Внешний источник опорного напряжения
|
||||
*
|
||||
*/
|
||||
#define ADC_EXTREF_OFF 0 /* Встроенный источник опорного напряжения 1,2 В */
|
||||
#define ADC_EXTREF_ON 1 /* Внешний источник опорного напряжения */
|
||||
|
||||
/*
|
||||
* Defines: Выбор внешнего ИОН
|
||||
*
|
||||
* Выбор внешнего источника опорного напряжения по отношению к встроенному в АЦП ИОН.
|
||||
*
|
||||
* ADC_EXTCLB_CLBREF - Настраиваемый ОИН
|
||||
* ADC_EXTCLB_ADCREF - Внешний вывод
|
||||
*
|
||||
*/
|
||||
#define ADC_EXTCLB_CLBREF 0 /* Настраиваемый ОИН */
|
||||
#define ADC_EXTCLB_ADCREF 1 /* Внешний вывод */
|
||||
|
||||
/*
|
||||
* Defines: Входы АЦП
|
||||
*
|
||||
* Номера выводов каналов АЦП и ADC_REF
|
||||
*
|
||||
* ADC_PORT_AS_FUNC3 - Четвертая функция вывода (аналоговый сигнал)
|
||||
* ADC_CHANNEL0_PORT_1_5 - Канал АЦП0 - PORT_1_5
|
||||
* ADC_CHANNEL1_PORT_1_7 - Канал АЦП1 - PORT_1_7
|
||||
* ADC_CHANNEL2_PORT_0_2 - Канал АЦП2 - PORT_0_2
|
||||
* ADC_CHANNEL3_PORT_0_4 - Канал АЦП3 - PORT_0_4
|
||||
* ADC_CHANNEL4_PORT_0_7 - Канал АЦП4 - PORT_0_7
|
||||
* ADC_CHANNEL5_PORT_0_9 - Канал АЦП5 - PORT_0_9
|
||||
* ADC_CHANNEL6_PORT_0_11 - Канал АЦП6 - PORT_0_11
|
||||
* ADC_CHANNEL7_PORT_0_13 - Канал АЦП7 - PORT_0_13
|
||||
* ADC_REF_PORT_1_10 - Внешний опорный сигнал - PORT_1_10
|
||||
*
|
||||
*/
|
||||
#define ADC_PORT_AS_FUNC3 0b11 /* Четвертая функция вывода (аналоговый сигнал) */
|
||||
#define ADC_CHANNEL0_PORT_1_5 5 /* Канал АЦП0 - PORT_1_5 */
|
||||
#define ADC_CHANNEL1_PORT_1_7 7 /* Канал АЦП1 - PORT_1_7 */
|
||||
#define ADC_CHANNEL2_PORT_0_2 2 /* Канал АЦП2 - PORT_0_2 */
|
||||
#define ADC_CHANNEL3_PORT_0_4 4 /* Канал АЦП3 - PORT_0_4 */
|
||||
#define ADC_CHANNEL4_PORT_0_7 7 /* Канал АЦП4 - PORT_0_7 */
|
||||
#define ADC_CHANNEL5_PORT_0_9 9 /* Канал АЦП5 - PORT_0_9 */
|
||||
#define ADC_CHANNEL6_PORT_0_11 11 /* Канал АЦП6 - PORT_0_11 */
|
||||
#define ADC_CHANNEL7_PORT_0_13 13 /* Канал АЦП7 - PORT_0_13 */
|
||||
#define ADC_REF_PORT_1_10 10 /* Внешний опорный сигнал - PORT_1_10 */
|
||||
|
||||
|
||||
/* Title: Структуры */
|
||||
|
||||
/*
|
||||
* Struct: ADC_InitTypeDef
|
||||
*
|
||||
* Настройки АЦП при инициализации
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* Variable: Sel
|
||||
* Выбор канала АЦП
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <ADC_CHANNEL0>;
|
||||
* - <ADC_CHANNEL1>;
|
||||
* - <ADC_CHANNEL2>;
|
||||
* - <ADC_CHANNEL3>;
|
||||
* - <ADC_CHANNEL4>;
|
||||
* - <ADC_CHANNEL5>;
|
||||
* - <ADC_CHANNEL6>;
|
||||
* - <ADC_CHANNEL7>.
|
||||
*
|
||||
*/
|
||||
uint8_t Sel;
|
||||
|
||||
/*
|
||||
* Variable: EXTRef
|
||||
* Выбор источника опорного напряжения
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <ADC_EXTREF_OFF>;
|
||||
* - <ADC_EXTREF_ON>.
|
||||
*
|
||||
*/
|
||||
uint8_t EXTRef;
|
||||
|
||||
/*
|
||||
* Variable: EXTClb
|
||||
* Выбор внешнего источника опорного напряжения
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <ADC_EXTCLB_CLBREF>;
|
||||
* - <ADC_EXTCLB_ADCREF>.
|
||||
*
|
||||
*/
|
||||
uint8_t EXTClb;
|
||||
|
||||
} ADC_InitTypeDef;
|
||||
|
||||
/*
|
||||
* Struct: ADC_HandleTypeDef
|
||||
* Настройки АЦП
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* Variable: Instance
|
||||
* Базоый адрес регистров ADC.
|
||||
*
|
||||
*/
|
||||
ANALOG_REG_TypeDef *Instance;
|
||||
|
||||
/*
|
||||
* Variable: Init
|
||||
* Настройки АЦП при инициализации
|
||||
*
|
||||
*/
|
||||
ADC_InitTypeDef Init;
|
||||
|
||||
} ADC_HandleTypeDef;
|
||||
|
||||
|
||||
/* Сменить канал АЦП */
|
||||
#ifdef MIK32V0
|
||||
#define ADC_SEL_CHANNEL(adc_instance, channel_selection) ((adc_instance)->ADC_CONFIG = (((adc_instance)->ADC_CONFIG & (~ADC_CONFIG_SEL_M)) | ((channel_selection) << ADC_CONFIG_SEL_S)))
|
||||
#else // MIK32V2
|
||||
#define ADC_SEL_CHANNEL(adc_instance, channel_selection) ((adc_instance)->ADC_CONFIG = (((adc_instance)->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) & (~ADC_CONFIG_SEL_M)) | (((adc_instance)->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) | ((channel_selection) << ADC_CONFIG_SEL_S))
|
||||
#endif // MIK32V0
|
||||
|
||||
/* Запустить однократное преобразование */
|
||||
#define HAL_ADC_SINGLE(adc_instance) ((adc_instance)->ADC_SINGLE = 1)
|
||||
|
||||
#define HAL_ADC_SINGLE_AND_SET_CH(adc_instance, adc_channel) ({(adc_instance)->ADC_SINGLE = 1; ADC_SEL_CHANNEL((adc_instance), (adc_channel));}) /* Запустить однократное преобразование */
|
||||
|
||||
|
||||
/* Title: Функции */
|
||||
|
||||
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc);
|
||||
|
||||
/*
|
||||
* Включить калибруемый ИОН
|
||||
*/
|
||||
void HAL_ADC_CLBEnable(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Выключить калибруемый ИОН
|
||||
*/
|
||||
void HAL_ADC_CLBDisable(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Задать коэфициент настройки ОИН
|
||||
*/
|
||||
void HAL_ADC_VCLBSet(ADC_HandleTypeDef *hadc, uint8_t v_coef);
|
||||
|
||||
/*
|
||||
* Задать коэфициент настройки опорного источника тока
|
||||
*/
|
||||
void HAL_ADC_ICLBSet(ADC_HandleTypeDef *hadc, uint8_t i_coef);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_ResetEnable
|
||||
* Установить бит Rn, управление сбросом АЦП, в 1.
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_ADC_ResetEnable(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_ResetDisable
|
||||
* Сбросить бит Rn, управление сбросом АЦП, в 0.
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_ADC_ResetDisable(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_Disable
|
||||
* Выключть питание АЦП
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_ADC_Disable(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_Enable
|
||||
* Включть питание АЦП
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_ADC_Enable(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_ChannelSet
|
||||
* Задать активный канал АЦП и перевести соответсвующий вывод в аналоговую функцию.
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_ADC_ChannelSet(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_Init
|
||||
* Инициализировать АЦП в соответсвии с настройками в hadc.
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_ADC_Init(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_Single
|
||||
* Запустить однократное измерение АЦП.
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_ADC_Single(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_ContiniusDisabled
|
||||
* Выключить непрерывное измерение АЦП.
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_ADC_ContinuousDisabled(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_ContiniusEnable
|
||||
* Выключить непрерывное измерение АЦП.
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_ADC_ContinuousEnable(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_WaitValid
|
||||
* Ожидать установку флага актуальных данных.
|
||||
*
|
||||
* Флаг VALID - Признак наличия актуальных данных.
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_ADC_WaitValid(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_GetValue
|
||||
* Получить результат преобразовния АЦП.
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* (uint16_t ) - Результат преобразования АЦП.
|
||||
*
|
||||
*/
|
||||
uint16_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_WaitAndGetValue
|
||||
* Ожидать актуальный результат преобразования АЦП и получить его значение.
|
||||
*
|
||||
* Parameters:
|
||||
* hadc - Указатель на структуру с настройками ADC.
|
||||
*
|
||||
* Returns:
|
||||
* (uint16_t ) - Результат преобразования АЦП.
|
||||
*
|
||||
*/
|
||||
uint16_t HAL_ADC_WaitAndGetValue(ADC_HandleTypeDef *hadc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,347 @@
|
||||
#ifndef MIK32_HAL_CRC32
|
||||
#define MIK32_HAL_CRC32
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "crc.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
|
||||
|
||||
|
||||
/* Title: Макросы */
|
||||
|
||||
/*
|
||||
* Defines: Перестановка битов/байтов данных
|
||||
*
|
||||
* CRC_REVERSE_OFF - Перестановка выключена
|
||||
* CRC_REVERSE_BITS - Биты в байтах перестанавливаются, байты не перестанавливаются
|
||||
* CRC_REVERSE_BITS_BYTES - Перестанавливаются и биты, и байты
|
||||
* CRC_REVERSE_BYTES - Биты в байтах не перестанавливаются, байты перестанавливаются
|
||||
*
|
||||
*/
|
||||
#define CRC_REVERSE_OFF 0 // Перестановка выключена
|
||||
#define CRC_REVERSE_BITS 1 // Биты в байтах перестанавливаются, байты не перестанавливаются
|
||||
#define CRC_REVERSE_BITS_BYTES 2 // Перестанавливаются и биты, и байты
|
||||
#define CRC_REVERSE_BYTES 3 // Биты в байтах не перестанавливаются, байты перестанавливаются
|
||||
|
||||
|
||||
/* Модификаторы */
|
||||
/*
|
||||
* Defines: Флаг RefIn
|
||||
*
|
||||
* Флаг RefIn, указывающий на начало и направление вычислений.
|
||||
*
|
||||
* Перестановка битов/байтов входных данных.
|
||||
*
|
||||
* Существует два варианта:
|
||||
*
|
||||
* - CRC_REFIN_FALSE начиная со старшего значащего бита (MSB-first);
|
||||
* - CRC_REFIN_TRUE с младшего (LSB-first).
|
||||
*
|
||||
* CRC_REFIN_FALSE - Биты в байтах не перестанавливаются, байты перестанавливаются
|
||||
* CRC_REFIN_TRUE - Перестанавливаются и биты, и байты
|
||||
*
|
||||
*/
|
||||
#define CRC_REFIN_FALSE CRC_REVERSE_BYTES // RefIn = false - CRC_REVERSE_BYTES
|
||||
#define CRC_REFIN_TRUE CRC_REVERSE_BITS_BYTES // RefIn = true - CRC_REVERSE_BITS_BYTES
|
||||
|
||||
/*
|
||||
* Defines: Флаг RefOut
|
||||
*
|
||||
* Флаг RefOut, определяющий, инвертируется ли порядок битов регистра при входе на элемент XOR.
|
||||
*
|
||||
* Перестановки битов/байтов выходных данных.
|
||||
*
|
||||
* CRC_REFOUT_FALSE - Биты в байтах не перестанавливаются, байты перестанавливаются
|
||||
* CRC_REFOUT_TRUE - Перестанавливаются и биты, и байты
|
||||
*
|
||||
*/
|
||||
#define CRC_REFOUT_FALSE CRC_REVERSE_OFF // RefOut = false - CRC_REVERSE_OFF
|
||||
#define CRC_REFOUT_TRUE CRC_REVERSE_BITS_BYTES // RefOUT = true - CRC_REVERSE_BITS_BYTES
|
||||
|
||||
/*
|
||||
* Defines: Флаг XorOut
|
||||
*
|
||||
* Инверсия контрольной суммы.
|
||||
* Число XorOut = 0xFFFFFFFF, с которым складывается по модулю 2 полученный результат. Побитовая инверсия результата.
|
||||
*
|
||||
* CRC_OUTPUTINVERSION_OFF - Инверсия выключена.
|
||||
* CRC_OUTPUTINVERSION_ON - Инверсия включена (операция XOR выполняется)
|
||||
*
|
||||
*/
|
||||
#define CRC_OUTPUTINVERSION_OFF 0 // Инверсия выключена
|
||||
#define CRC_OUTPUTINVERSION_ON 1 // Инверсия включена (операция XOR выполняется)
|
||||
|
||||
/*
|
||||
* Defines: Размер буфера
|
||||
*
|
||||
* CRC_MAX_WORDS - Максимальное количество слов в буфере.
|
||||
* CRC_MAX_BYTES - Максимальное количество байтов в буфере.
|
||||
*
|
||||
*/
|
||||
#define CRC_MAX_WORDS 16
|
||||
#define CRC_MAX_BYTES 64
|
||||
|
||||
/* Title: Структуры */
|
||||
|
||||
/*
|
||||
* Struct: CRC_HandleTypeDef
|
||||
* Настройки CRC
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* Variable: Instance
|
||||
* Базоый адрес регистров CRC
|
||||
*
|
||||
*/
|
||||
CRC_TypeDef *Instance;
|
||||
|
||||
/*
|
||||
* Variable: Poly
|
||||
* Значение порождающего многочлена.
|
||||
*
|
||||
* Этот параметр может быть 32-битным значением.
|
||||
*
|
||||
*/
|
||||
uint32_t Poly;
|
||||
|
||||
/*
|
||||
* Variable: Init
|
||||
* Стартовое значение данных.
|
||||
*
|
||||
* Этот параметр может быть 32-битным значением.
|
||||
*
|
||||
*/
|
||||
uint32_t Init;
|
||||
|
||||
/*
|
||||
* Variable: InputReverse
|
||||
* Перестановка битов/байтов входных данных.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <CRC_REFIN_FALSE>;
|
||||
* - <CRC_REFIN_TRUE>.
|
||||
*
|
||||
*/
|
||||
uint8_t InputReverse;
|
||||
|
||||
/*
|
||||
* Variable: OutputReverse
|
||||
* Перестановка битов/байтов выходных данных.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <CRC_REFOUT_FALSE>;
|
||||
* - <CRC_REFOUT_TRUE>.
|
||||
*
|
||||
*/
|
||||
uint8_t OutputReverse;
|
||||
|
||||
/*
|
||||
* Variable: OutputInversion
|
||||
* Инверсия контрольной суммы.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <CRC_OUTPUTINVERSION_OFF>;
|
||||
* - <CRC_OUTPUTINVERSION_ON>.
|
||||
*
|
||||
*/
|
||||
uint8_t OutputInversion;
|
||||
|
||||
} CRC_HandleTypeDef;
|
||||
|
||||
/* Title: Функции */
|
||||
|
||||
void HAL_CRC32_MspInit(CRC_HandleTypeDef* hcrc);
|
||||
|
||||
/*
|
||||
* Function: HAL_CRC_SetInputReverse
|
||||
* Задать перестановка битов/байтов входных данных в соответствии со значением <CRC_HandleTypeDef.InputReverse> (RefIn).
|
||||
*
|
||||
* Parameters:
|
||||
* hcrc - Указатель на структуру с настройками CRC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_CRC_SetInputReverse(CRC_HandleTypeDef *hcrc);
|
||||
|
||||
/*
|
||||
* Function: HAL_CRC_SetOutputInversion
|
||||
* Инверсия контрольной суммы в соответсвии со значением <CRC_HandleTypeDef.OutputInversion> (XorOut).
|
||||
*
|
||||
* Parameters:
|
||||
* hcrc - Указатель на структуру с настройками CRC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_CRC_SetOutputInversion(CRC_HandleTypeDef *hcrc);
|
||||
|
||||
/*
|
||||
* Function: HAL_CRC_SetOutputReverse
|
||||
* Перестановки битов/байтов выходных данных в соответствии со значением <CRC_HandleTypeDef.OutputReverse> (RefOut).
|
||||
*
|
||||
* Parameters:
|
||||
* hcrc - Указатель на структуру с настройками CRC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_CRC_SetOutputReverse(CRC_HandleTypeDef *hcrc);
|
||||
|
||||
/*
|
||||
* Function: HAL_CRC_SetInit
|
||||
* Задать начальное значение данных в соответсвии с <CRC_HandleTypeDef.Init>
|
||||
*
|
||||
* Parameters:
|
||||
* hcrc - Указатель на структуру с настройками CRC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_CRC_SetInit(CRC_HandleTypeDef *hcrc);
|
||||
|
||||
/*
|
||||
* Function: HAL_CRC_Init
|
||||
* Инициализировать CRC в соответствии с настройками <CRC_HandleTypeDef> *hcrc.
|
||||
*
|
||||
* Parameters:
|
||||
* hcrc - Указатель на структуру с настройками CRC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_CRC_Init(CRC_HandleTypeDef *hcrc);
|
||||
|
||||
/*
|
||||
* Function: HAL_CRC_WaitBusy
|
||||
* Ожидать сброса флага BUSY. Если флаг равен 0, то автомат закончил вычисления.
|
||||
*
|
||||
* Parameters:
|
||||
* hcrc - Указатель на структуру с настройками CRC.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_CRC_WaitBusy(CRC_HandleTypeDef *hcrc);
|
||||
|
||||
/*
|
||||
* Function: HAL_CRC_WaitBusy
|
||||
* Записать данные по байтам в буфер CRC.
|
||||
*
|
||||
* Parameters:
|
||||
* hcrc - Указатель на структуру с настройками CRC.
|
||||
* message - Массив с данными.
|
||||
* message_length - Количество передаваемых байтов.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_CRC_WriteData(CRC_HandleTypeDef *hcrc, uint8_t message[], uint32_t message_length);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_WriteData32
|
||||
* Записать данные по словам в буфер CRC.
|
||||
*
|
||||
* Parameters:
|
||||
* hcrc - Указатель на структуру с настройками CRC.
|
||||
* message - Массив с данными.
|
||||
* message_length - Количество передаваемых байтов.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_CRC_WriteData32(CRC_HandleTypeDef *hcrc, uint32_t message[], uint32_t message_length);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_ReadCRC
|
||||
* Получить значение CRC.
|
||||
*
|
||||
* Parameters:
|
||||
* hcrc - Указатель на структуру с настройками CRC.
|
||||
*
|
||||
* Returns:
|
||||
* (uint32_t ) - Значение CRC.
|
||||
*
|
||||
*/
|
||||
uint32_t HAL_CRC_ReadCRC(CRC_HandleTypeDef *hcrc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**************************************CRC-32**************************************/
|
||||
// hcrc.Poly = 0x04C11DB7;
|
||||
// hcrc.Init = 0xFFFFFFFF;
|
||||
// hcrc.InputReverse = CRC_REFIN_TRUE;
|
||||
// hcrc.OutputReverse = CRC_REFOUT_TRUE;
|
||||
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON;
|
||||
|
||||
/**************************************CRC-32/BZIP2**************************************/
|
||||
// hcrc.Poly = 0x04C11DB7;
|
||||
// hcrc.Init = 0xFFFFFFFF;
|
||||
// hcrc.InputReverse = CRC_REFIN_FALSE;
|
||||
// hcrc.OutputReverse = CRC_REFOUT_FALSE;
|
||||
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON;
|
||||
|
||||
/*******************************************CRC-32C*******************************************/
|
||||
// hcrc.Poly = 0x1EDC6F41;
|
||||
// hcrc.Init = 0xFFFFFFFF;
|
||||
// hcrc.InputReverse = CRC_REFIN_TRUE;
|
||||
// hcrc.OutputReverse = CRC_REFOUT_TRUE;
|
||||
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON;
|
||||
|
||||
/*******************************************CRC-32D*******************************************/
|
||||
// hcrc.Poly = 0xA833982B;
|
||||
// hcrc.Init = 0xFFFFFFFF;
|
||||
// hcrc.InputReverse = CRC_REFIN_TRUE;
|
||||
// hcrc.OutputReverse = CRC_REFOUT_TRUE;
|
||||
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON;
|
||||
|
||||
/****************************************CRC-32/JAMCRC****************************************/
|
||||
// hcrc.Poly = 0x04C11DB7;
|
||||
// hcrc.Init = 0xFFFFFFFF;
|
||||
// hcrc.InputReverse = CRC_REFIN_TRUE;
|
||||
// hcrc.OutputReverse = CRC_REFOUT_TRUE;
|
||||
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF;
|
||||
|
||||
/****************************************CRC-32/MPEG-2****************************************/
|
||||
// hcrc.Poly = 0x04C11DB7;
|
||||
// hcrc.Init = 0xFFFFFFFF;
|
||||
// hcrc.InputReverse = CRC_REFIN_FALSE;
|
||||
// hcrc.OutputReverse = CRC_REFOUT_FALSE;
|
||||
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF;
|
||||
|
||||
/*****************************************CRC-32/POSIX*****************************************/
|
||||
// hcrc.Poly = 0x04C11DB7;
|
||||
// hcrc.Init = 0x00000000;
|
||||
// hcrc.InputReverse = CRC_REFIN_FALSE;
|
||||
// hcrc.OutputReverse = CRC_REFOUT_FALSE;
|
||||
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON;
|
||||
|
||||
/*******************************************CRC-32Q*******************************************/
|
||||
// hcrc.Poly = 0x814141AB;
|
||||
// hcrc.Init = 0x00000000;
|
||||
// hcrc.InputReverse = CRC_REFIN_FALSE;
|
||||
// hcrc.OutputReverse = CRC_REFOUT_FALSE;
|
||||
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF;
|
||||
|
||||
/*****************************************CRC-32/XFER*****************************************/
|
||||
// hcrc.Poly = 0x000000AF;
|
||||
// hcrc.Init = 0x00000000;
|
||||
// hcrc.InputReverse = CRC_REFIN_FALSE;
|
||||
// hcrc.OutputReverse = CRC_REFOUT_FALSE;
|
||||
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF;
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
#ifndef MIK32_HAL_CRYPTO
|
||||
#define MIK32_HAL_CRYPTO
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "crypto.h"
|
||||
#include "pad_config.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
|
||||
|
||||
/**
|
||||
* @name Длина вектора инициализации
|
||||
* @{
|
||||
*/
|
||||
#define IV_LENGTH_KUZNECHIK_CBC 4 /**< Количество слов вектора инициализации в режиме шифрования CBC (Кузнечик). */
|
||||
#define IV_LENGTH_MAGMA_CBC 4 /**< Количество слов вектора инициализации в режиме шифрования CBC (Магма). */
|
||||
#define IV_LENGTH_AES_CBC 2 /**< Количество слов вектора инициализации в режиме шифрования CBC (AES). */
|
||||
#define IV_LENGTH_KUZNECHIK_CTR 2 /**< Количество слов вектора инициализации в режиме шифрования CTR (Кузнечик). */
|
||||
#define IV_LENGTH_MAGMA_CTR 2 /**< Количество слов вектора инициализации в режиме шифрования CTR (Магма). */
|
||||
#define IV_LENGTH_AES_CTR 1 /**< Количество слов вектора инициализации в режиме шифрования CTR (AES). */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Длина ключа
|
||||
* @{
|
||||
*/
|
||||
#define CRYPTO_KEY_KUZNECHIK 8 /**< Длина ключа Кузнечик. */
|
||||
#define CRYPTO_KEY_MAGMA 8 /**< Длина ключа Магма. */
|
||||
#define CRYPTO_KEY_AES 4 /**< Длина ключа AES. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Длина блока
|
||||
* @{
|
||||
*/
|
||||
#define CRYPTO_BLOCK_KUZNECHIK 4 /**< Длина блока Кузнечик. */
|
||||
#define CRYPTO_BLOCK_MAGMA 2 /**< Длина блока Магма. */
|
||||
#define CRYPTO_BLOCK_AES 4 /**< Длина блока AES. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Алгоритм шифрования
|
||||
* @{
|
||||
*/
|
||||
#define CRYPTO_ALG_KUZNECHIK 0 /**< Алгоритм шифрования Кузнечик. */
|
||||
#define CRYPTO_ALG_MAGMA 1 /**< Алгоритм шифрования Магма. */
|
||||
#define CRYPTO_ALG_AES 2 /**< Алгоритм шифрования AES. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Режим шифрования
|
||||
* @{
|
||||
*/
|
||||
#define CRYPTO_CIPHER_MODE_ECB 0 /**< Режим шифрования ECB (Electronic Codebook). */
|
||||
#define CRYPTO_CIPHER_MODE_CBC 1 /**< Режим шифрования CBC (Cipher Block Chaining). */
|
||||
#define CRYPTO_CIPHER_MODE_CTR 2 /**< Режим шифрования CTR (Counter mode). */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Перестановка слова
|
||||
* @{
|
||||
*/
|
||||
#define CRYPTO_SWAP_MODE_NONE 0 /**< Нет перестановки. */
|
||||
#define CRYPTO_SWAP_MODE_HALFWORD 1 /**< Перестановка по полуслову. */
|
||||
#define CRYPTO_SWAP_MODE_BYTE 2 /**< Перестановки по байтам. */
|
||||
#define CRYPTO_SWAP_MODE_BIT 3 /**< Перестановка по битам. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Порядок загрузки/выгрузки
|
||||
* @{
|
||||
*/
|
||||
#define CRYPTO_ORDER_MODE_LSW 0 /**< Порядка загрузки/выгрузки от младшего слова к старшему. */
|
||||
#define CRYPTO_ORDER_MODE_MSW 1 /**< Порядка загрузки/выгрузки от старшего слова к младшему. */
|
||||
/** @} */
|
||||
|
||||
|
||||
#define MAXIMUM_KEY_LENGTH 8 /**< Максимальная длина ключа. */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Настройки Crypto.
|
||||
*
|
||||
*/
|
||||
typedef struct __Crypto_HandleTypeDef
|
||||
{
|
||||
CRYPTO_TypeDef *Instance; /**< Базовый адрес регистров Crypto */
|
||||
|
||||
uint8_t Algorithm; /**< Выбор алгоритма шифрования. Этот параметр должен быть одним из значений: #CRYPTO_ALG_KUZNECHIK, #CRYPTO_ALG_MAGMA, #CRYPTO_ALG_AES.*/
|
||||
|
||||
uint8_t CipherMode; /**< Выбор режима шифрования. Этот параметр должен быть одним из значений: #CRYPTO_CIPHER_MODE_ECB, #CRYPTO_CIPHER_MODE_CBC, #CRYPTO_CIPHER_MODE_CTR. */
|
||||
|
||||
uint8_t SwapMode; /**< Перестановка слова. Этот параметр должен быть одним из значений: #CRYPTO_SWAP_MODE_NONE, #CRYPTO_SWAP_MODE_HALFWORD, #CRYPTO_SWAP_MODE_BYTE, #CRYPTO_SWAP_MODE_BIT. */
|
||||
|
||||
uint8_t OrderMode; /**< Выбор порядка загрузки/выгрузки. Этот параметр должен быть одним из значений: #CRYPTO_ORDER_MODE_LSW, #CRYPTO_ORDER_MODE_MSW. */
|
||||
|
||||
} Crypto_HandleTypeDef;
|
||||
|
||||
|
||||
void HAL_CRYPTO_MspInit(Crypto_HandleTypeDef* hcrypto);
|
||||
void HAL_Crypto_CounterReset(Crypto_HandleTypeDef *hcrypto);
|
||||
void HAL_Crypto_WaitReady(Crypto_HandleTypeDef *hcrypto);
|
||||
void HAL_Crypto_SetAlgorithm(Crypto_HandleTypeDef *hcrypto, uint8_t Algorithm);
|
||||
void HAL_Crypto_SetCipherMode(Crypto_HandleTypeDef *hcrypto, uint8_t CipherMode);
|
||||
void HAL_Crypto_SetSwapMode(Crypto_HandleTypeDef *hcrypto, uint8_t SwapMode);
|
||||
void HAL_Crypto_SetOrderMode(Crypto_HandleTypeDef *hcrypto, uint8_t OrderMode);
|
||||
void HAL_Crypto_SetIV(Crypto_HandleTypeDef *hcrypto, uint32_t InitVector[], uint32_t IvLength);
|
||||
void HAL_Crypto_SetKey(Crypto_HandleTypeDef *hcrypto, uint32_t crypto_key[]);
|
||||
void HAL_Crypto_Init(Crypto_HandleTypeDef *hcrypto);
|
||||
void HAL_Crypto_Encode(Crypto_HandleTypeDef *hcrypto, uint32_t plain_text[], uint32_t cipher_text[], uint32_t text_length);
|
||||
void HAL_Crypto_Decode(Crypto_HandleTypeDef *hcrypto, uint32_t cipher_text[], uint32_t plain_text[], uint32_t text_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,251 @@
|
||||
#ifndef MIK32_HAL_DAC
|
||||
#define MIK32_HAL_DAC
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "mik32_hal_gpio.h"
|
||||
#include "analog_reg.h"
|
||||
#include "pad_config.h"
|
||||
#include "stdbool.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
|
||||
/* Title: Макросы */
|
||||
|
||||
/*
|
||||
* Defines: Каналы ЦАП
|
||||
*
|
||||
* HAL_DAC1 - Канал ЦАП1 (PORT_1_12)
|
||||
* HAL_DAC2 - Канал ЦАП2 (PORT_1_13)
|
||||
*
|
||||
*/
|
||||
#define HAL_DAC1 &(ANALOG_REG->DAC0) /* Канал DAC1 - PORT_1_12 */
|
||||
#define HAL_DAC2 &(ANALOG_REG->DAC1) /* Канал DAC2 - PORT_1_13 */
|
||||
|
||||
/*
|
||||
* Defines: Выбор ИОН
|
||||
*
|
||||
* Выбор источника опорного напряжения.
|
||||
*
|
||||
* DAC_EXTREF_OFF - Встроенный источник опорного напряжения 1,2 В
|
||||
* DAC_EXTREF_ON - Внешний источник опорного напряжения
|
||||
*
|
||||
*/
|
||||
#define DAC_EXTREF_OFF 0 /* Встроенный источник опорного напряжения 1,2 В */
|
||||
#define DAC_EXTREF_ON 1 /* Внешний источник опорного напряжения */
|
||||
|
||||
/*
|
||||
* Defines: Выбор внешнего ИОН
|
||||
*
|
||||
* Выбор внешнего источника опорного напряжения по отношению к встроенному в АЦП ИОН.
|
||||
*
|
||||
* DAC_EXTCLB_CLBREF - Настраиваемый ОИН
|
||||
* DAC_EXTCLB_DACREF - Внешний вывод
|
||||
*
|
||||
*/
|
||||
#define DAC_EXTCLB_CLBREF 0 /* Настраиваемый ОИН */
|
||||
#define DAC_EXTCLB_DACREF 1 /* Внешний вывод */
|
||||
|
||||
/* Выводы ЦАП */
|
||||
/*
|
||||
* Defines: Входы АЦП
|
||||
*
|
||||
* Номера выводов каналов ЦАП и DAC_REF
|
||||
*
|
||||
* DAC_PORT_AS_FUNC3 - Четвертая функция вывода (аналоговый сигнал)
|
||||
* DAC1_PORT_1_12 - ЦАП1 - PORT_1_12
|
||||
* DAC2_PORT_1_13 - ЦАП2 - PORT_1_13
|
||||
* DAC_REF_PORT_1_11 - Внешний опорный сигнал DAC_REF - PORT_1_11
|
||||
*
|
||||
*/
|
||||
#define DAC_PORT_AS_FUNC3 0b11 /* Четвертая функция вывода (аналоговый сигнал) */
|
||||
#define DAC1_PORT_1_12 12 /* DAC1 - PORT_1_12 */
|
||||
#define DAC2_PORT_1_13 13 /* DAC2 - PORT_1_13 */
|
||||
#define DAC_REF_PORT_1_11 11 /* Внешний опорный сигнал - PORT_1_11 */
|
||||
|
||||
/* Title: Структуры */
|
||||
|
||||
/*
|
||||
* Struct: DAC_InitTypeDef
|
||||
*
|
||||
* Настройки ЦАП при инициализации
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* Variable: EXTRef
|
||||
* Выбор источника опорного напряжения
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <DAC_EXTREF_OFF>;
|
||||
* - <DAC_EXTREF_ON>.
|
||||
*
|
||||
*/
|
||||
uint8_t EXTRef;
|
||||
|
||||
/*
|
||||
* Variable: EXTClb
|
||||
* Выбор внешнего источника опорного напряжения
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <DAC_EXTCLB_CLBREF>;
|
||||
* - <DAC_EXTCLB_DACREF>.
|
||||
*
|
||||
*/
|
||||
uint8_t EXTClb;
|
||||
|
||||
/*
|
||||
* Variable: DIV
|
||||
* Значение делителя тактового сигнала.
|
||||
*
|
||||
* Частота определяется как F_ЦАП = F_IN/(Div+1).
|
||||
*
|
||||
* Значением может быть 8-битное число в пределах от 0 до 255
|
||||
*
|
||||
*/
|
||||
uint8_t DIV;
|
||||
|
||||
} DAC_InitTypeDef;
|
||||
|
||||
/*
|
||||
* Struct: DAC_HandleTypeDef
|
||||
*
|
||||
* Настройки ЦАП
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* Variable: Instance
|
||||
* Базоый адрес регистров ANALOG_REG.
|
||||
*
|
||||
*/
|
||||
ANALOG_REG_TypeDef *Instance;
|
||||
|
||||
/*
|
||||
* Variable: Instance_dac
|
||||
* Базоый адрес регистров DAC
|
||||
*
|
||||
*/
|
||||
volatile DAC_TypeDef *Instance_dac;
|
||||
|
||||
/*
|
||||
* Variable: Init
|
||||
* Настройки ЦАП при инициализации
|
||||
*
|
||||
*/
|
||||
DAC_InitTypeDef Init;
|
||||
|
||||
} DAC_HandleTypeDef;
|
||||
|
||||
/* Title: Функции */
|
||||
|
||||
void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac);
|
||||
void HAL_DAC_CLBEnable(DAC_HandleTypeDef *hdac);
|
||||
void HAL_DAC_CLBDisable(DAC_HandleTypeDef *hdac);
|
||||
void HAL_DAC_VCLBSet(DAC_HandleTypeDef *hdac, uint8_t v_coef);
|
||||
void HAL_DAC_ICLBSet(DAC_HandleTypeDef *hdac, uint8_t i_coef);
|
||||
|
||||
/*
|
||||
* Function: HAL_DAC_SetDiv
|
||||
* Установить значение делителя тактового сигнала ЦАП.
|
||||
*
|
||||
* Частота определяется как F_ЦАП = F_IN/(Div+1).
|
||||
*
|
||||
* Значением может быть 8-битное число в пределах от 0 до 255
|
||||
*
|
||||
* Parameters:
|
||||
* hdac - Указатель на структуру с настройками ЦАП.
|
||||
* div - Делитель частоты.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_DAC_SetDiv(DAC_HandleTypeDef *hdac, uint8_t div);
|
||||
|
||||
/*
|
||||
* Function: HAL_DAC_ResetEnable
|
||||
* Установить бит Rn, управление сбросом ЦАП, в 1.
|
||||
*
|
||||
* Parameters:
|
||||
* hdac - Указатель на структуру с настройками ЦАП.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_DAC_ResetEnable(DAC_HandleTypeDef *hdac);
|
||||
|
||||
/*
|
||||
* Function: HAL_DAC_ResetDisable
|
||||
* Сбросить бит Rn, управление сбросом ЦАП, в 0.
|
||||
*
|
||||
* Parameters:
|
||||
* hdac - Указатель на структуру с настройками ЦАП.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_DAC_ResetDisable(DAC_HandleTypeDef *hdac);
|
||||
|
||||
/*
|
||||
* Function: HAL_DAC_Disable
|
||||
* Выключть питание ЦАП
|
||||
*
|
||||
* Parameters:
|
||||
* hdac - Указатель на структуру с настройками ЦАП.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_DAC_Disable(DAC_HandleTypeDef *hdac);
|
||||
|
||||
/*
|
||||
* Function: HAL_ADC_Enable
|
||||
* Включть питание ЦАП
|
||||
*
|
||||
* Parameters:
|
||||
* hdac - Указатель на структуру с настройками ЦАП.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_DAC_Enable(DAC_HandleTypeDef *hdac);
|
||||
|
||||
/*
|
||||
* Function: HAL_DAC_Init
|
||||
* Инициализировать ЦАП в соответсвии с настройками в hdac.
|
||||
*
|
||||
* Parameters:
|
||||
* hdac - Указатель на структуру с настройками ЦАП.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void HAL_DAC_Init(DAC_HandleTypeDef *hdac);
|
||||
|
||||
/*
|
||||
* Function: HAL_DAC_SetValue
|
||||
* Задать входные данные для преобразования ЦАП.
|
||||
*
|
||||
* Входные данные могут быть в пределах от 0 до 4 095.
|
||||
*
|
||||
* Parameters:
|
||||
* hdac - Указатель на структуру с настройками ЦАП.
|
||||
* DAC_Value - Входные данные для преобразования ЦАП.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*
|
||||
*/
|
||||
void HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint16_t DAC_Value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef MIK32_HAL_DEF
|
||||
#define MIK32_HAL_DEF
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define HAL_PIN_MASK 0xFFFF
|
||||
#define HAL_PORT_S 16
|
||||
|
||||
typedef enum HAL_StatusTypeDef
|
||||
{
|
||||
HAL_OK = 0x00U,
|
||||
HAL_ERROR = 0x01U,
|
||||
HAL_BUSY = 0x02U,
|
||||
HAL_TIMEOUT = 0x03U
|
||||
} HAL_StatusTypeDef;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,210 @@
|
||||
#ifndef MIK32_HAL_DMA
|
||||
#define MIK32_HAL_DMA
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "mik32_hal_gpio.h"
|
||||
#include "stddef.h"
|
||||
#include "dma_config.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
#include "mik32_hal_def.h"
|
||||
|
||||
|
||||
|
||||
#define DMA_TIMEOUT_DEFAULT 1000000 /**< Стандартная задержка для ожидания timeout. */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Разрешить или запретить читать текущий статус канала.
|
||||
*
|
||||
* При разрешении чтения текущего статуса канала регистры CHx_DST, CHx_SRC, CHx_LEN возвращают текущие значения,
|
||||
* а в CHx_CFG при считывании меняются битовые поля.
|
||||
*/
|
||||
typedef enum __HAL_DMA_CurrentValueTypeDef
|
||||
{
|
||||
DMA_CURRENT_VALUE_ENABLE = 0, /**< Текущие значения. */
|
||||
DMA_CURRENT_VALUE_DISABLE = 1 /**< Значения при настройке. */
|
||||
} HAL_DMA_CurrentValueTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Номер канала.
|
||||
*
|
||||
* При совпадении приоритетов каналов меньший номер канала является более приоритетным.
|
||||
*/
|
||||
typedef enum __HAL_DMA_ChannelIndexTypeDef
|
||||
{
|
||||
DMA_CHANNEL_0 = 0,
|
||||
DMA_CHANNEL_1 = 1,
|
||||
DMA_CHANNEL_2 = 2,
|
||||
DMA_CHANNEL_3 = 3
|
||||
} HAL_DMA_ChannelIndexTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Приоритет канала.
|
||||
*
|
||||
* Арбитраж выбора канала происходит за два такта удержания линии запроса.
|
||||
* Если одновременно поступают несколько запросов ПДП, то схема арбитража выбирает наиболее
|
||||
* приоритетную линию запроса в соответствии с программной установкой каждого из каналов.
|
||||
* При совпадении приоритетов каналов меньший номер канала является более приоритетным.
|
||||
*/
|
||||
typedef enum __HAL_DMA_ChannelPriorityTypeDef
|
||||
{
|
||||
DMA_CHANNEL_PRIORITY_LOW = 0b00, /**< Низкий приоритет. */
|
||||
DMA_CHANNEL_PRIORITY_MEDIUM = 0b01, /**< Средний приоритет. */
|
||||
DMA_CHANNEL_PRIORITY_HIGH = 0b10, /**< Высокий приоритет. */
|
||||
DMA_CHANNEL_PRIORITY_VERY_HIGH = 0b11 /**< Высший приоритет. */
|
||||
} HAL_DMA_ChannelPriorityTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Режим адресации источника или назначения.
|
||||
*/
|
||||
typedef enum __HAL_DMA_ChannelModeTypeDef
|
||||
{
|
||||
DMA_CHANNEL_MODE_PERIPHERY = 0, /**< Режим адреса - периферия. */
|
||||
DMA_CHANNEL_MODE_MEMORY = 1 /**< Режим адреса - память. */
|
||||
} HAL_DMA_ChannelModeTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Наличие инкремента адреса источника или назначения.
|
||||
*/
|
||||
typedef enum __HAL_DMA_ChannelIncTypeDef
|
||||
{
|
||||
DMA_CHANNEL_INC_DISABLE = 0, /* Адрес не инкрементируется. */
|
||||
DMA_CHANNEL_INC_ENABLE = 1 /* Адрес инкрементируется. */
|
||||
} HAL_DMA_ChannelIncTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Разрядность адреса источника или назначения.
|
||||
* @warning Разрядность должна быть кратна количеству байт пересылки (LEN).
|
||||
*/
|
||||
typedef enum __HAL_DMA_ChannelSizeTypeDef
|
||||
{
|
||||
DMA_CHANNEL_SIZE_BYTE = 0, /**< Байт. */
|
||||
DMA_CHANNEL_SIZE_HALFWORD = 1, /**< Полуслово. */
|
||||
DMA_CHANNEL_SIZE_WORD = 2 /**< Слово. */
|
||||
} HAL_DMA_ChannelSizeTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Периферийные линии источника или назначения.
|
||||
*/
|
||||
typedef enum __HAL_DMA_ChannelRequestTypeDef
|
||||
{
|
||||
DMA_CHANNEL_USART_0_REQUEST = 0,
|
||||
DMA_CHANNEL_USART_1_REQUEST = 1,
|
||||
DMA_CHANNEL_CRYPTO_REQUEST = 2,
|
||||
DMA_CHANNEL_SPI_0_REQUEST = 3,
|
||||
DMA_CHANNEL_SPI_1_REQUEST = 4,
|
||||
DMA_CHANNEL_I2C_0_REQUEST = 5,
|
||||
DMA_CHANNEL_I2C_1_REQUEST = 6,
|
||||
DMA_CHANNEL_SPIFI_REQUEST = 7,
|
||||
DMA_CHANNEL_TIMER32_1_REQUEST = 8,
|
||||
DMA_CHANNEL_TIMER32_2_REQUEST = 9,
|
||||
|
||||
#ifdef MIK32V0
|
||||
DMA_CHANNEL_TIMER32_0_REQUEST = 10
|
||||
#else // MIK32V2
|
||||
DMA_CHANNEL_DAC_0_REQUEST = 10,
|
||||
DMA_CHANNEL_DAC_1_REQUEST = 11,
|
||||
DMA_CHANNEL_TIMER32_0_REQUEST = 12
|
||||
#endif // MIK32V0
|
||||
|
||||
} HAL_DMA_ChannelRequestTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Разрешение работы логики с откликом для адресата источника и назначения.
|
||||
*
|
||||
* Используется при работе с Timer32. При работе логики с откликом пакет данных передается
|
||||
* каждый раз при переполнении таймера. Если работа с откликом запрещена, то все пакеты передаются сразу после
|
||||
* первого переполнения таймера.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
DMA_CHANNEL_ACK_DISABLE = 0, /**< Работа логики с откликом запрещена. */
|
||||
DMA_CHANNEL_ACK_ENABLE = 1 /**< Работа логики с откликом разрешена. */
|
||||
} HAL_DMA_ChannelACKTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Разрешение прерываний.
|
||||
*
|
||||
* Используется при настройке глобального прерывания DMA, прерывания DMA при возникновении ошибки и
|
||||
* локального прерывания при завершении работы канала.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
DMA_IRQ_DISABLE = 0, /* Прерывание запрещено. */
|
||||
DMA_IRQ_ENABLE = 1 /* Прерывание разрешено. */
|
||||
} HAL_DMA_IRQTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Настройки канала DMA.
|
||||
*/
|
||||
typedef struct __DMA_ChannelInitHandleTypeDef
|
||||
{
|
||||
HAL_DMA_ChannelIndexTypeDef Channel; /**< Номер канала. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelIndexTypeDef. */
|
||||
HAL_DMA_ChannelPriorityTypeDef Priority; /**< Приоритет канала. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelPriorityTypeDef. */
|
||||
|
||||
HAL_DMA_ChannelModeTypeDef ReadMode; /**< Режим адресации источника. Данный параметр может иметь значение #DMA_CHANNEL_MODE_PERIPHERY или #DMA_CHANNEL_MODE_MEMORY. */
|
||||
HAL_DMA_ChannelIncTypeDef ReadInc; /**< Наличие инкремента адреса источника. Данный параметр может иметь значение #DMA_CHANNEL_INC_DISABLE или #DMA_CHANNEL_INC_ENABLE. */
|
||||
HAL_DMA_ChannelSizeTypeDef ReadSize; /**< Разрядность адреса источника. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelSizeTypeDef. @warning Разрядность должна быть кратна количеству байт пересылки (LEN + 1). */
|
||||
HAL_DMA_ChannelACKTypeDef ReadAck; /**< Разрешение работы логики с откликом для адресата источника. Данный параметр может иметь значение #DMA_CHANNEL_ACK_DISABLE или #DMA_CHANNEL_ACK_ENABLE */
|
||||
uint32_t ReadBurstSize; /**< Количество байт в пакете. Определяется как 2^{ReadBurstSize}. @warning Количество байт в пакете должно быть кратно ReadSize. */
|
||||
HAL_DMA_ChannelRequestTypeDef ReadRequest; /**< Выбор периферийной линии источника при ReadMode = DMA_CHANNEL_MODE_PERIPHERY. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelRequestTypeDef. */
|
||||
|
||||
HAL_DMA_ChannelModeTypeDef WriteMode; /**< Режим адресации назначения. Данный параметр может иметь значение #DMA_CHANNEL_MODE_PERIPHERY или #DMA_CHANNEL_MODE_MEMORY. */
|
||||
HAL_DMA_ChannelIncTypeDef WriteInc; /**< Наличие инкремента адреса назначения. Данный параметр может иметь значение #DMA_CHANNEL_INC_DISABLE или #DMA_CHANNEL_INC_ENABLE. */
|
||||
HAL_DMA_ChannelSizeTypeDef WriteSize; /**< Разрядность адреса назначения. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelSizeTypeDef. @warning Разрядность должна быть кратна количеству байт пересылки (LEN + 1). */
|
||||
HAL_DMA_ChannelACKTypeDef WriteAck; /**< Разрешение работы логики с откликом для адресата назначения. Данный параметр может иметь значение #DMA_CHANNEL_ACK_DISABLE или #DMA_CHANNEL_ACK_ENABLE */
|
||||
uint32_t WriteBurstSize; /**< Количество байт в пакете. Определяется как 2^{WriteBurstSize}. @warning Количество байт в пакете должно быть кратно WriteSize. */
|
||||
HAL_DMA_ChannelRequestTypeDef WriteRequest; /**< Выбор периферийной линии назначения при ReadMode = DMA_CHANNEL_MODE_PERIPHERY. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelRequestTypeDef. */
|
||||
|
||||
} DMA_ChannelInitHandleTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Структура для инициализации DMA.
|
||||
*/
|
||||
typedef struct __DMA_InitTypeDef
|
||||
{
|
||||
DMA_CONFIG_TypeDef *Instance; /**< Базовый адрес регистров DMA. Этот параметр может иметь значение #DMA_CONFIG. */
|
||||
HAL_DMA_CurrentValueTypeDef CurrentValue; /**< Разрешить или запретить читать текущий статус канала. При значении #DMA_CURRENT_VALUE_ENABLE регистры CHx_DST, CHx_SRC, CHx_LEN возвращают текущие значения, а в CHx_CFG при считывании меняются битовые поля. При значении #DMA_CURRENT_VALUE_DISABLE регистры возвращают значения при настройке. */
|
||||
} DMA_InitTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Структура для инициализации канала DMA.
|
||||
*/
|
||||
typedef struct __DMA_ChannelHandleTypeDef
|
||||
{
|
||||
DMA_InitTypeDef *dma; /**< Указатель на структуру для инициализации DMA. */
|
||||
DMA_ChannelInitHandleTypeDef ChannelInit; /**< Настройки канала DMA. */
|
||||
} DMA_ChannelHandleTypeDef;
|
||||
|
||||
|
||||
void HAL_DMA_MspInit(DMA_InitTypeDef* hdma);
|
||||
void HAL_DMA_SetChannel(DMA_ChannelHandleTypeDef *hdma_channel, HAL_DMA_ChannelIndexTypeDef ChannelIndex);
|
||||
void HAL_DMA_ClearLocalIrq(DMA_InitTypeDef *hdma);
|
||||
void HAL_DMA_ClearGlobalIrq(DMA_InitTypeDef *hdma);
|
||||
void HAL_DMA_ClearErrorIrq(DMA_InitTypeDef *hdma);
|
||||
void HAL_DMA_ClearIrq(DMA_InitTypeDef *hdma);
|
||||
void HAL_DMA_SetCurrentValue(DMA_InitTypeDef *hdma, HAL_DMA_CurrentValueTypeDef CurrentValue);
|
||||
int HAL_DMA_GetChannelCurrentValue(DMA_InitTypeDef *hdma);
|
||||
void HAL_DMA_GlobalIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission);
|
||||
void HAL_DMA_ErrorIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission);
|
||||
void HAL_DMA_LocalIRQEnable(DMA_ChannelHandleTypeDef* hdma_channel, HAL_DMA_IRQTypeDef Permission);
|
||||
HAL_StatusTypeDef HAL_DMA_Init(DMA_InitTypeDef *hdma);
|
||||
HAL_StatusTypeDef HAL_DMA_Wait(DMA_ChannelHandleTypeDef* hdma_channel, uint32_t Timeout);
|
||||
int HAL_DMA_GetChannelReadyStatus(DMA_ChannelHandleTypeDef* hdma_channel);
|
||||
int HAL_DMA_GetChannelIrq(DMA_ChannelHandleTypeDef* hdma_channel);
|
||||
int HAL_DMA_GetBusError(DMA_ChannelHandleTypeDef* hdma_channel);
|
||||
void HAL_DMA_ChannelDisable(DMA_ChannelHandleTypeDef *hdma_channel);
|
||||
void HAL_DMA_ChannelEnable(DMA_ChannelHandleTypeDef *hdma_channel);
|
||||
void HAL_DMA_Start(DMA_ChannelHandleTypeDef *hdma_channel, void* Source, void* Destination, uint32_t Len);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
#ifndef MIK32_HAL_EEPROM_H_INCLUDED
|
||||
#define MIK32_HAL_EEPROM_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_def.h"
|
||||
#include <mcu32_memory_map.h>
|
||||
#include <eeprom.h>
|
||||
#include <power_manager.h>
|
||||
|
||||
#ifndef HAL_EEPROM_TIMEOUT
|
||||
#define HAL_EEPROM_TIMEOUT 10000
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HAL_EEPROM_OP_READ = 0b00,
|
||||
HAL_EEPROM_OP_CLEAR = 0b01,
|
||||
HAL_EEPROM_OP_PROGRAM = 0b10,
|
||||
} HAL_EEPROM_OperationTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HAL_EEPROM_WRITE_SINGLE = 0b00,
|
||||
HAL_EEPROM_WRITE_EVEN = 0b01,
|
||||
HAL_EEPROM_WRITE_ODD = 0b10,
|
||||
HAL_EEPROM_WRITE_ALL = 0b11,
|
||||
} HAL_EEPROM_WriteBehaviourTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HAL_EEPROM_MODE_TWO_STAGE = 0b00,
|
||||
HAL_EEPROM_MODE_THREE_STAGE = 0b01,
|
||||
} HAL_EEPROM_ModeTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HAL_EEPROM_ECC_ENABLE = 0b00,
|
||||
HAL_EEPROM_ECC_DISABLE = 0b01,
|
||||
} HAL_EEPROM_ErrorCorrectionTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HAL_EEPROM_SERR_DISABLE = 0b00,
|
||||
HAL_EEPROM_SERR_ENABLE = 0b01,
|
||||
} HAL_EEPROM_EnableInterruptTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t N_LD;
|
||||
uint8_t N_R_1;
|
||||
uint8_t N_R_2;
|
||||
uint32_t N_EP_1;
|
||||
uint16_t N_EP_2;
|
||||
} HAL_EEPROM_TimingsTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
EEPROM_REGS_TypeDef *Instance;
|
||||
HAL_EEPROM_TimingsTypeDef Timings;
|
||||
HAL_EEPROM_ModeTypeDef Mode;
|
||||
HAL_EEPROM_ErrorCorrectionTypeDef ErrorCorrection;
|
||||
HAL_EEPROM_EnableInterruptTypeDef EnableInterrupt;
|
||||
} HAL_EEPROM_HandleTypeDef;
|
||||
|
||||
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_EEPROM_WaitBusy(HAL_EEPROM_HandleTypeDef *eeprom, uint32_t timeout)
|
||||
{
|
||||
while (timeout)
|
||||
{
|
||||
timeout--;
|
||||
if (!(eeprom->Instance->EESTA & EEPROM_EESTA_BSY_M))
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
#define HAL_EEPROM_INTERRUPT_GET(eeprom) ((*eeprom).Instance->EESTA & EEPROM_EESTA_SERR_M)
|
||||
#define HAL_EEPROM_INTERRUPT_FLAG_CLEAR(eeprom) (*eeprom).Instance->EESTA &= ~EEPROM_EESTA_SERR_M;
|
||||
|
||||
HAL_StatusTypeDef HAL_EEPROM_Init(HAL_EEPROM_HandleTypeDef *eeprom);
|
||||
|
||||
HAL_StatusTypeDef HAL_EEPROM_Erase(
|
||||
HAL_EEPROM_HandleTypeDef *eeprom,
|
||||
uint16_t address,
|
||||
uint8_t erasedWordsCount,
|
||||
HAL_EEPROM_WriteBehaviourTypeDef erasedPages,
|
||||
uint32_t timeout);
|
||||
|
||||
HAL_StatusTypeDef HAL_EEPROM_Write(
|
||||
HAL_EEPROM_HandleTypeDef *eeprom,
|
||||
uint16_t address,
|
||||
uint32_t *data,
|
||||
uint8_t length,
|
||||
HAL_EEPROM_WriteBehaviourTypeDef writedPages,
|
||||
uint32_t timeout);
|
||||
|
||||
HAL_StatusTypeDef HAL_EEPROM_Read(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint32_t *data, uint8_t length, uint32_t timeout);
|
||||
|
||||
void HAL_EEPROM_SetMode(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ModeTypeDef mode);
|
||||
|
||||
void HAL_EEPROM_SetErrorCorrection(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ErrorCorrectionTypeDef errorCorrection);
|
||||
|
||||
void HAL_EEPROM_SetInterrupt(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_EnableInterruptTypeDef enableInterrupt);
|
||||
|
||||
void HAL_EEPROM_CalculateTimings(HAL_EEPROM_HandleTypeDef *eeprom, int32_t frequency);
|
||||
|
||||
HAL_StatusTypeDef HAL_EEPROM_GetECC(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint8_t *buf_value_ecc, uint32_t timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MIK32_HAL_EEPROM_H_INCLUDED
|
||||
@@ -0,0 +1,391 @@
|
||||
#ifndef MIK32_HAL_GPIO_NEW
|
||||
#define MIK32_HAL_GPIO_NEW
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_def.h"
|
||||
#include "pad_config.h"
|
||||
#include "gpio.h"
|
||||
#include "gpio_irq.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
#include "mik32_hal_pcc.h"
|
||||
|
||||
#define GPIO_MODE_BIT_LEVEL_S 0 /**< Позиция бита для режима LEVEL_SET (тип прерывания по уровню низкий/высокий или по событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */
|
||||
#define GPIO_MODE_BIT_EDGE_S 1 /**< Позиция бита для режима EDGE (тип прерывания уровень или событие) в перечислении @ref HAL_GPIO_InterruptMode. */
|
||||
#define GPIO_MODE_BIT_ANYEDGE_S 2 /**< Позиция бита для режима ANYEDGE (режим прерывания по любому событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */
|
||||
#define GPIO_MODE_BIT_LEVEL_M (1 << GPIO_MODE_BIT_LEVEL_S) /**< Маска для режима LEVEL_SET (тип прерывания по уровню низкий/высокий или по событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */
|
||||
#define GPIO_MODE_BIT_EDGE_M (1 << GPIO_MODE_BIT_EDGE_S) /**< Маска для режима EDGE (тип прерывания уровень или событие) в перечислении @ref HAL_GPIO_InterruptMode. */
|
||||
#define GPIO_MODE_BIT_ANYEDGE_M (1 << GPIO_MODE_BIT_ANYEDGE_S) /**< Маска для режима ANYEDGE (режим прерывания по любому событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */
|
||||
#define GPIO_IRQ_LINE_S 4 /**< Позиция номера канала в перечислении @ref HAL_GPIO_Line @ref и @ref HAL_GPIO_Line_Config. */
|
||||
|
||||
#define __LOW GPIO_PIN_LOW /**< Псевдоним @ref GPIO_PIN_LOW. Низкий выходной уровень GPIO. */
|
||||
#define __HIGH GPIO_PIN_HIGH /**< Псевдоним @ref GPIO_PIN_HIGH. Высокий выходной уровень GPIO. */
|
||||
#define __INPUT HAL_GPIO_MODE_GPIO_INPUT /**< Псевдоним @ref HAL_GPIO_MODE_GPIO_INPUT. Режим вывода - GPIO. Вход. */
|
||||
#define __OUTPUT HAL_GPIO_MODE_GPIO_OUTPUT /**< Псевдоним @ref HAL_GPIO_MODE_GPIO_OUTPUT. Режим вывода - GPIO. Выход. */
|
||||
#define __PULL_NONE HAL_GPIO_PULL_NONE /**< Псевдоним @ref HAL_GPIO_PULL_NONE. Подтяжка не подключаются. */
|
||||
#define __PULL_UP HAL_GPIO_PULL_UP /**< Псевдоним @ref HAL_GPIO_PULL_UP. Подтяжка к питанию. */
|
||||
#define __PULL_DOWN HAL_GPIO_PULL_DOWN /**< Псевдоним @ref HAL_GPIO_PULL_DOWN. Подтяжка к земле. */
|
||||
#define __DS_2MA HAL_GPIO_DS_2MA /**< Псевдоним @ref HAL_GPIO_DS_2MA. Режим драйвера 2мА. */
|
||||
#define __DS_4MA HAL_GPIO_DS_4MA /**< Псевдоним @ref HAL_GPIO_DS_4MA. Режим драйвера 4мА. */
|
||||
#define __DS_8MA HAL_GPIO_DS_8MA /**< Псевдоним @ref HAL_GPIO_DS_8MA. Режим драйвера 8мА. */
|
||||
|
||||
/**
|
||||
* @brief Маска выводов.
|
||||
*/
|
||||
typedef enum __HAL_PinsTypeDef
|
||||
{
|
||||
GPIO_PIN_0 = (1 << 0), /**< Выбран пин 0. */
|
||||
GPIO_PIN_1 = (1 << 1), /**< Выбран пин 1. */
|
||||
GPIO_PIN_2 = (1 << 2), /**< Выбран пин 2. */
|
||||
GPIO_PIN_3 = (1 << 3), /**< Выбран пин 3. */
|
||||
GPIO_PIN_4 = (1 << 4), /**< Выбран пин 4. */
|
||||
GPIO_PIN_5 = (1 << 5), /**< Выбран пин 5. */
|
||||
GPIO_PIN_6 = (1 << 6), /**< Выбран пин 6. */
|
||||
GPIO_PIN_7 = (1 << 7), /**< Выбран пин 7. */
|
||||
GPIO_PIN_8 = (1 << 8), /**< Выбран пин 8. */
|
||||
GPIO_PIN_9 = (1 << 9), /**< Выбран пин 9. */
|
||||
GPIO_PIN_10 = (1 << 10), /**< Выбран пин 10. */
|
||||
GPIO_PIN_11 = (1 << 11), /**< Выбран пин 11. */
|
||||
GPIO_PIN_12 = (1 << 12), /**< Выбран пин 12. */
|
||||
GPIO_PIN_13 = (1 << 13), /**< Выбран пин 13. */
|
||||
GPIO_PIN_14 = (1 << 14), /**< Выбран пин 14. */
|
||||
GPIO_PIN_15 = (1 << 15), /**< Выбран пин 15. */
|
||||
GPIO_PIN_ALL = 0xFFFF /**< Выбраны все пины порта. */
|
||||
|
||||
} HAL_PinsTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Перечисление состояний выходного уровня GPIO.
|
||||
*/
|
||||
typedef enum __GPIO_PinState
|
||||
{
|
||||
GPIO_PIN_LOW = 0, /**< Низкий выходной уровень GPIO. */
|
||||
GPIO_PIN_HIGH = 1 /**< Высокий выходной уровень GPIO.*/
|
||||
} GPIO_PinState;
|
||||
|
||||
/**
|
||||
* @brief Перечисление режимов вывода.
|
||||
*/
|
||||
typedef enum __HAL_GPIO_ModeTypeDef
|
||||
{
|
||||
#ifdef MIK32V0
|
||||
HAL_GPIO_MODE_GPIO_INPUT = 0b101, /**< Режим вывода - GPIO. Вход. */
|
||||
HAL_GPIO_MODE_GPIO_OUTPUT = 0b001, /**< Режим вывода - GPIO. Выход. */
|
||||
HAL_GPIO_MODE_SERIAL = 0b00, /**< Режим вывода - последовательный интерфейс. */
|
||||
#else // MIK32V2
|
||||
HAL_GPIO_MODE_GPIO_INPUT = 0b100, /**< Режим вывода - GPIO. Вход. */
|
||||
HAL_GPIO_MODE_GPIO_OUTPUT = 0b000, /**< Режим вывода - GPIO. Выход. */
|
||||
HAL_GPIO_MODE_SERIAL = 0b01, /**< Режим вывода - последовательный интерфейс. */
|
||||
#endif // MIK32V0
|
||||
|
||||
HAL_GPIO_MODE_TIMER_SERIAL = 0b10, /**< Режим вывода - последовательный интерфейс или таймер. */
|
||||
HAL_GPIO_MODE_ANALOG = 0b11 /**< Аналоговый сигнал. */
|
||||
} HAL_GPIO_ModeTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Перечисление режимов подтяжки.
|
||||
*/
|
||||
typedef enum __HAL_GPIO_PullTypeDef
|
||||
{
|
||||
HAL_GPIO_PULL_NONE = 0b00, /**< Подтяжка не подключаются. */
|
||||
HAL_GPIO_PULL_UP = 0b01, /**< Подтяжка к питанию. */
|
||||
HAL_GPIO_PULL_DOWN = 0b10 /**< Подтяжка к земле. */
|
||||
} HAL_GPIO_PullTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Перечисление режимов нагрузочной способности.
|
||||
*/
|
||||
typedef enum __HAL_GPIO_DSTypeDef
|
||||
{
|
||||
HAL_GPIO_DS_2MA = 0b00, /**< Режим драйвера 2мА. */
|
||||
HAL_GPIO_DS_4MA = 0b01, /**< Режим драйвера 4мА. */
|
||||
HAL_GPIO_DS_8MA = 0b10 /**< Режим драйвера 8мА. */
|
||||
} HAL_GPIO_DSTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Настройки для конфигурации выводов.
|
||||
*/
|
||||
typedef struct __GPIO_InitTypeDef
|
||||
{
|
||||
/**
|
||||
* @brief Маска выводов, к которым применяется инициализация..
|
||||
*
|
||||
* Этот параметр является маской из значений @ref HAL_PinsTypeDef.
|
||||
*/
|
||||
HAL_PinsTypeDef Pin;
|
||||
|
||||
/**
|
||||
* @brief Режим выводов или направление GPIO.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref HAL_GPIO_MODE_GPIO_INPUT - режим вывода - GPIO. Вход
|
||||
* - @ref HAL_GPIO_MODE_GPIO_OUTPUT - режим вывода - GPIO. Выход
|
||||
* - @ref HAL_GPIO_MODE_SERIAL - режим вывода - последовательный интерфейс
|
||||
* - @ref HAL_GPIO_MODE_TIMER_SERIAL - режим вывода - последовательный интерфейс или таймер
|
||||
* - @ref HAL_GPIO_MODE_ANALOG - режим вывода аналоговый сигнал
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Режим выводов или направление GPIO.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref HAL_GPIO_MODE_GPIO_INPUT - режим вывода GPIO. Направление вывода как вход;
|
||||
* - @ref HAL_GPIO_MODE_GPIO_OUTPUT - режим вывода GPIO. Направление вывода как выход;
|
||||
* - @ref HAL_GPIO_MODE_SERIAL - режим вывода последовательный интерфейс;
|
||||
* - @ref HAL_GPIO_MODE_TIMER_SERIAL - режим вывода последовательный интерфейс или таймер;
|
||||
* - @ref HAL_GPIO_MODE_ANALOG - режим вывода аналоговый сигнал.
|
||||
*/
|
||||
HAL_GPIO_ModeTypeDef Mode;
|
||||
|
||||
/**
|
||||
* @brief Режим подтяжки.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref HAL_GPIO_PULL_NONE подтяжка не подключаются
|
||||
* - @ref HAL_GPIO_PULL_UP подтяжка к питанию
|
||||
* - @ref HAL_GPIO_PULL_DOWN подтяжка к земле
|
||||
*/
|
||||
HAL_GPIO_PullTypeDef Pull;
|
||||
|
||||
/**
|
||||
* @brief Нагрузочная способность выводов.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref HAL_GPIO_DS_2MA режим драйвера 2мА
|
||||
* - @ref HAL_GPIO_DS_4MA режим драйвера 4мА
|
||||
* - @ref HAL_GPIO_DS_8MA режим драйвера 8мА
|
||||
*/
|
||||
HAL_GPIO_DSTypeDef DS;
|
||||
} GPIO_InitTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Перечисление масок для линий внешних прерываний.
|
||||
*/
|
||||
typedef enum __HAL_GPIO_Line
|
||||
{
|
||||
GPIO_LINE_0 = 0 << GPIO_IRQ_LINE_S, /**< Линия прерываний 0.*/
|
||||
GPIO_LINE_1 = 1 << GPIO_IRQ_LINE_S, /**< Линия прерываний 1.*/
|
||||
GPIO_LINE_2 = 2 << GPIO_IRQ_LINE_S, /**< Линия прерываний 2.*/
|
||||
GPIO_LINE_3 = 3 << GPIO_IRQ_LINE_S, /**< Линия прерываний 3.*/
|
||||
GPIO_LINE_4 = 4 << GPIO_IRQ_LINE_S, /**< Линия прерываний 4.*/
|
||||
GPIO_LINE_5 = 5 << GPIO_IRQ_LINE_S, /**< Линия прерываний 5.*/
|
||||
GPIO_LINE_6 = 6 << GPIO_IRQ_LINE_S, /**< Линия прерываний 6.*/
|
||||
GPIO_LINE_7 = 7 << GPIO_IRQ_LINE_S, /**< Линия прерываний 7.*/
|
||||
} HAL_GPIO_Line;
|
||||
|
||||
/**
|
||||
* @brief Конфигурация линии прерывания.
|
||||
*
|
||||
* @note значение представляется в виде 0b0LLLMMMM, где L - биты номера линии, M - биты выбранного входа мультиплексора линии.
|
||||
*/
|
||||
typedef enum __HAL_GPIO_Line_Config
|
||||
{
|
||||
GPIO_MUX_LINE_0_PORT0_0 = 0 | GPIO_LINE_0, /**< PORT0_0 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_LINE_0_PORT0_8 = 1 | GPIO_LINE_0, /**< PORT0_8 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_LINE_0_PORT1_0 = 2 | GPIO_LINE_0, /**< PORT1_0 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_LINE_0_PORT1_8 = 3 | GPIO_LINE_0, /**< PORT1_8 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_LINE_0_PORT2_0 = 4 | GPIO_LINE_0, /**< PORT2_0 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_LINE_0_PORT0_4 = 5 | GPIO_LINE_0, /**< PORT0_4 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_LINE_0_PORT0_12 = 6 | GPIO_LINE_0, /**< PORT0_12 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_LINE_0_PORT1_4 = 7 | GPIO_LINE_0, /**< PORT1_4 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_LINE_0_PORT1_12 = 8 | GPIO_LINE_0, /**< PORT1_12 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_LINE_0_PORT2_4 = 9 | GPIO_LINE_0, /**< PORT2_4 как вход для линии прерывания 0. */
|
||||
|
||||
GPIO_MUX_PORT0_0_LINE_0 = 0 | GPIO_LINE_0, /**< PORT0_0 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_PORT0_8_LINE_0 = 1 | GPIO_LINE_0, /**< PORT0_8 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_PORT1_0_LINE_0 = 2 | GPIO_LINE_0, /**< PORT1_0 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_PORT1_8_LINE_0 = 3 | GPIO_LINE_0, /**< PORT1_8 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_PORT2_0_LINE_0 = 4 | GPIO_LINE_0, /**< PORT2_0 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_PORT0_4_LINE_0 = 5 | GPIO_LINE_0, /**< PORT0_4 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_PORT0_12_LINE_0 = 6 | GPIO_LINE_0, /**< PORT0_12 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_PORT1_4_LINE_0 = 7 | GPIO_LINE_0, /**< PORT1_4 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_PORT1_12_LINE_0 = 8 | GPIO_LINE_0, /**< PORT1_12 как вход для линии прерывания 0. */
|
||||
GPIO_MUX_PORT2_4_LINE_0 = 9 | GPIO_LINE_0, /**< PORT2_4 как вход для линии прерывания 0. */
|
||||
|
||||
GPIO_MUX_LINE_1_PORT0_1 = 0 | GPIO_LINE_1, /**< PORT0_1 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_LINE_1_PORT0_9 = 1 | GPIO_LINE_1, /**< PORT0_9 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_LINE_1_PORT1_1 = 2 | GPIO_LINE_1, /**< PORT1_1 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_LINE_1_PORT1_9 = 3 | GPIO_LINE_1, /**< PORT1_9 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_LINE_1_PORT2_1 = 4 | GPIO_LINE_1, /**< PORT2_1 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_LINE_1_PORT0_5 = 5 | GPIO_LINE_1, /**< PORT0_5 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_LINE_1_PORT0_13 = 6 | GPIO_LINE_1, /**< PORT0_13 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_LINE_1_PORT1_5 = 7 | GPIO_LINE_1, /**< PORT1_5 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_LINE_1_PORT1_13 = 8 | GPIO_LINE_1, /**< PORT1_13 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_LINE_1_PORT2_5 = 9 | GPIO_LINE_1, /**< PORT2_5 как вход для линии прерывания 1. */
|
||||
|
||||
GPIO_MUX_PORT0_1_LINE_1 = 0 | GPIO_LINE_1, /**< PORT0_1 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_PORT0_9_LINE_1 = 1 | GPIO_LINE_1, /**< PORT0_9 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_PORT1_1_LINE_1 = 2 | GPIO_LINE_1, /**< PORT1_1 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_PORT1_9_LINE_1 = 3 | GPIO_LINE_1, /**< PORT1_9 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_PORT2_1_LINE_1 = 4 | GPIO_LINE_1, /**< PORT2_1 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_PORT0_5_LINE_1 = 5 | GPIO_LINE_1, /**< PORT0_5 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_PORT0_13_LINE_1 = 6 | GPIO_LINE_1, /**< PORT0_13 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_PORT1_5_LINE_1 = 7 | GPIO_LINE_1, /**< PORT1_5 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_PORT1_13_LINE_1 = 8 | GPIO_LINE_1, /**< PORT1_13 как вход для линии прерывания 1. */
|
||||
GPIO_MUX_PORT2_5_LINE_1 = 9 | GPIO_LINE_1, /**< PORT2_5 как вход для линии прерывания 1. */
|
||||
|
||||
GPIO_MUX_LINE_2_PORT0_2 = 0 | GPIO_LINE_2, /**< PORT0_2 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_LINE_2_PORT0_10 = 1 | GPIO_LINE_2, /**< PORT0_10 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_LINE_2_PORT1_2 = 2 | GPIO_LINE_2, /**< PORT1_2 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_LINE_2_PORT1_10 = 3 | GPIO_LINE_2, /**< PORT1_10 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_LINE_2_PORT2_2 = 4 | GPIO_LINE_2, /**< PORT2_2 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_LINE_2_PORT0_6 = 5 | GPIO_LINE_2, /**< PORT0_6 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_LINE_2_PORT0_14 = 6 | GPIO_LINE_2, /**< PORT0_14 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_LINE_2_PORT1_6 = 7 | GPIO_LINE_2, /**< PORT1_6 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_LINE_2_PORT1_14 = 8 | GPIO_LINE_2, /**< PORT1_14 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_LINE_2_PORT2_6 = 9 | GPIO_LINE_2, /**< PORT2_6 как вход для линии прерывания 2. */
|
||||
|
||||
GPIO_MUX_PORT0_2_LINE_2 = 0 | GPIO_LINE_2, /**< PORT0_2 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_PORT0_10_LINE_2 = 1 | GPIO_LINE_2, /**< PORT0_10 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_PORT1_2_LINE_2 = 2 | GPIO_LINE_2, /**< PORT1_2 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_PORT1_10_LINE_2 = 3 | GPIO_LINE_2, /**< PORT1_10 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_PORT2_2_LINE_2 = 4 | GPIO_LINE_2, /**< PORT2_2 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_PORT0_6_LINE_2 = 5 | GPIO_LINE_2, /**< PORT0_6 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_PORT0_14_LINE_2 = 6 | GPIO_LINE_2, /**< PORT0_14 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_PORT1_6_LINE_2 = 7 | GPIO_LINE_2, /**< PORT1_6 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_PORT1_14_LINE_2 = 8 | GPIO_LINE_2, /**< PORT1_14 как вход для линии прерывания 2. */
|
||||
GPIO_MUX_PORT2_6_LINE_2 = 9 | GPIO_LINE_2, /**< PORT2_6 как вход для линии прерывания 2. */
|
||||
|
||||
GPIO_MUX_LINE_3_PORT0_3 = 0 | GPIO_LINE_3, /**< PORT0_3 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_LINE_3_PORT0_11 = 1 | GPIO_LINE_3, /**< PORT0_11 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_LINE_3_PORT1_3 = 2 | GPIO_LINE_3, /**< PORT1_3 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_LINE_3_PORT1_11 = 3 | GPIO_LINE_3, /**< PORT1_11 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_LINE_3_PORT2_3 = 4 | GPIO_LINE_3, /**< PORT2_3 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_LINE_3_PORT0_7 = 5 | GPIO_LINE_3, /**< PORT0_7 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_LINE_3_PORT0_15 = 6 | GPIO_LINE_3, /**< PORT0_15 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_LINE_3_PORT1_7 = 7 | GPIO_LINE_3, /**< PORT1_7 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_LINE_3_PORT1_15 = 8 | GPIO_LINE_3, /**< PORT1_15 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_LINE_3_PORT2_7 = 9 | GPIO_LINE_3, /**< PORT2_7 как вход для линии прерывания 3. */
|
||||
|
||||
GPIO_MUX_PORT0_3_LINE_3 = 0 | GPIO_LINE_3, /**< PORT0_3 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_PORT0_11_LINE_3 = 1 | GPIO_LINE_3, /**< PORT0_11 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_PORT1_3_LINE_3 = 2 | GPIO_LINE_3, /**< PORT1_3 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_PORT1_11_LINE_3 = 3 | GPIO_LINE_3, /**< PORT1_11 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_PORT2_3_LINE_3 = 4 | GPIO_LINE_3, /**< PORT2_3 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_PORT0_7_LINE_3 = 5 | GPIO_LINE_3, /**< PORT0_7 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_PORT0_15_LINE_3 = 6 | GPIO_LINE_3, /**< PORT0_15 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_PORT1_7_LINE_3 = 7 | GPIO_LINE_3, /**< PORT1_7 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_PORT1_15_LINE_3 = 8 | GPIO_LINE_3, /**< PORT1_15 как вход для линии прерывания 3. */
|
||||
GPIO_MUX_PORT2_7_LINE_3 = 9 | GPIO_LINE_3, /**< PORT2_7 как вход для линии прерывания 3. */
|
||||
|
||||
GPIO_MUX_LINE_4_PORT0_4 = 0 | GPIO_LINE_4, /**< PORT0_4 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_LINE_4_PORT0_12 = 1 | GPIO_LINE_4, /**< PORT0_12 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_LINE_4_PORT1_4 = 2 | GPIO_LINE_4, /**< PORT1_4 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_LINE_4_PORT1_12 = 3 | GPIO_LINE_4, /**< PORT1_12 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_LINE_4_PORT2_4 = 4 | GPIO_LINE_4, /**< PORT2_4 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_LINE_4_PORT0_0 = 5 | GPIO_LINE_4, /**< PORT0_0 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_LINE_4_PORT0_8 = 6 | GPIO_LINE_4, /**< PORT0_8 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_LINE_4_PORT1_0 = 7 | GPIO_LINE_4, /**< PORT1_0 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_LINE_4_PORT1_8 = 8 | GPIO_LINE_4, /**< PORT1_8 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_LINE_4_PORT2_0 = 9 | GPIO_LINE_4, /**< PORT2_0 как вход для линии прерывания 4. */
|
||||
|
||||
GPIO_MUX_PORT0_4_LINE_4 = 0 | GPIO_LINE_4, /**< PORT0_4 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_PORT0_12_LINE_4 = 1 | GPIO_LINE_4, /**< PORT0_12 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_PORT1_4_LINE_4 = 2 | GPIO_LINE_4, /**< PORT1_4 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_PORT1_12_LINE_4 = 3 | GPIO_LINE_4, /**< PORT1_12 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_PORT2_4_LINE_4 = 4 | GPIO_LINE_4, /**< PORT2_4 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_PORT0_0_LINE_4 = 5 | GPIO_LINE_4, /**< PORT0_0 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_PORT0_8_LINE_4 = 6 | GPIO_LINE_4, /**< PORT0_8 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_PORT1_0_LINE_4 = 7 | GPIO_LINE_4, /**< PORT1_0 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_PORT1_8_LINE_4 = 8 | GPIO_LINE_4, /**< PORT1_8 как вход для линии прерывания 4. */
|
||||
GPIO_MUX_PORT2_0_LINE_4 = 9 | GPIO_LINE_4, /**< PORT2_0 как вход для линии прерывания 4. */
|
||||
|
||||
GPIO_MUX_LINE_5_PORT0_5 = 0 | GPIO_LINE_5, /**< PORT0_5 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_LINE_5_PORT0_13 = 1 | GPIO_LINE_5, /**< PORT0_13 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_LINE_5_PORT1_5 = 2 | GPIO_LINE_5, /**< PORT1_5 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_LINE_5_PORT1_13 = 3 | GPIO_LINE_5, /**< PORT1_13 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_LINE_5_PORT2_5 = 4 | GPIO_LINE_5, /**< PORT2_5 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_LINE_5_PORT0_1 = 5 | GPIO_LINE_5, /**< PORT0_1 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_LINE_5_PORT0_9 = 6 | GPIO_LINE_5, /**< PORT0_9 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_LINE_5_PORT1_1 = 7 | GPIO_LINE_5, /**< PORT1_1 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_LINE_5_PORT1_9 = 8 | GPIO_LINE_5, /**< PORT1_9 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_LINE_5_PORT2_1 = 9 | GPIO_LINE_5, /**< PORT2_1 как вход для линии прерывания 5. */
|
||||
|
||||
GPIO_MUX_PORT0_5_LINE_5 = 0 | GPIO_LINE_5, /**< PORT0_5 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_PORT0_13_LINE_5 = 1 | GPIO_LINE_5, /**< PORT0_13 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_PORT1_5_LINE_5 = 2 | GPIO_LINE_5, /**< PORT1_5 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_PORT1_13_LINE_5 = 3 | GPIO_LINE_5, /**< PORT1_13 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_PORT2_5_LINE_5 = 4 | GPIO_LINE_5, /**< PORT2_5 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_PORT0_1_LINE_5 = 5 | GPIO_LINE_5, /**< PORT0_1 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_PORT0_9_LINE_5 = 6 | GPIO_LINE_5, /**< PORT0_9 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_PORT1_1_LINE_5 = 7 | GPIO_LINE_5, /**< PORT1_1 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_PORT1_9_LINE_5 = 8 | GPIO_LINE_5, /**< PORT1_9 как вход для линии прерывания 5. */
|
||||
GPIO_MUX_PORT2_1_LINE_5 = 9 | GPIO_LINE_5, /**< PORT2_1 как вход для линии прерывания 5. */
|
||||
|
||||
GPIO_MUX_LINE_6_PORT0_6 = 0 | GPIO_LINE_6, /**< PORT0_6 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_LINE_6_PORT0_14 = 1 | GPIO_LINE_6, /**< PORT0_14 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_LINE_6_PORT1_6 = 2 | GPIO_LINE_6, /**< PORT1_6 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_LINE_6_PORT1_14 = 3 | GPIO_LINE_6, /**< PORT1_14 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_LINE_6_PORT2_6 = 4 | GPIO_LINE_6, /**< PORT2_6 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_LINE_6_PORT0_2 = 5 | GPIO_LINE_6, /**< PORT0_2 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_LINE_6_PORT0_10 = 6 | GPIO_LINE_6, /**< PORT0_10 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_LINE_6_PORT1_2 = 7 | GPIO_LINE_6, /**< PORT1_2 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_LINE_6_PORT1_10 = 8 | GPIO_LINE_6, /**< PORT1_10 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_LINE_6_PORT2_2 = 9 | GPIO_LINE_6, /**< PORT2_2 как вход для линии прерывания 6. */
|
||||
|
||||
GPIO_MUX_PORT0_6_LINE_6 = 0 | GPIO_LINE_6, /**< PORT0_6 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_PORT0_14_LINE_6 = 1 | GPIO_LINE_6, /**< PORT0_14 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_PORT1_6_LINE_6 = 2 | GPIO_LINE_6, /**< PORT1_6 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_PORT1_14_LINE_6 = 3 | GPIO_LINE_6, /**< PORT1_14 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_PORT2_6_LINE_6 = 4 | GPIO_LINE_6, /**< PORT2_6 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_PORT0_2_LINE_6 = 5 | GPIO_LINE_6, /**< PORT0_2 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_PORT0_10_LINE_6 = 6 | GPIO_LINE_6, /**< PORT0_10 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_PORT1_2_LINE_6 = 7 | GPIO_LINE_6, /**< PORT1_2 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_PORT1_10_LINE_6 = 8 | GPIO_LINE_6, /**< PORT1_10 как вход для линии прерывания 6. */
|
||||
GPIO_MUX_PORT2_2_LINE_6 = 9 | GPIO_LINE_6, /**< PORT2_2 как вход для линии прерывания 6. */
|
||||
|
||||
GPIO_MUX_LINE_7_PORT0_7 = 0 | GPIO_LINE_7, /**< PORT0_7 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_LINE_7_PORT0_15 = 1 | GPIO_LINE_7, /**< PORT0_15 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_LINE_7_PORT1_7 = 2 | GPIO_LINE_7, /**< PORT1_7 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_LINE_7_PORT1_15 = 3 | GPIO_LINE_7, /**< PORT1_15 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_LINE_7_PORT2_7 = 4 | GPIO_LINE_7, /**< PORT2_7 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_LINE_7_PORT0_3 = 5 | GPIO_LINE_7, /**< PORT0_3 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_LINE_7_PORT0_11 = 6 | GPIO_LINE_7, /**< PORT0_11 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_LINE_7_PORT1_3 = 7 | GPIO_LINE_7, /**< PORT1_3 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_LINE_7_PORT1_11 = 8 | GPIO_LINE_7, /**< PORT1_11 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_LINE_7_PORT2_3 = 9 | GPIO_LINE_7, /**< PORT2_3 как вход для линии прерывания 7. */
|
||||
|
||||
GPIO_MUX_PORT0_7_LINE_7 = 0 | GPIO_LINE_7, /**< PORT0_7 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_PORT0_15_LINE_7 = 1 | GPIO_LINE_7, /**< PORT0_15 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_PORT1_7_LINE_7 = 2 | GPIO_LINE_7, /**< PORT1_7 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_PORT1_15_LINE_7 = 3 | GPIO_LINE_7, /**< PORT1_15 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_PORT2_7_LINE_7 = 4 | GPIO_LINE_7, /**< PORT2_7 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_PORT0_3_LINE_7 = 5 | GPIO_LINE_7, /**< PORT0_3 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_PORT0_11_LINE_7 = 6 | GPIO_LINE_7, /**< PORT0_11 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_PORT1_3_LINE_7 = 7 | GPIO_LINE_7, /**< PORT1_3 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_PORT1_11_LINE_7 = 8 | GPIO_LINE_7, /**< PORT1_11 как вход для линии прерывания 7. */
|
||||
GPIO_MUX_PORT2_3_LINE_7 = 9 | GPIO_LINE_7, /**< PORT2_3 как вход для линии прерывания 7. */
|
||||
|
||||
} HAL_GPIO_Line_Config;
|
||||
|
||||
/**
|
||||
* @brief Режим прерывания линии GPIO.
|
||||
* \note Функция инициализации @ref HAL_GPIO_InitInterruptLine не включает прерывания GPIO в EPIC.
|
||||
*/
|
||||
typedef enum __HAL_GPIO_InterruptMode
|
||||
{
|
||||
GPIO_INT_MODE_LOW = 0, /**< Режим прерывания по низкому уровню на выводе. */
|
||||
GPIO_INT_MODE_HIGH = GPIO_MODE_BIT_LEVEL_M, /**< Режим прерывания по высокому уровню на выводе. */
|
||||
GPIO_INT_MODE_FALLING = GPIO_MODE_BIT_EDGE_M, /**< Режим прерывания по смене уровня на выводе с высокого на низкий. */
|
||||
GPIO_INT_MODE_RISING = GPIO_MODE_BIT_LEVEL_M | GPIO_MODE_BIT_EDGE_M, /**< Режим прерывания по смене уровня на выводе с низкого на высокий. */
|
||||
GPIO_INT_MODE_CHANGE = GPIO_MODE_BIT_EDGE_M | GPIO_MODE_BIT_ANYEDGE_M, /**< Режим прерывания по изменению уровня на выводе. */
|
||||
} HAL_GPIO_InterruptMode;
|
||||
|
||||
HAL_StatusTypeDef HAL_GPIO_Init(GPIO_TypeDef *GPIO_x, GPIO_InitTypeDef *GPIO_Init);
|
||||
HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, HAL_GPIO_ModeTypeDef mode, HAL_GPIO_PullTypeDef pull, HAL_GPIO_DSTypeDef driveStrength);
|
||||
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin);
|
||||
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState);
|
||||
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin);
|
||||
HAL_StatusTypeDef HAL_GPIO_InitInterruptLine(HAL_GPIO_Line_Config mux, HAL_GPIO_InterruptMode mode);
|
||||
HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine);
|
||||
uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine);
|
||||
GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine);
|
||||
void HAL_GPIO_ClearInterrupts();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MIK32_HAL_GPIO
|
||||
@@ -0,0 +1,615 @@
|
||||
#ifndef MIK32_HAL_I2C
|
||||
#define MIK32_HAL_I2C
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "mik32_hal_gpio.h"
|
||||
#include "mik32_hal_def.h"
|
||||
#include "i2c.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
#include "mik32_hal_dma.h"
|
||||
|
||||
|
||||
/*
|
||||
* Define: I2C_TIMEOUT
|
||||
* Количество циклов ожидания установки флага TXIS или RXNE
|
||||
*
|
||||
*/
|
||||
#define I2C_TIMEOUT_DEFAULT 1000000 /* Количество циклов ожидания установки флага TXIS или RXNE */
|
||||
/*
|
||||
* Define: I2C_NBYTE_MAX
|
||||
* Максимальлное количество байт в посылке (NBYTES)
|
||||
*
|
||||
*/
|
||||
#define I2C_NBYTE_MAX 255 /* Максимальное количество байт в посылке (NBYTES) */
|
||||
|
||||
#define I2C_ADDRESS_7BIT_MAX 0x7F /* Максимальный 7 битный адрес */
|
||||
#define I2C_ADDRESS_10BIT_MAX 0x3FF /* Максимальный 10 битный адрес */
|
||||
|
||||
#define I2C_INTMASK 0b11111110 /* Маска для разрешенных прерываний */
|
||||
|
||||
/* I2C_error - номера ошибок I2C*/
|
||||
/* Номер канала */
|
||||
typedef enum
|
||||
{
|
||||
I2C_ERROR_NONE = 0, /* Ошибок нет */
|
||||
I2C_ERROR_TIMEOUT = 1, /* Превышено ожидание установки флага TXIS или RXNE */
|
||||
I2C_ERROR_NACK = 2, /* Во время передачи не получено подтверждение данных (NACK) */
|
||||
I2C_ERROR_BERR = 3, /* Ошибка шины */
|
||||
I2C_ERROR_ARLO = 4, /* Проигрыш арбитража */
|
||||
I2C_ERROR_OVR = 5, /* Переполнение или недозагрузка */
|
||||
I2C_ERROR_STOP = 6, /* Обнаружение STOP на линии */
|
||||
} HAL_I2C_ErrorTypeDef;
|
||||
|
||||
/* I2C_addressing_mode - Режим адреса */
|
||||
typedef enum
|
||||
{
|
||||
I2C_ADDRESSINGMODE_7BIT = 0, /* 7 битный адрес */
|
||||
I2C_ADDRESSINGMODE_10BIT = 1 /* 10 битный адрес */
|
||||
} HAL_I2C_AddressingModeTypeDef;
|
||||
|
||||
/* I2C_dual_addressing_mode - Режим дополнительного адреса 7 бит */
|
||||
typedef enum
|
||||
{
|
||||
I2C_DUALADDRESS_DISABLE = 0, /* Выключить дополнительный адрес */
|
||||
I2C_DUALADDRESS_ENABLE = 1 /* Включить дополнительный адрес */
|
||||
} HAL_I2C_DualAddressTypeDef;
|
||||
|
||||
/* I2C_general_call_mode - Адрес общего вызова */
|
||||
typedef enum
|
||||
{
|
||||
I2C_GENERALCALL_DISABLE = 0, /* Выключить адрес общего вызова */
|
||||
I2C_GENERALCALL_ENABLE = 1 /* Включить адрес общего вызова */
|
||||
} HAL_I2C_GeneralCallTypeDef;
|
||||
|
||||
/* I2C_nostretch_mode - Режим удержания SCL ведомым */
|
||||
typedef enum
|
||||
{
|
||||
I2C_NOSTRETCH_DISABLE = 0, /* Растягивание активно */
|
||||
I2C_NOSTRETCH_ENABLE = 1 /* растягивание выключено */
|
||||
} HAL_I2C_NoStretchModeTypeDef;
|
||||
|
||||
/* I2C_sbc_mode - Режим аппаратного контроля байта ведомым */
|
||||
typedef enum
|
||||
{
|
||||
I2C_SBC_DISABLE = 0, /* Аппаратный контроль выключен */
|
||||
I2C_SBC_ENABLE = 1 /* Аппаратный контроль включен */
|
||||
} HAL_I2C_SBCModeTypeDef;
|
||||
|
||||
/* I2C_reload_mode - Режим перезаписи NBYTES: */
|
||||
typedef enum
|
||||
{
|
||||
I2C_RELOAD_DISABLE = 0, /* Транзакция завершена после пересылки NBYTES байт данных (на шине ожидаются STOP или RESTART) */
|
||||
I2C_RELOAD_ENABLE = 1 /* Транзакция не завершена после пересылки NBYTES байт данных (значение NBYTES будет перезаписано) */
|
||||
} HAL_I2C_ReloadModeTypeDef;
|
||||
|
||||
/* I2C_autoend_mode - Режим автоматического окончания */
|
||||
typedef enum
|
||||
{
|
||||
I2C_AUTOEND_DISABLE = 0, /* Режим автоматического окончания отключен */
|
||||
I2C_AUTOEND_ENABLE = 1 /* Режим автоматического окончания включен */
|
||||
} HAL_I2C_AutoEndModeTypeDef;
|
||||
|
||||
/* I2C_transfer_direction - Направление передачи */
|
||||
typedef enum
|
||||
{
|
||||
I2C_TRANSFER_WRITE = 0, /* Ведущий запрашивает транзакцию записи */
|
||||
I2C_TRANSFER_READ = 1 /* Ведущий запрашивает транзакцию чтения */
|
||||
} HAL_I2C_TransferDirectionTypeDef;
|
||||
|
||||
/* I2C_OwnAddress2_mask - Маска второго собственного адреса */
|
||||
typedef enum
|
||||
{
|
||||
I2C_OWNADDRESS2_MASK_DISABLE = 0, /* Нет маски */
|
||||
I2C_OWNADDRESS2_MASK_111111x = 1, /* Сравниваются только OA2[7:2] */
|
||||
I2C_OWNADDRESS2_MASK_11111xx = 2, /* Сравниваются только OA2[7:3]; */
|
||||
I2C_OWNADDRESS2_MASK_1111xxx = 3, /* Сравниваются только OA2[7:4]; */
|
||||
I2C_OWNADDRESS2_MASK_111xxxx = 4, /* Сравниваются только OA2[7:5]; */
|
||||
I2C_OWNADDRESS2_MASK_11xxxxx = 5, /* Сравниваются только OA2[7:6]; */
|
||||
I2C_OWNADDRESS2_MASK_1xxxxxx = 6, /* Сравниваются только OA2[7]; */
|
||||
I2C_OWNADDRESS2_MASK_1111111 = 7 /* OA2[7:1] маскируются, подтверждаются (ACK) все 7-битные адреса (кроме зарезервированных) */
|
||||
} HAL_I2C_OwnAddress2MaskTypeDef;
|
||||
|
||||
/* I2C_digital_filter - Цифровой фильтр */
|
||||
typedef enum
|
||||
{
|
||||
I2C_DIGITALFILTER_OFF = 0,
|
||||
I2C_DIGITALFILTER_1CLOCKCYCLES = 1,
|
||||
I2C_DIGITALFILTER_2CLOCKCYCLES = 2,
|
||||
I2C_DIGITALFILTER_15CLOCKCYCLES = 15
|
||||
} HAL_I2C_DigitalFilterTypeDef;
|
||||
|
||||
/* I2C_analog_filter - Цифровой фильтр */
|
||||
typedef enum
|
||||
{
|
||||
I2C_ANALOGFILTER_ENABLE = 0,
|
||||
I2C_ANALOGFILTER_DISABLE = 1
|
||||
} HAL_I2C_AnalogFilterTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HAL_I2C_MODE_MASTER = 0, /* Режим ведущего */
|
||||
HAL_I2C_MODE_SLAVE = 1, /* Режим ведомого */
|
||||
|
||||
} HAL_I2C_ModeTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
HAL_I2C_ModeTypeDef Mode; /* Режим ведомый или ведущий */
|
||||
|
||||
/*
|
||||
* Variable: OwnAddress1
|
||||
* Основной собственный адрес.
|
||||
*
|
||||
* Когда включен дополнительный адрес, длинна основного адреса должна быть 7 бит.
|
||||
*
|
||||
* Этот параметр должен быть 7-битным или 10-битным числом
|
||||
*
|
||||
*/
|
||||
uint32_t OwnAddress1;
|
||||
|
||||
/*
|
||||
* Variable: DualAddressMode
|
||||
* Активация дополнительного 7 битного адреса
|
||||
*
|
||||
* Можно использовать, если длина основного адреса 7 бит
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <I2C_DUALADDRESS_DISABLE>;
|
||||
* - <I2C_DUALADDRESS_ENABLE>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
HAL_I2C_DualAddressTypeDef DualAddressMode;
|
||||
|
||||
/*
|
||||
* Variable: OwnAddress2
|
||||
* Дополнительный 7 битный адрес
|
||||
*
|
||||
* Можно использовать, если длина основного адреса 7 бит
|
||||
*
|
||||
* Этот параметр должен быть 7 битным числом.
|
||||
*
|
||||
*/
|
||||
uint32_t OwnAddress2;
|
||||
|
||||
HAL_I2C_GeneralCallTypeDef GeneralCall;
|
||||
|
||||
/*
|
||||
* Variable: OwnAddress2Mask
|
||||
* Маска сравнения дополнительного 7 битного адреса
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <I2C_OWNADDRESS2_MASK_DISABLE>
|
||||
* - <I2C_OWNADDRESS2_MASK_111111x>
|
||||
* - <I2C_OWNADDRESS2_MASK_11111xx>
|
||||
* - <I2C_OWNADDRESS2_MASK_1111xxx>
|
||||
* - <I2C_OWNADDRESS2_MASK_111xxxx>
|
||||
* - <I2C_OWNADDRESS2_MASK_11xxxxx>
|
||||
* - <I2C_OWNADDRESS2_MASK_1xxxxxx>
|
||||
* - <I2C_OWNADDRESS2_MASK_1111111>
|
||||
*
|
||||
*/
|
||||
HAL_I2C_OwnAddress2MaskTypeDef OwnAddress2Mask;
|
||||
|
||||
/*
|
||||
* Variable: NoStretchMode
|
||||
* Растягивания тактового сигнала в режиме "ведомый".
|
||||
*
|
||||
* Не совместим с режимом SBC
|
||||
*
|
||||
* В режиме ведущий значение всегда I2C_NOSTRETCH_DISABLE
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <I2C_NOSTRETCH_DISABLE>
|
||||
* - <I2C_NOSTRETCH_ENABLE>
|
||||
*
|
||||
*/
|
||||
HAL_I2C_NoStretchModeTypeDef NoStretchMode;
|
||||
|
||||
/*
|
||||
* Variable: SBCMode
|
||||
* Режим аппаратного контроля передачи данных в режиме "ведомый"
|
||||
*
|
||||
* Не совместим с режимом NOSTRETCH
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <I2C_SBC_DISABLE>
|
||||
* - <I2C_SBC_ENABLE>
|
||||
*
|
||||
*/
|
||||
HAL_I2C_SBCModeTypeDef SBCMode;
|
||||
|
||||
/*
|
||||
* Variable: AutoEnd
|
||||
* Управление режимом автоматического окончания в режиме "ведущий"
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <AUTOEND_DISABLE>
|
||||
* - <AUTOEND_ENABLE>
|
||||
*
|
||||
*/
|
||||
HAL_I2C_AutoEndModeTypeDef AutoEnd;
|
||||
|
||||
/*
|
||||
* Variable: Filter
|
||||
* Цифровой фильтр
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <I2C_FILTER_OFF>
|
||||
* - <I2C_FILTER_1CLOCKCYCLES>
|
||||
* - <I2C_FILTER_2CLOCKCYCLES>
|
||||
* - <I2C_FILTER_15CLOCKCYCLES>
|
||||
*
|
||||
*/
|
||||
HAL_I2C_DigitalFilterTypeDef DigitalFilter;
|
||||
|
||||
HAL_I2C_AnalogFilterTypeDef AnalogFilter;
|
||||
|
||||
} I2C_InitTypeDef;
|
||||
|
||||
/*
|
||||
* Struct: I2C_ClockTypeDef
|
||||
*
|
||||
* Настройки временных ограничений
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* Variable: PRESC
|
||||
* Предварительный делитель частоты I2CCLK.
|
||||
*
|
||||
* Используется для вычисления значения t_PRESC используемого счетчиками предустановки, удержания, низкого и высокого уровней.
|
||||
*
|
||||
* Этот параметр может быть числом в пределах от 0 до 15
|
||||
*
|
||||
*/
|
||||
uint32_t PRESC;
|
||||
|
||||
/*
|
||||
* Variable: SCLDEL
|
||||
* Длительность предустановки данных.
|
||||
*
|
||||
* Задержка между изменением SDA и фронтом SCL.
|
||||
*
|
||||
* Этот параметр может быть числом в пределах от 0 до 15.
|
||||
*
|
||||
*/
|
||||
uint32_t SCLDEL;
|
||||
|
||||
/*
|
||||
* Variable: SDADEL
|
||||
* Длительность предустановки данных.
|
||||
*
|
||||
* Задержка между спадом SCL и изменением SDA в режиме ведущего и ведомого при NOSTRETCH = 0.
|
||||
*
|
||||
* Этот параметр может быть числом в пределах от 0 до 15.
|
||||
*
|
||||
*/
|
||||
uint32_t SDADEL;
|
||||
|
||||
/*
|
||||
* Variable: SCLH
|
||||
* Длительность удержания SCL в состоянии логической "1" в режиме "ведущий".
|
||||
*
|
||||
* Этот параметр может быть от 0 до 255.
|
||||
*
|
||||
*/
|
||||
uint32_t SCLH;
|
||||
|
||||
/*
|
||||
* Variable: SCLL
|
||||
* Длительность удержания SCL в состоянии логического "0" в режиме "ведущий".
|
||||
*
|
||||
* Этот параметр может быть от 0 до 255.
|
||||
*
|
||||
*/
|
||||
uint32_t SCLL;
|
||||
|
||||
} I2C_ClockTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HAL_I2C_STATE_READY, /* Готов к передаче */
|
||||
HAL_I2C_STATE_BUSY, /* Идет передача */
|
||||
HAL_I2C_STATE_END, /* Передача завершена */
|
||||
HAL_I2C_STATE_ERROR /* Ошибка при передаче */
|
||||
} HAL_I2C_StateTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* Variable: Instance
|
||||
* Базовый адрес регистров I2C
|
||||
*
|
||||
*/
|
||||
I2C_TypeDef *Instance;
|
||||
|
||||
/*
|
||||
* Variable: Init
|
||||
* Параметры инициализации I2C
|
||||
*
|
||||
*/
|
||||
I2C_InitTypeDef Init;
|
||||
|
||||
/*
|
||||
* Variable: Clock
|
||||
* Параметры частоты I2C
|
||||
*
|
||||
*/
|
||||
I2C_ClockTypeDef Clock;
|
||||
|
||||
/*
|
||||
* Variable: ErrorCode
|
||||
* Код ошибки I2C
|
||||
*
|
||||
*/
|
||||
HAL_I2C_ErrorTypeDef ErrorCode;
|
||||
|
||||
/*
|
||||
* Variable: hdmatx
|
||||
* Канала DMA для отправки данных
|
||||
*/
|
||||
DMA_ChannelHandleTypeDef *hdmatx;
|
||||
|
||||
/*
|
||||
* Variable: hdmarx
|
||||
* Канала DMA для приема данных
|
||||
*/
|
||||
DMA_ChannelHandleTypeDef *hdmarx;
|
||||
|
||||
volatile HAL_I2C_StateTypeDef State;
|
||||
|
||||
uint8_t *pBuffPtr;
|
||||
uint32_t TransferSize;
|
||||
uint32_t TransferCount;
|
||||
|
||||
} I2C_HandleTypeDef;
|
||||
|
||||
|
||||
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c);
|
||||
void HAL_I2C_Disable(I2C_HandleTypeDef *hi2c);
|
||||
void HAL_I2C_Reset(I2C_HandleTypeDef *hi2c);
|
||||
void HAL_I2C_Enable(I2C_HandleTypeDef *hi2c);
|
||||
void HAL_I2C_AnalogFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_AnalogFilterTypeDef AnalogFilter);
|
||||
void HAL_I2C_DigitalFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_DigitalFilterTypeDef DigitalFilter);
|
||||
void HAL_I2C_SetClockSpeed(I2C_HandleTypeDef *hi2c);
|
||||
void HAL_I2C_NoStretchMode(I2C_HandleTypeDef *hi2c, HAL_I2C_NoStretchModeTypeDef NoStretchMode);
|
||||
void HAL_I2C_OwnAddress1(I2C_HandleTypeDef *hi2c);
|
||||
void HAL_I2C_OwnAddress2(I2C_HandleTypeDef *hi2c);
|
||||
void HAL_I2C_GeneralCall(I2C_HandleTypeDef *hi2c, HAL_I2C_GeneralCallTypeDef GeneralCall);
|
||||
void HAL_I2C_SBCMode(I2C_HandleTypeDef *hi2c, HAL_I2C_SBCModeTypeDef SBCMode);
|
||||
void HAL_I2C_SlaveInit(I2C_HandleTypeDef *hi2c);
|
||||
void HAL_I2C_MasterInit(I2C_HandleTypeDef *hi2c);
|
||||
HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
|
||||
void HAL_I2C_AutoEnd(I2C_HandleTypeDef *hi2c, HAL_I2C_AutoEndModeTypeDef AutoEnd);
|
||||
HAL_StatusTypeDef HAL_I2C_Master_WaitTXIS(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_I2C_Master_WaitRXNE(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
|
||||
void HAL_I2C_Master_SlaveAddress(I2C_HandleTypeDef *hi2h, uint16_t SlaveAddress);
|
||||
HAL_StatusTypeDef HAL_I2C_WaitBusy(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
|
||||
void HAL_I2C_Master_NBYTES(I2C_HandleTypeDef *hi2c);
|
||||
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_WaitADDR(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_WaitTXIS(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_WaitRXNE(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_WaitTCR(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
|
||||
void HAL_I2C_Slave_ACK(I2C_HandleTypeDef *hi2c);
|
||||
void HAL_I2C_Slave_NACK(I2C_HandleTypeDef *hi2c);
|
||||
extern HAL_StatusTypeDef HAL_I2C_Slave_SBC(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t ByteCount);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_ReceiveSBC(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize);
|
||||
HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
|
||||
|
||||
void HAL_I2C_InterruptDisable(I2C_HandleTypeDef *hi2c, uint32_t IntDisMask);
|
||||
void HAL_I2C_InterruptEnable(I2C_HandleTypeDef *hi2c, uint32_t IntEnMask);
|
||||
HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize);
|
||||
HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_Transmit_NOSTRETCH_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_Receive_NOSTRETCH_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
|
||||
HAL_StatusTypeDef HAL_I2C_Slave_ReceiveSBC_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
|
||||
|
||||
static inline __attribute__((always_inline)) void HAL_I2C_ADDR_IRQ(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
if (hi2c->Instance->CR1 & I2C_CR1_SBC_M)
|
||||
{
|
||||
hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M;
|
||||
hi2c->Instance->CR2 |= I2C_CR2_NBYTES(0x1);
|
||||
}
|
||||
|
||||
/* Сброс флага ADDR */
|
||||
hi2c->Instance->ICR |= I2C_ICR_ADDRCF_M;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void HAL_I2C_ERR_IRQ(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
hi2c->State = HAL_I2C_STATE_ERROR;
|
||||
/* Выключить все прерывания I2C */
|
||||
hi2c->Instance->CR1 &= ~I2C_INTMASK;
|
||||
/* Сброс I2C */
|
||||
hi2c->ErrorCode = I2C_ERROR_NONE;
|
||||
hi2c->Instance->CR1 &= ~I2C_CR1_PE_M;
|
||||
hi2c->Instance->CR1 |= I2C_CR1_PE_M;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void HAL_I2C_NACK_IRQ(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
hi2c->State = HAL_I2C_STATE_ERROR;
|
||||
/* Выключить все прерывания I2C */
|
||||
hi2c->Instance->CR1 &= ~I2C_INTMASK;
|
||||
/* Сброс I2C */
|
||||
hi2c->ErrorCode = I2C_ERROR_NONE;
|
||||
hi2c->Instance->CR1 &= ~I2C_CR1_PE_M;
|
||||
hi2c->Instance->CR1 |= I2C_CR1_PE_M;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void HAL_I2C_STOP_IRQ(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
hi2c->State = HAL_I2C_STATE_END;
|
||||
/* Сброс содержимого TXDR */
|
||||
hi2c->Instance->ISR |= I2C_ISR_TXE_M;
|
||||
/* Сброс флага детектирования STOP на шине */
|
||||
hi2c->Instance->ICR |= I2C_ICR_STOPCF_M;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void HAL_I2C_TXIS_IRQ(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
hi2c->Instance->TXDR = *((uint8_t *)hi2c->pBuffPtr);
|
||||
hi2c->pBuffPtr++;
|
||||
hi2c->TransferCount++;
|
||||
if (hi2c->TransferCount == hi2c->TransferSize)
|
||||
{
|
||||
hi2c->State = HAL_I2C_STATE_END;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void HAL_I2C_RXNE_IRQ(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
*((uint8_t *)hi2c->pBuffPtr) = (uint8_t)hi2c->Instance->RXDR;
|
||||
|
||||
if (hi2c->Instance->CR1 & I2C_CR1_SBC_M)
|
||||
{
|
||||
if (HAL_I2C_Slave_SBC(hi2c, hi2c->pBuffPtr - hi2c->TransferCount, hi2c->TransferSize, hi2c->TransferCount) != HAL_OK)
|
||||
{
|
||||
hi2c->State = HAL_I2C_STATE_END;
|
||||
/* Выключить все прерывания I2C */
|
||||
hi2c->Instance->CR1 &= ~I2C_INTMASK;
|
||||
/* Сброс I2C */
|
||||
hi2c->ErrorCode = I2C_ERROR_NONE;
|
||||
hi2c->Instance->CR1 &= ~I2C_CR1_PE_M;
|
||||
hi2c->Instance->CR1 |= I2C_CR1_PE_M;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
hi2c->pBuffPtr++;
|
||||
hi2c->TransferCount++;
|
||||
if (hi2c->TransferCount == hi2c->TransferSize)
|
||||
{
|
||||
hi2c->State = HAL_I2C_STATE_END;
|
||||
}
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void HAL_I2C_TCR_IRQ(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
if (hi2c->Instance->CR1 & I2C_CR1_SBC_M)
|
||||
{
|
||||
if (hi2c->TransferCount < hi2c->TransferSize)
|
||||
{
|
||||
hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M;
|
||||
hi2c->Instance->CR2 |= I2C_CR2_NBYTES(0x1);
|
||||
}
|
||||
else
|
||||
{
|
||||
hi2c->State = HAL_I2C_STATE_END;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M;
|
||||
/* Подготовка перед отправкой */
|
||||
|
||||
if ((hi2c->TransferSize - hi2c->TransferCount) <= I2C_NBYTE_MAX)
|
||||
{
|
||||
hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M;
|
||||
hi2c->Instance->CR2 |= I2C_CR2_NBYTES(hi2c->TransferSize - hi2c->TransferCount);
|
||||
hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M;
|
||||
hi2c->Instance->CR2 &= ~I2C_CR2_AUTOEND_M;
|
||||
hi2c->Instance->CR2 |= hi2c->Init.AutoEnd << I2C_CR2_AUTOEND_S;
|
||||
}
|
||||
else /* DataSize > 255 */
|
||||
{
|
||||
hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M;
|
||||
hi2c->Instance->CR2 |= I2C_CR2_NBYTES(I2C_NBYTE_MAX);
|
||||
/* При RELOAD = 1 AUTOEND игнорируется */
|
||||
hi2c->Instance->CR2 |= I2C_CR2_RELOAD_M;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void HAL_I2C_TC_IRQ(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
hi2c->State = HAL_I2C_STATE_END;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void HAL_I2C_IRQHandler(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
uint32_t int_mask = hi2c->Instance->CR1 & I2C_INTMASK; /* разрешенные прерывания */
|
||||
uint32_t interrupt_status = hi2c->Instance->ISR; /* Флаги */
|
||||
|
||||
if ((interrupt_status & I2C_ISR_ADDR_M) && (int_mask & I2C_CR1_ADDRIE_M))
|
||||
{
|
||||
// xprintf("ADDR\n");
|
||||
HAL_I2C_ADDR_IRQ(hi2c);
|
||||
}
|
||||
|
||||
if ((interrupt_status & (I2C_ISR_BERR_M | I2C_ISR_ARLO_M | I2C_ISR_OVR_M)) && (int_mask & I2C_CR1_ERRIE_M))
|
||||
{
|
||||
// xprintf("Err, count %d, ISR %d\n", hi2c->TransferCount, hi2c->Instance->ISR);
|
||||
HAL_I2C_ERR_IRQ(hi2c);
|
||||
}
|
||||
|
||||
if ((interrupt_status & I2C_ISR_NACKF_M) && (int_mask & I2C_CR1_NACKIE_M))
|
||||
{
|
||||
// xprintf("NACK\n");
|
||||
HAL_I2C_NACK_IRQ(hi2c);
|
||||
}
|
||||
|
||||
if ((interrupt_status & I2C_ISR_STOPF_M) && (int_mask & I2C_CR1_STOPIE_M))
|
||||
{
|
||||
// xprintf("Stop\n");
|
||||
HAL_I2C_STOP_IRQ(hi2c);
|
||||
}
|
||||
|
||||
if ((interrupt_status & I2C_ISR_TXIS_M) && (int_mask & I2C_CR1_TXIE_M))
|
||||
{
|
||||
// xprintf("TXIS %d (%d)\n", hi2c->TransferCount, *((uint8_t *)hi2c->pBuffPtr));
|
||||
HAL_I2C_TXIS_IRQ(hi2c);
|
||||
}
|
||||
|
||||
if ((interrupt_status & I2C_ISR_RXNE_M) && (int_mask & I2C_CR1_RXIE_M))
|
||||
{
|
||||
// xprintf("RXNE %d\n", hi2c->TransferCount);
|
||||
HAL_I2C_RXNE_IRQ(hi2c);
|
||||
}
|
||||
|
||||
if ((interrupt_status & I2C_ISR_TCR_M) && (int_mask & I2C_CR1_TCIE_M))
|
||||
{
|
||||
// xprintf("TCR\n");
|
||||
HAL_I2C_TCR_IRQ(hi2c);
|
||||
}
|
||||
|
||||
if ((interrupt_status & I2C_ISR_TC_M) && (int_mask & I2C_CR1_TCIE_M))
|
||||
{
|
||||
// xprintf("TC\n");
|
||||
HAL_I2C_TC_IRQ(hi2c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,333 @@
|
||||
#ifndef MIK32_HAL_IRQ
|
||||
#define MIK32_HAL_IRQ
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "epic.h"
|
||||
#include "csr.h"
|
||||
#include "scr1_csr_encoding.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
|
||||
|
||||
/* Title: Макросы */
|
||||
#ifdef MIK32V0
|
||||
/*
|
||||
* Defines: Маска линии прерывания
|
||||
*
|
||||
*
|
||||
* HAL_EPIC_TIMER32_0_MASK - Маска для линии прерывания Timer32_0
|
||||
* HAL_EPIC_UART_0_MASK - Маска для линии прерывания USART_0
|
||||
* HAL_EPIC_UART_1_MASK - Маска для линии прерывания USART_1
|
||||
* HAL_EPIC_SPI_0_MASK - Маска для линии прерывания SPI_0
|
||||
* HAL_EPIC_SPI_1_MASK - Маска для линии прерывания SPI_1
|
||||
* HAL_EPIC_GPIO_IRQ_MASK - Маска для линии прерывания GPIO
|
||||
* HAL_EPIC_I2C_0_MASK - Маска для линии прерывания I2C_0
|
||||
* HAL_EPIC_I2C_1_MASK - Маска для линии прерывания I2C_1
|
||||
* HAL_EPIC_WDT_MASK - Маска для линии прерывания Сторожевой таймер
|
||||
* HAL_EPIC_TIMER16_0_MASK - Маска для линии прерывания Timer16_0
|
||||
* HAL_EPIC_TIMER16_1_MASK - Маска для линии прерывания Timer16_1
|
||||
* HAL_EPIC_TIMER16_2_MASK - Маска для линии прерывания Timer16_2
|
||||
* HAL_EPIC_TIMER32_1_MASK - Маска для линии прерывания Timer32_1
|
||||
* HAL_EPIC_TIMER32_2_MASK - Маска для линии прерывания Timer32_2
|
||||
* HAL_EPIC_SPIFI_MASK - Маска для линии прерывания SPIFI
|
||||
* HAL_EPIC_RTC_MASK - Маска для линии прерывания RTC
|
||||
* HAL_EPIC_EEPROM_MASK - Маска для линии прерывания EEPROM
|
||||
* HAL_EPIC_WDT_DOM3_MASK - Маска для линии прерывания Сторожевой таймер шины (периферийные устройства)
|
||||
* HAL_EPIC_WDT_SPIFI_MASK - Маска для линии прерывания Сторожевой таймер шины (SPIFI)
|
||||
* HAL_EPIC_WDT_EEPROM_MASK - Маска для линии прерывания Сторожевой таймер шины (EEPROM)
|
||||
* HAL_EPIC_DMA_GLB_ERR_MASK - Маска для линии прерывания ПДП глобальное прерывание
|
||||
* HAL_EPIC_DMA_CHANNELS_MASK - Маска для линии прерывания ПДП локальное прерывание
|
||||
* HAL_EPIC_FREQ_MON_MASK - Маска для линии прерывания Монитор частоты
|
||||
* HAL_EPIC_PVD_AVCC_UNDER - Маска для линии прерывания Монитор напряжения AVCC (ниже порога)
|
||||
* HAL_EPIC_PVD_AVCC_OVER - Маска для линии прерывания Монитор напряжения AVCC (выше порога)
|
||||
* HAL_EPIC_PVD_VCC_UNDER - Маска для линии прерывания Монитор напряжения VCC (ниже порога)
|
||||
* HAL_EPIC_PVD_VCC_OVER - Маска для линии прерывания Монитор напряжения VCC (выше порога)
|
||||
* HAL_EPIC_BATTERY_NON_GOOD - Маска для линии прерывания Недостаточное напряжение батареи
|
||||
* HAL_EPIC_BOR_MASK - Маска для линии прерывания BrouwnOut детектор
|
||||
* HAL_EPIC_TSENS_MASK - Маска для линии прерывания Монитор температуры
|
||||
* HAL_EPIC_ADC_MASK - Маска для линии прерывания АЦП
|
||||
*
|
||||
*/
|
||||
#define HAL_EPIC_TIMER32_0_MASK ( 1 << EPIC_TIMER32_0_INDEX )
|
||||
#define HAL_EPIC_UART_0_MASK ( 1 << EPIC_UART_0_INDEX )
|
||||
#define HAL_EPIC_UART_1_MASK ( 1 << EPIC_UART_1_INDEX )
|
||||
#define HAL_EPIC_SPI_0_MASK ( 1 << EPIC_SPI_0_INDEX )
|
||||
#define HAL_EPIC_SPI_1_MASK ( 1 << EPIC_SPI_1_INDEX )
|
||||
#define HAL_EPIC_GPIO_IRQ_MASK ( 1 << EPIC_GPIO_IRQ_INDEX )
|
||||
#define HAL_EPIC_I2C_0_MASK ( 1 << EPIC_I2C_0_INDEX )
|
||||
#define HAL_EPIC_I2C_1_MASK ( 1 << EPIC_I2C_1_INDEX )
|
||||
#define HAL_EPIC_WDT_MASK ( 1 << EPIC_WDT_INDEX )
|
||||
#define HAL_EPIC_TIMER16_0_MASK ( 1 << EPIC_TIMER16_0_INDEX )
|
||||
#define HAL_EPIC_TIMER16_1_MASK ( 1 << EPIC_TIMER16_1_INDEX )
|
||||
#define HAL_EPIC_TIMER16_2_MASK ( 1 << EPIC_TIMER16_2_INDEX )
|
||||
#define HAL_EPIC_TIMER32_1_MASK ( 1 << EPIC_TIMER32_1_INDEX )
|
||||
#define HAL_EPIC_TIMER32_2_MASK ( 1 << EPIC_TIMER32_2_INDEX )
|
||||
#define HAL_EPIC_SPIFI_MASK ( 1 << EPIC_SPIFI_INDEX )
|
||||
#define HAL_EPIC_RTC_MASK ( 1 << EPIC_RTC_INDEX )
|
||||
#define HAL_EPIC_EEPROM_MASK ( 1 << EPIC_EEPROM_INDEX )
|
||||
#define HAL_EPIC_WDT_DOM3_MASK ( 1 << EPIC_WDT_DOM3_INDEX )
|
||||
#define HAL_EPIC_WDT_SPIFI_MASK ( 1 << EPIC_WDT_SPIFI_INDEX )
|
||||
#define HAL_EPIC_WDT_EEPROM_MASK ( 1 << EPIC_WDT_EEPROM_INDEX )
|
||||
#define HAL_EPIC_DMA_GLB_ERR_MASK ( 1 << EPIC_DMA_GLB_ERR_INDEX )
|
||||
#define HAL_EPIC_DMA_CHANNELS_MASK ( 1 << EPIC_DMA_CHANNELS_INDEX )
|
||||
#define HAL_EPIC_FREQ_MON_MASK ( 1 << EPIC_FREQ_MON_INDEX )
|
||||
#define HAL_EPIC_PVD_AVCC_UNDER ( 1 << EPIC_PVD_AVCC_UNDER )
|
||||
#define HAL_EPIC_PVD_AVCC_OVER ( 1 << EPIC_PVD_AVCC_OVER )
|
||||
#define HAL_EPIC_PVD_VCC_UNDER ( 1 << EPIC_PVD_VCC_UNDER )
|
||||
#define HAL_EPIC_PVD_VCC_OVER ( 1 << EPIC_PVD_VCC_OVER )
|
||||
#define HAL_EPIC_BATTERY_NON_GOOD ( 1 << EPIC_BATTERY_NON_GOOD )
|
||||
#define HAL_EPIC_BOR_MASK ( 1 << EPIC_BOR_INDEX )
|
||||
#define HAL_EPIC_TSENS_MASK ( 1 << EPIC_TSENS_INDEX )
|
||||
#define HAL_EPIC_ADC_MASK ( 1 << EPIC_ADC_INDEX )
|
||||
|
||||
/*
|
||||
* macros: Проверка флагов линий прерываний в EPIC
|
||||
*
|
||||
*
|
||||
* EPIC_CHECK_Timer32_0 - Проверка флага Timer32_0
|
||||
* EPIC_CHECK_UART_0 - Проверка флага USART_0
|
||||
* EPIC_CHECK_UART_1 - Проверка флага USART_1
|
||||
* EPIC_CHECK_SPI_0 - Проверка флага SPI_0
|
||||
* EPIC_CHECK_SPI_1 - Проверка флага SPI_1
|
||||
* EPIC_CHECK_GPIO - Проверка флага GPIO
|
||||
* EPIC_CHECK_I2C_0 - Проверка флага I2C_0
|
||||
* EPIC_CHECK_I2C_1 - Проверка флага I2C_1
|
||||
* EPIC_CHECK_WDT - Проверка флага Сторожевой таймер
|
||||
* EPIC_CHECK_TIMER16_0 - Проверка флага Timer16_0
|
||||
* EPIC_CHECK_TIMER16_1 - Проверка флага Timer16_1
|
||||
* EPIC_CHECK_TIMER16_2 - Проверка флага Timer16_2
|
||||
* EPIC_CHECK_TIMER32_1 - Проверка флага Timer32_1
|
||||
* EPIC_CHECK_TIMER32_2 - Проверка флага Timer32_2
|
||||
* EPIC_CHECK_SPIFI - Проверка флага SPIFI
|
||||
* EPIC_CHECK_RTC - Проверка флага RTC
|
||||
* EPIC_CHECK_EEPROM - Проверка флага EEPROM
|
||||
* EPIC_CHECK_WDT_DOM3 - Проверка флага Сторожевой таймер шины (периферийные устройства)
|
||||
* EPIC_CHECK_WDT_SPIFI - Проверка флага Сторожевой таймер шины (SPIFI)
|
||||
* EPIC_CHECK_WDT_EEPROM - Проверка флага Сторожевой таймер шины (EEPROM)
|
||||
* EPIC_CHECK_DMA_GLB_ERR - Проверка флага ПДП глобальное прерывание
|
||||
* EPIC_CHECK_DMA_CHANNELS - Проверка флага ПДП локальное прерывание
|
||||
* EPIC_CHECK_FREQ_MON - Проверка флага Монитор частоты
|
||||
* EPIC_CHECK_PVD_AVCC_UNDER - Проверка флага Монитор напряжения AVCC (ниже порога)
|
||||
* EPIC_CHECK_PVD_AVCC_OVER - Проверка флага Монитор напряжения AVCC (выше порога)
|
||||
* EPIC_CHECK_PVD_VCC_UNDER - Проверка флага Монитор напряжения VCC (ниже порога)
|
||||
* EPIC_CHECK_PVD_VCC_OVER - Проверка флага Монитор напряжения VCC (выше порога)
|
||||
* EPIC_CHECK_BATTERY_NON_GOOD - Проверка флага Недостаточное напряжение батареи
|
||||
* EPIC_CHECK_BOR - Проверка флага BrouwnOut детектор
|
||||
* EPIC_CHECK_TSENS - Проверка флага Монитор температуры
|
||||
* EPIC_CHECK_ADC - Проверка флага АЦП
|
||||
*
|
||||
*/
|
||||
#define EPIC_CHECK_TIMER32_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_0_INDEX))
|
||||
#define EPIC_CHECK_UART_0() (EPIC->RAW_STATUS & (1 << EPIC_UART_0_INDEX))
|
||||
#define EPIC_CHECK_UART_1() (EPIC->RAW_STATUS & (1 << EPIC_UART_1_INDEX))
|
||||
#define EPIC_CHECK_SPI_0() (EPIC->RAW_STATUS & (1 << EPIC_SPI_0_INDEX))
|
||||
#define EPIC_CHECK_SPI_1() (EPIC->RAW_STATUS & (1 << EPIC_SPI_1_INDEX))
|
||||
#define EPIC_CHECK_GPIO_IRQ() (EPIC->RAW_STATUS & (1 << EPIC_GPIO_IRQ_INDEX))
|
||||
#define EPIC_CHECK_I2C_0() (EPIC->RAW_STATUS & (1 << EPIC_I2C_0_INDEX))
|
||||
#define EPIC_CHECK_I2C_1() (EPIC->RAW_STATUS & (1 << EPIC_I2C_1_INDEX))
|
||||
#define EPIC_CHECK_WDT() (EPIC->STATUS & (1 << EPIC_WDT_INDEX))
|
||||
#define EPIC_CHECK_TIMER16_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_0_INDEX))
|
||||
#define EPIC_CHECK_TIMER16_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_1_INDEX))
|
||||
#define EPIC_CHECK_TIMER16_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_2_INDEX))
|
||||
#define EPIC_CHECK_TIMER32_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_1_INDEX))
|
||||
#define EPIC_CHECK_TIMER32_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_2_INDEX))
|
||||
#define EPIC_CHECK_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_SPIFI_INDEX))
|
||||
#define EPIC_CHECK_RTC() (EPIC->RAW_STATUS & (1 << EPIC_RTC_INDEX))
|
||||
#define EPIC_CHECK_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_EEPROM_INDEX))
|
||||
#define EPIC_CHECK_WDT_DOM3() (EPIC->RAW_STATUS & (1 << EPIC_WDT_DOM3_INDEX))
|
||||
#define EPIC_CHECK_WDT_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_WDT_SPIFI_INDEX))
|
||||
#define EPIC_CHECK_WDT_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_WDT_EEPROM_INDEX))
|
||||
#define EPIC_CHECK_DMA_GLB_ERR() (EPIC->RAW_STATUS & (1 << EPIC_DMA_GLB_ERR_INDEX))
|
||||
#define EPIC_CHECK_DMA_CHANNELS() (EPIC->RAW_STATUS & (1 << EPIC_DMA_CHANNELS_INDEX))
|
||||
#define EPIC_CHECK_FREQ_MON() (EPIC->STATUS & (1 << EPIC_FREQ_MON_INDEX))
|
||||
#define EPIC_CHECK_PVD_AVCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_UNDER))
|
||||
#define EPIC_CHECK_PVD_AVCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_OVER))
|
||||
#define EPIC_CHECK_PVD_VCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_UNDER))
|
||||
#define EPIC_CHECK_PVD_VCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_OVER))
|
||||
#define EPIC_CHECK_BATTERY_NON_GOOD() (EPIC->STATUS & (1 << EPIC_BATTERY_NON_GOOD))
|
||||
#define EPIC_CHECK_BOR() (EPIC->STATUS & (1 << EPIC_BOR_INDEX))
|
||||
#define EPIC_CHECK_TSENS() (EPIC->RAW_STATUS & (1 << EPIC_TSENS_INDEX))
|
||||
#define EPIC_CHECK_ADC() (EPIC->STATUS & (1 << EPIC_ADC_INDEX))
|
||||
#else // MIK32V2
|
||||
#define HAL_EPIC_TIMER32_0_MASK (1 << EPIC_TIMER32_0_INDEX)
|
||||
#define HAL_EPIC_UART_0_MASK (1 << EPIC_UART_0_INDEX)
|
||||
#define HAL_EPIC_UART_1_MASK (1 << EPIC_UART_1_INDEX)
|
||||
#define HAL_EPIC_SPI_0_MASK (1 << EPIC_SPI_0_INDEX)
|
||||
#define HAL_EPIC_SPI_1_MASK (1 << EPIC_SPI_1_INDEX)
|
||||
#define HAL_EPIC_GPIO_IRQ_MASK (1 << EPIC_GPIO_IRQ_INDEX)
|
||||
#define HAL_EPIC_I2C_0_MASK (1 << EPIC_I2C_0_INDEX)
|
||||
#define HAL_EPIC_I2C_1_MASK (1 << EPIC_I2C_1_INDEX)
|
||||
#define HAL_EPIC_WDT_MASK (1 << EPIC_WDT_INDEX)
|
||||
#define HAL_EPIC_TIMER16_0_MASK (1 << EPIC_TIMER16_0_INDEX)
|
||||
#define HAL_EPIC_TIMER16_1_MASK (1 << EPIC_TIMER16_1_INDEX)
|
||||
#define HAL_EPIC_TIMER16_2_MASK (1 << EPIC_TIMER16_2_INDEX)
|
||||
#define HAL_EPIC_TIMER32_1_MASK (1 << EPIC_TIMER32_1_INDEX)
|
||||
#define HAL_EPIC_TIMER32_2_MASK (1 << EPIC_TIMER32_2_INDEX)
|
||||
#define HAL_EPIC_SPIFI_MASK (1 << EPIC_SPIFI_INDEX)
|
||||
#define HAL_EPIC_RTC_MASK (1 << EPIC_RTC_INDEX)
|
||||
#define HAL_EPIC_EEPROM_MASK (1 << EPIC_EEPROM_INDEX)
|
||||
#define HAL_EPIC_WDT_DOM3_MASK (1 << EPIC_WDT_DOM3_INDEX)
|
||||
#define HAL_EPIC_WDT_SPIFI_MASK (1 << EPIC_WDT_SPIFI_INDEX)
|
||||
#define HAL_EPIC_WDT_EEPROM_MASK (1 << EPIC_WDT_EEPROM_INDEX)
|
||||
#define HAL_EPIC_DMA_MASK (1 << EPIC_DMA_INDEX)
|
||||
#define HAL_EPIC_FREQ_MON_MASK (1 << EPIC_FREQ_MON_INDEX)
|
||||
#define HAL_EPIC_PVD_AVCC_MASK (1 << EPIC_PVD_AVCC_UNDER)
|
||||
#define HAL_EPIC_PVD_AVCCMASK (1 << EPIC_PVD_AVCC_OVER)
|
||||
#define HAL_EPIC_PVD_VCC_MASK (1 << EPIC_PVD_VCC_UNDER)
|
||||
#define HAL_EPIC_PVD_VCCMASK (1 << EPIC_PVD_VCC_OVER)
|
||||
#define HAL_EPIC_BATTERY_NONMASK (1 << EPIC_BATTERY_NON_GOOD)
|
||||
#define HAL_EPIC_BOR_MASK (1 << EPIC_BOR_INDEX)
|
||||
#define HAL_EPIC_TSENS_MASK (1 << EPIC_TSENS_INDEX)
|
||||
#define HAL_EPIC_ADC_MASK (1 << EPIC_ADC_INDEX)
|
||||
#define HAL_EPIC_DAC0_MASK (1 << EPIC_DAC0_INDEX)
|
||||
#define HAL_EPIC_DAC1_MASK (1 << EPIC_DAC1_INDEX)
|
||||
|
||||
#define EPIC_CHECK_TIMER32_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_0_INDEX))
|
||||
#define EPIC_CHECK_UART_0() (EPIC->RAW_STATUS & (1 << EPIC_UART_0_INDEX))
|
||||
#define EPIC_CHECK_UART_1() (EPIC->RAW_STATUS & (1 << EPIC_UART_1_INDEX))
|
||||
#define EPIC_CHECK_SPI_0() (EPIC->RAW_STATUS & (1 << EPIC_SPI_0_INDEX))
|
||||
#define EPIC_CHECK_SPI_1() (EPIC->RAW_STATUS & (1 << EPIC_SPI_1_INDEX))
|
||||
#define EPIC_CHECK_GPIO_IRQ() (EPIC->RAW_STATUS & (1 << EPIC_GPIO_IRQ_INDEX))
|
||||
#define EPIC_CHECK_I2C_0() (EPIC->RAW_STATUS & (1 << EPIC_I2C_0_INDEX))
|
||||
#define EPIC_CHECK_I2C_1() (EPIC->RAW_STATUS & (1 << EPIC_I2C_1_INDEX))
|
||||
#define EPIC_CHECK_WDT() (EPIC->STATUS & (1 << EPIC_WDT_INDEX))
|
||||
#define EPIC_CHECK_TIMER16_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_0_INDEX))
|
||||
#define EPIC_CHECK_TIMER16_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_1_INDEX))
|
||||
#define EPIC_CHECK_TIMER16_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_2_INDEX))
|
||||
#define EPIC_CHECK_TIMER32_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_1_INDEX))
|
||||
#define EPIC_CHECK_TIMER32_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_2_INDEX))
|
||||
#define EPIC_CHECK_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_SPIFI_INDEX))
|
||||
#define EPIC_CHECK_RTC() (EPIC->RAW_STATUS & (1 << EPIC_RTC_INDEX))
|
||||
#define EPIC_CHECK_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_EEPROM_INDEX))
|
||||
#define EPIC_CHECK_WDT_DOM3() (EPIC->RAW_STATUS & (1 << EPIC_WDT_DOM3_INDEX))
|
||||
#define EPIC_CHECK_WDT_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_WDT_SPIFI_INDEX))
|
||||
#define EPIC_CHECK_WDT_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_WDT_EEPROM_INDEX))
|
||||
#define EPIC_CHECK_DMA() (EPIC->RAW_STATUS & (1 << EPIC_DMA_INDEX))
|
||||
#define EPIC_CHECK_FREQ_MON() (EPIC->STATUS & (1 << EPIC_FREQ_MON_INDEX))
|
||||
#define EPIC_CHECK_PVD_AVCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_UNDER))
|
||||
#define EPIC_CHECK_PVD_AVCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_OVER))
|
||||
#define EPIC_CHECK_PVD_VCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_UNDER))
|
||||
#define EPIC_CHECK_PVD_VCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_OVER))
|
||||
#define EPIC_CHECK_BATTERY_NON_GOOD() (EPIC->STATUS & (1 << EPIC_BATTERY_NON_GOOD))
|
||||
#define EPIC_CHECK_BOR() (EPIC->STATUS & (1 << EPIC_BOR_INDEX))
|
||||
#define EPIC_CHECK_TSENS() (EPIC->RAW_STATUS & (1 << EPIC_TSENS_INDEX))
|
||||
#define EPIC_CHECK_ADC() (EPIC->STATUS & (1 << EPIC_ADC_INDEX))
|
||||
#define EPIC_CHECK_DAC0() (EPIC->STATUS & (1 << EPIC_DAC0_INDEX))
|
||||
#define EPIC_CHECK_DAC1() (EPIC->STATUS & (1 << EPIC_DAC1_INDEX))
|
||||
#endif // MIK32V0
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function: HAL_IRQ_EnableInterrupts
|
||||
* Разрешить глобальные прерывания.
|
||||
*
|
||||
* Разрешается машинное программное прерывание.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_IRQ_EnableInterrupts();
|
||||
|
||||
/*
|
||||
* Function: HAL_IRQ_DisableInterrupts
|
||||
* Запретить машинное программное прерывание.
|
||||
*
|
||||
* Глобальные прерывания не запрещаются.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_IRQ_DisableInterrupts();
|
||||
/* Прерывание по фронту */
|
||||
|
||||
/*
|
||||
* Function: HAL_EPIC_MaskSet
|
||||
* Задать маску разрешенных линий прерываний по фронту
|
||||
*
|
||||
* Parameters:
|
||||
* InterruptMask - Маска разрешенных линий прерываний
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_EPIC_MaskEdgeSet(uint32_t InterruptMask);
|
||||
|
||||
/*
|
||||
* Function: HAL_EPIC_MaskClear
|
||||
* Сбросить маску разрешенный линий прерываний по фронту
|
||||
*
|
||||
* Parameters:
|
||||
* InterruptMask - Маска сбрасываемых линий прерываний
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_EPIC_MaskEdgeClear(uint32_t InterruptMask);
|
||||
|
||||
/*
|
||||
* Function: HAL_EPIC_MaskSet
|
||||
* Задать маску разрешенных линий прерываний по уровню
|
||||
*
|
||||
* Parameters:
|
||||
* InterruptMask - Маска разрешенных линий прерываний
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_EPIC_MaskLevelSet(uint32_t InterruptMask);
|
||||
|
||||
/*
|
||||
* Function: HAL_EPIC_MaskClear
|
||||
* Сбросить маску разрешенный линий прерываний по уровню
|
||||
*
|
||||
* Parameters:
|
||||
* InterruptMask - Маска сбрасываемых линий прерываний
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_EPIC_MaskLevelClear(uint32_t InterruptMask);
|
||||
|
||||
/*
|
||||
* Function: HAL_EPIC_Clear
|
||||
* Сбросить прерывания
|
||||
*
|
||||
* Parameters:
|
||||
* InterruptMask - Маска сбрасываемых линий прерываний
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void HAL_EPIC_Clear(uint32_t InterruptMask)
|
||||
{
|
||||
EPIC->CLEAR = InterruptMask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: HAL_EPIC_GetStatus
|
||||
* Получить текущий статус прерываний в соответствии с маской разрешенных прерываний
|
||||
*
|
||||
* Returns:
|
||||
* (uint32_t ) - Текущий статус прерываний в соответствии с маской разрешенных прерываний
|
||||
*/
|
||||
uint32_t HAL_EPIC_GetStatus();
|
||||
|
||||
/*
|
||||
* Function: HAL_EPIC_GetRawStatus
|
||||
* Получить текущий статус прерываний
|
||||
*
|
||||
* В данном статусе маска разрешенных прерываний не учитывается
|
||||
*
|
||||
* Returns:
|
||||
* (uint32_t ) - текущий статус прерываний
|
||||
*/
|
||||
uint32_t HAL_EPIC_GetRawStatus();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
#ifndef MIK32_HAL_OTP
|
||||
#define MIK32_HAL_OTP
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "mik32_hal_gpio.h"
|
||||
#include "power_manager.h"
|
||||
#include "otp.h"
|
||||
#include "pad_config.h"
|
||||
#include "stdbool.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
|
||||
|
||||
/* Выбор напряжения на UPP матрицы. */
|
||||
#define OTP_UPP_READ_2V 0b000 /**< 2 В. */
|
||||
#define OTP_UPP_READ_2_5V 0b001 /**< 2,5 В. */
|
||||
#define OTP_UPP_READ_3V 0b011 /**< 3 В. */
|
||||
#define OTP_UPP_READ_VDD18 0b010 /**< VDD18. */
|
||||
#define OTP_UPP_READ_VDD5 0b110 /**< VDD5. */
|
||||
|
||||
/* Выбор тока считывания. */
|
||||
#define OTP_READ_CUR_2 0 /**< 2 мкА. */
|
||||
#define OTP_READ_CUR_0_2 1 /**< 0,2 мкА. */
|
||||
|
||||
#define OTP_POWER_OFF 1 /**< Hard IP введен в режим пониженного энергопотребления, операции записи и чтения запрещены. */
|
||||
#define OTP_POWER_ON 0 /**< Hard IP выведен из режима пониженного энергопотребления и может выполнять операции чтения и записи. */
|
||||
|
||||
|
||||
/* Режим чтения. */
|
||||
#define OPT_READ_2STAGES 0 /**< Чтение в 2 этапа. Вводятся такты ожидания APB. */
|
||||
#define OPT_READ_3STAGES 1 /**< Чтение в 3 этапа. Опрос флага BSY. Нет тактов ожидания APB. */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Настройки OTP.
|
||||
*
|
||||
*/
|
||||
typedef struct __OTP_HandleTypeDef
|
||||
{
|
||||
OTP_TypeDef *Instance; /**< Базовый адрес регистров OTP. */
|
||||
|
||||
uint8_t ReadMode; /**< Режим чтения. */
|
||||
|
||||
} OTP_HandleTypeDef;
|
||||
|
||||
|
||||
void HAL_OTP_MspInit(OTP_HandleTypeDef* hotp);
|
||||
void HAL_OTP_PowerOff(OTP_HandleTypeDef *hotp, uint8_t PowerOff);
|
||||
void HAL_OTP_SetUppRead(OTP_HandleTypeDef *hotp, uint8_t UppReadVoltage);
|
||||
void HAL_OTP_SetReadCur(OTP_HandleTypeDef *hotp, uint8_t ReadCur);
|
||||
void HAL_OPT_TimeInit(OTP_HandleTypeDef *hotp);
|
||||
void HAL_OTP_Init(OTP_HandleTypeDef *hotp);
|
||||
void HAL_OTP_WaitBSY(OTP_HandleTypeDef *hotp);
|
||||
void HAL_OTP_WriteTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength);
|
||||
void HAL_OTP_WriteTestRow(OTP_HandleTypeDef *hotp, uint32_t Data);
|
||||
void HAL_OTP_WriteTestBit(OTP_HandleTypeDef *hotp, uint32_t Data);
|
||||
void HAL_OTP_Write(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength);
|
||||
void HAL_OTP_ReadTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength);
|
||||
uint32_t HAL_OTP_ReadTestRow(OTP_HandleTypeDef *hotp);
|
||||
uint32_t HAL_OTP_ReadTestBit(OTP_HandleTypeDef *hotp);
|
||||
void HAL_OTP_Read(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,280 @@
|
||||
#ifndef MIK32_HAL_PCC
|
||||
#define MIK32_HAL_PCC
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "wakeup.h"
|
||||
#include "power_manager.h"
|
||||
#include "mik32_hal_def.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
#include "mik32_hal.h"
|
||||
|
||||
#define CLOCKSWITCH_TIMEOUT_VALUE 500000 /**< Стандартная задержка для ожидания детектирования источника тактирования, на который происходит переключение */
|
||||
|
||||
/**
|
||||
* @brief Источники тактирования.
|
||||
*
|
||||
* Используется как маска для включения источников частоты и
|
||||
* для назначения приоритетного источника тактирования системы в мониторе частоты.
|
||||
*/
|
||||
typedef enum __HAL_PCC_OscillatorTypeTypeDef
|
||||
{
|
||||
PCC_OSCILLATORTYPE_NONE = 0b0000, /**< Автоматический выбор источника тактирования RTC */
|
||||
PCC_OSCILLATORTYPE_HSI32M = 0b0001, /**< Внутренний источник тактирования 32МГц */
|
||||
PCC_OSCILLATORTYPE_OSC32M = 0b0010, /**< Внешний источник тактирования 32МГц */
|
||||
PCC_OSCILLATORTYPE_LSI32K = 0b0100, /**< Внутренний источник тактирования 32КГц */
|
||||
PCC_OSCILLATORTYPE_OSC32K = 0b1000, /**< Внешний источник тактирования 32КГц */
|
||||
PCC_OSCILLATORTYPE_ALL = 0b1111 /**< Все источники */
|
||||
} HAL_PCC_OscillatorTypeTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Принудительный выбор источника тактирования системы.
|
||||
*
|
||||
* Используется для включения или отключения автоматического переключения источника тактирования системы.
|
||||
*/
|
||||
typedef enum __HAL_PCC_ForceOscSysTypeDef
|
||||
{
|
||||
PCC_FORCE_OSC_SYS_UNFIXED = 0, /**< Источник тактирования системы не выбирается принудительно */
|
||||
PCC_FORCE_OSC_SYS_FIXED = 1 /**< Источник тактирования системы выбирается принудительно */
|
||||
} HAL_PCC_ForceOscSysTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Опорный источник тактирования монитора частоты.
|
||||
*
|
||||
* Используется для назначения приоритетного опорного источника тактирования монитора частоты.
|
||||
*/
|
||||
typedef enum __HAL_PCC_FreqMonitorSourceTypeDef
|
||||
{
|
||||
PCC_FREQ_MONITOR_SOURCE_AUTO = 0b00, /**< Опорный источник частоты монитора частоты выбирается автоматически */
|
||||
PCC_FREQ_MONITOR_SOURCE_LSI32K = 0b01, /**< Опорный источник частоты монитора частоты принудительно выбран как LSI32K */
|
||||
PCC_FREQ_MONITOR_SOURCE_OSC32K = 0b10 /**< Опорный источник частоты монитора частоты принудительно выбран как OSC32K */
|
||||
} HAL_PCC_FreqMonitorSourceTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Источники тактирования RTC.
|
||||
*
|
||||
* Используются для назначения приоритетного источника тактирования модуля RTC.
|
||||
*/
|
||||
typedef enum __HAL_PCC_RTCClockSourceTypeDef
|
||||
{
|
||||
PCC_RTC_CLOCK_SOURCE_AUTO = 0b00, /**< Источник тактирования RTC выбирается автоматически. Если присутствуют оба тактовых сигнала 32K, то выбирается LSI32K */
|
||||
PCC_RTC_CLOCK_SOURCE_LSI32K = 0b01, /**< Приоритетный источник тактирования RTC - LSI32K */
|
||||
PCC_RTC_CLOCK_SOURCE_OSC32K = 0b10 /**< Приоритетный источник тактирования RTC - OSC32K */
|
||||
} HAL_PCC_RTCClockSourceTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Источники тактирования RTC в составе ядра.
|
||||
*
|
||||
* Используются для назначения приоритетного источника тактирования RTC в составе ядра.
|
||||
*/
|
||||
typedef enum __HAL_PCC_CPURTCClockSourceTypeDef
|
||||
{
|
||||
PCC_CPU_RTC_CLOCK_SOURCE_OSC32K = 0, /**< Источник тактирования RTC в составе ядра - OSC32K */
|
||||
PCC_CPU_RTC_CLOCK_SOURCE_LSI32K = 1 /**< Источник тактирования RTC в составе ядра - LSI32K */
|
||||
} HAL_PCC_CPURTCClockSourceTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @name Шина AHB
|
||||
* @brief Макросы для включения и отключения тактирования периферии на шине AHB
|
||||
@{
|
||||
*/
|
||||
|
||||
#define __HAL_PCC_CPU_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CPU_M) /**< Включить тактирование CPU */
|
||||
#define __HAL_PCC_CPU_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CPU_M) /**< Выключить тактирование CPU */
|
||||
|
||||
#define __HAL_PCC_EEPROM_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_EEPROM_M) /**< Включить тактирование EEPROM */
|
||||
#define __HAL_PCC_EEPROM_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_EEPROM_M) /**< Выключить тактирование EEPROM */
|
||||
|
||||
#define __HAL_PCC_RAM_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_RAM_M) /**< Включить тактирование RAM */
|
||||
#define __HAL_PCC_RAM_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_RAM_M) /**< Выключить тактирование SPIFI */
|
||||
|
||||
#define __HAL_PCC_SPIFI_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_SPIFI_M) /**< Включить тактирование SPIFI */
|
||||
#define __HAL_PCC_SPIFI_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_SPIFI_M) /**< Выключить тактирование SPIFI */
|
||||
|
||||
#define __HAL_PCC_TCB_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_TCB_M) /**< Включить тактирование блока TCB */
|
||||
#define __HAL_PCC_TCB_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_TCB_M) /**< Выключить тактирование блока TCB */
|
||||
|
||||
#define __HAL_PCC_DMA_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_DMA_M) /**< Включить тактирование DMA */
|
||||
#define __HAL_PCC_DMA_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_DMA_M) /**< Выключить тактирование DMA */
|
||||
|
||||
#define __HAL_PCC_CRYPTO_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRYPTO_M) /**< Включить тактирование крипто-блока */
|
||||
#define __HAL_PCC_CRYPTO_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRYPTO_M) /**< Выключить тактирование крипто-блока */
|
||||
|
||||
#define __HAL_PCC_CRC32_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRC32_M) /**< Включить тактирование CRC */
|
||||
#define __HAL_PCC_CRC32_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRC32_M) /**< Выключить тактирование CRC */
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Шина APB_M
|
||||
* @brief Макросы для включения и отключения тактирования периферии на шине APB_M
|
||||
@{
|
||||
*/
|
||||
|
||||
#define __HAL_PCC_PM_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_PM_M) /**< Включить тактирование Power manager */
|
||||
#define __HAL_PCC_PM_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_PM_M) /**< Выключить тактирование Power manager */
|
||||
|
||||
#define __HAL_PCC_EPIC_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_EPIC_M) /**< Включить тактирование контроллера прерываний */
|
||||
#define __HAL_PCC_EPIC_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_EPIC_M) /**< Выключить тактирование контроллера прерываний */
|
||||
|
||||
#define __HAL_PCC_TIMER32_0_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_TIMER32_0_M) /**< Включить тактирование TIMER32_0 */
|
||||
#define __HAL_PCC_TIMER32_0_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_TIMER32_0_M) /**< Выключить тактирование TIMER32_0 */
|
||||
|
||||
#define __HAL_PCC_PAD_CONFIG_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_PAD_CONFIG_M) /**< Включить тактирование контроллера выводов */
|
||||
#define __HAL_PCC_PAD_CONFIG_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_PAD_CONFIG_M) /**< Выключить тактирование контроллера выводов */
|
||||
|
||||
#define __HAL_PCC_WDT_BUS_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_WDT_BUS_M) /**< Включить тактирование сторожевого таймера шины */
|
||||
#define __HAL_PCC_WDT_BUS_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_WDT_BUS_M) /**< Выключить тактирование сторожевого таймера шины */
|
||||
|
||||
#define __HAL_PCC_OTP_CONTROLLER_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_OTP_CONTROLLER_M) /**< Включить тактирование OTP */
|
||||
#define __HAL_PCC_OTP_CONTROLLER_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_OTP_CONTROLLER_M) /**< Выключить тактирование OTP */
|
||||
|
||||
#define __HAL_PCC_PVD_CONTROL_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_PVD_CONTROL_M) /**< Включить тактирование Монитора напряжения */
|
||||
#define __HAL_PCC_PVD_CONTROL_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_PVD_CONTROL_M) /**< Выключить тактирование Монитора напряжения */
|
||||
|
||||
#define __HAL_PCC_WU_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_WU_M) /**< Включить тактирование Wake up */
|
||||
#define __HAL_PCC_WU_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_WU_M) /**< Выключить тактирование Wake up */
|
||||
|
||||
#define __HAL_PCC_RTC_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_RTC_M) /**< Включить тактирование RTC */
|
||||
#define __HAL_PCC_RTC_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_RTC_M) /**< Выключить тактирование RTC */
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Шина APB_P
|
||||
* @brief Макросы для включения и отключения тактирования периферии на шине APB_P
|
||||
@{
|
||||
*/
|
||||
|
||||
#define __HAL_PCC_WDT_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_WDT_M) /**< Включить тактирование сторожевого таймера */
|
||||
#define __HAL_PCC_WDT_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_WDT_M) /**< Выключить тактирование сторожевого таймера */
|
||||
|
||||
#define __HAL_PCC_UART_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_UART_0_M) /**< Включить тактирование UART_0 */
|
||||
#define __HAL_PCC_UART_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_UART_0_M) /**< Выключить тактирование UART_0 */
|
||||
|
||||
#define __HAL_PCC_UART_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_UART_1_M) /**< Включить тактирование UART_1 */
|
||||
#define __HAL_PCC_UART_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_UART_1_M) /**< Выключить тактирование UART_1 */
|
||||
|
||||
#define __HAL_PCC_TIMER16_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER16_0_M) /**< Включить тактирование Timer16_0 */
|
||||
#define __HAL_PCC_TIMER16_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER16_0_M) /**< Выключить тактирование Timer16_0 */
|
||||
|
||||
#define __HAL_PCC_TIMER16_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER16_1_M) /**< Включить тактирование Timer16_1 */
|
||||
#define __HAL_PCC_TIMER16_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER16_1_M) /**< Выключить тактирование Timer16_1 */
|
||||
|
||||
#define __HAL_PCC_TIMER16_2_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER16_2_M) /**< Включить тактирование Timer16_2 */
|
||||
#define __HAL_PCC_TIMER16_2_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER16_2_M) /**< Выключить тактирование Timer16_2 */
|
||||
|
||||
#define __HAL_PCC_TIMER32_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER32_1_M) /**< Включить тактирование Timer32_1 */
|
||||
#define __HAL_PCC_TIMER32_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER32_1_M) /**< Выключить тактирование Timer32_1 */
|
||||
|
||||
#define __HAL_PCC_TIMER32_2_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER32_2_M) /**< Включить тактирование Timer32_2 */
|
||||
#define __HAL_PCC_TIMER32_2_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER32_2_M) /**< Выключить тактирование Timer32_2 */
|
||||
|
||||
#define __HAL_PCC_SPI_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_SPI_0_M) /**< Включить тактирование SPI_0 */
|
||||
#define __HAL_PCC_SPI_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_SPI_0_M) /**< Выключить тактирование SPI_0 */
|
||||
|
||||
#define __HAL_PCC_SPI_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_SPI_1_M) /**< Включить тактирование SPI_1 */
|
||||
#define __HAL_PCC_SPI_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_SPI_1_M) /**< Выключить тактирование SPI_1 */
|
||||
|
||||
#define __HAL_PCC_I2C_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_I2C_0_M) /**< Включить тактирование I2C_0 */
|
||||
#define __HAL_PCC_I2C_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_I2C_0_M) /**< Выключить тактирование I2C_0 */
|
||||
|
||||
#define __HAL_PCC_I2C_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_I2C_1_M) /**< Включить тактирование I2C_1 */
|
||||
#define __HAL_PCC_I2C_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_I2C_1_M) /**< Выключить тактирование I2C_1 */
|
||||
|
||||
#define __HAL_PCC_GPIO_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_0_M) /**< Включить тактирование GPIO_0 */
|
||||
#define __HAL_PCC_GPIO_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_0_M) /**< Выключить тактирование GPIO_0 */
|
||||
|
||||
#define __HAL_PCC_GPIO_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_1_M) /**< Включить тактирование GPIO_1 */
|
||||
#define __HAL_PCC_GPIO_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_1_M) /**< Выключить тактирование GPIO_1 */
|
||||
|
||||
#define __HAL_PCC_GPIO_2_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_2_M) /**< Включить тактирование GPIO_2 */
|
||||
#define __HAL_PCC_GPIO_2_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_2_M) /**< Выключить тактирование GPIO_2 */
|
||||
|
||||
#define __HAL_PCC_ANALOG_REGS_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_ANALOG_REGS_M) /**< Включить тактирование аналоговых блоков */
|
||||
#define __HAL_PCC_ANALOG_REGS_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_ANALOG_REGS_M) /**< Выключить тактирование аналоговых блоков */
|
||||
|
||||
#define __HAL_PCC_GPIO_IRQ_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_IRQ_M) /**< Включить тактирование схемы формирования прерываний GPIO */
|
||||
#define __HAL_PCC_GPIO_IRQ_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_IRQ_M) /**< Выключить тактирование схемы формирования прерываний GPIO */
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Структура с состояниями ошибок.
|
||||
*
|
||||
* Используется только как возвращаемое значение функции HAL_PCC_Config(PCC_InitTypeDef *PCC_Init).
|
||||
*/
|
||||
typedef struct __PCC_ConfigErrorsTypeDef
|
||||
{
|
||||
HAL_StatusTypeDef FreqMonRef; /**< Ошибка, возвращаемая функцией HAL_PCC_FreqMonRefSet(HAL_PCC_FreqMonitorSourceTypeDef Force32KClk) */
|
||||
|
||||
HAL_StatusTypeDef SetOscSystem; /**< Ошибка, возвращаемая функцией HAL_PCC_SetOscSystem(uint32_t OscillatorSystem, HAL_PCC_ForceOscSysTypeDef ForceOscSys) */
|
||||
|
||||
HAL_StatusTypeDef RTCClock; /**< Ошибка, возвращаемая функцией HAL_PCC_RTCClock(HAL_PCC_RTCClockSourceTypeDef Oscillator) */
|
||||
|
||||
HAL_StatusTypeDef CPURTCClock; /**< Ошибка, возвращаемая функцией HAL_PCC_CPURTCClock(HAL_PCC_CPURTCClockSourceTypeDef Oscillator) */
|
||||
|
||||
} PCC_ConfigErrorsTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Настройки монитора частоты
|
||||
*/
|
||||
typedef struct __PCC_FreqMonTypeDef
|
||||
{
|
||||
uint8_t OscillatorSystem; /**< Источник тактирования системы. Может принимать одно из значений HAL_PCC_OscillatorTypeTypeDef. */
|
||||
|
||||
HAL_PCC_ForceOscSysTypeDef ForceOscSys; /**< Разрешение принудительного выбора источника тактирования системы. Может принимать одно из значений HAL_PCC_ForceOscSysTypeDef. */
|
||||
|
||||
HAL_PCC_FreqMonitorSourceTypeDef Force32KClk; /**< Опорный источник монитора частоты. Может принимать одно из значений HAL_PCC_FreqMonitorSourceTypeDef. */
|
||||
|
||||
} PCC_FreqMonTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Настройки тактирования и монитора частоты
|
||||
*/
|
||||
typedef struct __PCC_InitTypeDef
|
||||
{
|
||||
uint8_t OscillatorEnable; /**< Осциллятор, который должен быть включен. Этот параметр может быть маской из значений HAL_PCC_OscillatorTypeTypeDef. */
|
||||
|
||||
PCC_FreqMonTypeDef FreqMon; /**< Настройки монитора частоты. */
|
||||
|
||||
uint32_t AHBDivider; /**< Делитель частоты AHB. Этот параметр должен быть числом между Min = 0 и Max = 255 */
|
||||
|
||||
uint32_t APBMDivider; /**< Делитель частоты APB_M. Этот параметр должен быть числом между Min = 0 и Max = 255 */
|
||||
|
||||
uint32_t APBPDivider; /**< Делитель частоты APB_P. Этот параметр должен быть числом между Min = 0 и Max = 255 */
|
||||
|
||||
uint8_t HSI32MCalibrationValue; /**< Поправочный коэффициент HSI32M. Этот параметр должен быть числом между Min = 0 и Max = 255 */
|
||||
|
||||
uint8_t LSI32KCalibrationValue; /**< Поправочный коэффициент LSI32K. Этот параметр должен быть числом между Min = 0 и Max = 255 */
|
||||
|
||||
HAL_PCC_RTCClockSourceTypeDef RTCClockSelection; /**< Источник тактирования RTC. Может принимать одно из значений HAL_PCC_RTCClockSourceTypeDef. */
|
||||
|
||||
HAL_PCC_CPURTCClockSourceTypeDef RTCClockCPUSelection; /**< Источник тактирования RTC в составе ядра. Может принимать одно из значений HAL_PCC_CPURTCClockSourceTypeDef. */
|
||||
|
||||
} PCC_InitTypeDef;
|
||||
|
||||
|
||||
|
||||
void HAL_PCC_OscEnable(HAL_PCC_OscillatorTypeTypeDef Oscillator);
|
||||
void HAL_PCC_OscDisable(uint32_t Oscillator);
|
||||
HAL_StatusTypeDef HAL_PCC_FreqMonRefSet(HAL_PCC_FreqMonitorSourceTypeDef Force32KClk);
|
||||
HAL_StatusTypeDef HAL_PCC_SetOscSystem(uint32_t OscillatorSystem, HAL_PCC_ForceOscSysTypeDef ForceOscSys);
|
||||
HAL_StatusTypeDef HAL_PCC_RTCClock(HAL_PCC_RTCClockSourceTypeDef Oscillator);
|
||||
HAL_StatusTypeDef HAL_PCC_CPURTCClock(HAL_PCC_CPURTCClockSourceTypeDef Oscillator);
|
||||
void HAL_PCC_DividerAHB(uint32_t DividerAHB);
|
||||
void HAL_PCC_DividerAPB_M(uint32_t DividerAPB_M);
|
||||
void HAL_PCC_DividerAPB_P(uint32_t DividerAPB_P);
|
||||
PCC_ConfigErrorsTypeDef HAL_PCC_Config(PCC_InitTypeDef *PCC_Init);
|
||||
uint32_t HAL_PCC_GetSysClockFreq();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,485 @@
|
||||
#ifndef MIK32_HAL_RTC
|
||||
#define MIK32_HAL_RTC
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "mik32_hal_gpio.h"
|
||||
#include "rtc.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
|
||||
/* Title: Макросы */
|
||||
|
||||
/*
|
||||
* Defines: Месяц
|
||||
*
|
||||
*
|
||||
* RTC_MONTH_JANUARY - Январь
|
||||
* RTC_MONTH_FEBRUARY - Февраль
|
||||
* RTC_MONTH_MARCH - Март
|
||||
* RTC_MONTH_APRIL - Апрель
|
||||
* RTC_MONTH_MAY - Май
|
||||
* RTC_MONTH_JUNE - Июнь
|
||||
* RTC_MONTH_JULY - Июль
|
||||
* RTC_MONTH_AUGUST - Август
|
||||
* RTC_MONTH_SEPTEMBER - Сентябрь
|
||||
* RTC_MONTH_OCTOBER - Октябрь
|
||||
* RTC_MONTH_NOVEMBER - Ноябрь
|
||||
* RTC_MONTH_DECEMBER - Декабрь
|
||||
*
|
||||
*/
|
||||
/* Месяц */
|
||||
#define RTC_MONTH_JANUARY 1
|
||||
#define RTC_MONTH_FEBRUARY 2
|
||||
#define RTC_MONTH_MARCH 3
|
||||
#define RTC_MONTH_APRIL 4
|
||||
#define RTC_MONTH_MAY 5
|
||||
#define RTC_MONTH_JUNE 6
|
||||
#define RTC_MONTH_JULY 7
|
||||
#define RTC_MONTH_AUGUST 8
|
||||
#define RTC_MONTH_SEPTEMBER 9
|
||||
#define RTC_MONTH_OCTOBER 10
|
||||
#define RTC_MONTH_NOVEMBER 11
|
||||
#define RTC_MONTH_DECEMBER 12
|
||||
|
||||
/* Title: Макросы */
|
||||
|
||||
/*
|
||||
* Defines: День недели
|
||||
*
|
||||
*
|
||||
* RTC_WEEKDAY_MONDAY - Понедельник
|
||||
* RTC_WEEKDAY_TUESDAY - Вторник
|
||||
* RTC_WEEKDAY_WEDNESDAY - Среда
|
||||
* RTC_WEEKDAY_THURSDAY - Четверг
|
||||
* RTC_WEEKDAY_FRIDAY - Пятница
|
||||
* RTC_WEEKDAY_SATURDAY - Суббота
|
||||
* RTC_WEEKDAY_SUNDAY - Воскресенье
|
||||
*
|
||||
*/
|
||||
/* День недели */
|
||||
#define RTC_WEEKDAY_MONDAY 1
|
||||
#define RTC_WEEKDAY_TUESDAY 2
|
||||
#define RTC_WEEKDAY_WEDNESDAY 3
|
||||
#define RTC_WEEKDAY_THURSDAY 4
|
||||
#define RTC_WEEKDAY_FRIDAY 5
|
||||
#define RTC_WEEKDAY_SATURDAY 6
|
||||
#define RTC_WEEKDAY_SUNDAY 7
|
||||
|
||||
/*
|
||||
* Defines: Прерывание будильника Alarm
|
||||
*
|
||||
*
|
||||
* RTC_ALARM_IRQ_DISABLE - Запретить прерывание Alarm
|
||||
* RTC_ALARM_IRQ_ENABLE - Разрешить прерывание Alarm
|
||||
*
|
||||
*/
|
||||
#define RTC_ALARM_IRQ_DISABLE 0 /* Запретить прерывание Alarm */
|
||||
#define RTC_ALARM_IRQ_ENABLE 1 /* Разрешить прерывание Alarm */
|
||||
|
||||
/* Title: Структуры */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Alarm; /* Разрешение прерывания при наличии установленного бита ALRM */
|
||||
|
||||
} RTC_IRQnTypeDef;
|
||||
|
||||
/*
|
||||
* Struct: RTC_HandleTypeDef
|
||||
* Настройки инициализации RTC
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* Variable: Instance
|
||||
* Базовый адрес регистров RTC
|
||||
*
|
||||
*/
|
||||
RTC_TypeDef *Instance;
|
||||
|
||||
RTC_IRQnTypeDef Interrupts; /* Прерывания RTC */
|
||||
|
||||
} RTC_HandleTypeDef;
|
||||
|
||||
/*
|
||||
* Struct: RTC_HandleTypeDef
|
||||
* Время и день недели
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* Variable: Dow
|
||||
* День недели
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <RTC_WEEKDAY_MONDAY>
|
||||
* - <RTC_WEEKDAY_TUESDAY>
|
||||
* - <RTC_WEEKDAY_WEDNESDAY>
|
||||
* - <RTC_WEEKDAY_THURSDAY>
|
||||
* - <RTC_WEEKDAY_FRIDAY>
|
||||
* - <RTC_WEEKDAY_SATURDAY>
|
||||
* - <RTC_WEEKDAY_SUNDAY>
|
||||
*
|
||||
*/
|
||||
uint8_t Dow; /* Параметр RTC. День недели.
|
||||
Этот параметр должен быть числом между Min = 1 и Max = 7 */
|
||||
|
||||
/*
|
||||
* Variable: Hours
|
||||
* Часы
|
||||
*
|
||||
* Этот параметр должен быть числом в диапазоне от 0 до 23.
|
||||
*
|
||||
*/
|
||||
uint8_t Hours;
|
||||
|
||||
/*
|
||||
* Variable: Minutes
|
||||
* Минуты
|
||||
*
|
||||
* Этот параметр должен быть числом в диапазоне от 0 до 59.
|
||||
*
|
||||
*/
|
||||
uint8_t Minutes;
|
||||
|
||||
/*
|
||||
* Variable: Seconds
|
||||
* Секунды
|
||||
*
|
||||
* Этот параметр должен быть числом в диапазоне от 0 до 59.
|
||||
*
|
||||
*/
|
||||
uint8_t Seconds;
|
||||
|
||||
} RTC_TimeTypeDef;
|
||||
|
||||
/*
|
||||
* Struct: RTC_DateTypeDef
|
||||
* Дата
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* Variable: Century
|
||||
* Секунды
|
||||
*
|
||||
* Этот параметр должен быть числом в диапазоне от 0 до 99.
|
||||
*
|
||||
*/
|
||||
uint8_t Century;
|
||||
|
||||
/*
|
||||
* Variable: Day
|
||||
* Число
|
||||
*
|
||||
* Этот параметр должен быть числом в диапазоне от 1 до 31.
|
||||
*
|
||||
*/
|
||||
uint8_t Day;
|
||||
|
||||
/*
|
||||
* Variable: Day
|
||||
* Месяц
|
||||
*
|
||||
* Этот параметр должен быть числом в диапазоне от 1 до 12.
|
||||
*
|
||||
*/
|
||||
uint8_t Month;
|
||||
|
||||
/*
|
||||
* Variable: Day
|
||||
* Год
|
||||
*
|
||||
* Этот параметр должен быть числом в диапазоне от 0 до 99.
|
||||
*
|
||||
*/
|
||||
uint8_t Year;
|
||||
|
||||
} RTC_DateTypeDef;
|
||||
|
||||
/*
|
||||
* Struct: RTC_DateTypeDef
|
||||
* Дата и время будильника
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* Variable: AlarmTime
|
||||
* Время и день недели будильника
|
||||
*
|
||||
*/
|
||||
RTC_TimeTypeDef AlarmTime;
|
||||
|
||||
/*
|
||||
* Variable: AlarmDate
|
||||
* Дата будильника
|
||||
*
|
||||
*/
|
||||
RTC_DateTypeDef AlarmDate;
|
||||
|
||||
/*
|
||||
* Variable: MaskAlarmTime
|
||||
* Маска сравнений будильника по времени
|
||||
*
|
||||
*/
|
||||
uint32_t MaskAlarmTime;
|
||||
|
||||
/*
|
||||
* Variable: MaskAlarmDate
|
||||
* Маска сравнений будильника по дате
|
||||
*
|
||||
*/
|
||||
uint32_t MaskAlarmDate;
|
||||
|
||||
} RTC_AlarmTypeDef;
|
||||
|
||||
/* Title: Функции */
|
||||
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_WaitFlag
|
||||
*
|
||||
* Ожидать после записи в регистр RTC установку Flag в 0
|
||||
*
|
||||
* Сигнал проведения синхронизации между тактовыми доменами. После записи в любой регистр и пока данный флаг
|
||||
* читается равным 1, запрещено выполнять любую новую запись.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*
|
||||
*/
|
||||
void HAL_RTC_WaitFlag(RTC_HandleTypeDef *hrtc);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_Disable
|
||||
*
|
||||
* Выключить модуль RTC
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_RTC_Disable(RTC_HandleTypeDef *hrtc);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_Disable
|
||||
*
|
||||
* Включить модуль RTC
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_RTC_Enable(RTC_HandleTypeDef *hrtc);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_SetTime
|
||||
*
|
||||
* Установить временя и день недели RTC в соответствии с параметрами sTime
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
* sTime - Указатель на структуру с настройками времени и дня недели.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_SetDate
|
||||
*
|
||||
* Установить дату в соответствии с параметрами sDate
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
* sDate - Указатель на структуру с настройками даты.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_Alarm_SetTime
|
||||
*
|
||||
* Установить время будильника в соответствии с параметрами sAlarm
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
* sAlarm - Указатель на структуру с настройками времени и дня недели будильника.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_RTC_Alarm_SetTime(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_Alarm_SetDate
|
||||
*
|
||||
* Установить время будильника в соответствии с параметрами sAlarm
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
* sAlarm - Указатель на структуру с настройками даты будильника.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_RTC_Alarm_SetDate(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_SetAlarm
|
||||
*
|
||||
* Установить дату и время будильника в соответствии с параметрами sAlarm
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
* sAlarm - Указатель на структуру с настройками даты и времени будильника.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_AlarmDisable
|
||||
*
|
||||
* Запретить все сравнения будильника
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_RTC_AlarmDisable(RTC_HandleTypeDef *hrtc);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_AlarmDisable
|
||||
*
|
||||
* Очистить флаг будильника Alrm
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_RTC_ClearAlrmFlag(RTC_HandleTypeDef *hrtc);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_GetAlrmFlag
|
||||
*
|
||||
* Получить значение флага будильника Alrm
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
int HAL_RTC_GetAlrmFlag(RTC_HandleTypeDef *hrtc);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_GetDate
|
||||
*
|
||||
* Получить текущую дату RTC
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
*
|
||||
* Returns:
|
||||
* (RTC_DateTypeDef ) - Структура с текущей датой RTC
|
||||
*/
|
||||
RTC_DateTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_GetTime
|
||||
*
|
||||
* Получить текущее время RTC
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
*
|
||||
* Returns:
|
||||
* (RTC_DateTypeDef ) - Структура с текущей датой RTC
|
||||
*/
|
||||
RTC_TimeTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_SetInterruptAlarm
|
||||
* Задать разрешение на включение прерывания Alarm в соответствии с InterruptEnable
|
||||
*
|
||||
* Parameters:
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
* InterruptEnable - Разрешение прерывания Alarm.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
*
|
||||
* - <RTC_ALARM_IRQ_DISABLE>
|
||||
* - <RTC_ALARM_IRQ_ENABLE>
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_RTC_SetInterruptAlarm(RTC_HandleTypeDef *hrtc, uint32_t InterruptEnable);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_InterruptInit
|
||||
* Инициализировать прерывания RTC в соответствии с настройками hrtc
|
||||
*
|
||||
* Parameters:
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
*
|
||||
* Returns:
|
||||
* void.
|
||||
*/
|
||||
void HAL_RTC_InterruptInit(RTC_HandleTypeDef *hrtc);
|
||||
|
||||
/*
|
||||
* Function: HAL_RTC_GetINTE
|
||||
* Получить текущее значение бита разрешения прерывания Alarm - INTE
|
||||
*
|
||||
* Parameters:
|
||||
* hrtc - Указатель на структуру с настройками RTC.
|
||||
*
|
||||
* Returns:
|
||||
* (int ) - Текущее значение бита разрешения прерывания Alarm - INTE
|
||||
*
|
||||
*/
|
||||
int HAL_RTC_GetINTE(RTC_HandleTypeDef *hrtc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,484 @@
|
||||
#ifndef MIK32_HAL_SPI
|
||||
#define MIK32_HAL_SPI
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stddef.h"
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "mik32_hal_gpio.h"
|
||||
#include "power_manager.h"
|
||||
#include "spi_.h"
|
||||
#include "mik32_hal_def.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
|
||||
|
||||
/** Значение timeout по умолчанию. */
|
||||
#define SPI_TIMEOUT_DEFAULT 1000000
|
||||
|
||||
/* Ошибки SPI */
|
||||
#define HAL_SPI_ERROR_NONE 0b00000000 /**< Значение при отсутствии ошибок. */
|
||||
#define HAL_SPI_ERROR_MODF 0b00000001 /**< Маска для ошибки MODE_FAIL - напряжение на выводе n_ss_in не соответствую режиму работы SPI. */
|
||||
#define HAL_SPI_ERROR_OVR 0b00000010 /**< Маска для ошибки RX_OVERFLOW - прерывание при переполнении RX_FIFO. */
|
||||
|
||||
/* Выбор ведомых устройств. */
|
||||
#define SPI_CS_NONE 0b1111 /**< Ведомое устройство не выбрано. */
|
||||
#define SPI_CS_0 0b1110 /**< Ведомое устройство 1. */
|
||||
#define SPI_CS_1 0b1101 /**< Ведомое устройство 2. */
|
||||
#define SPI_CS_2 0b1011 /**< Ведомое устройство 3. */
|
||||
#define SPI_CS_3 0b0111 /**< Ведомое устройство 4. */
|
||||
|
||||
/* Коэффициент деления частоты spi_ref_clk. */
|
||||
#define SPI_BAUDRATE_DIV4 0b001 /**< Коэффициент деления частоты spi_ref_clk - 4. */
|
||||
#define SPI_BAUDRATE_DIV8 0b010 /**< Коэффициент деления частоты spi_ref_clk - 8. */
|
||||
#define SPI_BAUDRATE_DIV16 0b011 /**< Коэффициент деления частоты spi_ref_clk - 16. */
|
||||
#define SPI_BAUDRATE_DIV32 0b100 /**< Коэффициент деления частоты spi_ref_clk - 32. */
|
||||
#define SPI_BAUDRATE_DIV64 0b101 /**< Коэффициент деления частоты spi_ref_clk - 64. */
|
||||
#define SPI_BAUDRATE_DIV128 0b110 /**< Коэффициент деления частоты spi_ref_clk - 128. */
|
||||
#define SPI_BAUDRATE_DIV256 0b111 /**< Коэффициент деления частоты spi_ref_clk - 256. */
|
||||
|
||||
/* Режим управления сигналом выбора ведомого CS. */
|
||||
#define SPI_MANUALCS_OFF 0 /**< Автоматический режим. */
|
||||
#define SPI_MANUALCS_ON 1 /**< Ручной режим. */
|
||||
|
||||
/* Настройки фазы тактового сигнала. */
|
||||
#define SPI_PHASE_OFF 0 /**< Тактовая частота SPI активна вне слова */
|
||||
#define SPI_PHASE_ON 1 /**< Тактовая частота SPI неактивна вне слова */
|
||||
|
||||
/* Настройки полярности тактового сигнала вне слова. */
|
||||
#define SPI_POLARITY_LOW 0 /**< Тактовый сигнал вне слова удерживается на низком уровне. */
|
||||
#define SPI_POLARITY_HIGH 1 /**< Тактовый сигнал вне слова удерживается на высоком уровне. */
|
||||
|
||||
/* Использование внешнего декодера. */
|
||||
#define SPI_DECODER_NONE 0 /**< Внешний декодер не используется. Выбор только 1 из 4 ведомых устройств. */
|
||||
#define SPI_DECODER_USE 1 /**< Используется внешний декодер. */
|
||||
|
||||
/* Длина передаваемой посылки. */
|
||||
#define SPI_DATASIZE_8BITS 0 /**< Длина передаваемой посылки - 8 бит. */
|
||||
#define SPI_DATASIZE_16BITS 1 /**< Длина передаваемой посылки - 16 бит. */
|
||||
#define SPI_DATASIZE_24BITS 2 /**< Длина передаваемой посылки - 24 бит. */
|
||||
#define SPI_DATASIZE_32BITS 3 /**< Длина передаваемой посылки - 32 бит. */
|
||||
|
||||
/* Значения по умолчанию порогового значения TX_FIFO. */
|
||||
#define SPI_THRESHOLD_DEFAULT 4 /* Значение Threshold_of_TX_FIFO по умолчанию*/
|
||||
|
||||
/* Прерывания. */
|
||||
#define TX_FIFO_UNDERFLOW 6 /**< Регистр TX FIFO опустошен. */
|
||||
#define RX_FIFO_FULL 5 /**< Регистр RX_FIFO заполнен. */
|
||||
#define RX_FIFO_NOT_EMPTY 4 /**< Регистр RX_FIFO не пустой. */
|
||||
#define TX_FIFO_FULL 3 /**< Регистр TX_FIFO заполнен. */
|
||||
#define TX_FIFO_NOT_FULL 2 /**< Регистр TX_FIFO не заполнен. */
|
||||
#define MODE_FAIL 1 /**< Напряжение на выводе n_ss_in не соответствую режиму работы SPI. */
|
||||
#define RX_OVERFLOW 0 /**< Прерывание при переполнении RX_FIFO, значение сбрасывается при чтении. */
|
||||
|
||||
#define SPI_BUFFER_SIZE 8 /**< Размер буферов RX и TX. */
|
||||
|
||||
/** @brief Включить модуль SPI.
|
||||
* @param __HANDLE__ Указатель SPI Handle.
|
||||
*/
|
||||
#define __HAL_SPI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->ENABLE = SPI_ENABLE_M)
|
||||
|
||||
/** @brief Выключить модуль SPI.
|
||||
* @param __HANDLE__ Указатель SPI Handle.
|
||||
*/
|
||||
#define __HAL_SPI_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->ENABLE &= ~SPI_ENABLE_M)
|
||||
|
||||
/** @brief Проверить установлен ли указанный флаг SPI или нет.
|
||||
* @param __HANDLE__ Указатель SPI Handle.
|
||||
* @param __FLAG__ Флаг для проверки.
|
||||
* Этот параметр должен быть одним из следующих значений:
|
||||
* - @ref SPI_INT_STATUS_SPI_ACTIVE_M: Флаг статуса сеанса передачи
|
||||
* - @ref SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M: Флаг опустошения буфера TX_FIFO в режиме ведомого перед началом обмена
|
||||
* - @ref SPI_INT_STATUS_RX_FIFO_FULL_M: Флаг заполнения буфера RX_FIFO
|
||||
* - @ref SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M: Флаг наличия данных в буфере RX_FIFO
|
||||
* - @ref SPI_INT_STATUS_TX_FIFO_FULL_M: Флаг заполнения буфера TX_FIFO
|
||||
* - @ref SPI_INT_STATUS_TX_FIFO_NOT_FULL_M: Флаг заполнения буфера TX_FIFO ниже порогового значения
|
||||
* - @ref SPI_INT_STATUS_MODE_FAIL_M: Флаг детектирования напряжение на выводе n_ss_in не соответствую режиму работы SPI
|
||||
* - @ref SPI_INT_STATUS_RX_OVERFLOW_M: Флаг переполнения буфера RX_FIFO
|
||||
*
|
||||
* @return Состояние флага @p __FLAG__ (TRUE или FALSE).
|
||||
*/
|
||||
#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->ENABLE) & (__FLAG__)) == (__FLAG__))
|
||||
|
||||
/**
|
||||
* @brief Выбор режима ведущий/ведомый.
|
||||
*/
|
||||
typedef enum __HAL_SPI_ModeTypeDef
|
||||
{
|
||||
HAL_SPI_MODE_SLAVE = 0, /**< Режим ведомого. */
|
||||
HAL_SPI_MODE_MASTER = 1, /**< Режим ведущего. */
|
||||
|
||||
} HAL_SPI_ModeTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Состояние модуля SPI.
|
||||
*/
|
||||
typedef enum __HAL_SPI_StateTypeDef
|
||||
{
|
||||
HAL_SPI_STATE_READY, /**< Готов к передаче. */
|
||||
HAL_SPI_STATE_BUSY, /**< Идет передача. */
|
||||
HAL_SPI_STATE_END, /**< Передача завершена. */
|
||||
HAL_SPI_STATE_ERROR /**< Ошибка при передаче. */
|
||||
} HAL_SPI_StateTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Определение структуры конфигурации SPI
|
||||
*/
|
||||
typedef struct __SPI_InitTypeDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Выбор режима ведущий/ведомый.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref HAL_SPI_MODE_SLAVE - режим ведомого
|
||||
* - @ref HAL_SPI_MODE_MASTER - режим ведущего
|
||||
*/
|
||||
HAL_SPI_ModeTypeDef SPI_Mode;
|
||||
|
||||
/**
|
||||
* @brief Коэффициент деления частоты.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref SPI_BAUDRATE_DIV4;
|
||||
* - @ref SPI_BAUDRATE_DIV8;
|
||||
* - @ref SPI_BAUDRATE_DIV16;
|
||||
* - @ref SPI_BAUDRATE_DIV32;
|
||||
* - @ref SPI_BAUDRATE_DIV64;
|
||||
* - @ref SPI_BAUDRATE_DIV128;
|
||||
* - @ref SPI_BAUDRATE_DIV256.
|
||||
*/
|
||||
uint8_t BaudRateDiv;
|
||||
|
||||
/**
|
||||
* @brief Режим управления сигналом выбора ведомого CS.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref SPI_MANUALCS_OFF - сигнал выбора ведомого CS управляется автоматически
|
||||
* - @ref SPI_MANUALCS_ON - сигнал выбора ведомого CS управляется вручную
|
||||
*/
|
||||
uint8_t ManualCS;
|
||||
|
||||
/**
|
||||
* @brief Настройка фазы тактового сигнала.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref SPI_PHASE_OFF - тактовая частота SPI активна вне слова. Сигналы SS переводятся в неактивное состояние между словами.
|
||||
* Длительность импульса всегда 1 период тактового сигнала шины APB_P
|
||||
* - @ref SPI_PHASE_ON - тактовая частота SPI неактивна вне слова. Сигналы SS не переводятся в неактивное состояние между словами
|
||||
*/
|
||||
uint8_t CLKPhase;
|
||||
|
||||
/**
|
||||
* @brief Настройка полярности тактового сигнала вне слова.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref SPI_POLARITY_LOW - тактовый сигнал вне слова удерживается на низком уровне
|
||||
* - @ref SPI_POLARITY_HIGH - тактовый сигнал вне слова удерживается на высоком уровне
|
||||
*/
|
||||
uint8_t CLKPolarity;
|
||||
|
||||
/**
|
||||
* @brief Использование внешнего декодера.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref SPI_DECODER_NONE - внешний декодер не используется. Выбирается один ведомый из четырех, подключенный к одному из выводов CS0 - CS3
|
||||
* - @ref SPI_DECODER_USE - используется внешний декодер. Значение @ref SPI_InitTypeDef::ChipSelect "SPI_HandleTypeDef.Init.ChipSelect"
|
||||
* отображается на выводах CS0 - CS3
|
||||
*
|
||||
*/
|
||||
uint8_t Decoder;
|
||||
|
||||
/**
|
||||
* @brief Пороговое значение TX_FIFO.
|
||||
*
|
||||
* Уровень, при котором TX_FIFO считается незаполненным и формируется прерывание TX_FIFO_NOT_full (IXR_TXOW).
|
||||
*/
|
||||
uint8_t ThresholdTX;
|
||||
|
||||
/**
|
||||
* @brief Выбранное ведомое устройство.
|
||||
*
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref SPI_CS_NONE - ведомое устройство не выбрано
|
||||
* - @ref SPI_CS_0 - ведомое устройство 1
|
||||
* - @ref SPI_CS_1 - ведомое устройство 2
|
||||
* - @ref SPI_CS_2 - ведомое устройство 3
|
||||
* - @ref SPI_CS_3 - ведомое устройство 4
|
||||
*/
|
||||
uint8_t ChipSelect;
|
||||
|
||||
} SPI_InitTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Определение структуры SPI Handle.
|
||||
*/
|
||||
typedef struct __SPI_HandleTypeDef
|
||||
{
|
||||
|
||||
SPI_TypeDef *Instance; /**< Адрес регистров SPI. */
|
||||
|
||||
SPI_InitTypeDef Init; /**< Параметры SPI. */
|
||||
|
||||
uint8_t ErrorCode; /**< Код ошибки при работе SPI. */
|
||||
|
||||
HAL_SPI_StateTypeDef State; /**< Состояние модуля SPI. */
|
||||
|
||||
uint8_t *pTxBuffPtr; /**< Указатель на буфер для передачи данных по SPI. */
|
||||
|
||||
uint32_t TxCount; /**< Счетчик байт при передачи данных по SPI. */
|
||||
|
||||
uint8_t *pRxBuffPtr; /**< Указатель на буфер для считывания данных по SPI. */
|
||||
|
||||
uint32_t RxCount; /**< Счетчик байт при считывания данных по SPI. */
|
||||
|
||||
} SPI_HandleTypeDef;
|
||||
|
||||
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi);
|
||||
void HAL_SPI_Enable(SPI_HandleTypeDef *hspi);
|
||||
void HAL_SPI_Disable(SPI_HandleTypeDef *hspi);
|
||||
void HAL_SPI_SetDelayBTWN(SPI_HandleTypeDef *hspi, uint8_t btwn);
|
||||
void HAL_SPI_SetDelayAFTER(SPI_HandleTypeDef *hspi, uint8_t after);
|
||||
void HAL_SPI_SetDelayINIT(SPI_HandleTypeDef *hspi, uint8_t init);
|
||||
void HAL_SPI_SetSlaveIdleCounter(SPI_HandleTypeDef *hspi, uint8_t slave_idle_counter);
|
||||
void HAL_SPI_SetThresholdTX(SPI_HandleTypeDef *hspi, uint32_t threshold);
|
||||
uint32_t HAL_SPI_ReadModuleID(SPI_HandleTypeDef *hspi);
|
||||
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi);
|
||||
void HAL_SPI_ClearTXFIFO(SPI_HandleTypeDef *hspi);
|
||||
void HAL_SPI_ClearRXFIFO(SPI_HandleTypeDef *hspi);
|
||||
void HAL_SPI_ClearError(SPI_HandleTypeDef *hspi);
|
||||
void HAL_SPI_CS_Enable(SPI_HandleTypeDef *hspi, uint32_t CS_M);
|
||||
void HAL_SPI_CS_Disable(SPI_HandleTypeDef *hspi);
|
||||
HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_SPI_Exchange_IT(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Разрешить прерывания в соответствии с маской.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param IntEnMask маска разрешенных прерываний.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void HAL_SPI_InterruptEnable(SPI_HandleTypeDef *hspi, uint32_t IntEnMask)
|
||||
{
|
||||
hspi->Instance->INT_ENABLE |= IntEnMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Запретить прерывания в соответствии с маской.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param IntDisMask маска запрещенных прерываний.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void HAL_SPI_InterruptDisable(SPI_HandleTypeDef *hspi, uint32_t IntDisMask)
|
||||
{
|
||||
hspi->Instance->INT_DISABLE |= IntDisMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получить состояние флага прерывания с учетом маски разрешенных прерываний.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param Interrupt Флаг прерывания.
|
||||
* Этот параметр должен быть одним из следующих значений:
|
||||
* - @ref TX_FIFO_UNDERFLOW - регистр TX FIFO опустошен
|
||||
* - @ref RX_FIFO_FULL - регистр RX_FIFO заполнен
|
||||
* - @ref RX_FIFO_NOT_EMPTY - регистр RX_FIFO не пустой
|
||||
* - @ref TX_FIFO_FULL - регистр TX_FIFO заполнен
|
||||
* - @ref TX_FIFO_NOT_FULL - регистр TX_FIFO не заполнен
|
||||
* - @ref MODE_FAIL - напряжение на выводе n_ss_in не соответствую режиму работы SPI
|
||||
* - @ref RX_OVERFLOW - прерывание при переполнении RX_FIFO, значение сбрасывается при чтении
|
||||
* @return Состояние флага.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint8_t HAL_SPI_GetInterruptStatus(SPI_HandleTypeDef *hspi, uint32_t Interrupt)
|
||||
{
|
||||
uint32_t interrupt_status = hspi->Instance->INT_STATUS & hspi->Instance->INT_MASK;
|
||||
|
||||
switch (Interrupt)
|
||||
{
|
||||
case TX_FIFO_UNDERFLOW:
|
||||
interrupt_status = (interrupt_status & SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M) >> SPI_INT_STATUS_TX_FIFO_UNDERFLOW_S;
|
||||
break;
|
||||
case RX_FIFO_FULL:
|
||||
interrupt_status = (interrupt_status & SPI_INT_STATUS_RX_FIFO_FULL_M) >> SPI_INT_STATUS_RX_FIFO_FULL_S;
|
||||
break;
|
||||
|
||||
case RX_FIFO_NOT_EMPTY:
|
||||
interrupt_status = (interrupt_status & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M) >> SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_S;
|
||||
break;
|
||||
|
||||
case TX_FIFO_FULL:
|
||||
interrupt_status = (interrupt_status & SPI_INT_STATUS_TX_FIFO_FULL_M) >> SPI_INT_STATUS_TX_FIFO_FULL_S;
|
||||
break;
|
||||
|
||||
case TX_FIFO_NOT_FULL:
|
||||
interrupt_status = (interrupt_status & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M) >> SPI_INT_STATUS_TX_FIFO_NOT_FULL_S;
|
||||
break;
|
||||
|
||||
case MODE_FAIL:
|
||||
interrupt_status = (interrupt_status & SPI_INT_STATUS_MODE_FAIL_M) >> SPI_INT_STATUS_MODE_FAIL_S;
|
||||
break;
|
||||
|
||||
case RX_OVERFLOW:
|
||||
interrupt_status = (interrupt_status & SPI_INT_STATUS_RX_OVERFLOW_M) >> SPI_INT_STATUS_RX_OVERFLOW_S;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return interrupt_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Обработчик прерывания RX_OVERFLOW (IXR_RXOVR) - переполнение буфера RX.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void HAL_SPI_RXOverflow_IRQ(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
hspi->State = HAL_SPI_STATE_ERROR;
|
||||
hspi->ErrorCode |= HAL_SPI_ERROR_OVR;
|
||||
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M |
|
||||
SPI_INT_STATUS_MODE_FAIL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_NOT_FULL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_FULL_M |
|
||||
SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M |
|
||||
SPI_INT_STATUS_RX_FIFO_FULL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Обработчик прерывания MODE_FAIL (IXR_MODF) - напряжение на выводе n_ss_in не соответствую режиму работы SPI.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void HAL_SPI_ModeFail_IRQ(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
hspi->State = HAL_SPI_STATE_ERROR;
|
||||
hspi->ErrorCode |= HAL_SPI_ERROR_MODF;
|
||||
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M |
|
||||
SPI_INT_STATUS_MODE_FAIL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_NOT_FULL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_FULL_M |
|
||||
SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M |
|
||||
SPI_INT_STATUS_RX_FIFO_FULL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Обработчик прерывания TX_FIFO_NOT_full (IXR_TXOW) - регистр TX_FIFO не заполнен (меньше значения ThresholdTX).
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void HAL_SPI_TXFifoNotFull_IRQ(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
uint32_t write_read_bytes = SPI_BUFFER_SIZE - hspi->Init.ThresholdTX + 1; /* Число байт для записи и чтения в итерации */
|
||||
|
||||
for (volatile uint32_t i = 0; (i < write_read_bytes) && hspi->TxCount; i++)
|
||||
{
|
||||
hspi->Instance->TXDATA = *(hspi->pTxBuffPtr);
|
||||
hspi->pTxBuffPtr++;
|
||||
hspi->TxCount--;
|
||||
}
|
||||
|
||||
if (hspi->TxCount == 0)
|
||||
{
|
||||
|
||||
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_TX_FIFO_NOT_FULL_M);
|
||||
|
||||
if (hspi->RxCount == 0)
|
||||
{
|
||||
hspi->State = HAL_SPI_STATE_END;
|
||||
__HAL_SPI_DISABLE(hspi);
|
||||
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */
|
||||
volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */
|
||||
(void)unused;
|
||||
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M |
|
||||
SPI_INT_STATUS_MODE_FAIL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_NOT_FULL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_FULL_M |
|
||||
SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M |
|
||||
SPI_INT_STATUS_RX_FIFO_FULL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Обработчик прерывания RX_FIFO_NOT_EMPTY (IXR_RXNEMPTY) - Регистр RX_FIFO не пустой.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void HAL_SPI_RXFifoNotEmpty_IRQ(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
/* Чтение одного байта */
|
||||
*(hspi->pRxBuffPtr) = hspi->Instance->RXDATA;
|
||||
hspi->pRxBuffPtr++;
|
||||
hspi->RxCount--;
|
||||
|
||||
if (hspi->RxCount == 0)
|
||||
{
|
||||
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M | SPI_INT_STATUS_RX_OVERFLOW_M);
|
||||
|
||||
if (hspi->TxCount == 0)
|
||||
{
|
||||
hspi->State = HAL_SPI_STATE_END;
|
||||
__HAL_SPI_DISABLE(hspi);
|
||||
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */
|
||||
volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */
|
||||
(void)unused;
|
||||
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M |
|
||||
SPI_INT_STATUS_MODE_FAIL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_NOT_FULL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_FULL_M |
|
||||
SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M |
|
||||
SPI_INT_STATUS_RX_FIFO_FULL_M |
|
||||
SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Обработчик запроса прерывания SPI.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
uint32_t interrupt_status = hspi->Instance->INT_STATUS & hspi->Instance->INT_MASK;
|
||||
|
||||
if (!(interrupt_status & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M | SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M)))
|
||||
{
|
||||
if (interrupt_status & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M)
|
||||
{
|
||||
HAL_SPI_RXFifoNotEmpty_IRQ(hspi);
|
||||
}
|
||||
|
||||
if (interrupt_status & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M)
|
||||
{
|
||||
HAL_SPI_TXFifoNotFull_IRQ(hspi);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (interrupt_status & SPI_INT_STATUS_RX_OVERFLOW_M)
|
||||
{
|
||||
HAL_SPI_RXOverflow_IRQ(hspi);
|
||||
return;
|
||||
}
|
||||
|
||||
if (interrupt_status & SPI_INT_STATUS_MODE_FAIL_M)
|
||||
{
|
||||
HAL_SPI_ModeFail_IRQ(hspi);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,234 @@
|
||||
#ifndef MIK32_HAL_SPIFI
|
||||
#define MIK32_HAL_SPIFI
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "mik32_hal_def.h"
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "mik32_hal_gpio.h"
|
||||
#include <spifi.h>
|
||||
#include <mcu32_memory_map.h>
|
||||
|
||||
#define HAL_SPIFI_TIMEOUT 100000
|
||||
|
||||
typedef enum __HAL_SPIFI_CacheEnableTypeDef
|
||||
{
|
||||
SPIFI_CACHE_DISABLE = 0,
|
||||
SPIFI_CACHE_ENABLE = 1,
|
||||
} HAL_SPIFI_CacheEnableTypeDef;
|
||||
|
||||
typedef enum __HAL_SPIFI_DataCacheEnableTypeDef
|
||||
{
|
||||
SPIFI_DATA_CACHE_ENABLE = 0,
|
||||
SPIFI_DATA_CACHE_DISABLE = 1,
|
||||
} HAL_SPIFI_DataCacheEnableTypeDef;
|
||||
|
||||
typedef enum __HAL_SPIFI_InterruptEnableTypeDef
|
||||
{
|
||||
SPIFI_INTERRUPT_DISABLE = 0,
|
||||
SPIFI_INTERRUPT_ENABLE = 1,
|
||||
} HAL_SPIFI_InterruptEnableTypeDef;
|
||||
|
||||
typedef enum __HAL_SPIFI_Mode3EnableTypeDef
|
||||
{
|
||||
SPIFI_MODE3_DISABLE = 0,
|
||||
SPIFI_MODE3_ENABLE = 1,
|
||||
} HAL_SPIFI_Mode3EnableTypeDef;
|
||||
|
||||
typedef enum __HAL_SPIFI_PrefetchEnableTypeDef
|
||||
{
|
||||
SPIFI_PREFETCH_ENABLE = 0,
|
||||
SPIFI_PREFETCH_DISABLE = 1,
|
||||
} HAL_SPIFI_PrefetchEnableTypeDef;
|
||||
|
||||
typedef enum __HAL_SPIFI_DualModeEnableTypeDef
|
||||
{
|
||||
SPIFI_DUAL_MODE_ENABLE = 0,
|
||||
SPIFI_DUAL_MODE_DISABLE = 1,
|
||||
} HAL_SPIFI_DualModeEnableTypeDef;
|
||||
|
||||
typedef enum __HAL_SPIFI_DMAEnableTypeDef
|
||||
{
|
||||
SPIFI_DMA_ENABLE = 0,
|
||||
SPIFI_DMA_DISABLE = 1,
|
||||
} HAL_SPIFI_DMAEnableTypeDef;
|
||||
|
||||
typedef enum __HAL_SPIFI_FieldFormTypeDef
|
||||
{
|
||||
SPIFI_FIELDFORM_ALL_SERIAL = SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL,
|
||||
SPIFI_FIELDFORM_DATA_PARALLEL = SPIFI_CONFIG_CMD_FIELDFORM_DATA_PARALLEL,
|
||||
SPIFI_FIELDFORM_OPCODE_SERIAL = SPIFI_CONFIG_CMD_FIELDFORM_OPCODE_SERIAL,
|
||||
SPIFI_FIELDFORM_ALL_PARALLEL = SPIFI_CONFIG_CMD_FIELDFORM_ALL_PARALLEL,
|
||||
} HAL_SPIFI_FieldFormTypeDef;
|
||||
|
||||
typedef enum __HAL_SPIFI_FrameFormTypeDef
|
||||
{
|
||||
SPIFI_FRAMEFORM_OPCODE = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_NOADDR,
|
||||
SPIFI_FRAMEFORM_OPCODE_1ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_1ADDR,
|
||||
SPIFI_FRAMEFORM_OPCODE_2ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_2ADDR,
|
||||
SPIFI_FRAMEFORM_OPCODE_3ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_3ADDR,
|
||||
SPIFI_FRAMEFORM_OPCODE_4ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_4ADDR,
|
||||
SPIFI_FRAMEFORM_3ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_NOOPCODE_3ADDR,
|
||||
SPIFI_FRAMEFORM_4ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_NOOPCODE_4ADDR,
|
||||
} HAL_SPIFI_FrameFormTypeDef;
|
||||
|
||||
typedef enum __HAL_SPIFI_DirectionTypeDef
|
||||
{
|
||||
SPIFI_DIRECTION_INPUT = SPIFI_CONFIG_CMD_DOUT_M ^ (1 << SPIFI_CONFIG_CMD_DOUT_S),
|
||||
SPIFI_DIRECTION_OUTPUT = SPIFI_CONFIG_CMD_DOUT_M
|
||||
} HAL_SPIFI_DirectionTypeDef;
|
||||
|
||||
typedef struct __SPIFI_MemoryCommandTypeDef
|
||||
{
|
||||
uint32_t InterimData;
|
||||
|
||||
uint8_t InterimLength;
|
||||
|
||||
HAL_SPIFI_FieldFormTypeDef FieldForm;
|
||||
|
||||
HAL_SPIFI_FrameFormTypeDef FrameForm;
|
||||
|
||||
uint8_t OpCode;
|
||||
|
||||
} SPIFI_MemoryCommandTypeDef;
|
||||
|
||||
typedef struct __SPIFI_MemoryModeConfig_HandleTypeDef
|
||||
{
|
||||
|
||||
SPIFI_CONFIG_TypeDef *Instance;
|
||||
|
||||
HAL_SPIFI_CacheEnableTypeDef CacheEnable;
|
||||
|
||||
uint32_t CacheLimit;
|
||||
|
||||
SPIFI_MemoryCommandTypeDef Command;
|
||||
|
||||
} SPIFI_MemoryModeConfig_HandleTypeDef;
|
||||
|
||||
typedef struct __SPIFI_HandleTypeDef
|
||||
{
|
||||
|
||||
SPIFI_CONFIG_TypeDef *Instance;
|
||||
|
||||
uint16_t timeout;
|
||||
|
||||
uint8_t CS_High;
|
||||
|
||||
HAL_SPIFI_CacheEnableTypeDef cacheEnabled;
|
||||
|
||||
HAL_SPIFI_DataCacheEnableTypeDef dataCacheEnabled;
|
||||
|
||||
HAL_SPIFI_InterruptEnableTypeDef interruptEnabled;
|
||||
|
||||
HAL_SPIFI_Mode3EnableTypeDef mode3Enabled;
|
||||
|
||||
uint8_t divider;
|
||||
|
||||
HAL_SPIFI_PrefetchEnableTypeDef prefetchEnabled;
|
||||
|
||||
HAL_SPIFI_DualModeEnableTypeDef dualModeEnabled;
|
||||
|
||||
bool DMAEnabled;
|
||||
|
||||
} SPIFI_HandleTypeDef;
|
||||
|
||||
typedef struct __SPIFI_CommandTypeDef
|
||||
{
|
||||
HAL_SPIFI_DirectionTypeDef Direction;
|
||||
|
||||
uint32_t InterimData;
|
||||
|
||||
uint8_t InterimLength;
|
||||
|
||||
HAL_SPIFI_FieldFormTypeDef FieldForm;
|
||||
|
||||
HAL_SPIFI_FrameFormTypeDef FrameForm;
|
||||
|
||||
uint8_t OpCode;
|
||||
|
||||
} SPIFI_CommandTypeDef;
|
||||
|
||||
__attribute__((weak)) void HAL_SPIFI_MspInit();
|
||||
|
||||
void HAL_SPIFI_MemoryMode_Init(SPIFI_MemoryModeConfig_HandleTypeDef *spifi);
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_SendCommand(
|
||||
SPIFI_HandleTypeDef *spifi,
|
||||
SPIFI_CommandTypeDef *cmd,
|
||||
uint32_t address,
|
||||
uint16_t bufferSize,
|
||||
uint8_t *readBuffer,
|
||||
uint8_t *writeBuffer,
|
||||
uint32_t timeout);
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_SendCommand_LL(
|
||||
SPIFI_HandleTypeDef *spifi,
|
||||
uint32_t cmdRegCfg,
|
||||
uint32_t address,
|
||||
uint16_t bufferSize,
|
||||
uint8_t *readBuffer,
|
||||
uint8_t *writeBuffer,
|
||||
uint32_t interimData,
|
||||
uint32_t timeout);
|
||||
|
||||
bool HAL_SPIFI_IsMemoryModeEnabled(SPIFI_HandleTypeDef *spifi);
|
||||
|
||||
static inline __attribute__((always_inline)) bool HAL_SPIFI_IsCommandCompleted(SPIFI_HandleTypeDef *spifi)
|
||||
{
|
||||
return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) != 0;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_WaitCommandProcessing(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
|
||||
{
|
||||
while (timeout-- > 0)
|
||||
{
|
||||
if (HAL_SPIFI_IsCommandCompleted(spifi))
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
void HAL_SPIFI_Reset(SPIFI_HandleTypeDef *spifi);
|
||||
|
||||
bool HAL_SPIFI_IsReady(SPIFI_HandleTypeDef *spifi);
|
||||
|
||||
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_WaitInterruptRequest(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
|
||||
{
|
||||
while (timeout-- != 0)
|
||||
{
|
||||
if ((spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) != 0)
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_WaitInterruptClear(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
|
||||
{
|
||||
while (timeout-- != 0)
|
||||
{
|
||||
if ((spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) == 0)
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) bool HAL_SPIFI_IsInterruptRequest(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
|
||||
{
|
||||
return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) != 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MIK32_HAL_SPIFI
|
||||
@@ -0,0 +1,318 @@
|
||||
#ifndef MIK32_HAL_TIMER16
|
||||
#define MIK32_HAL_TIMER16
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "mik32_hal_gpio.h"
|
||||
#include "power_manager.h"
|
||||
#include "timer16.h"
|
||||
#include "pad_config.h"
|
||||
#include "stdbool.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Источник тактирования.
|
||||
*/
|
||||
typedef enum __HAL_Timer16_SourceTypeDef
|
||||
{
|
||||
TIMER16_SOURCE_INTERNAL_SYSTEM = 0x0, /**< Тактирование от системной частоты (sys_clk). */
|
||||
TIMER16_SOURCE_INTERNAL_AHB = 0x1, /**< Тактирование от частоты шины AHB. */
|
||||
TIMER16_SOURCE_INTERNAL_OSC32M = 0x2, /**< Тактирование от частоты внешнего осциллятора OSC32М. */
|
||||
TIMER16_SOURCE_INTERNAL_HSI32M = 0x3, /**< Тактирование от частоты встроенного осциллятора HSI32M. */
|
||||
TIMER16_SOURCE_INTERNAL_OSC32K = 0x4, /**< Тактирование от частоты внешнего осциллятора OSC32К. */
|
||||
TIMER16_SOURCE_INTERNAL_LSI32K = 0x5, /**< Тактирование от частоты встроенного осциллятора LSI32K. */
|
||||
TIMER16_SOURCE_EXTERNAL_INPUT1 = 0x6 /**< Тактирование от внешнего вывода Input1. */
|
||||
} HAL_Timer16_SourceTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Делитель частоты.
|
||||
*/
|
||||
typedef enum __HAL_Timer16_PrescalerTypeDef
|
||||
{
|
||||
TIMER16_PRESCALER_1 = 0b000, /**< Делитель частоты 1. */
|
||||
TIMER16_PRESCALER_2 = 0b001, /**< Делитель частоты 2. */
|
||||
TIMER16_PRESCALER_4 = 0b010, /**< Делитель частоты 4. */
|
||||
TIMER16_PRESCALER_8 = 0b011, /**< Делитель частоты 8. */
|
||||
TIMER16_PRESCALER_16 = 0b100, /**< Делитель частоты 16. */
|
||||
TIMER16_PRESCALER_32 = 0b101, /**< Делитель частоты 32. */
|
||||
TIMER16_PRESCALER_64 = 0b110, /**< Делитель частоты 64. */
|
||||
TIMER16_PRESCALER_128 = 0b111 /**< Делитель частоты 128. */
|
||||
} HAL_Timer16_PrescalerTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Источник тактового сигнала таймера для синхронизации счетчика.
|
||||
*/
|
||||
typedef enum __HAL_Timer16_CountModeTypeDef
|
||||
{
|
||||
TIMER16_COUNTMODE_INTERNAL = 0, /**< Счетчик увеличивается после каждого внутреннего тактового импульса. */
|
||||
TIMER16_COUNTMODE_EXTERNAL = 1 /**< Счетчик увеличивается после каждого действительного тактового импульса на внешнем выводе input1. */
|
||||
} HAL_Timer16_CountModeTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Полярность синхронизации.
|
||||
* Выбор активного фронта при тактировании от внешнего источника.
|
||||
*
|
||||
*/
|
||||
typedef enum __HAL_Timer16_ActiveEdgeTypeDef
|
||||
{
|
||||
TIMER16_ACTIVEEDGE_RISING = 0b00, /**< Нарастающий фронт является активным фронтом, используемым для подсчета. */
|
||||
TIMER16_ACTIVEEDGE_FOLLING = 0b01, /**< Спадающий фронт является активным фронтом, используемым для подсчета. */
|
||||
TIMER16_ACTIVEEDGE_BOTH = 0b10 /**< Оба фронта являются активными фронтами. */
|
||||
} HAL_Timer16_ActiveEdgeTypeDef;
|
||||
|
||||
/* Title: Источник триггера */
|
||||
|
||||
typedef enum __HAL_Timer16_TriggerTypeDef
|
||||
{
|
||||
TIMER16_TRIGGER_TIM0_GPIO0_7 = 0b000, /**< GPIO0_7 источник триггера для Timer16_0. */
|
||||
TIMER16_TRIGGER_TIM0_GPIO0_4 = 0b001, /**< GPIO0_4 источник триггера для Timer16_0. */
|
||||
TIMER16_TRIGGER_TIM0_GPIO0_15 = 0b010, /**< GPIO0_15 источник триггера для Timer16_0. */
|
||||
TIMER16_TRIGGER_TIM0_GPIO0_14 = 0b011, /**< GPIO0_14 источник триггера для Timer16_0. */
|
||||
|
||||
TIMER16_TRIGGER_TIM1_GPIO1_9 = 0b000, /**< GPIO1_9 источник триггера для Timer16_1. */
|
||||
TIMER16_TRIGGER_TIM1_GPIO1_8 = 0b001, /**< GPIO1_8 источник триггера для Timer16_1. */
|
||||
TIMER16_TRIGGER_TIM1_GPIO1_7 = 0b010, /**< GPIO1_7 источник триггера для Timer16_1. */
|
||||
TIMER16_TRIGGER_TIM1_GPIO1_6 = 0b011, /**< GPIO1_6 источник триггера для Timer16_1. */
|
||||
|
||||
TIMER16_TRIGGER_TIM2_GPIO2_3 = 0b000, /**< GPIO2_3 источник триггера для Timer16_2. */
|
||||
TIMER16_TRIGGER_TIM2_GPIO2_2 = 0b001, /**< GPIO2_2 источник триггера для Timer16_2. */
|
||||
TIMER16_TRIGGER_TIM2_GPIO2_1 = 0b010, /**< GPIO2_1 источник триггера для Timer16_2. */
|
||||
TIMER16_TRIGGER_TIM2_GPIO2_0 = 0b011, /**< GPIO2_0 источник триггера для Timer16_2. */
|
||||
|
||||
TIMER16_TRIGGER_TEMPERATURE = 0b100, /**< Источник триггера - термосенсор. */
|
||||
TIMER16_TRIGGER_ADC = 0b101, /**< Источник триггера - окончание преобразования АЦП. */
|
||||
TIMER16_TRIGGER_RTC = 0b110, /**< Источник триггера - прерывание RTC. */
|
||||
TIMER16_TRIGGER_AlARM = 0b111 /**< Источник триггера - Будильник. */
|
||||
} HAL_Timer16_TriggerTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Полярность синхронизации.
|
||||
* Выбор активного фронта при тактировании от внешнего источника.
|
||||
*/
|
||||
typedef enum __HAL_Timer16_Trigger_ActiveEdgeTypeDef
|
||||
{
|
||||
TIMER16_TRIGGER_ACTIVEEDGE_SOFTWARE = 0b00, /**< Программный триггер. Запускается при установленном CNTSTRT или SNGSTRT. */
|
||||
TIMER16_TRIGGER_ACTIVEEDGE_RISING = 0b01, /**< Нарастающий фронт является активным фронтом. */
|
||||
TIMER16_TRIGGER_ACTIVEEDGE_FOLLING = 0b10, /**< Спадающий фронт является активным фронтом. */
|
||||
TIMER16_TRIGGER_ACTIVEEDGE_BOTH = 0b11 /**< Оба фронта являются активными фронтами. */
|
||||
} HAL_Timer16_Trigger_ActiveEdgeTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Функция тайм-аут.
|
||||
*/
|
||||
typedef enum __HAL_Timer16_TimeoutTypeDef
|
||||
{
|
||||
TIMER16_TIMEOUT_DISABLE = 0, /**< Триггерное событие, поступающее, когда таймер уже запущен, будет проигнорировано. */
|
||||
TIMER16_TIMEOUT_ENABLE = 1 /**< Триггерное событие, поступающее, когда таймер уже запущен, сбросит и перезапустит счетчик. */
|
||||
} HAL_Timer16_TimeoutTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Режим обновления регистров ARR и CMP.
|
||||
*/
|
||||
typedef enum __HAL_Timer16_PreloadTypeDef
|
||||
{
|
||||
TIMER16_PRELOAD_AFTERWRITE = 0, /**< Регистры обновляются после каждого доступа к записи на шине APB. */
|
||||
TIMER16_PRELOAD_ENDPERIOD = 1 /**< Регистры обновляются в конце текущего периода Timer16. */
|
||||
} HAL_Timer16_PreloadTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Фильтр для внешнего тактового генератора/триггера.
|
||||
*/
|
||||
typedef enum __HAL_Timer16_FilterTypeDef
|
||||
{
|
||||
TIMER16_FILTER_NONE = 0b00, /**< Фильтр отключен. */
|
||||
TIMER16_FILTER_2CLOCK = 0b01, /**< Фильтр на 2 такта. */
|
||||
TIMER16_FILTER_4CLOCK = 0b10, /**< Фильтр на 4 такта. */
|
||||
TIMER16_FILTER_8CLOCK = 0b11 /**< Фильтр на 8 тактов. */
|
||||
} HAL_Timer16_FilterTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Режим энкодера.
|
||||
*/
|
||||
typedef enum __HAL_Timer16_EncoderTypeDef
|
||||
{
|
||||
TIMER16_ENCODER_DISABLE = 0, /**< Режим энкодера выключен. */
|
||||
TIMER16_ENCODER_ENABLE = 1 /**< Режим энкодера включен. */
|
||||
} HAL_Timer16_EncoderTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Генерация волновой формы.
|
||||
*/
|
||||
typedef enum __HAL_Timer16_WaveformGenTypeDef
|
||||
{
|
||||
TIMER16_WAVEFORM_GENERATION_ENABLE = 0, /**< Выключить генерацию волновой формы. */
|
||||
TIMER16_WAVEFORM_GENERATION_DISABLE = 1 /**< Включить генерацию волновой формы. */
|
||||
} HAL_Timer16_WaveformGenTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Полярность волновой формы.
|
||||
*/
|
||||
typedef enum __HAL_Timer16_WaveformPolarityTypeDef
|
||||
{
|
||||
TIMER16_WAVEFORM_POLARITY_NONINVERTED = 0, /**< Неинвертированная полярность волновой формы. */
|
||||
TIMER16_WAVEFORM_POLARITY_INVERTED = TIMER16_CFGR_WAVPOL_M /**< Инвертированная полярность волновой формы. */
|
||||
} HAL_Timer16_WaveformPolarityTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Настройки источника тактирования.
|
||||
*/
|
||||
typedef struct __Timer16_ClockConfigTypeDef
|
||||
{
|
||||
uint8_t Source; /**< Источник тактирования. */
|
||||
uint8_t Prescaler; /**< Делитель частоты. */
|
||||
|
||||
} Timer16_ClockConfigTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Настройки генерации волновой формы.
|
||||
*/
|
||||
typedef struct __Timer16_WaveformConfigTypeDef
|
||||
{
|
||||
HAL_Timer16_WaveformGenTypeDef Enable; /**< Включить или выключить генерацию волновой формы. */
|
||||
HAL_Timer16_WaveformPolarityTypeDef Polarity; /**< Полярность выходного сигнала. */
|
||||
|
||||
} Timer16_WaveformConfigTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Настройки триггера.
|
||||
*/
|
||||
typedef struct __Timer16_TriggerConfigTypeDef
|
||||
{
|
||||
uint8_t Source; /**< Источник триггера. */
|
||||
uint8_t ActiveEdge; /**< Активный фронт. */
|
||||
uint8_t TimeOut; /**< Функция тайм-аут. */
|
||||
|
||||
} Timer16_TriggerConfigTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Настройки фильтров.
|
||||
*/
|
||||
typedef struct __Timer16_FilterConfigTypeDef
|
||||
{
|
||||
uint8_t ExternalClock; /**< Фильтр для внешнего тактового генератора. */
|
||||
uint8_t Trigger; /**< фильтр для триггера. */
|
||||
|
||||
} Timer16_FilterConfigTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Настройки Timer16
|
||||
*/
|
||||
typedef struct __Timer16_HandleTypeDef
|
||||
{
|
||||
TIMER16_TypeDef *Instance; /**< Базовый адрес регистров Timer16. #TIMER16_0, #TIMER16_1, #TIMER16_2. */
|
||||
Timer16_ClockConfigTypeDef Clock; /**< Настройки тактирования. */
|
||||
uint8_t CountMode; /**< Источник синхронизации. */
|
||||
uint8_t ActiveEdge; /**< Активный фронт. */
|
||||
uint8_t Preload; /**< Режим записи в ARR и CMP. */
|
||||
Timer16_TriggerConfigTypeDef Trigger; /**< Настройки триггера. */
|
||||
Timer16_FilterConfigTypeDef Filter; /**< Настройки фильтра. */
|
||||
Timer16_WaveformConfigTypeDef Waveform; /**< Настройки генерации волновой формы. */
|
||||
uint8_t EncoderMode; /**< Включить или выключить режим энкодера. */
|
||||
|
||||
} Timer16_HandleTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Запустить таймер16 в продолжительном режиме.
|
||||
*/
|
||||
#define __HAL_TIMER16_START_CONTINUOUS(__HANDLE__) ((__HANDLE__)->Instance->CR |= TIMER16_CR_CNTSTRT_M)
|
||||
|
||||
/**
|
||||
* @brief Запустить таймер16 в однократном режиме.
|
||||
*/
|
||||
#define __HAL_TIMER16_START_SINGLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= TIMER16_CR_SNGSTRT_M)
|
||||
|
||||
|
||||
void HAL_TIMER16_MspInit(Timer16_HandleTypeDef* htimer16);
|
||||
void HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_SetActiveEdge(Timer16_HandleTypeDef *htimer16, uint8_t ActiveEdge);
|
||||
void HAL_Timer16_SetSourceClock(Timer16_HandleTypeDef *htimer16, uint8_t SourceClock);
|
||||
void HAL_Timer16_SetCountMode(Timer16_HandleTypeDef *htimer16, uint8_t CountMode);
|
||||
void HAL_Timer16_ClockInit(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_SetPreload(Timer16_HandleTypeDef *htimer16, uint8_t Preload);
|
||||
void HAL_Timer16_WaitARROK(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_WaitCMPOK(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_SetARR(Timer16_HandleTypeDef *htimer16, uint16_t Period);
|
||||
void HAL_Timer16_SetCMP(Timer16_HandleTypeDef *htimer16, uint16_t Compare);
|
||||
void HAL_Timer16_SelectTrigger(Timer16_HandleTypeDef *htimer16, uint8_t TriggerSource);
|
||||
void HAL_Timer16_SetTriggerEdge(Timer16_HandleTypeDef *htimer16, uint8_t TriggerEdge);
|
||||
void HAL_Timer16_SetTimeOut(Timer16_HandleTypeDef *htimer16, uint8_t TimeOut);
|
||||
void HAL_Timer16_SetFilterExternalClock(Timer16_HandleTypeDef *htimer16, uint8_t FilterExternalClock);
|
||||
void HAL_Timer16_SetFilterTrigger(Timer16_HandleTypeDef *htimer16, uint8_t FilterTrigger);
|
||||
void HAL_Timer16_SetEncoderMode(Timer16_HandleTypeDef *htimer16, uint8_t EncoderMode);
|
||||
void HAL_Timer16_WaveformPolarity(Timer16_HandleTypeDef *htimer16, HAL_Timer16_WaveformPolarityTypeDef WaveformPolarity);
|
||||
void HAL_Timer16_SetPrescaler(Timer16_HandleTypeDef *htimer16, uint8_t Prescaler);
|
||||
void HAL_Timer16_Init(Timer16_HandleTypeDef *htimer16);
|
||||
uint16_t HAL_Timer16_GetCounterValue(Timer16_HandleTypeDef *htimer16);
|
||||
uint8_t HAL_Timer16_CheckCMP(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_WaitCMP(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_Counter_Start(Timer16_HandleTypeDef *htimer16, uint32_t Period);
|
||||
void HAL_Timer16_StartPWM(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
|
||||
void HAL_Timer16_StartOneShot(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
|
||||
void HAL_Timer16_StartSetOnes(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
|
||||
void HAL_Timer16_Encoder_Start(Timer16_HandleTypeDef *htimer16, uint32_t Period);
|
||||
void HAL_Timer16_Encoder_Stop(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_Stop(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_Counter_Start_IT(Timer16_HandleTypeDef *htimer16, uint32_t Period);
|
||||
void HAL_Timer16_StartPWM_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
|
||||
void HAL_Timer16_StartOneShot_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
|
||||
void HAL_Timer16_StartSetOnes_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
|
||||
void HAL_Timer16_Encoder_Start_IT(Timer16_HandleTypeDef *htimer16, uint32_t Period);
|
||||
void HAL_Timer16_Encoder_Stop_IT(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_Stop_IT(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_WaitTrigger(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_SetInterruptMask(Timer16_HandleTypeDef *htimer16, uint32_t InterruptMask);
|
||||
void HAL_Timer16_SetInterruptDOWN(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_SetInterruptUP(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_SetInterruptARROK(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_SetInterruptCMPOK(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_SetInterruptEXTTRIG(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_SetInterruptARRM(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_SetInterruptCMPM(Timer16_HandleTypeDef *htimer16);
|
||||
void HAL_Timer16_InterruptInit(Timer16_HandleTypeDef *htimer16);
|
||||
|
||||
/**
|
||||
* @brief Получить статус прерываний Timer16.
|
||||
* Функция возвращает статус прерываний в соответствии с маской разрешенный прерываний.
|
||||
* @param htimer16 Указатель на структуру с настройками Timer16.
|
||||
* @return Статус прерываний.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t HAL_Timer16_GetInterruptStatus(Timer16_HandleTypeDef *htimer16)
|
||||
{
|
||||
uint32_t interrupt_status = htimer16->Instance->ISR & htimer16->Instance->IER;
|
||||
|
||||
return interrupt_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Очистить флаг прерывания.
|
||||
* @param htimer16 Указатель на структуру с настройками Timer16.
|
||||
* @param Interrupt Номер прерывания Timer16 в регистре ICR.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void HAL_Timer16_ClearInterruptFlag(Timer16_HandleTypeDef *htimer16, uint32_t Interrupt)
|
||||
{
|
||||
htimer16->Instance->ICR = 1 << Interrupt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Очистить флаги прерываний по маске.
|
||||
* @param htimer16 Указатель на структуру с настройками Timer16.
|
||||
* @param InterruptMask Маска очищаемых флагов прерываний.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void HAL_Timer16_ClearInterruptMask(Timer16_HandleTypeDef *htimer16, uint32_t InterruptMask)
|
||||
{
|
||||
htimer16->Instance->ICR = InterruptMask;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,265 @@
|
||||
#ifndef MIK32_HAL_TIMER32
|
||||
#define MIK32_HAL_TIMER32
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "mik32_hal_gpio.h"
|
||||
#include <timer32.h>
|
||||
#include <power_manager.h>
|
||||
#include "mik32_hal_def.h"
|
||||
#include <mcu32_memory_map.h>
|
||||
|
||||
#define TIMER32_TIMEOUT 10000000
|
||||
|
||||
#define TIMER32_INTERRUPT_CLEAR_MASK 0x3FF
|
||||
|
||||
/* Сдвиг настройки тактирования таймера в регистре Timer_CFG */
|
||||
#define MUX_TIM32_0 0
|
||||
#define MUX_TIM32_1 3
|
||||
#define MUX_TIM32_2 6
|
||||
|
||||
/* Значение в регистре Timer_CFG при тактировании таймера от TIM1 или TIM2 */
|
||||
#define TIMER32_TIM1_SYS_CLK 0b00
|
||||
#define TIMER32_TIM1_HCLK 0b01
|
||||
#define TIMER32_TIM2_OSC32K 0b00
|
||||
#define TIMER32_TIM2_LSI32K 0b10
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TIMER32_SOURCE_PRESCALER, /* Выход с делителя - частота шины AHB (hclk) */
|
||||
TIMER32_SOURCE_TIM1_SYS_CLK, /* Системная частота */
|
||||
TIMER32_SOURCE_TIM1_HCLK, /* частота шины AHB */
|
||||
TIMER32_SOURCE_TIM2_OSC32K, /* Внешний источник 32кГц */
|
||||
TIMER32_SOURCE_TIM2_LSI32K, /* Внутренний источник 32кГц */
|
||||
TIMER32_SOURCE_TX_PAD, /* Внешний вывод TX_PAD */
|
||||
} HAL_TIMER32_SourceTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TIMER32_COUNTMODE_FORWARD = 0b00,
|
||||
TIMER32_COUNTMODE_REVERSE = 0b01,
|
||||
TIMER32_COUNTMODE_BIDIRECTIONAL = 0b10
|
||||
} HAL_TIMER32_CountModeTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TIMER32_STATE_DISABLE = 0b00,
|
||||
TIMER32_STATE_ENABLE = 0b01
|
||||
} HAL_TIMER32_StateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TIMER32_CHANNEL_STATE_DISABLE,
|
||||
TIMER32_CHANNEL_STATE_ENABLE,
|
||||
} HAL_TIMER32_CHANNEL_StateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TIMER32_CHANNEL_NON_INVERTED_PWM = 0,
|
||||
TIMER32_CHANNEL_INVERTED_PWM = 1
|
||||
} HAL_TIMER32_CHANNEL_PWMInvertTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TIMER32_CHANNEL_MODE_COMPARE = 0b01, /* Режим сравнения */
|
||||
TIMER32_CHANNEL_MODE_CAPTURE = 0b10, /* Режим захвата */
|
||||
TIMER32_CHANNEL_MODE_PWM = 0b11, /* ШИМ */
|
||||
} HAL_TIMER32_CHANNEL_ModeTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TIMER32_CHANNEL_CAPTUREEDGE_RISING = 0,
|
||||
TIMER32_CHANNEL_CAPTUREEDGE_FALLING = 1
|
||||
} HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TIMER32_CHANNEL_FILTER_OFF = 0,
|
||||
TIMER32_CHANNEL_FILTER_ON = 1
|
||||
} HAL_TIMER32_CHANNEL_NoiseTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TIMER32_CHANNEL_0 = 0,
|
||||
TIMER32_CHANNEL_1 = 1,
|
||||
TIMER32_CHANNEL_2 = 2,
|
||||
TIMER32_CHANNEL_3 = 3
|
||||
} HAL_TIMER32_CHANNEL_IndexTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Источник тактирования таймера для счета*/
|
||||
HAL_TIMER32_SourceTypeDef Source;
|
||||
|
||||
/* Делитель частоты. Частота делится на Prescaler + 1 */
|
||||
uint32_t Prescaler;
|
||||
|
||||
} TIMER32_ClockConfigTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TIMER32_TypeDef *Instance;
|
||||
|
||||
/* Настройки тактирования */
|
||||
TIMER32_ClockConfigTypeDef Clock;
|
||||
|
||||
/* Режим счета */
|
||||
HAL_TIMER32_CountModeTypeDef CountMode;
|
||||
|
||||
/* Максимальное значение счета */
|
||||
uint32_t Top;
|
||||
|
||||
HAL_TIMER32_StateTypeDef State;
|
||||
|
||||
uint32_t InterruptMask;
|
||||
|
||||
} TIMER32_HandleTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TIMER32_TypeDef *TimerInstance;
|
||||
|
||||
TIMER32_CHANNEL_TypeDef *Instance;
|
||||
|
||||
HAL_TIMER32_CHANNEL_IndexTypeDef ChannelIndex;
|
||||
|
||||
/* Инверсия ГИМ */
|
||||
HAL_TIMER32_CHANNEL_PWMInvertTypeDef PWM_Invert;
|
||||
|
||||
/* Режим канала */
|
||||
HAL_TIMER32_CHANNEL_ModeTypeDef Mode;
|
||||
|
||||
/* Активный фронт в режиме захвата*/
|
||||
HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef CaptureEdge;
|
||||
|
||||
/* Значение сравнения канала */
|
||||
uint32_t OCR;
|
||||
|
||||
/* Фильтр */
|
||||
HAL_TIMER32_CHANNEL_NoiseTypeDef Noise;
|
||||
|
||||
uint8_t State;
|
||||
|
||||
} TIMER32_CHANNEL_HandleTypeDef;
|
||||
|
||||
|
||||
#define HAL_TIMER32_VALUE_GET(timer_instance) (*timer_instance).Instance->VALUE;
|
||||
#define HAL_TIMER32_INTERRUPTFLAGS_CLEAR(timer_instance) (*timer_instance).Instance->INT_CLEAR = TIMER32_INTERRUPT_CLEAR_MASK;
|
||||
#define HAL_TIMER32_VALUE_CLEAR(timer_instance) (*timer_instance).Instance->ENABLE |= TIMER32_ENABLE_TIM_CLR_M;
|
||||
|
||||
static inline __attribute__((always_inline)) uint32_t HAL_Timer32_Channel_ICR_Get(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
return timerChannel->Instance->ICR;
|
||||
}
|
||||
static inline __attribute__((always_inline)) uint32_t HAL_Timer32_InterruptFlags_Get(TIMER32_HandleTypeDef *timer)
|
||||
{
|
||||
return timer->Instance->INT_FLAGS;
|
||||
}
|
||||
static inline __attribute__((always_inline)) uint32_t HAL_Timer32_Value_Get(TIMER32_HandleTypeDef *timer)
|
||||
{
|
||||
return timer->Instance->VALUE;
|
||||
}
|
||||
static inline __attribute__((always_inline)) void HAL_Timer32_InterruptFlags_Clear(TIMER32_HandleTypeDef *timer)
|
||||
{
|
||||
timer->Instance->INT_CLEAR = TIMER32_INTERRUPT_CLEAR_MASK;
|
||||
}
|
||||
static inline __attribute__((always_inline)) void HAL_Timer32_Value_Clear(TIMER32_HandleTypeDef *timer)
|
||||
{
|
||||
timer->Instance->ENABLE |= TIMER32_ENABLE_TIM_CLR_M;
|
||||
}
|
||||
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_Channel_WaitFlagCapture(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t timeout)
|
||||
{
|
||||
while (timeout)
|
||||
{
|
||||
timeout--;
|
||||
if (timerChannel->TimerInstance->INT_FLAGS & TIMER32_INT_IC_M(timerChannel->ChannelIndex))
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_Channel_WaitFlagCompare(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t timeout)
|
||||
{
|
||||
while (timeout)
|
||||
{
|
||||
timeout--;
|
||||
if (timerChannel->TimerInstance->INT_FLAGS & TIMER32_INT_OC_M(timerChannel->ChannelIndex))
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_WaitFlagOverflow(TIMER32_HandleTypeDef *timer, uint32_t timeout)
|
||||
{
|
||||
while (timeout)
|
||||
{
|
||||
timeout--;
|
||||
if (timer->Instance->INT_FLAGS & TIMER32_INT_OVERFLOW_M)
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_WaitFlagUnderflow(TIMER32_HandleTypeDef *timer, uint32_t timeout)
|
||||
{
|
||||
while (timeout)
|
||||
{
|
||||
timeout--;
|
||||
if (timer->Instance->INT_FLAGS & TIMER32_INT_UNDERFLOW_M)
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32);
|
||||
void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel);
|
||||
HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer);
|
||||
void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state);
|
||||
void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top);
|
||||
void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler);
|
||||
void HAL_Timer32_Source_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_SourceTypeDef source);
|
||||
void HAL_Timer32_InterruptMask_Set(TIMER32_HandleTypeDef *timer, uint32_t intMask);
|
||||
void HAL_Timer32_InterruptMask_Clear(TIMER32_HandleTypeDef *timer, uint32_t intMask);
|
||||
void HAL_Timer32_CountMode_Set(TIMER32_HandleTypeDef *timer, uint8_t countMode);
|
||||
void HAL_Timer32_InterruptFlags_ClearMask(TIMER32_HandleTypeDef *timer, uint32_t clearMask);
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerChannel);
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_DeInit(TIMER32_CHANNEL_HandleTypeDef *timerChannel);
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_Enable(TIMER32_CHANNEL_HandleTypeDef *timerChannel);
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_Disable(TIMER32_CHANNEL_HandleTypeDef *timerChannel);
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_PWM_Invert_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_PWMInvertTypeDef PWM_Invert);
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_Mode_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_ModeTypeDef mode);
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_CaptureEdge_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef captureEdge);
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_OCR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t OCR);
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t ICR);
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Clear(TIMER32_CHANNEL_HandleTypeDef *timerChannel);
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_Noise_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint8_t noise);
|
||||
void HAL_Timer32_Start(TIMER32_HandleTypeDef *timer);
|
||||
void HAL_Timer32_Stop(TIMER32_HandleTypeDef *timer);
|
||||
void HAL_Timer32_Base_Start_IT(TIMER32_HandleTypeDef *timer);
|
||||
void HAL_Timer32_Base_Stop_IT(TIMER32_HandleTypeDef *timer);
|
||||
HAL_StatusTypeDef HAL_Timer32_PWM_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
|
||||
void HAL_Timer32_PWM_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
|
||||
HAL_StatusTypeDef HAL_Timer32_Compare_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
|
||||
void HAL_Timer32_Compare_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
|
||||
HAL_StatusTypeDef HAL_Timer32_Capture_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
|
||||
void HAL_Timer32_Capture_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
|
||||
void HAL_Timer32_Start_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask);
|
||||
void HAL_Timer32_Stop_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MIK32_HAL_TIMER32
|
||||
@@ -0,0 +1,158 @@
|
||||
#ifndef MIK32_TSENS
|
||||
#define MIK32_TSENS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef MIK32V0
|
||||
|
||||
#include "analog_reg.h"
|
||||
#include "pad_config.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
#include "power_manager.h"
|
||||
#include "mik32_hal_def.h"
|
||||
#include "mik32_hal_pcc.h"
|
||||
|
||||
|
||||
#define TSENS_OPTIMAL_FREQUENCY 40000 /**< Рекомендуемая частота работы термосенсора. */
|
||||
|
||||
#define __HAL_TSENS_FORCE_RESET(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CFG &= ~TSENS_CFG_NRST_M) /**< Установить состояние сброса термосенсора. */
|
||||
#define __HAL_TSENS_RELEASE_RESET(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CFG |= TSENS_CFG_NRST_M) /**< Снять состояние сброса термосенсора. */
|
||||
|
||||
#define __HAL_TSENS_SINGLE_START(__HANDLE__) ((__HANDLE__)->Instance->TSENS_SINGLE = 1) /**< Запустить одиночное измерение температуры. */
|
||||
#define __HAL_TSENS_CONTINUOUS_START(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CONTINUOUS = 1) /**< Запуск непрерывного измерения температуры. */
|
||||
#define __HAL_TSENS_CONTINUOUS_STOP(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CONTINUOUS = 0) /**< Остановка непрерывного измерения температуры. */
|
||||
#define __HAL_TSENS_GET_EOC(__HANDLE__) (((__HANDLE__)->Instance->TSENS_VALUE & TSENS_VALUE_EOC_M) == TSENS_VALUE_EOC_M) /**< Получить состояние флага окончания преобразования (EOC). */
|
||||
#define __HAL_TSENS_READ_MEASUREMENT(__HANDLE__) ((__HANDLE__)->Instance->TSENS_VALUE & TSENS_VALUE_VALUE_M) /**< Получить результат измерения термосенсора. */
|
||||
|
||||
#define __HAL_TSENS_IRQ_ENABLE_LOWIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ |= TSENS_IRQ_LOW_MASK_M) /**< Разрешить прерывание по выходу за нижний порог температуры. */
|
||||
#define __HAL_TSENS_IRQ_DISABLE_LOWIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~TSENS_IRQ_LOW_MASK_M) /**< Запретить прерывание по выходу за нижний порог температуры. */
|
||||
#define __HAL_TSENS_IRQ_CLEAR_LOWIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = TSENS_CLEAR_IRQ_LOW_CLEAR_M) /**< Очистить флаг прерывания по выходу за нижний порог температуры (LOW_IRQ). */
|
||||
#define __HAL_TSENS_IRQ_GET_LOWIRQ(__HANDLE__) (((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_LOW_IRQ_M) == TSENS_IRQ_LOW_IRQ_M) /**< Получить состояние флага прерывания по выходу за нижний порог температуры (LOW_IRQ). */
|
||||
/** Получить состояние флага прерывания по выходу за нижний порог температуры (LOW_IRQ) с учетом маски разрешенных прерываний. */
|
||||
#define __HAL_TSENS_IRQ_GET_LOWIRQ_MASK(__HANDLE__) ((((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_LOW_IRQ_M) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == TSENS_IRQ_LOW_IRQ_M)
|
||||
|
||||
#define __HAL_TSENS_IRQ_ENABLE_HIIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ |= TSENS_IRQ_HI_MASK_M) /**< Разрешить прерывание по выходу за верхний порог температуры. */
|
||||
#define __HAL_TSENS_IRQ_DISABLE_HIIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~TSENS_IRQ_HI_MASK_M) /**< Запретить прерывание по выходу за верхний порог температуры. */
|
||||
#define __HAL_TSENS_IRQ_CLEAR_HIIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = TSENS_CLEAR_IRQ_HI_CLEAR_M) /**< Очистить флаг прерывания по выходу за верхний порог температуры (HI_IRQ). */
|
||||
#define __HAL_TSENS_IRQ_GET_HIIRQ(__HANDLE__) (((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_HI_IRQ_M) == TSENS_IRQ_HI_IRQ_M) /**< Получить состояние флага прерывания по выходу за верхний порог температуры (HI_IRQ). */
|
||||
/** Получить состояние флага прерывания по выходу за верхний порог температуры (HI_IRQ) с учетом маски разрешенных прерываний. */
|
||||
#define __HAL_TSENS_IRQ_GET_HIIRQ_MASK(__HANDLE__) ((((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_HI_IRQ_M) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == TSENS_IRQ_HI_IRQ_M)
|
||||
|
||||
#define __HAL_TSENS_IRQ_ENABLE_EOC(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ |= TSENS_IRQ_EOC_MASK_M) /**< Разрешить прерывание по окончанию преобразования. */
|
||||
#define __HAL_TSENS_IRQ_DISABLE_EOC(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~TSENS_IRQ_EOC_MASK_M) /**< Запретить прерывание по окончанию преобразования. */
|
||||
#define __HAL_TSENS_IRQ_CLEAR_EOC(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = TSENS_CLEAR_IRQ_EOC_CLEAR_M) /**< Очистить флаг прерывания по окончанию преобразования (EOC_IRQ). */
|
||||
#define __HAL_TSENS_IRQ_GET_EOC(__HANDLE__) (((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_EOC_IRQ_M) == TSENS_IRQ_EOC_IRQ_M) /**< Получить состояние флага прерывания по окончанию преобразования (EOC_IRQ). */
|
||||
/** Получить состояние флага прерывания по окончанию преобразования (EOC_IRQ) с учетом маски разрешенных прерываний. */
|
||||
#define __HAL_TSENS_IRQ_GET_EOC_MASK(__HANDLE__) ((((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_EOC_IRQ_M) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == TSENS_IRQ_EOC_IRQ_M)
|
||||
|
||||
/**
|
||||
* Разрешить прерывание . __INTERRUPT__ может быть одним из значений:
|
||||
* - TSENS_IRQ_LOW_MASK_M: выход за нижний порог температуры;
|
||||
* - TSENS_IRQ_HI_MASK_M: выход за верхний порог температуры;
|
||||
* - TSENS_IRQ_EOC_MASK_M: окончание преобразования.
|
||||
*/
|
||||
#define __HAL_TSENS_IRQ_ENABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->TSENS_IRQ |= (__INTERRUPT__))
|
||||
/**
|
||||
* Запретить прерывание. __INTERRUPT__ может быть одним из значений:
|
||||
* - TSENS_IRQ_LOW_MASK_M: выход за нижний порог температуры;
|
||||
* - TSENS_IRQ_HI_MASK_M: выход за верхний порог температуры;
|
||||
* - TSENS_IRQ_EOC_MASK_M: окончание преобразования.
|
||||
*/
|
||||
#define __HAL_TSENS_IRQ_DISABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~(__INTERRUPT__))
|
||||
/**
|
||||
* Очистить флаг прерывания. __FLAG__ может быть одним из значений:
|
||||
* - TSENS_CLEAR_IRQ_LOW_CLEAR_M: выход за нижний порог температуры;
|
||||
* - TSENS_CLEAR_IRQ_HI_CLEAR_M: выход за верхний порог температуры;
|
||||
* - TSENS_CLEAR_IRQ_EOC_CLEAR_M: окончание преобразования.
|
||||
*/
|
||||
#define __HAL_TSENS_IRQ_CLEAR(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = (__FLAG__))
|
||||
/**
|
||||
* Получить состояние флага прерывания. __FLAG__ может быть одним из значений:
|
||||
* - TSENS_IRQ_LOW_IRQ_M: выход за нижний порог температуры;
|
||||
* - TSENS_IRQ_HI_IRQ_M: выход за верхний порог температуры;
|
||||
* - TSENS_IRQ_EOC_IRQ_M: окончание преобразования.
|
||||
*/
|
||||
#define __HAL_TSENS_IRQ_GET(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->TSENS_IRQ & (__FLAG__)) == (__FLAG__))
|
||||
/**
|
||||
* Получить состояние флага прерывания с учетом маски разрешенных прерываний.. __FLAG__ может быть одним из значений:
|
||||
* - TSENS_IRQ_LOW_IRQ_M: выход за нижний порог температуры;
|
||||
* - TSENS_IRQ_HI_IRQ_M: выход за верхний порог температуры;
|
||||
* - TSENS_IRQ_EOC_IRQ_M: окончание преобразования.
|
||||
*/
|
||||
#define __HAL_TSENS_IRQ_GET_MASK(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->TSENS_IRQ & (__FLAG__)) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == (__FLAG__))
|
||||
|
||||
|
||||
/*
|
||||
* Define
|
||||
* Константы-параметры функции установки источника тактирования TSENS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Перечисление источников тактирования термосенсора.
|
||||
*/
|
||||
typedef enum __HAL_TSENS_ClockTypeDef
|
||||
{
|
||||
HAL_TSENS_SYS_CLK = 0x0, /**< Системная частота (sys_clk). */
|
||||
HAL_TSENS_HCLK = 0x1, /**< Частота шины AHB (hclk). */
|
||||
HAL_TSENS_OSC32M = 0x2, /**< Частота внешнего высокочастотного осциллятора до 32 МГц. */
|
||||
HAL_TSENS_HSI32M = 0x3, /**< Частота внутреннего высокочастотного осциллятора 32 МГц. */
|
||||
HAL_TSENS_OSC32K = 0x4, /**< Частота внешнего осциллятора 32 кГц. */
|
||||
HAL_TSENS_LSI32K = 0x5 /**< Частота внутреннего осциллятора 32 кГц. */
|
||||
} HAL_TSENS_ClockTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Определение структуры TSENS Handle.
|
||||
*/
|
||||
typedef struct __SPI_HandleTypeDef
|
||||
{
|
||||
|
||||
ANALOG_REG_TypeDef *Instance; /**< Адрес регистров блока управления аналоговой подсистемой. */
|
||||
|
||||
HAL_TSENS_ClockTypeDef Clock; /**< Источник тактирования TSENS. */
|
||||
|
||||
uint32_t Frequency; /**< Частота работы температурного сенсора в Гц. Значение этого параметра может быть не больше 100кГц. */
|
||||
|
||||
} TSENS_HandleTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Возвращаемая структура для функции @ref HAL_TSENS_SingleStart.
|
||||
*/
|
||||
typedef struct __WDT_ClockTypeDef
|
||||
{
|
||||
HAL_StatusTypeDef statusHAL; /**< Статус HAL. */
|
||||
|
||||
uint32_t value; /**< Значение температуры в градусах Цельсия. Значение в 100 раз больше. */
|
||||
|
||||
} TSENS_ValueTypeDef;
|
||||
|
||||
|
||||
void HAL_TSENS_MspInit(TSENS_HandleTypeDef *htsens);
|
||||
HAL_StatusTypeDef HAL_TSENS_Init(TSENS_HandleTypeDef *htsens);
|
||||
HAL_StatusTypeDef HAL_TSENS_ClockSource(TSENS_HandleTypeDef *htsens, HAL_TSENS_ClockTypeDef clk_source);
|
||||
HAL_StatusTypeDef HAL_TSENS_ClockDivider(TSENS_HandleTypeDef *htsens, uint16_t clk_div);
|
||||
HAL_StatusTypeDef HAL_TSENS_Clock(TSENS_HandleTypeDef *htsens, uint32_t f_enter);
|
||||
|
||||
|
||||
HAL_StatusTypeDef HAL_TSENS_SetLowThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t low_tres);
|
||||
HAL_StatusTypeDef HAL_TSENS_SetHiThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t hi_tres);
|
||||
HAL_StatusTypeDef HAL_TSENS_SetLowThreshold(TSENS_HandleTypeDef *htsens, int low_temp_border);
|
||||
HAL_StatusTypeDef HAL_TSENS_SetHiThreshold(TSENS_HandleTypeDef *htsens, int hi_temp_border);
|
||||
|
||||
|
||||
uint32_t HAL_TSENS_GetTemperature(TSENS_HandleTypeDef *htsens);
|
||||
void HAL_TSENS_ContinuousStart(TSENS_HandleTypeDef *htsens);
|
||||
TSENS_ValueTypeDef HAL_TSENS_SingleStart(TSENS_HandleTypeDef *htsens, uint32_t timeout);
|
||||
void HAL_TSENS_ContinuousStart_IT(TSENS_HandleTypeDef *htsens);
|
||||
void HAL_TSENS_SingleStart_IT(TSENS_HandleTypeDef *htsens);
|
||||
void HAL_TSENS_Stop_IT(TSENS_HandleTypeDef *htsens);
|
||||
|
||||
|
||||
#endif // MIK32V0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MIK32_TSENS
|
||||
@@ -0,0 +1,120 @@
|
||||
#ifndef MCU32_HAL_WDT
|
||||
#define MCU32_HAL_WDT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_pcc.h"
|
||||
#include "mcu32_memory_map.h"
|
||||
#include "wdt.h"
|
||||
#include "wdt_bus.h"
|
||||
#include "power_manager.h"
|
||||
#include "mik32_hal_def.h"
|
||||
#include "stddef.h"
|
||||
|
||||
#define WDT_CLOCK32K_VALUE 32768 /**< Частота осцилляторов OSC32K или LSI32K. */
|
||||
#define WDT_CLOCK32M_VALUE 32000000 /**< Частота осцилляторов OSC32M или HSI32M. */
|
||||
#define WDT_MAX_VALUE_CLOCK32K 511875 /**< Максимально возможный интервал времени в миллисекундах при тактировании от OSC32K или LSI32K. */
|
||||
#define WDT_MAX_VALUE_CLOCK32M 524 /**< Максимально возможный интервал времени в миллисекундах при тактировании от OSC32M или HSI32M. */
|
||||
#define WDT_TIMEOUT_DEFAULT 10000 /**< Значение задержки по умолчанию. */
|
||||
|
||||
/** @brief Проверить установлен ли указанный флаг SPI или нет.
|
||||
* @param __HANDLE__ Указатель WDT Handle.
|
||||
* @param __FLAG__ Флаг для проверки.
|
||||
* Этот параметр должен быть одним из следующих значений:
|
||||
* - @ref WDT_STA_ENABLED_M: флаг активности таймера
|
||||
* - @ref WDT_STA_LOADING_M: флаг перезагрузки значения
|
||||
* - @ref WDT_STA_RST_FLAG_M: флаг генерации сброса сторожевым таймером. Сбрасывается в 0 только при снятии и последующей подаче питания.
|
||||
*
|
||||
* @return Состояние флага @p __FLAG__ (TRUE или FALSE).
|
||||
*/
|
||||
#define __HAL_WDT_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->STA) & (__FLAG__)) == (__FLAG__))
|
||||
|
||||
/**
|
||||
* @brief Задать источник тактирования сторожевого таймера.
|
||||
* @param __WDT_CLOCK__ Bсточник тактирования сторожевого таймера.
|
||||
* Этот параметр должен быть одним из значений перечисления @ref HAL_WDT_Clocks.
|
||||
*/
|
||||
#define __HAL_WDT_SET_CLOCK(__WDT_CLOCK__) (PM->WDT_CLK_MUX = (__WDT_CLOCK__) & PM_WDT_CLK_MUX_M)
|
||||
|
||||
/**
|
||||
* @brief Перечисление делителей входной частоты сторожевого таймера.
|
||||
*
|
||||
*/
|
||||
typedef enum __HAL_WDT_Prescale
|
||||
{
|
||||
HAL_WDT_PRESCALE_1 = 0, /**< Делитель входной частоты сторожевого таймера 1. */
|
||||
HAL_WDT_PRESCALE_2 = 1, /**< Делитель входной частоты сторожевого таймера 2. */
|
||||
HAL_WDT_PRESCALE_4 = 2, /**< Делитель входной частоты сторожевого таймера 4. */
|
||||
HAL_WDT_PRESCALE_16 = 3, /**< Делитель входной частоты сторожевого таймера 16. */
|
||||
HAL_WDT_PRESCALE_64 = 4, /**< Делитель входной частоты сторожевого таймера 64. */
|
||||
HAL_WDT_PRESCALE_256 = 5, /**< Делитель входной частоты сторожевого таймера 256. */
|
||||
HAL_WDT_PRESCALE_1024 = 6, /**< Делитель входной частоты сторожевого таймера 1024. */
|
||||
HAL_WDT_PRESCALE_4096 = 7 /**< Делитель входной частоты сторожевого таймера 4096. */
|
||||
} HAL_WDT_Prescale;
|
||||
|
||||
/**
|
||||
* @brief Перечисление источников тактирования сторожевого таймера.
|
||||
*/
|
||||
typedef enum __HAL_WDT_Clocks
|
||||
{
|
||||
HAL_WDT_OSC32M, /**< Внешний 32МГц. */
|
||||
HAL_WDT_HSI32M, /**< Внутренний 32МГц. */
|
||||
HAL_WDT_OSC32K, /**< Внешний 32кГц. */
|
||||
HAL_WDT_LSI32K /**< Внутренний 32кГц. */
|
||||
} HAL_WDT_Clocks;
|
||||
|
||||
/**
|
||||
* @brief Определение структуры конфигурации WDT.
|
||||
*/
|
||||
typedef struct __WDT_InitTypeDef
|
||||
{
|
||||
HAL_WDT_Clocks Clock; /**< Источник тактирования WDT. */
|
||||
|
||||
/**
|
||||
* @brief Время до перезагрузки контроллера в миллисекундах.
|
||||
*
|
||||
* Значение не должно превышать 524 мс при тактировании от источника 32 Мгц и
|
||||
* 511875 мс при тактировании от источника 32 кГц.
|
||||
*/
|
||||
uint32_t ReloadMs;
|
||||
|
||||
} WDT_InitTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Определение структуры WDT Handle.
|
||||
*/
|
||||
typedef struct __WDT_HandleTypeDef
|
||||
{
|
||||
WDT_TypeDef *Instance; /**< Адрес регистров WDT. */
|
||||
|
||||
WDT_InitTypeDef Init; /**< Параметры WDT. */
|
||||
|
||||
} WDT_HandleTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Возвращаемая структура для функции @ref HAL_WDT_MillisInClock.
|
||||
*/
|
||||
typedef struct __WDT_ClockTypeDef
|
||||
{
|
||||
uint32_t tick; /**< Начальное значение таймера при запуске или перезапуске для отсчета WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.Init.ReloadMs" миллисекунд. */
|
||||
|
||||
int divIndex; /**< Значение делителя частоты таймера для отсчета @ref WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.Init.ReloadMs" миллисекунд. */
|
||||
|
||||
} WDT_ClockTypeDef;
|
||||
|
||||
|
||||
void HAL_RTC_MspInit(WDT_HandleTypeDef* hwdt);
|
||||
HAL_StatusTypeDef HAL_WDT_Init(WDT_HandleTypeDef *hwdt, uint32_t timeout);
|
||||
HAL_StatusTypeDef HAL_WDT_Refresh(WDT_HandleTypeDef *hwdt, uint32_t timeout);
|
||||
HAL_StatusTypeDef HAL_WDT_Start(WDT_HandleTypeDef *hwdt, uint32_t timeout);
|
||||
HAL_StatusTypeDef HAL_WDT_Stop(WDT_HandleTypeDef *hwdt, uint32_t timeout);
|
||||
void HAL_WDT_SetPrescale(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale prescale);
|
||||
void HAL_WDT_SetPreload(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale preload);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MCU32_HAL_WDT
|
||||
Whitespace-only changes.
@@ -0,0 +1,15 @@
|
||||
#include "mik32_hal.h"
|
||||
|
||||
|
||||
__attribute__((weak)) void HAL_MspInit()
|
||||
{
|
||||
__HAL_PCC_PAD_CONFIG_CLK_ENABLE();
|
||||
__HAL_PCC_EPIC_CLK_ENABLE();
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Init()
|
||||
{
|
||||
HAL_MspInit();
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
#include "mik32_hal_adc.h"
|
||||
|
||||
__attribute__((weak)) void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
__HAL_PCC_ANALOG_REGS_CLK_ENABLE();
|
||||
|
||||
if ((hadc->Init.EXTClb == ADC_EXTCLB_ADCREF) && (hadc->Init.EXTRef == ADC_EXTREF_ON))
|
||||
{
|
||||
#ifdef MIK32V0
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
#else // MIK32V2
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
#endif // MIK32V0
|
||||
}
|
||||
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_ANALOG;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
|
||||
switch (hadc->Init.Sel)
|
||||
{
|
||||
case ADC_CHANNEL0:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_5;
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
break;
|
||||
|
||||
case ADC_CHANNEL1:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_7;
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
break;
|
||||
|
||||
case ADC_CHANNEL2:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
|
||||
break;
|
||||
|
||||
case ADC_CHANNEL3:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_4;
|
||||
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
|
||||
break;
|
||||
|
||||
case ADC_CHANNEL4:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_7;
|
||||
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
|
||||
break;
|
||||
|
||||
case ADC_CHANNEL5:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
|
||||
break;
|
||||
|
||||
case ADC_CHANNEL6:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
|
||||
break;
|
||||
|
||||
case ADC_CHANNEL7:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_13;
|
||||
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void HAL_ADC_CLBEnable(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
hadc->Instance->REFV_CONFIG |= 1 << REF_CLB_EN_S;
|
||||
}
|
||||
|
||||
void HAL_ADC_CLBDisable(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
hadc->Instance->REFV_CONFIG &= ~(1 << REF_CLB_EN_S);
|
||||
}
|
||||
|
||||
void HAL_ADC_VCLBSet(ADC_HandleTypeDef *hadc, uint8_t v_coef)
|
||||
{
|
||||
hadc->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_VCOEF_S);
|
||||
hadc->Instance->REFV_CONFIG |= ((v_coef & 0xF) << REF_CLB_VCOEF_S);
|
||||
}
|
||||
|
||||
void HAL_ADC_ICLBSet(ADC_HandleTypeDef *hadc, uint8_t i_coef)
|
||||
{
|
||||
hadc->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_ICOEF_S);
|
||||
hadc->Instance->REFV_CONFIG |= ((i_coef & 0xF) << REF_CLB_ICOEF_S);
|
||||
}
|
||||
|
||||
void HAL_ADC_ResetEnable(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
#ifdef MIK32V0
|
||||
hadc->Instance->ADC_CONFIG |= (1 << ADC_CONFIG_RESETN_S);
|
||||
#else // MIK32V2
|
||||
hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) |
|
||||
((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) |
|
||||
(1 << ADC_CONFIG_RESETN_S);
|
||||
#endif // MIK32V0
|
||||
}
|
||||
|
||||
void HAL_ADC_ResetDisable(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
|
||||
#ifdef MIK32V0
|
||||
hadc->Instance->ADC_CONFIG &= ~(1 << ADC_CONFIG_RESETN_S);
|
||||
#else // MIK32V2
|
||||
hadc->Instance->ADC_CONFIG = ((hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_RESETN_M)) & (~ADC_CONFIG_SAH_TIME_M)) |
|
||||
((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M);
|
||||
#endif // MIK32V0
|
||||
}
|
||||
|
||||
void HAL_ADC_Disable(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
hadc->Instance->ADC_CONFIG &= ~(1 << ADC_CONFIG_EN_S);
|
||||
HAL_ADC_ResetDisable(hadc);
|
||||
}
|
||||
|
||||
void HAL_ADC_Enable(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
#ifdef MIK32V0
|
||||
hadc->Instance->ADC_CONFIG |= (1 << ADC_CONFIG_EN_S);
|
||||
#else // MIK32V2
|
||||
hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) |
|
||||
((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) |
|
||||
(1 << ADC_CONFIG_EN_S);
|
||||
|
||||
#endif // MIK32V0
|
||||
HAL_ADC_ResetEnable(hadc);
|
||||
}
|
||||
|
||||
void HAL_ADC_ChannelSet(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
|
||||
#ifdef MIK32V0
|
||||
hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SEL_M)) | (hadc->Init.Sel << ADC_CONFIG_SEL_S); /* Настройка канала АЦП */
|
||||
#else // MIK32V2
|
||||
hadc->Instance->ADC_CONFIG = ((hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) & (~ADC_CONFIG_SEL_M)) |
|
||||
(hadc->Init.Sel << ADC_CONFIG_SEL_S) |
|
||||
((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M);
|
||||
#endif // MIK32V0
|
||||
}
|
||||
|
||||
void HAL_ADC_Init(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
HAL_ADC_MspInit(hadc);
|
||||
#ifdef MIK32V0
|
||||
hadc->Instance->ADC_CONFIG = 0;
|
||||
#else // MIK32V2
|
||||
hadc->Instance->ADC_CONFIG = 0x3C00;
|
||||
#endif // MIK32V0
|
||||
|
||||
HAL_ADC_Enable(hadc);
|
||||
|
||||
HAL_ADC_ChannelSet(hadc); /* Настройка канала АЦП. Перевод используемого вывода в аналоговый режим */
|
||||
|
||||
#ifdef MIK32V0
|
||||
hadc->Instance->ADC_CONFIG |= (hadc->Init.EXTRef << ADC_CONFIG_EXTREF_S) | /* Настройка источника опорного напряжения */
|
||||
(hadc->Init.EXTClb << ADC_CONFIG_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */
|
||||
#else // MIK32V2
|
||||
hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) |
|
||||
((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) |
|
||||
(hadc->Init.EXTRef << ADC_CONFIG_EXTREF_S) | /* Настройка источника опорного напряжения */
|
||||
(hadc->Init.EXTClb << ADC_CONFIG_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */
|
||||
#endif // MIK32V0
|
||||
}
|
||||
|
||||
void HAL_ADC_Single(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
hadc->Instance->ADC_SINGLE = 1;
|
||||
}
|
||||
|
||||
void HAL_ADC_ContinuousDisabled(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
hadc->Instance->ADC_CONTINUOUS = 0;
|
||||
}
|
||||
|
||||
void HAL_ADC_ContinuousEnable(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
hadc->Instance->ADC_CONTINUOUS = 1;
|
||||
}
|
||||
|
||||
void HAL_ADC_WaitValid(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
/* Ожидание актуальных данных - ADC_VALID = 1 */
|
||||
while (!(hadc->Instance->ADC_VALID))
|
||||
;
|
||||
}
|
||||
|
||||
uint16_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
uint16_t value = hadc->Instance->ADC_VALUE;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t HAL_ADC_WaitAndGetValue(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
HAL_ADC_WaitValid(hadc);
|
||||
|
||||
uint16_t value = HAL_ADC_GetValue(hadc);
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
#include "mik32_hal_crc32.h"
|
||||
|
||||
|
||||
__attribute__((weak)) void HAL_CRC32_MspInit(CRC_HandleTypeDef* hcrc)
|
||||
{
|
||||
__HAL_PCC_CRC32_CLK_ENABLE();
|
||||
}
|
||||
|
||||
void HAL_CRC_SetPoly(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Задается полином */
|
||||
hcrc->Instance->POLY = hcrc->Poly;
|
||||
}
|
||||
|
||||
void HAL_CRC_SetInputReverse(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Найстройка перестановки битов/байтов входных данных */
|
||||
hcrc->Instance->CTRL &= ~(0b11 << CRC_CTRL_TOT_S);
|
||||
hcrc->Instance->CTRL |= hcrc->InputReverse << CRC_CTRL_TOT_S;
|
||||
}
|
||||
|
||||
void HAL_CRC_SetOutputInversion(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
hcrc->Instance->CTRL &= ~(1 << CRC_CTRL_FXOR_S);
|
||||
hcrc->Instance->CTRL |= hcrc->OutputInversion << CRC_CTRL_FXOR_S;
|
||||
}
|
||||
|
||||
void HAL_CRC_SetOutputReverse(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Найстройка перестановки битов/байтов выходных данных */
|
||||
hcrc->Instance->CTRL &= ~(0b11 << CRC_CTRL_TOTR_S);
|
||||
hcrc->Instance->CTRL |= hcrc->OutputReverse << CRC_CTRL_TOTR_S;
|
||||
}
|
||||
|
||||
void HAL_CRC_SetInit(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Назначение регистра данных: 1 – записываем начальное значение */
|
||||
hcrc->Instance->CTRL |= CRC_CTRL_WAS_M;
|
||||
|
||||
/* Pапись в регистр данных 32-разрядное начальное значение */
|
||||
hcrc->Instance->DATA32 = hcrc->Init;
|
||||
|
||||
/* Назначение регистра данных: 0 – записываем данные */
|
||||
hcrc->Instance->CTRL &= ~CRC_CTRL_WAS_M;
|
||||
}
|
||||
|
||||
void HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
HAL_CRC32_MspInit(hcrc);
|
||||
|
||||
/* Найстройка перестановки битов/байтов входных данных */
|
||||
HAL_CRC_SetInputReverse(hcrc);
|
||||
|
||||
/* Найстройка перестановки битов/байтов выходных данных */
|
||||
HAL_CRC_SetOutputReverse(hcrc);
|
||||
|
||||
/* Инверсия контрольной суммы */
|
||||
HAL_CRC_SetOutputInversion(hcrc);
|
||||
|
||||
/* Задается полином */
|
||||
HAL_CRC_SetPoly(hcrc);
|
||||
}
|
||||
|
||||
void HAL_CRC_WaitBusy(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Ожидание 1 такта для установления флага BUSY в 1 после записи в регистр данных слова */
|
||||
for (uint8_t i = 0; i < 100; i++);
|
||||
/* Ожидание когда флаг BUSY станет 0 - автомат закончил вычисления */
|
||||
while (hcrc->Instance->CTRL & CRC_CTRL_BUSY_M);
|
||||
}
|
||||
|
||||
void HAL_CRC_WriteData(CRC_HandleTypeDef *hcrc, uint8_t message[], uint32_t message_length)
|
||||
{
|
||||
if(message_length > CRC_MAX_BYTES)
|
||||
{
|
||||
#ifdef MIK32_CRC_DEBUG
|
||||
xprintf("Ошибка: переполнение буфера\n");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Запись начального значения Init */
|
||||
HAL_CRC_SetInit(hcrc);
|
||||
|
||||
uint32_t i = 0;
|
||||
while (i < message_length)
|
||||
{
|
||||
if (i + 3 < message_length)
|
||||
{
|
||||
hcrc->Instance->DATA32 = (message[i+3] << 0) |
|
||||
(message[i+2] << 8) |
|
||||
(message[i+1] << 16) |
|
||||
(message[i] << 24);
|
||||
i += 4;
|
||||
}
|
||||
else if (i + 1 < message_length)
|
||||
{
|
||||
hcrc->Instance->DATA16 = (message[i+1] << 0) |
|
||||
(message[i] << 8);
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
hcrc->Instance->DATA8 = message[i];
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_CRC_WriteData32(CRC_HandleTypeDef *hcrc, uint32_t message[], uint32_t message_length)
|
||||
{
|
||||
if(message_length > CRC_MAX_WORDS)
|
||||
{
|
||||
#ifdef MIK32_CRC_DEBUG
|
||||
xprintf("Ошибка: переполнение буфера\n");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Запись начального значения Init */
|
||||
HAL_CRC_SetInit(hcrc);
|
||||
|
||||
uint32_t data;
|
||||
for(uint32_t i = 0; i < message_length; i++)
|
||||
{
|
||||
data = message[i];
|
||||
hcrc->Instance->DATA32 = data;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t HAL_CRC_ReadCRC(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
uint32_t CRCValue;
|
||||
/* Ожидание завершения вычисления CRC */
|
||||
HAL_CRC_WaitBusy(hcrc);
|
||||
|
||||
CRCValue = CRC->DATA32;
|
||||
|
||||
return CRCValue;
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
#include "mik32_hal_crypto.h"
|
||||
|
||||
/**
|
||||
* @brief Включение тактирования модуля Crypto.
|
||||
* @note Эта weak функция может быть переопределена пользователем.
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
*/
|
||||
__attribute__((weak)) void HAL_CRYPTO_MspInit(Crypto_HandleTypeDef* hcrypto)
|
||||
{
|
||||
__HAL_PCC_CRYPTO_CLK_ENABLE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Сброс счётчиков загружаемых/выгружаемых данных.
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
*/
|
||||
void HAL_Crypto_CounterReset(Crypto_HandleTypeDef *hcrypto)
|
||||
{
|
||||
hcrypto->Instance->CONFIG |= CRYPTO_CONFIG_C_RESET_M;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ожидать когда модуль станет доступен.
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
*/
|
||||
void HAL_Crypto_WaitReady(Crypto_HandleTypeDef *hcrypto)
|
||||
{
|
||||
while (!(hcrypto->Instance->CONFIG & CRYPTO_CONFIG_READY_M));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать алгоритм шифрования.
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
* @param Algorithm Алгоритм шифрования.
|
||||
*/
|
||||
void HAL_Crypto_SetAlgorithm(Crypto_HandleTypeDef *hcrypto, uint8_t Algorithm)
|
||||
{
|
||||
hcrypto->Algorithm = Algorithm;
|
||||
|
||||
uint32_t ConfigTemp = hcrypto->Instance->CONFIG;
|
||||
|
||||
ConfigTemp &= ~CRYPTO_CONFIG_CORE_SEL_M; /* Обнуление DECODE */
|
||||
|
||||
ConfigTemp |= Algorithm << CRYPTO_CONFIG_CORE_SEL_S;
|
||||
|
||||
hcrypto->Instance->CONFIG = ConfigTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать режим шифрования.
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
* @param CipherMode Режим шифрования.
|
||||
*/
|
||||
void HAL_Crypto_SetCipherMode(Crypto_HandleTypeDef *hcrypto, uint8_t CipherMode)
|
||||
{
|
||||
hcrypto->CipherMode = CipherMode;
|
||||
|
||||
uint32_t ConfigTemp = hcrypto->Instance->CONFIG;
|
||||
|
||||
ConfigTemp &= ~CRYPTO_CONFIG_MODE_SEL_M; /* Обнуление MODE_SEL */
|
||||
|
||||
ConfigTemp |= CipherMode << CRYPTO_CONFIG_MODE_SEL_S;
|
||||
|
||||
hcrypto->Instance->CONFIG = ConfigTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать режим перестановки слова.
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
* @param SwapMode Режим перестановки слова.
|
||||
*/
|
||||
void HAL_Crypto_SetSwapMode(Crypto_HandleTypeDef *hcrypto, uint8_t SwapMode)
|
||||
{
|
||||
hcrypto->SwapMode = SwapMode;
|
||||
|
||||
uint32_t ConfigTemp = hcrypto->Instance->CONFIG;
|
||||
|
||||
ConfigTemp &= ~CRYPTO_CONFIG_SWAP_MODE_M; /* Обнуление SWAP_MODE */
|
||||
|
||||
ConfigTemp |= SwapMode << CRYPTO_CONFIG_SWAP_MODE_S;
|
||||
|
||||
hcrypto->Instance->CONFIG = ConfigTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать порядок загрузки/выгрузки данных.
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
* @param OrderMode Порядок загрузки/выгрузки данных.
|
||||
*/
|
||||
void HAL_Crypto_SetOrderMode(Crypto_HandleTypeDef *hcrypto, uint8_t OrderMode)
|
||||
{
|
||||
hcrypto->OrderMode = OrderMode;
|
||||
|
||||
uint32_t ConfigTemp = hcrypto->Instance->CONFIG;
|
||||
|
||||
ConfigTemp &= ~CRYPTO_CONFIG_ORDER_MODE_M; /* Обнуление ORDER_MODE */
|
||||
|
||||
ConfigTemp |= OrderMode << CRYPTO_CONFIG_ORDER_MODE_S;
|
||||
|
||||
hcrypto->Instance->CONFIG = ConfigTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать вектор инициализации.
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
* @param InitVector Вектор инициализации (IV).
|
||||
* @param IvLength Количество слов в InitVector.
|
||||
*/
|
||||
void HAL_Crypto_SetIV(Crypto_HandleTypeDef *hcrypto, uint32_t InitVector[], uint32_t IvLength)
|
||||
{
|
||||
|
||||
for (uint32_t i = 0; i < IvLength; i++)
|
||||
{
|
||||
hcrypto->Instance->INIT = InitVector[i];
|
||||
}
|
||||
|
||||
/* В режиме шифрования CTR длина вектора инициализации равна половине блока и такое же количество нулей */
|
||||
if(hcrypto->CipherMode == CRYPTO_CIPHER_MODE_CTR)
|
||||
{
|
||||
for (uint32_t i = 0; i < IvLength; i++)
|
||||
{
|
||||
hcrypto->Instance->INIT = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать мастер-ключ.
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
* @param crypto_key Ключ.
|
||||
*
|
||||
* @warning Ключ должен быть инициализирован в режиме шифрования (CONFIG.DECODE = 0).
|
||||
*/
|
||||
void HAL_Crypto_SetKey(Crypto_HandleTypeDef *hcrypto, uint32_t crypto_key[])
|
||||
{
|
||||
uint32_t key_length = 0;
|
||||
|
||||
switch (hcrypto->Algorithm)
|
||||
{
|
||||
case CRYPTO_ALG_KUZNECHIK:
|
||||
key_length = CRYPTO_KEY_KUZNECHIK;
|
||||
break;
|
||||
case CRYPTO_ALG_MAGMA:
|
||||
key_length = CRYPTO_KEY_MAGMA;
|
||||
break;
|
||||
case CRYPTO_ALG_AES:
|
||||
key_length = CRYPTO_KEY_AES;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Ключ должен быть инициализирован в режиме шифрования */
|
||||
hcrypto->Instance->CONFIG &= ~CRYPTO_CONFIG_DECODE_M;
|
||||
|
||||
for (uint32_t i = 0; i < key_length; i++)
|
||||
{
|
||||
hcrypto->Instance->KEY = crypto_key[i];
|
||||
}
|
||||
|
||||
HAL_Crypto_WaitReady(hcrypto);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Инициализировать Crypto в соответствии с настройками @ref Crypto_HandleTypeDef *hcrypto.
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
*/
|
||||
void HAL_Crypto_Init(Crypto_HandleTypeDef *hcrypto)
|
||||
{
|
||||
HAL_CRYPTO_MspInit(hcrypto);
|
||||
|
||||
HAL_Crypto_SetAlgorithm(hcrypto, hcrypto->Algorithm); /* Настройка алгоритма шифрования */
|
||||
HAL_Crypto_SetCipherMode(hcrypto, hcrypto->CipherMode); /* Настройка режима шифрования */
|
||||
HAL_Crypto_SetSwapMode(hcrypto, hcrypto->SwapMode); /* Настройка перестановки слова */
|
||||
HAL_Crypto_SetOrderMode(hcrypto, hcrypto->OrderMode); /* Настройка порядка загрузки/выгрузки */
|
||||
|
||||
|
||||
#ifdef MIK32_CRYPTO_DEBUG
|
||||
|
||||
switch (hcrypto->Algorithm)
|
||||
{
|
||||
case CRYPTO_ALG_KUZNECHIK:
|
||||
xprintf("KUZNECHIK- ");
|
||||
break;
|
||||
case CRYPTO_ALG_MAGMA:
|
||||
xprintf("MAGMA - ");
|
||||
break;
|
||||
case CRYPTO_ALG_AES:
|
||||
xprintf("AES - ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (hcrypto->CipherMode)
|
||||
{
|
||||
case CRYPTO_CIPHER_MODE_ECB:
|
||||
xprintf("ECB\n");
|
||||
break;
|
||||
case CRYPTO_CIPHER_MODE_CBC:
|
||||
xprintf("CBC\n");
|
||||
break;
|
||||
case CRYPTO_CIPHER_MODE_CTR:
|
||||
xprintf("CTR\n");
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Зашифровать текст.
|
||||
*
|
||||
* Зашифрованный текст передается в массив cipher_text.
|
||||
*
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
* @param plain_text Массив с данными незашифрованного текста.
|
||||
* @param cipher_text Массив с данными для зашифрованного текста.
|
||||
* @param text_length Количество слов в тексте.
|
||||
*/
|
||||
void HAL_Crypto_Encode(Crypto_HandleTypeDef *hcrypto, uint32_t plain_text[], uint32_t cipher_text[], uint32_t text_length)
|
||||
{
|
||||
uint8_t block_size = 0;
|
||||
|
||||
switch (hcrypto->Algorithm)
|
||||
{
|
||||
case CRYPTO_ALG_KUZNECHIK:
|
||||
block_size = CRYPTO_BLOCK_KUZNECHIK;
|
||||
break;
|
||||
case CRYPTO_ALG_MAGMA:
|
||||
block_size = CRYPTO_BLOCK_MAGMA;
|
||||
break;
|
||||
case CRYPTO_ALG_AES:
|
||||
block_size = CRYPTO_BLOCK_AES;
|
||||
break;
|
||||
}
|
||||
|
||||
if(((text_length % block_size) != 0)/* && (hcrypto->CipherMode != CRYPTO_CIPHER_MODE_CTR) */)
|
||||
{
|
||||
#ifdef MIK32_CRYPTO_DEBUG
|
||||
xprintf("Длина текста не кратна длине блока\n");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Режим шифрования */
|
||||
hcrypto->Instance->CONFIG &= ~CRYPTO_CONFIG_DECODE_M;
|
||||
|
||||
for (volatile uint32_t block_index = 0; block_index < text_length; block_index += block_size)
|
||||
{
|
||||
for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++)
|
||||
{
|
||||
if (word_index >= text_length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
hcrypto->Instance->BLOCK = plain_text[word_index];
|
||||
|
||||
}
|
||||
|
||||
HAL_Crypto_WaitReady(hcrypto);
|
||||
|
||||
for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++)
|
||||
{
|
||||
if (word_index >= text_length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
cipher_text[word_index] = hcrypto->Instance->BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Расшифровать текст.
|
||||
*
|
||||
* Расшифрованный текст передается в массив plain_text.
|
||||
*
|
||||
* @param hcrypto Указатель на структуру с настройками Crypto.
|
||||
* @param cipher_text Массив с данными зашифрованного текста.
|
||||
* @param plain_text Массив с данными для незашифрованного текста.
|
||||
* @param text_length Количество слов в тексте.
|
||||
*/
|
||||
void HAL_Crypto_Decode(Crypto_HandleTypeDef *hcrypto, uint32_t cipher_text[], uint32_t plain_text[], uint32_t text_length)
|
||||
{
|
||||
uint8_t block_size = 0;
|
||||
|
||||
switch (hcrypto->Algorithm)
|
||||
{
|
||||
case CRYPTO_ALG_KUZNECHIK:
|
||||
block_size = CRYPTO_BLOCK_KUZNECHIK;
|
||||
break;
|
||||
case CRYPTO_ALG_MAGMA:
|
||||
block_size = CRYPTO_BLOCK_MAGMA;
|
||||
break;
|
||||
case CRYPTO_ALG_AES:
|
||||
block_size = CRYPTO_BLOCK_AES;
|
||||
break;
|
||||
}
|
||||
|
||||
if(((text_length % block_size) != 0)/* && (hcrypto->CipherMode != CRYPTO_CIPHER_MODE_CTR)*/)
|
||||
{
|
||||
#ifdef MIK32_CRYPTO_DEBUG
|
||||
xprintf("Длина текста не кратна длине блока\n");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Режим расшифровки */
|
||||
hcrypto->Instance->CONFIG |= CRYPTO_CONFIG_DECODE_M;
|
||||
|
||||
for (volatile uint32_t block_index = 0; block_index < text_length; block_index += block_size)
|
||||
{
|
||||
for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++)
|
||||
{
|
||||
if (word_index >= text_length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
hcrypto->Instance->BLOCK = cipher_text[word_index];
|
||||
}
|
||||
|
||||
HAL_Crypto_WaitReady(hcrypto);
|
||||
|
||||
for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++)
|
||||
{
|
||||
if (word_index >= text_length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
plain_text[word_index] = hcrypto->Instance->BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
#include "mik32_hal_dac.h"
|
||||
|
||||
__attribute__((weak)) void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
__HAL_PCC_ANALOG_REGS_CLK_ENABLE();
|
||||
|
||||
if ((hdac->Init.EXTClb == DAC_EXTCLB_DACREF) && (hdac->Init.EXTRef == DAC_EXTREF_ON))
|
||||
{
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
}
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_ANALOG;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
|
||||
if (hdac->Instance_dac == &(ANALOG_REG->DAC0))
|
||||
{
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_12;
|
||||
}
|
||||
|
||||
if (hdac->Instance_dac == &(ANALOG_REG->DAC1))
|
||||
{
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_13;
|
||||
}
|
||||
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
void HAL_DAC_CLBEnable(DAC_HandleTypeDef *hdac)
|
||||
{
|
||||
hdac->Instance->REFV_CONFIG |= 1 << REF_CLB_EN_S;
|
||||
}
|
||||
|
||||
void HAL_DAC_CLBDisable(DAC_HandleTypeDef *hdac)
|
||||
{
|
||||
hdac->Instance->REFV_CONFIG &= ~(1 << REF_CLB_EN_S);
|
||||
}
|
||||
|
||||
void HAL_DAC_VCLBSet(DAC_HandleTypeDef *hdac, uint8_t v_coef)
|
||||
{
|
||||
hdac->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_VCOEF_S);
|
||||
hdac->Instance->REFV_CONFIG |= ((v_coef & 0xF) << REF_CLB_VCOEF_S);
|
||||
}
|
||||
|
||||
void HAL_DAC_ICLBSet(DAC_HandleTypeDef *hdac, uint8_t i_coef)
|
||||
{
|
||||
hdac->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_ICOEF_S);
|
||||
hdac->Instance->REFV_CONFIG |= ((i_coef & 0xF) << REF_CLB_ICOEF_S);
|
||||
}
|
||||
|
||||
void HAL_DAC_SetDiv(DAC_HandleTypeDef *hdac, uint8_t div)
|
||||
{
|
||||
//div &= ~(1<<7); // div должно быть 7-битным
|
||||
|
||||
hdac->Init.DIV = div;
|
||||
|
||||
uint32_t DAC_CFG = hdac->Instance_dac->CFG;
|
||||
|
||||
DAC_CFG &= ~DAC_CFG_DIV_M;
|
||||
DAC_CFG |= DAC_CFG_DIV_M;
|
||||
|
||||
hdac->Instance_dac->CFG = DAC_CFG;
|
||||
|
||||
}
|
||||
|
||||
void HAL_DAC_ResetEnable(DAC_HandleTypeDef *hdac)
|
||||
{
|
||||
hdac->Instance_dac->CFG |= DAC_CFG_RESN_M;
|
||||
}
|
||||
|
||||
void HAL_DAC_ResetDisable(DAC_HandleTypeDef *hdac)
|
||||
{
|
||||
hdac->Instance_dac->CFG &= ~DAC_CFG_RESN_M;
|
||||
}
|
||||
|
||||
void HAL_DAC_Disable(DAC_HandleTypeDef *hdac)
|
||||
{
|
||||
hdac->Instance_dac->CFG &= ~DAC_CFG_EN18_M;
|
||||
HAL_DAC_ResetDisable(hdac);
|
||||
}
|
||||
|
||||
void HAL_DAC_Enable(DAC_HandleTypeDef *hdac)
|
||||
{
|
||||
hdac->Instance_dac->CFG |= DAC_CFG_EN18_M;
|
||||
HAL_DAC_ResetEnable(hdac);
|
||||
}
|
||||
|
||||
void HAL_DAC_Init(DAC_HandleTypeDef *hdac)
|
||||
{
|
||||
HAL_DAC_MspInit(hdac);
|
||||
|
||||
/* Очищение регистра настроек ЦАП */
|
||||
hdac->Instance_dac->CFG = 0;
|
||||
|
||||
HAL_DAC_Enable(hdac);
|
||||
|
||||
/* Перевод вывода DAC_REF в аналоговый режим */
|
||||
if((hdac->Init.EXTRef == DAC_EXTREF_ON) || (hdac->Init.EXTClb == DAC_EXTCLB_DACREF))
|
||||
{
|
||||
PAD_CONFIG->PORT_1_CFG |= (DAC_PORT_AS_FUNC3 << 2 * DAC_REF_PORT_1_11);
|
||||
}
|
||||
|
||||
/* Перевод вывода ЦАП в аналоговый режим */
|
||||
if(hdac->Instance_dac == HAL_DAC1)
|
||||
{
|
||||
PAD_CONFIG->PORT_1_CFG |= (DAC_PORT_AS_FUNC3 << 2 * DAC1_PORT_1_12);
|
||||
}
|
||||
if(hdac->Instance_dac == HAL_DAC2)
|
||||
{
|
||||
PAD_CONFIG->PORT_1_CFG |= (DAC_PORT_AS_FUNC3 << 2 * DAC2_PORT_1_13);
|
||||
}
|
||||
|
||||
HAL_DAC_SetDiv(hdac, hdac->Init.DIV); /* Задание делителя */
|
||||
|
||||
hdac->Instance_dac->CFG |= (hdac->Init.EXTRef << DAC_CFG_EXTEN_S) | /* Настройка источника опорного напряжения */
|
||||
(hdac->Init.EXTClb << DAC_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */
|
||||
|
||||
|
||||
}
|
||||
|
||||
void HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint16_t DAC_Value)
|
||||
{
|
||||
DAC_Value &= ~(0xF << 12);
|
||||
hdac->Instance_dac->VALUE = DAC_Value;
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
#include "mik32_hal_dma.h"
|
||||
|
||||
/**
|
||||
* @brief Данная переменная хранит последнее записанное значение в регистр CHx_CFG.
|
||||
* @warning Не следует изменять значение данной переменной.
|
||||
*/
|
||||
static uint32_t CFGWriteBuffer[4] = {0};
|
||||
|
||||
/**
|
||||
* @brief Данная переменная используется для хранения значения битовых полей CONFIG_STATUS[8:6].
|
||||
* @warning Не следует изменять значение данной переменной.
|
||||
*/
|
||||
static uint32_t ConfigStatusWriteBuffer = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Включение тактирования модуля OTP.
|
||||
*
|
||||
* Эта функция может быть переопределена пользователем.
|
||||
* @param hdma Указатель на структуру для инициализации DMA.
|
||||
*/
|
||||
__attribute__((weak)) void HAL_DMA_MspInit(DMA_InitTypeDef* hdma)
|
||||
{
|
||||
__HAL_PCC_DMA_CLK_ENABLE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать номер канала.
|
||||
* @param hdma_channel Указатель на структуру для инициализации канала DMA.
|
||||
* @param ChannelIndex Номер канала.
|
||||
*/
|
||||
void HAL_DMA_SetChannel(DMA_ChannelHandleTypeDef *hdma_channel, HAL_DMA_ChannelIndexTypeDef ChannelIndex)
|
||||
{
|
||||
hdma_channel->ChannelInit.Channel = ChannelIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Очистить все флаги локального прерывания.
|
||||
* @param hdma Указатель на структуру для инициализации DMA.
|
||||
*/
|
||||
void HAL_DMA_ClearLocalIrq(DMA_InitTypeDef *hdma)
|
||||
{
|
||||
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
|
||||
ConfigStatusWriteBuffer |= DMA_CONFIG_CLEAR_LOCAL_IRQ_M;
|
||||
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
|
||||
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Очистить флаг глобального прерывания.
|
||||
* @param hdma Указатель на структуру для инициализации DMA.
|
||||
*/
|
||||
void HAL_DMA_ClearGlobalIrq(DMA_InitTypeDef *hdma)
|
||||
{
|
||||
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
|
||||
ConfigStatusWriteBuffer |= DMA_CONFIG_CLEAR_GLOBAL_IRQ_M;
|
||||
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
|
||||
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Очистить флаг прерывания ошибки.
|
||||
* @param hdma Указатель на структуру для инициализации DMA.
|
||||
*/
|
||||
void HAL_DMA_ClearErrorIrq(DMA_InitTypeDef *hdma)
|
||||
{
|
||||
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
|
||||
ConfigStatusWriteBuffer |= DMA_CONFIG_CLEAR_ERROR_IRQ_M;
|
||||
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
|
||||
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Очистить все флаги прерываний.
|
||||
*
|
||||
* Очищаются флаги локальных прерываний, глобального прерывания, прерывания ошибки.
|
||||
* @param hdma Указатель на структуру для инициализации DMA.
|
||||
*/
|
||||
void HAL_DMA_ClearIrq(DMA_InitTypeDef *hdma)
|
||||
{
|
||||
HAL_DMA_ClearLocalIrq(hdma);
|
||||
HAL_DMA_ClearGlobalIrq(hdma);
|
||||
HAL_DMA_ClearErrorIrq(hdma);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать разрешение чтения текущего статуса канала.
|
||||
*
|
||||
* При значении #DMA_CURRENT_VALUE_ENABLE регистры CHx_DST, CHx_SRC, CHx_LEN возвращают текущие значения,
|
||||
* а в CHx_CFG при считывании меняются битовые поля. При значении #DMA_CURRENT_VALUE_DISABLE регистры возвращают значения при настройке.
|
||||
* @param hdma Указатель на структуру для инициализации DMA.
|
||||
* @param CurrentValue Разрешение или запрет чтения текущего статуса канала.
|
||||
*/
|
||||
void HAL_DMA_SetCurrentValue(DMA_InitTypeDef *hdma, HAL_DMA_CurrentValueTypeDef CurrentValue)
|
||||
{
|
||||
hdma->CurrentValue = CurrentValue;
|
||||
ConfigStatusWriteBuffer &= ~DMA_CONFIG_CURRENT_VALUE_M;
|
||||
ConfigStatusWriteBuffer |= CurrentValue << DMA_CONFIG_CURRENT_VALUE_S;
|
||||
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Разрешить или запретить глобальное прерывание.
|
||||
* @param hdma Указатель на структуру для инициализации DMA.
|
||||
* @param Permission Разрешение (#DMA_IRQ_ENABLE) или запрет (#DMA_IRQ_DISABLE) прерывания.
|
||||
*/
|
||||
void HAL_DMA_GlobalIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission)
|
||||
{
|
||||
ConfigStatusWriteBuffer &= ~DMA_CONFIG_GLOBAL_IRQ_ENA_M;
|
||||
ConfigStatusWriteBuffer |= Permission << DMA_CONFIG_GLOBAL_IRQ_ENA_S;
|
||||
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Разрешить или запретить прерывание ошибки.
|
||||
* @param hdma Указатель на структуру для инициализации DMA.
|
||||
* @param Permission Разрешение (#DMA_IRQ_ENABLE) или запрет (#DMA_IRQ_DISABLE) прерывания.
|
||||
*/
|
||||
void HAL_DMA_ErrorIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission)
|
||||
{
|
||||
ConfigStatusWriteBuffer &= ~DMA_CONFIG_ERROR_IRQ_ENA_M;
|
||||
ConfigStatusWriteBuffer |= Permission << DMA_CONFIG_ERROR_IRQ_ENA_S;
|
||||
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Разрешить или запретить локальное прерывание.
|
||||
*
|
||||
* Прерывание формируется, когда канал завершил задачу.
|
||||
* @param hdma_channel Структура для инициализации канала DMA.
|
||||
* @param Permission Разрешение (#DMA_IRQ_ENABLE) или запрет (#DMA_IRQ_DISABLE) прерывания.
|
||||
*/
|
||||
void HAL_DMA_LocalIRQEnable(DMA_ChannelHandleTypeDef* hdma_channel, HAL_DMA_IRQTypeDef Permission)
|
||||
{
|
||||
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
|
||||
|
||||
CFGWriteBuffer[ChannelIndex] &= ~DMA_CH_CFG_IRQ_EN_M;
|
||||
CFGWriteBuffer[ChannelIndex] |= Permission << DMA_CH_CFG_IRQ_EN_S;
|
||||
|
||||
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Инициализация DMA в соответствии с настройками структуры hdma.
|
||||
* @param hdma Указатель на структуру для инициализации DMA.
|
||||
* @return Статус функции после её выполнения (HAL Status).
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_Init(DMA_InitTypeDef *hdma)
|
||||
{
|
||||
if (hdma == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
HAL_DMA_MspInit(hdma);
|
||||
|
||||
ConfigStatusWriteBuffer = 0;
|
||||
|
||||
HAL_DMA_ClearIrq(hdma);
|
||||
HAL_DMA_SetCurrentValue(hdma, hdma->CurrentValue);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ожидание готовности канала.
|
||||
* @param hdma_channel Структура для инициализации канала DMA.
|
||||
* @param Timeout Количество циклов ожидания. Стандартное значение #DMA_TIMEOUT_DEFAULT.
|
||||
* @return Статус функции после её выполнения (HAL Status).
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_Wait(DMA_ChannelHandleTypeDef* hdma_channel, uint32_t Timeout)
|
||||
{
|
||||
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
|
||||
|
||||
uint32_t mask = (1 << ChannelIndex) << DMA_STATUS_READY_S;
|
||||
|
||||
while (Timeout-- != 0)
|
||||
{
|
||||
if ((hdma_channel->dma->Instance->CONFIG_STATUS & mask) != 0)
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получить статус готовности канала.
|
||||
* @param hdma_channel Структура для инициализации канала DMA.
|
||||
* @return Статус готовности канала. 0 - канал занят, 1 - канал готов к работе.
|
||||
*/
|
||||
int HAL_DMA_GetChannelReadyStatus(DMA_ChannelHandleTypeDef* hdma_channel)
|
||||
{
|
||||
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
|
||||
|
||||
uint32_t status = ((hdma_channel->dma->Instance->CONFIG_STATUS) & ((1 << ChannelIndex) << DMA_STATUS_READY_S));
|
||||
status = (status >> DMA_STATUS_READY_S ) >> ChannelIndex;
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получить статус локального прерывания канала.
|
||||
* @param hdma_channel Структура для инициализации канала DMA.
|
||||
* @return Статус локального прерывания канала. 0 - прерывания нет, 1 - прерывание есть.
|
||||
*/
|
||||
int HAL_DMA_GetChannelIrq(DMA_ChannelHandleTypeDef* hdma_channel)
|
||||
{
|
||||
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
|
||||
uint32_t ChannelIrq = (hdma_channel->dma->Instance->CONFIG_STATUS) & ((1 << ChannelIndex) << DMA_STATUS_CHANNEL_IRQ_S);
|
||||
ChannelIrq = ( ChannelIrq >> DMA_STATUS_CHANNEL_IRQ_S ) >> ChannelIndex;
|
||||
return ChannelIrq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получить статус состояния канала при ошибках на шине.
|
||||
* @param hdma_channel Структура для инициализации канала DMA.
|
||||
* @return Статус состояния канала при ошибках на шине. 0 - нет ошибки, 1 - есть ошибка.
|
||||
*/
|
||||
int HAL_DMA_GetBusError(DMA_ChannelHandleTypeDef* hdma_channel)
|
||||
{
|
||||
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
|
||||
uint32_t BusError = ((hdma_channel->dma->Instance->CONFIG_STATUS) & ((1 << ChannelIndex) << DMA_STATUS_CHANNEL_BUS_ERROR_S));
|
||||
BusError = ( BusError >> DMA_STATUS_CHANNEL_BUS_ERROR_S ) >> ChannelIndex;
|
||||
return BusError;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Принудительная остановка работы канала.
|
||||
* @param hdma_channel Структура для инициализации канала DMA.
|
||||
*/
|
||||
void HAL_DMA_ChannelDisable(DMA_ChannelHandleTypeDef *hdma_channel)
|
||||
{
|
||||
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
|
||||
CFGWriteBuffer[ChannelIndex] &= ~(DMA_CH_CFG_ENABLE_M);
|
||||
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Инициализация работы канала.
|
||||
* @param hdma_channel Структура для инициализации канала DMA.
|
||||
*/
|
||||
void HAL_DMA_ChannelEnable(DMA_ChannelHandleTypeDef *hdma_channel)
|
||||
{
|
||||
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
|
||||
CFGWriteBuffer[ChannelIndex] |= DMA_CH_CFG_ENABLE_M;
|
||||
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Запуск работы канала с настройками из структуры hdma_channel.
|
||||
* @param hdma_channel Структура для инициализации канала DMA.
|
||||
* @param SRC Адрес источника.
|
||||
* @param DST Адрес назначения
|
||||
* @param Len Количество байт пересылки. Значение следует записывать на 1 меньше числа пересылаемых байт.
|
||||
* Например, для отправки 8 байт значение Len = 7.
|
||||
*/
|
||||
void HAL_DMA_Start(DMA_ChannelHandleTypeDef *hdma_channel, void* SRC, void* DST, uint32_t Len)
|
||||
{
|
||||
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
|
||||
|
||||
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].SRC = (uint32_t) SRC;
|
||||
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].DST = (uint32_t) DST;
|
||||
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].LEN = Len;
|
||||
|
||||
|
||||
CFGWriteBuffer[ChannelIndex] |= DMA_CH_CFG_ENABLE_M
|
||||
| (hdma_channel->ChannelInit.Priority << DMA_CH_CFG_PRIOR_S)
|
||||
| (hdma_channel->ChannelInit.ReadMode << DMA_CH_CFG_READ_MODE_S)
|
||||
| (hdma_channel->ChannelInit.ReadInc << DMA_CH_CFG_READ_INCREMENT_S)
|
||||
| (hdma_channel->ChannelInit.ReadSize << DMA_CH_CFG_READ_SIZE_S)
|
||||
| (hdma_channel->ChannelInit.ReadBurstSize << DMA_CH_CFG_READ_BURST_SIZE_S)
|
||||
| (hdma_channel->ChannelInit.ReadRequest << DMA_CH_CFG_READ_REQUETS_S)
|
||||
| (hdma_channel->ChannelInit.ReadAck << DMA_CH_CFG_READ_ACK_EN_S)
|
||||
| (hdma_channel->ChannelInit.WriteMode << DMA_CH_CFG_WRITE_MODE_S)
|
||||
| (hdma_channel->ChannelInit.WriteInc << DMA_CH_CFG_WRITE_INCREMENT_S)
|
||||
| (hdma_channel->ChannelInit.WriteSize << DMA_CH_CFG_WRITE_SIZE_S)
|
||||
| (hdma_channel->ChannelInit.WriteBurstSize << DMA_CH_CFG_WRITE_BURST_SIZE_S)
|
||||
| (hdma_channel->ChannelInit.WriteRequest << DMA_CH_CFG_WRITE_REQUETS_S)
|
||||
| (hdma_channel->ChannelInit.WriteAck << DMA_CH_CFG_WRITE_ACK_EN_S);
|
||||
|
||||
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
#include "mik32_hal_eeprom.h"
|
||||
|
||||
const uint8_t N_LD_DEFAULT = 1;
|
||||
const uint8_t N_R_2_DEFAULT = 1;
|
||||
|
||||
HAL_StatusTypeDef HAL_EEPROM_Init(HAL_EEPROM_HandleTypeDef *eeprom)
|
||||
{
|
||||
if (eeprom->Instance != EEPROM_REGS)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
eeprom->Instance->EECON = 0;
|
||||
HAL_EEPROM_SetMode(eeprom, eeprom->Mode);
|
||||
HAL_EEPROM_SetErrorCorrection(eeprom, eeprom->ErrorCorrection);
|
||||
HAL_EEPROM_SetInterrupt(eeprom, eeprom->EnableInterrupt);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_EEPROM_Erase(
|
||||
HAL_EEPROM_HandleTypeDef *eeprom,
|
||||
uint16_t address,
|
||||
uint8_t erasedWordsCount,
|
||||
HAL_EEPROM_WriteBehaviourTypeDef erasedPages,
|
||||
uint32_t timeout)
|
||||
{
|
||||
eeprom->Instance->EECON |= EEPROM_EECON_BWE_M | (erasedPages << EEPROM_EECON_WRBEH_S);
|
||||
|
||||
if (eeprom->Mode == HAL_EEPROM_MODE_TWO_STAGE)
|
||||
{
|
||||
eeprom->Instance->EEA = address;
|
||||
for (int i = 0; i < erasedWordsCount; i++)
|
||||
{
|
||||
eeprom->Instance->EEDAT = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
for (int i = 0; i < erasedWordsCount; i++)
|
||||
{
|
||||
eeprom->Instance->EEA = address + i * 4;
|
||||
eeprom->Instance->EEDAT = 0;
|
||||
if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
eeprom->Instance->EECON |= EEPROM_EECON_OP(EEPROM_EECON_OP_ER) | EEPROM_EECON_EX_M;
|
||||
|
||||
return HAL_EEPROM_WaitBusy(eeprom, timeout);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_EEPROM_Write(
|
||||
HAL_EEPROM_HandleTypeDef *eeprom,
|
||||
uint16_t address,
|
||||
uint32_t *data,
|
||||
uint8_t length,
|
||||
HAL_EEPROM_WriteBehaviourTypeDef writedPages,
|
||||
uint32_t timeout)
|
||||
{
|
||||
eeprom->Instance->EECON |= EEPROM_EECON_BWE_M | (writedPages << EEPROM_EECON_WRBEH_S);
|
||||
|
||||
if (eeprom->Mode == HAL_EEPROM_MODE_TWO_STAGE)
|
||||
{
|
||||
eeprom->Instance->EEA = address;
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
eeprom->Instance->EEDAT = data[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
eeprom->Instance->EEA = address + i * 4;
|
||||
eeprom->Instance->EEDAT = data[i];
|
||||
if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
eeprom->Instance->EECON |= EEPROM_EECON_OP(EEPROM_EECON_OP_PR) | EEPROM_EECON_EX_M;
|
||||
|
||||
return HAL_EEPROM_WaitBusy(eeprom, timeout);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_EEPROM_Read(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint32_t *data, uint8_t length, uint32_t timeout)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if (eeprom->Mode == HAL_EEPROM_MODE_TWO_STAGE)
|
||||
{
|
||||
eeprom->Instance->EEA = address;
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
data[i] = eeprom->Instance->EEDAT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
eeprom->Instance->EEA = address + i * 4;
|
||||
if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK)
|
||||
return status;
|
||||
data[i] = eeprom->Instance->EEDAT;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void HAL_EEPROM_SetMode(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ModeTypeDef mode)
|
||||
{
|
||||
eeprom->Mode = mode;
|
||||
|
||||
if (eeprom->Mode == HAL_EEPROM_MODE_THREE_STAGE)
|
||||
{
|
||||
eeprom->Instance->EECON |= EEPROM_EECON_APBNWS_M;
|
||||
}
|
||||
else
|
||||
{
|
||||
eeprom->Instance->EECON &= ~EEPROM_EECON_APBNWS_M;
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_EEPROM_SetErrorCorrection(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ErrorCorrectionTypeDef errorCorrection)
|
||||
{
|
||||
eeprom->ErrorCorrection = errorCorrection;
|
||||
|
||||
if (eeprom->ErrorCorrection == HAL_EEPROM_ECC_DISABLE)
|
||||
{
|
||||
eeprom->Instance->EECON |= EEPROM_EECON_DISECC_M;
|
||||
}
|
||||
else
|
||||
{
|
||||
eeprom->Instance->EECON &= ~EEPROM_EECON_DISECC_M;
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_EEPROM_SetInterrupt(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_EnableInterruptTypeDef enableInterrupt)
|
||||
{
|
||||
eeprom->EnableInterrupt = enableInterrupt;
|
||||
|
||||
if (eeprom->EnableInterrupt == HAL_EEPROM_SERR_ENABLE)
|
||||
{
|
||||
eeprom->Instance->EECON |= EEPROM_EECON_IESERR_M;
|
||||
}
|
||||
else
|
||||
{
|
||||
eeprom->Instance->EECON &= ~EEPROM_EECON_IESERR_M;
|
||||
}
|
||||
}
|
||||
|
||||
const int32_t N_EP_1_denominator = 1000 * 1000 * 1000 / (2 * 1000 * 1000);
|
||||
|
||||
const int32_t N_EP_2_reduce = 5 * 1000;
|
||||
const int32_t N_EP_2_numerator = 15 * 1000 / N_EP_2_reduce;
|
||||
const int32_t N_EP_2_denominator = 1000 * 1000 * 1000 / N_EP_2_reduce;
|
||||
|
||||
void HAL_EEPROM_CalculateTimings(HAL_EEPROM_HandleTypeDef *eeprom, int32_t frequency)
|
||||
{
|
||||
eeprom->Timings.N_LD = N_LD_DEFAULT;
|
||||
eeprom->Timings.N_R_2 = N_R_2_DEFAULT;
|
||||
|
||||
eeprom->Timings.N_EP_1 = frequency / N_EP_1_denominator;
|
||||
|
||||
eeprom->Timings.N_EP_2 = (frequency * N_EP_2_numerator) / N_EP_2_denominator;
|
||||
|
||||
int32_t n_r_1_step_1 = (frequency / 1000) * 51;
|
||||
int32_t n_r_1_step_2 = n_r_1_step_1 / (1000 * 1000);
|
||||
|
||||
if ((n_r_1_step_1 % (1000 * 1000)) != 0)
|
||||
{
|
||||
n_r_1_step_2 += 1;
|
||||
}
|
||||
|
||||
eeprom->Timings.N_R_1 = n_r_1_step_2;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_EEPROM_GetECC(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint8_t *buf_value_ecc, uint32_t timeout)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
eeprom->Instance->EEA = address;
|
||||
if (eeprom->Mode == HAL_EEPROM_MODE_THREE_STAGE)
|
||||
{
|
||||
|
||||
if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK)
|
||||
return status;
|
||||
}
|
||||
*buf_value_ecc = eeprom->Instance->EERB;
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
#include "mik32_hal_gpio.h"
|
||||
|
||||
/** Для обхода бага МК, чтение из регистра IRQ_LINE_MUX всегда возвращает 0
|
||||
* \note Используется в функциях HAL_GPIO_InitInterruptLine и HAL_GPIO_DeInitInterruptLine
|
||||
*/
|
||||
volatile uint32_t current_irq_line_mux = 0;
|
||||
|
||||
/**
|
||||
* @brief Инициализация модуля GPIO_x в соответствии с указанными параметрами в GPIO_Init.
|
||||
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
|
||||
* @param GPIO_Init указатель на структуру GPIO_InitTypeDef, которая содержит информацию о конфигурации для указанного модуля GPIO.
|
||||
* @return статус HAL.
|
||||
* @warning функция не включает тактирование выбранного модуля GPIO. Включить тактирование можно, например, с помощью макроса @ref __HAL_PCC_GPIO_2_CLK_ENABLE.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_GPIO_Init(GPIO_TypeDef *GPIO_x, GPIO_InitTypeDef *GPIO_Init)
|
||||
{
|
||||
uint32_t *port_cfg = 0;
|
||||
uint32_t *port_ds = 0;
|
||||
uint32_t *port_pupd = 0;
|
||||
|
||||
uint32_t position = 0;
|
||||
uint32_t current_pin = 0;
|
||||
|
||||
switch ((uint32_t)GPIO_x)
|
||||
{
|
||||
case (uint32_t)GPIO_0:
|
||||
port_cfg = (uint32_t *)&(PAD_CONFIG->PORT_0_CFG);
|
||||
port_ds = (uint32_t *)&(PAD_CONFIG->PORT_0_DS);
|
||||
port_pupd = (uint32_t *)&(PAD_CONFIG->PORT_0_PUPD);
|
||||
break;
|
||||
case (uint32_t)GPIO_1:
|
||||
port_cfg = (uint32_t *)&(PAD_CONFIG->PORT_1_CFG);
|
||||
port_ds = (uint32_t *)&(PAD_CONFIG->PORT_1_DS);
|
||||
port_pupd = (uint32_t *)&(PAD_CONFIG->PORT_1_PUPD);
|
||||
break;
|
||||
case (uint32_t)GPIO_2:
|
||||
port_cfg = (uint32_t *)&(PAD_CONFIG->PORT_2_CFG);
|
||||
port_ds = (uint32_t *)&(PAD_CONFIG->PORT_2_DS);
|
||||
port_pupd = (uint32_t *)&(PAD_CONFIG->PORT_2_PUPD);
|
||||
break;
|
||||
|
||||
default:
|
||||
return HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
// magic_foo(pinMask, port_cfg, port_pupd, port_ds)
|
||||
while (((GPIO_Init->Pin) >> position) != 0)
|
||||
{
|
||||
current_pin = GPIO_Init->Pin & (1 << position);
|
||||
|
||||
if (current_pin)
|
||||
{
|
||||
*port_cfg = (*port_cfg & (~PAD_CONFIG_PIN_M(position))) | PAD_CONFIG_PIN(position, GPIO_Init->Mode & 0b11);
|
||||
|
||||
if ((GPIO_Init->Mode == HAL_GPIO_MODE_GPIO_INPUT) || (GPIO_Init->Mode == HAL_GPIO_MODE_GPIO_OUTPUT))
|
||||
{
|
||||
if (GPIO_Init->Mode == HAL_GPIO_MODE_GPIO_INPUT)
|
||||
{
|
||||
GPIO_x->DIRECTION_IN = 1 << position;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_x->DIRECTION_OUT = 1 << position;
|
||||
}
|
||||
}
|
||||
|
||||
*port_ds = (*port_ds & (~PAD_CONFIG_PIN_M(position))) | PAD_CONFIG_PIN(position, GPIO_Init->DS);
|
||||
*port_pupd = (*port_pupd & (~PAD_CONFIG_PIN_M(position))) | PAD_CONFIG_PIN(position, GPIO_Init->Pull);
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Инициализация модуля GPIO_x.
|
||||
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
|
||||
* @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки.
|
||||
* @param mode режим вывода.
|
||||
* @param pull режим подтяжки вывода.
|
||||
* @param driveStrength перечисление режимов нагрузочной способности.
|
||||
* @return Статус HAL.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, HAL_GPIO_ModeTypeDef mode, HAL_GPIO_PullTypeDef pull, HAL_GPIO_DSTypeDef driveStrength)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
GPIO_InitStruct.Pin = pin;
|
||||
GPIO_InitStruct.Mode = mode;
|
||||
GPIO_InitStruct.Pull = pull;
|
||||
GPIO_InitStruct.DS = driveStrength;
|
||||
return HAL_GPIO_Init(GPIO_x, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Считать текущее состояние выводов порта GPIO_x.
|
||||
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
|
||||
* @param pin маска выводов порта GPIO_x, с которых считывание значение.
|
||||
* @return @ref GPIO_PIN_HIGH если с одного или больше выводов, указанных в pin, считалась 1. Иначе @ref GPIO_PIN_LOW.
|
||||
*/
|
||||
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin)
|
||||
{
|
||||
GPIO_PinState bitStatus;
|
||||
|
||||
if ((GPIO_x->SET & pin) != (uint32_t)GPIO_PIN_LOW)
|
||||
{
|
||||
bitStatus = GPIO_PIN_HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitStatus = GPIO_PIN_LOW;
|
||||
}
|
||||
return bitStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать логический уровень выходного сигнала для указанных выводов порта GPIO_x.
|
||||
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
|
||||
* @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки.
|
||||
* @param pinState значение состояние вывода, в которое будут установлены указанные выводы.
|
||||
* Этот параметр должен быть одним из значений:
|
||||
* - @ref GPIO_PIN_LOW низкий выходной уровень
|
||||
* - @ref GPIO_PIN_HIGH высокий выходной уровень
|
||||
*/
|
||||
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState)
|
||||
{
|
||||
if (pinState == GPIO_PIN_LOW)
|
||||
{
|
||||
GPIO_x->CLEAR = pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_x->SET = pin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Переключить логический уровень выходного сигнала для указанных выводов порта GPIO_x.
|
||||
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
|
||||
* @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки.
|
||||
*/
|
||||
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin)
|
||||
{
|
||||
GPIO_x->OUTPUT_ ^= pin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция инициализации линии прерывания.
|
||||
* \param mux настройка мультиплексора линии прерывания.
|
||||
* \param mode режим линии прерывания.
|
||||
* @return Статус HAL.
|
||||
* \note Номер линии прерывания можно получить после настройки мультиплексора.
|
||||
* Введите в mux GPIO_MUX_GPIO_X_X, где X - номера порта и вывода,
|
||||
* и нажмите Ctrl+Пробел: появятся варианты констант для данного вывода,
|
||||
* далее достаточно выбрать константу для доступной линии.
|
||||
* В mode введите GPIO_INT_MODE и нажмите Ctrl+Пробел: появятся варианты типов прерываний канала.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_GPIO_InitInterruptLine(HAL_GPIO_Line_Config mux, HAL_GPIO_InterruptMode mode)
|
||||
{
|
||||
int irq_line_num = mux >> GPIO_IRQ_LINE_S;
|
||||
mode &= 0b111;
|
||||
if (irq_line_num > 7)
|
||||
return HAL_ERROR;
|
||||
|
||||
current_irq_line_mux &= ~GPIO_IRQ_LINE_MUX_M(irq_line_num);
|
||||
current_irq_line_mux |= GPIO_IRQ_LINE_MUX(mux, irq_line_num);
|
||||
GPIO_IRQ->LINE_MUX = current_irq_line_mux;
|
||||
|
||||
if (mode & GPIO_MODE_BIT_LEVEL_M) // GPIO_INT_MODE_HIGH, GPIO_INT_MODE_RISING
|
||||
{
|
||||
GPIO_IRQ->LEVEL_SET = (1 << irq_line_num); // нарастающий фронт или логический уровень 1
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_IRQ->LEVEL_CLEAR = (1 << irq_line_num); // спадающий фронт или логический уровень 0
|
||||
}
|
||||
|
||||
if (mode & GPIO_MODE_BIT_EDGE_M) // GPIO_INT_MODE_FALLING, GPIO_INT_MODE_RISING, GPIO_INT_MODE_CHANGE
|
||||
{
|
||||
GPIO_IRQ->EDGE = (1 << irq_line_num); // тип прерывания - событие (фронт/спад)
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_IRQ->LEVEL = (1 << irq_line_num); // тип прерывания - логический уровень
|
||||
}
|
||||
|
||||
if (mode & GPIO_MODE_BIT_ANYEDGE_M) // GPIO_INT_MODE_CHANGE
|
||||
{
|
||||
GPIO_IRQ->ANY_EDGE_SET = (1 << irq_line_num); // разрешено прерывание по любому фронту
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_IRQ->ANY_EDGE_CLEAR = (1 << irq_line_num); // запрещено прерывание по любому фронту
|
||||
}
|
||||
|
||||
GPIO_IRQ->ENABLE_SET = (1 << irq_line_num);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция деинициализации линии прерывания, запрещает прерывание и возвращает настройки по умолчанию для указанной лини.
|
||||
* @param irqLine номер линии прерывания.
|
||||
* @return Статус HAL.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine)
|
||||
{
|
||||
int irq_line_num = irqLine >> GPIO_IRQ_LINE_S;
|
||||
|
||||
if (irq_line_num > 7)
|
||||
return HAL_ERROR;
|
||||
|
||||
GPIO_IRQ->ENABLE_CLEAR = (1 << irq_line_num);
|
||||
|
||||
current_irq_line_mux &= ~GPIO_IRQ_LINE_MUX_M(irq_line_num);
|
||||
GPIO_IRQ->LINE_MUX = current_irq_line_mux;
|
||||
|
||||
GPIO_IRQ->LEVEL = (1 << irq_line_num);
|
||||
GPIO_IRQ->LEVEL_CLEAR = (1 << irq_line_num);
|
||||
GPIO_IRQ->ANY_EDGE_CLEAR = (1 << irq_line_num);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получить состояние линии прерывания.
|
||||
* @param irqLine номер линии прерывания.
|
||||
* @return Возвращает 1 если сработало прерывание данной линии, иначе 0.
|
||||
*/
|
||||
uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine)
|
||||
{
|
||||
int irq_line_num = irqLine >> GPIO_IRQ_LINE_S;
|
||||
return (GPIO_IRQ->INTERRUPT & (1 << (irq_line_num))) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция чтения логического уровня вывода, подключенного к линии прерывания.
|
||||
* @param irqLine номер линии прерывания.
|
||||
* @return Логический уровень вывода.
|
||||
*/
|
||||
GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine)
|
||||
{
|
||||
int irq_line_num = irqLine >> GPIO_IRQ_LINE_S;
|
||||
return (GPIO_PinState)((GPIO_IRQ->STATE & (1 << (irq_line_num))) >> irq_line_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция сброса регистра состояния прерываний.
|
||||
* @note Когда срабатывает прерывание на одной из линии, в регистре INTERRUPT
|
||||
* выставляется 1 в разряде, соответствующем линии прерывания.
|
||||
* После обработки прерывания необходимо сбросить данный регистр
|
||||
* в обработчике прерывания trap_handler().
|
||||
* Если после обработки прерывания регистр не был сброшен,
|
||||
* обработчик будет вызван снова, программа будет бесконечно вызывать обработчик.
|
||||
*/
|
||||
void HAL_GPIO_ClearInterrupts()
|
||||
{
|
||||
GPIO_IRQ->CLEAR = 0b11111111;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,56 @@
|
||||
#include "mik32_hal_irq.h"
|
||||
|
||||
// #define MIK32_IRQ_DEBUG
|
||||
|
||||
void HAL_IRQ_EnableInterrupts()
|
||||
{
|
||||
set_csr(mstatus, MSTATUS_MIE);
|
||||
set_csr(mie, MIE_MEIE);
|
||||
}
|
||||
|
||||
void HAL_IRQ_DisableInterrupts()
|
||||
{
|
||||
clear_csr(mie, MIE_MEIE);
|
||||
}
|
||||
|
||||
void HAL_EPIC_MaskEdgeSet(uint32_t InterruptMask)
|
||||
{
|
||||
EPIC->MASK_EDGE_SET |= InterruptMask;
|
||||
}
|
||||
|
||||
void HAL_EPIC_MaskEdgeClear(uint32_t InterruptMask)
|
||||
{
|
||||
EPIC->MASK_EDGE_CLEAR |= InterruptMask;
|
||||
}
|
||||
|
||||
void HAL_EPIC_MaskLevelSet(uint32_t InterruptMask)
|
||||
{
|
||||
EPIC->MASK_LEVEL_SET |= InterruptMask;
|
||||
}
|
||||
|
||||
void HAL_EPIC_MaskLevelClear(uint32_t InterruptMask)
|
||||
{
|
||||
EPIC->MASK_LEVEL_CLEAR |= InterruptMask;
|
||||
}
|
||||
|
||||
uint32_t HAL_EPIC_GetStatus()
|
||||
{
|
||||
return EPIC->STATUS;
|
||||
}
|
||||
|
||||
uint32_t HAL_EPIC_GetRawStatus()
|
||||
{
|
||||
return EPIC->RAW_STATUS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,388 @@
|
||||
#include "mik32_hal_otp.h"
|
||||
#include "mik32_hal.h"
|
||||
|
||||
/**
|
||||
* @brief Включение тактирования модуля OTP.
|
||||
*
|
||||
* Эта функция может быть переопределена пользователем.
|
||||
*
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
*/
|
||||
__attribute__((weak)) void HAL_OTP_MspInit(OTP_HandleTypeDef* hotp)
|
||||
{
|
||||
__HAL_PCC_OTP_CONTROLLER_CLK_ENABLE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Включить/выключить режим пониженного энергопотребления.
|
||||
*
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
* @param PowerOff Режим пониженного энергопотребления.
|
||||
*/
|
||||
void HAL_OTP_PowerOff(OTP_HandleTypeDef *hotp, uint8_t PowerOff)
|
||||
{
|
||||
uint32_t OtpadjConfig = hotp->Instance->OTPADJ;
|
||||
|
||||
OtpadjConfig &= ~OTP_OTPADJ_POWER_OFF_I_M;
|
||||
OtpadjConfig |= PowerOff << OTP_OTPADJ_POWER_OFF_I_S;
|
||||
|
||||
hotp->Instance->OTPADJ = OtpadjConfig;
|
||||
|
||||
/* После выхода из режима пониженного энергопотребления необходимо выдержать паузу */
|
||||
for (volatile int i = 0; i < 1000; i++);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать напряжение на UPP матрице.
|
||||
*
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
* @param UppReadVoltage Напряжение на UPP матрице.
|
||||
*/
|
||||
void HAL_OTP_SetUppRead(OTP_HandleTypeDef *hotp, uint8_t UppReadVoltage)
|
||||
{
|
||||
uint32_t OtpadjConfig = hotp->Instance->OTPADJ;
|
||||
|
||||
OtpadjConfig &= ~OTP_OTPADJ_SEL_UPP_READ_I_M;
|
||||
OtpadjConfig |= UppReadVoltage << OTP_OTPADJ_SEL_UPP_READ_I_S;
|
||||
|
||||
hotp->Instance->OTPADJ = OtpadjConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать ток считывания.
|
||||
*
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
* @param ReadCur Ток считывания.
|
||||
*/
|
||||
void HAL_OTP_SetReadCur(OTP_HandleTypeDef *hotp, uint8_t ReadCur)
|
||||
{
|
||||
uint32_t OtpadjConfig = hotp->Instance->OTPADJ;
|
||||
|
||||
OtpadjConfig &= ~OTP_OTPADJ_SEL_READ_CUR_I_M;
|
||||
OtpadjConfig |= ReadCur << OTP_OTPADJ_SEL_READ_CUR_I_S;
|
||||
|
||||
hotp->Instance->OTPADJ = OtpadjConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Инициализация рекомендуемых временных интервалов.
|
||||
*
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
*/
|
||||
void HAL_OPT_TimeInit(OTP_HandleTypeDef *hotp)
|
||||
{
|
||||
uint8_t APBMDivider = PM->DIV_APB_M;
|
||||
uint8_t AHBDivider = PM->DIV_AHB;
|
||||
uint32_t OscillatorSystem = PM->AHB_CLK_MUX & PM_AHB_CLK_MUX_M;
|
||||
|
||||
uint32_t OtpadjConfig = hotp->Instance->OTPADJ;
|
||||
uint32_t otpwt1_config = hotp->Instance->OTPWT1;
|
||||
uint32_t otpwt2_config = hotp->Instance->OTPWT2;
|
||||
|
||||
/* Рекомендуемое значение для N_RA, N_RH, N_SU, N_H. ceil(40/Period), где Period в нс */
|
||||
uint32_t Div = 0;
|
||||
/* Тактирование от 32МГц */
|
||||
if((OscillatorSystem == PM_AHB_CLK_MUX_HSI32M_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32M_M))
|
||||
{
|
||||
Div = 1000;
|
||||
}
|
||||
|
||||
/* Тактирование от 32кГц */
|
||||
if((OscillatorSystem == PM_AHB_CLK_MUX_LSI32K_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32K_M))
|
||||
{
|
||||
Div = 1000000;
|
||||
}
|
||||
|
||||
uint32_t recommended_value = 0;
|
||||
if((40 * 32) % (((APBMDivider + 1) * (AHBDivider + 1)) * Div) == 0)
|
||||
{
|
||||
recommended_value = (40 * 32) / (((APBMDivider + 1) * (AHBDivider + 1)) * Div);
|
||||
}
|
||||
else
|
||||
{
|
||||
recommended_value = (40 * 32) / (((APBMDivider + 1) * (AHBDivider + 1)) * Div) + 1;
|
||||
}
|
||||
|
||||
|
||||
/* Рекомендуемое значение N_W = 50 000 000 нс / Pclk, где Pclk – период тактового сигнала в нс */
|
||||
uint32_t recommended_N_W = 0;
|
||||
if((OscillatorSystem == PM_AHB_CLK_MUX_HSI32M_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32M_M))
|
||||
{
|
||||
recommended_N_W = (5 * 32 * 10000) / ((APBMDivider + 1) * (AHBDivider + 1));
|
||||
}
|
||||
|
||||
/* Тактирование от 32кГц */
|
||||
if((OscillatorSystem == PM_AHB_CLK_MUX_LSI32K_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32K_M))
|
||||
{
|
||||
recommended_N_W = (5 * 32 * 10) / ((APBMDivider + 1) * (AHBDivider + 1));
|
||||
}
|
||||
|
||||
OtpadjConfig &= ~OTP_OTPADJ_N_RSU_M; /* При частоте менее 200МГц рекомендуемое значение 0 */
|
||||
|
||||
OtpadjConfig &= ~OTP_OTPADJ_N_RA_M;
|
||||
OtpadjConfig |= recommended_value << OTP_OTPADJ_N_RA_S;
|
||||
|
||||
OtpadjConfig &= ~OTP_OTPADJ_N_RH_M;
|
||||
OtpadjConfig |= recommended_value << OTP_OTPADJ_N_RH_S;
|
||||
|
||||
otpwt1_config &= ~OTP_OTPWT1_N_SU_M;
|
||||
otpwt1_config |= recommended_value << OTP_OTPWT1_N_SU_S;
|
||||
|
||||
otpwt1_config &= ~OTP_OTPWT1_N_H_M;
|
||||
otpwt1_config |= recommended_value << OTP_OTPWT1_N_H_S;
|
||||
|
||||
otpwt2_config &= ~OTP_OTPWT2_N_W_M;
|
||||
otpwt2_config |= recommended_N_W << OTP_OTPWT2_N_W_S;
|
||||
|
||||
hotp->Instance->OTPADJ = OtpadjConfig;
|
||||
hotp->Instance->OTPWT1 = otpwt1_config;
|
||||
hotp->Instance->OTPWT2 = otpwt2_config;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
* @param ReadMode Режим чтения
|
||||
*/
|
||||
void HAL_OPT_SetReadMode(OTP_HandleTypeDef *hotp, uint8_t ReadMode)
|
||||
{
|
||||
uint32_t OtpconConfig = hotp->Instance->OTPCON;
|
||||
|
||||
OtpconConfig &= ~OTP_OTPCON_APBNWS_M;
|
||||
OtpconConfig |= ReadMode << OTP_OTPCON_APBNWS_S;
|
||||
|
||||
hotp->Instance->OTPCON = OtpconConfig;
|
||||
hotp->ReadMode = ReadMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Инициализировать OTP.
|
||||
*
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
*/
|
||||
void HAL_OTP_Init(OTP_HandleTypeDef *hotp)
|
||||
{
|
||||
|
||||
HAL_OTP_MspInit(hotp);
|
||||
|
||||
// /* Настройка временных ограничений */
|
||||
HAL_OPT_TimeInit(hotp);
|
||||
|
||||
// /* Выбор напряжения на UPP матрицы */
|
||||
HAL_OTP_SetUppRead(hotp, OTP_UPP_READ_2_5V);
|
||||
|
||||
/* Режим чтения */
|
||||
HAL_OPT_SetReadMode(hotp, hotp->ReadMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ожидать сброса флага BSY.
|
||||
*
|
||||
* Флаг BSY = 1 - Блок занят (выполняется запрошенная операция).
|
||||
* Используется при операции записи и чтении в 3 этапа.
|
||||
*
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
*/
|
||||
void HAL_OTP_WaitBSY(OTP_HandleTypeDef *hotp)
|
||||
{
|
||||
/* Опрос флага BSY пока он не станет очищен */
|
||||
while (hotp->Instance->OTPSTA & OTP_OTPSTA_BSY_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Записать массив данных в тестовый столбец.
|
||||
*
|
||||
* @warning Если в массиве Data количество бит больше размера столбца, начиная с Address, то запись продолжится с начала столбца.
|
||||
*
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
* @param Address Начальная ячейка столбца. Значение может быть в пределах от 0 до 7.
|
||||
* @param Data Данные для записи в тестовый столбец.
|
||||
* @param DataLength Размер массива Data.
|
||||
*/
|
||||
void HAL_OTP_WriteTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength)
|
||||
{
|
||||
/* OTPA[4:3] = 10b - тестовый столбец OTP */
|
||||
hotp->Instance->OTPA = 0b10000 + (Address & 0b111);
|
||||
|
||||
for (uint32_t i = 0; i < DataLength; i++)
|
||||
{
|
||||
hotp->Instance->OTPDAT = Data[i];
|
||||
HAL_OTP_WaitBSY(hotp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Записать данные в тестовую строку.
|
||||
*
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
* @param Data Данные для записи в тестовую строку.
|
||||
*/
|
||||
void HAL_OTP_WriteTestRow(OTP_HandleTypeDef *hotp, uint32_t Data)
|
||||
{
|
||||
/* OTPA[4:3] = 01b - тестовая строка OTP */
|
||||
hotp->Instance->OTPA = 0b01000;
|
||||
|
||||
hotp->Instance->OTPDAT = Data;
|
||||
HAL_OTP_WaitBSY(hotp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Записать бит в тестовую ячейку.
|
||||
*
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
* @param Data Бит для записи в тестовую ячейку.
|
||||
*/
|
||||
void HAL_OTP_WriteTestBit(OTP_HandleTypeDef *hotp, uint32_t Data)
|
||||
{
|
||||
/* OTPA[4:3] = 11b - последняя тестовая ячейка в тестовой строке */
|
||||
hotp->Instance->OTPA = 0b11000;
|
||||
|
||||
hotp->Instance->OTPDAT = Data;
|
||||
HAL_OTP_WaitBSY(hotp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Записать данные в основной массив OTP.
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
* @param Address Начальная строка. Значение может быть в пределах от 0 до 7.
|
||||
* @param Data Данные для записи в основной массив OTP.
|
||||
* @param DataLength Размер массива Data.
|
||||
*/
|
||||
void HAL_OTP_Write(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength)
|
||||
{
|
||||
/* OTPA[4:3] = 00b - основной массив OTP */
|
||||
hotp->Instance->OTPA = 0b00000 + (Address & 0b111);
|
||||
|
||||
for (uint32_t i = 0; i < DataLength; i++)
|
||||
{
|
||||
hotp->Instance->OTPDAT = Data[i];
|
||||
HAL_OTP_WaitBSY(hotp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Прочитать данные из тестового столбца.
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
* @param Address Начальная ячейка столбца. Значение может быть в пределах от 0 до 7.
|
||||
* @param DataRead Массив для считывания данных тестового столбца.
|
||||
* @param DataLength Размер массива DataRead.
|
||||
*/
|
||||
void HAL_OTP_ReadTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength)
|
||||
{
|
||||
if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */
|
||||
{
|
||||
/* OTPA[4:3] = 10b - тестовый столбец OTP */
|
||||
uint8_t address_mask = 0b00111;
|
||||
uint8_t address_column_mask = (1 << 4);
|
||||
|
||||
for (uint32_t i = 0; i < DataLength; i++)
|
||||
{
|
||||
hotp->Instance->OTPA = ((Address + i) & address_mask) | address_column_mask;
|
||||
HAL_OTP_WaitBSY(hotp);
|
||||
DataRead[i] = hotp->Instance->OTPDAT;
|
||||
}
|
||||
}
|
||||
else /* Чтение в 2 этапа. Со вставкой тактов ожидания. Без опроса BSY. С автоинкрементированием адреса OTPA. */
|
||||
{
|
||||
/* OTPA[4:3] = 10b - тестовый столбец OTP */
|
||||
uint8_t address_column = 0b10000 + (Address & 0b111);
|
||||
hotp->Instance->OTPA = address_column;
|
||||
DataRead[0] = hotp->Instance->OTPDAT;
|
||||
|
||||
for (uint32_t i = 0; i < DataLength; i++)
|
||||
{
|
||||
DataRead[i] = hotp->Instance->OTPDAT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Прочитать данные из тестовой строки.
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
* @return Тестовая строка.
|
||||
*/
|
||||
uint32_t HAL_OTP_ReadTestRow(OTP_HandleTypeDef *hotp)
|
||||
{
|
||||
uint32_t DataRead = 0;
|
||||
|
||||
/* OTPA[4:3] = 01b - тестовая строка OTP */
|
||||
hotp->Instance->OTPA = 0b01000;
|
||||
|
||||
if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */
|
||||
{
|
||||
HAL_OTP_WaitBSY(hotp);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataRead = hotp->Instance->OTPDAT;
|
||||
}
|
||||
|
||||
DataRead = hotp->Instance->OTPDAT;
|
||||
|
||||
return DataRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Прочитать бит из тестовой ячейки.
|
||||
* @param hotp hotp - Указатель на структуру с настройками OTP.
|
||||
* @return Бит из тестовой ячейки.
|
||||
*/
|
||||
uint32_t HAL_OTP_ReadTestBit(OTP_HandleTypeDef *hotp)
|
||||
{
|
||||
uint32_t DataRead = 0;
|
||||
|
||||
/* OTPA[4:3] = 11b - последняя тестовая ячейка в тестовой строке */
|
||||
hotp->Instance->OTPA = 0b11000;
|
||||
|
||||
if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */
|
||||
{
|
||||
HAL_OTP_WaitBSY(hotp);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataRead = hotp->Instance->OTPDAT;
|
||||
}
|
||||
|
||||
DataRead = hotp->Instance->OTPDAT;
|
||||
|
||||
return DataRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Прочитать данные из основного массива OTP.
|
||||
* @param hotp Указатель на структуру с настройками OTP.
|
||||
* @param Address Начальная строка основного массива OTP. Значение может быть в пределах от 0 до 7.
|
||||
* @param DataRead Массив для считывания данных основного массива OTP.
|
||||
* @param DataLength Размер массива DataRead.
|
||||
*/
|
||||
void HAL_OTP_Read(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength)
|
||||
{
|
||||
if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */
|
||||
{
|
||||
/* OTPA[4:3] = 00b - основной массив OTP */
|
||||
uint8_t address_mask = 0b00111;
|
||||
|
||||
for (uint32_t i = 0; i < DataLength; i++)
|
||||
{
|
||||
hotp->Instance->OTPA = (Address + i) & address_mask;
|
||||
HAL_OTP_WaitBSY(hotp);
|
||||
DataRead[i] = hotp->Instance->OTPDAT;
|
||||
}
|
||||
}
|
||||
else /* Чтение в 2 этапа. Со вставкой тактов ожидания. Без опроса BSY. С автоинкрементированием адреса OTPA. */
|
||||
{
|
||||
/* OTPA[4:3] = 00b - основной массив OTP */
|
||||
hotp->Instance->OTPA = 0b00000 + (Address & 0b111);
|
||||
DataRead[0] = hotp->Instance->OTPDAT;
|
||||
|
||||
for (uint32_t i = 0; i < DataLength; i++)
|
||||
{
|
||||
DataRead[i] = hotp->Instance->OTPDAT;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,399 @@
|
||||
#include "mik32_hal_pcc.h"
|
||||
|
||||
/**
|
||||
* @brief Включить источник тактирования.
|
||||
* @param Oscillator Источник тактирования для включения.
|
||||
* @warning Аргумент функции не является маской.
|
||||
*
|
||||
*/
|
||||
void HAL_PCC_OscEnable(HAL_PCC_OscillatorTypeTypeDef Oscillator)
|
||||
{
|
||||
switch (Oscillator)
|
||||
{
|
||||
case PCC_OSCILLATORTYPE_HSI32M:
|
||||
WU->CLOCKS_SYS &= ~(1 << WU_CLOCKS_SYS_HSI32M_EN_S); // Включить HSI32M
|
||||
break;
|
||||
case PCC_OSCILLATORTYPE_OSC32M:
|
||||
WU->CLOCKS_SYS &= ~(1 << WU_CLOCKS_SYS_OSC32M_EN_S); // Включить OSC32M
|
||||
break;
|
||||
case PCC_OSCILLATORTYPE_LSI32K:
|
||||
WU->CLOCKS_BU &= ~(1 << WU_CLOCKS_BU_LSI32K_EN_S); // Включить LSI32K
|
||||
break;
|
||||
case PCC_OSCILLATORTYPE_OSC32K:
|
||||
WU->CLOCKS_BU &= ~(1 << WU_CLOCKS_BU_OSC32K_EN_S); // Включить OSC32K
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Выключить источник тактирования.
|
||||
* @param Oscillator Источник тактирования для выключения.
|
||||
* @warning Аргумент функции не является маской.
|
||||
*
|
||||
*/
|
||||
void HAL_PCC_OscDisable(uint32_t Oscillator)
|
||||
{
|
||||
switch (Oscillator)
|
||||
{
|
||||
case PCC_OSCILLATORTYPE_HSI32M:
|
||||
WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_HSI32M_EN_S); // Выключить HSI32M
|
||||
break;
|
||||
case PCC_OSCILLATORTYPE_OSC32M:
|
||||
WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_OSC32M_EN_S); // Выключить OSC32M
|
||||
break;
|
||||
case PCC_OSCILLATORTYPE_LSI32K:
|
||||
WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_LSI32K_EN_S); // Выключить LSI32K
|
||||
break;
|
||||
case PCC_OSCILLATORTYPE_OSC32K:
|
||||
WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_OSC32K_EN_S); // Выключить OSC32K
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Выбрать опорный источник тактирования монитора частоты.
|
||||
*
|
||||
* Функция предназначена для назначения опорного источника тактирования монитора частоты.
|
||||
*
|
||||
* @param Force32KClk Опорный источник тактирования монитора частоты.
|
||||
* @return Состояние об ошибках.
|
||||
* @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций,
|
||||
* то функция вернет ошибку HAL_TIMEOUT, а выбранный источник не будет назначен.
|
||||
*
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PCC_FreqMonRefSet(HAL_PCC_FreqMonitorSourceTypeDef Force32KClk)
|
||||
{
|
||||
uint32_t clockswitch_timeout = 0;
|
||||
uint32_t ref_clk_m = 0;
|
||||
uint32_t ref_clk_flag_m = 0;
|
||||
|
||||
switch (Force32KClk)
|
||||
{
|
||||
case PCC_FREQ_MONITOR_SOURCE_AUTO:
|
||||
WU->CLOCKS_SYS &= ~WU_CLOCKS_SYS_FORCE_32K_CLK_M;
|
||||
return HAL_OK;
|
||||
case PCC_FREQ_MONITOR_SOURCE_OSC32K:
|
||||
ref_clk_m = WU_CLOCKS_SYS_FORCE_32K_CLK_OSC32K_M;
|
||||
ref_clk_flag_m = PM_FREQ_STATUS_OSC32K_M;
|
||||
break;
|
||||
case PCC_FREQ_MONITOR_SOURCE_LSI32K:
|
||||
ref_clk_m = WU_CLOCKS_SYS_FORCE_32K_CLK_LSI32K_M;
|
||||
ref_clk_flag_m = PM_FREQ_STATUS_LSI32K_M;
|
||||
break;
|
||||
default:
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
while (!(PM->FREQ_STATUS & ref_clk_flag_m))
|
||||
{
|
||||
clockswitch_timeout++;
|
||||
if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
WU->CLOCKS_SYS = (WU->CLOCKS_SYS & ~(WU_CLOCKS_SYS_FORCE_32K_CLK_M)) | ref_clk_m;
|
||||
for (volatile int i = 0; i < 100; i++)
|
||||
;
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Выбрать приоритетный источник тактирования системы.
|
||||
*
|
||||
* Функция предназначена для назначения приоритетного источника тактирования системы. Если ForceOscSys = #PCC_FORCE_OSC_SYS_FIXED,
|
||||
* то источник тактирования системы не будет автоматически переключаться, при пропадании сигнала.
|
||||
*
|
||||
* @param OscillatorSystem Источник тактирования системы.
|
||||
* @param ForceOscSys Запрет автоматического переключения с выбранного источника тактирования.
|
||||
* @return Состояние об ошибках.
|
||||
* @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций,
|
||||
* то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник будет назначен приоритетным. Разрешение автоматического
|
||||
* переключения будет установлено как #PCC_FORCE_OSC_SYS_UNFIXED.
|
||||
*
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PCC_SetOscSystem(uint32_t OscillatorSystem, HAL_PCC_ForceOscSysTypeDef ForceOscSys)
|
||||
{
|
||||
uint32_t clockswitch_timeout = 0;
|
||||
uint32_t sys_clk_m = 0;
|
||||
uint32_t osc_clk_flag_m = 0;
|
||||
|
||||
/* Настройка источника тактирования системы */
|
||||
switch (OscillatorSystem)
|
||||
{
|
||||
case PCC_OSCILLATORTYPE_HSI32M:
|
||||
sys_clk_m = PM_AHB_CLK_MUX_HSI32M_M;
|
||||
osc_clk_flag_m = PM_FREQ_STATUS_HSI32M_M;
|
||||
break;
|
||||
case PCC_OSCILLATORTYPE_OSC32M:
|
||||
sys_clk_m = PM_AHB_CLK_MUX_OSC32M_M;
|
||||
osc_clk_flag_m = PM_FREQ_STATUS_OSC32M_M;
|
||||
break;
|
||||
case PCC_OSCILLATORTYPE_LSI32K:
|
||||
sys_clk_m = PM_AHB_CLK_MUX_LSI32K_M;
|
||||
osc_clk_flag_m = PM_FREQ_STATUS_LSI32K_M;
|
||||
break;
|
||||
case PCC_OSCILLATORTYPE_OSC32K:
|
||||
sys_clk_m = PM_AHB_CLK_MUX_OSC32K_M;
|
||||
osc_clk_flag_m = PM_FREQ_STATUS_OSC32K_M;
|
||||
break;
|
||||
default:
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
while (!(PM->FREQ_STATUS & osc_clk_flag_m))
|
||||
{
|
||||
clockswitch_timeout++;
|
||||
if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE)
|
||||
{
|
||||
PM->AHB_CLK_MUX = sys_clk_m | PM_AHB_FORCE_MUX_UNFIXED;
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
PM->AHB_CLK_MUX = sys_clk_m | (ForceOscSys << PM_AHB_FORCE_MUX_S);
|
||||
|
||||
for (volatile int i = 0; i < 100; i++)
|
||||
;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Выбрать приоритетный источник тактирования RTC.
|
||||
*
|
||||
* Функция предназначена для назначения приоритетного источника RTC.
|
||||
*
|
||||
* @param Oscillator Источник тактирования RTC.
|
||||
* @return Состояние об ошибках.
|
||||
* @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций,
|
||||
* то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник не будет назначен приоритетным.
|
||||
*
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PCC_RTCClock(HAL_PCC_RTCClockSourceTypeDef Oscillator)
|
||||
{
|
||||
uint32_t clockswitch_timeout = 0;
|
||||
uint32_t rtc_clk_m = 0;
|
||||
uint32_t osc_clk_flag_m = 0;
|
||||
|
||||
switch (Oscillator)
|
||||
{
|
||||
case PCC_RTC_CLOCK_SOURCE_AUTO:
|
||||
WU->CLOCKS_BU &= ~WU_CLOCKS_BU_RTC_CLK_MUX_M;
|
||||
return HAL_OK;
|
||||
case PCC_RTC_CLOCK_SOURCE_LSI32K:
|
||||
rtc_clk_m = WU_CLOCKS_BU_RTC_CLK_MUX_LSI32K_M;
|
||||
osc_clk_flag_m = PM_FREQ_STATUS_LSI32K_M;
|
||||
break;
|
||||
case PCC_RTC_CLOCK_SOURCE_OSC32K:
|
||||
rtc_clk_m = WU_CLOCKS_BU_RTC_CLK_MUX_OSC32K_M;
|
||||
osc_clk_flag_m = PM_FREQ_STATUS_OSC32K_M;
|
||||
break;
|
||||
default:
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
while (!(PM->FREQ_STATUS & osc_clk_flag_m))
|
||||
{
|
||||
clockswitch_timeout++;
|
||||
if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Выбор источника тактирования RTC */
|
||||
WU->CLOCKS_BU = (WU->CLOCKS_BU & ~WU_CLOCKS_BU_RTC_CLK_MUX_M) | rtc_clk_m;
|
||||
WU->RTC_CONRTOL = WU_RTC_CONTROL_RESET_CLEAR_M;
|
||||
|
||||
for (volatile int i = 0; i < 100; i++)
|
||||
;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Выбрать источник тактирования RTC в составе ядра.
|
||||
*
|
||||
* Функция предназначена для выбора приоритетного источника RTC в составе ядра.
|
||||
*
|
||||
* @param Oscillator Источник тактирования RTC в составе ядра.
|
||||
* @return Состояние об ошибках.
|
||||
* @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций,
|
||||
* то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник не будет выбран.
|
||||
*
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PCC_CPURTCClock(HAL_PCC_CPURTCClockSourceTypeDef Oscillator)
|
||||
{
|
||||
uint32_t clockswitch_timeout = 0;
|
||||
uint32_t rtc_clk_m = 0;
|
||||
uint32_t osc_clk_flag_m = 0;
|
||||
|
||||
switch (Oscillator)
|
||||
{
|
||||
case PCC_CPU_RTC_CLOCK_SOURCE_LSI32K:
|
||||
rtc_clk_m = PM_CPU_RTC_CLK_MUX_LSI32K_M;
|
||||
osc_clk_flag_m = PM_FREQ_STATUS_LSI32K_M;
|
||||
break;
|
||||
case PCC_CPU_RTC_CLOCK_SOURCE_OSC32K:
|
||||
rtc_clk_m = PM_CPU_RTC_CLK_MUX_OSC32K_M;
|
||||
osc_clk_flag_m = PM_FREQ_STATUS_OSC32K_M;
|
||||
break;
|
||||
default:
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
while (!(PM->FREQ_STATUS & osc_clk_flag_m))
|
||||
{
|
||||
clockswitch_timeout++;
|
||||
if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
PM->CPU_RTC_CLK_MUX = rtc_clk_m;
|
||||
|
||||
for (volatile int i = 0; i < 100; i++)
|
||||
;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать делитель шины AHB.
|
||||
* @param DividerAHB Делитель.
|
||||
*
|
||||
* Делитель является 32-х битным числом. Частота шины AHB определяется по формуле: @f$ \frac{F_{sys\_clk}}{DividerAHB + 1} @f$.
|
||||
*/
|
||||
void HAL_PCC_DividerAHB(uint32_t DividerAHB)
|
||||
{
|
||||
PM->DIV_AHB = DividerAHB;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать делитель шины APB_M.
|
||||
* @param DividerAPB_M Делитель.
|
||||
*
|
||||
* Делитель является 32-х битным числом. Частота шины APB_M определяется по формуле: @f$ \frac{F_{AHB}}{DividerAPB\_M + 1} @f$.
|
||||
*/
|
||||
void HAL_PCC_DividerAPB_M(uint32_t DividerAPB_M)
|
||||
{
|
||||
PM->DIV_APB_M = DividerAPB_M;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать делитель шины APB_P.
|
||||
* @param DividerAPB_P Делитель.
|
||||
*
|
||||
* Делитель является 32-х битным числом. Частота шины APB_M определяется по формуле: @f$ \frac{F_{AHB}}{DividerAPB\_P + 1} @f$.
|
||||
*/
|
||||
void HAL_PCC_DividerAPB_P(uint32_t DividerAPB_P)
|
||||
{
|
||||
PM->DIV_APB_P = DividerAPB_P;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Настроить тактирование и монитор частоты.
|
||||
*
|
||||
* Функция для настройки тактирования и монитора частоты в соответствии с заданными настройками в PCC_Init.
|
||||
*
|
||||
* @param PCC_Init Структура с настройками.
|
||||
* @return Структура с состояниями об ошибках.
|
||||
* @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций,
|
||||
* то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник не будет применен. Если такая ошибка возникла при
|
||||
* при выборе системного источника, то выбранный источник будет назначен приоритетным. Разрешение автоматического
|
||||
* переключения будет установлено как #PCC_FORCE_OSC_SYS_UNFIXED.
|
||||
*
|
||||
*/
|
||||
PCC_ConfigErrorsTypeDef HAL_PCC_Config(PCC_InitTypeDef *PCC_Init)
|
||||
{
|
||||
PCC_ConfigErrorsTypeDef errors = {HAL_OK};
|
||||
|
||||
/* Включить все источники тактирования */
|
||||
WU->CLOCKS_SYS &= ~(0b11 << WU_CLOCKS_SYS_OSC32M_EN_S); // Включить OSC32M и HSI32M
|
||||
WU->CLOCKS_BU &= ~(0b11 << WU_CLOCKS_BU_OSC32K_EN_S); // Включить OSC32K и LSI32K
|
||||
|
||||
WU->CLOCKS_SYS = WU_CLOCKS_SYS_ADJ_HSI32M(PCC_Init->HSI32MCalibrationValue); // Поправочный коэффициент HSI32M
|
||||
WU->CLOCKS_BU = WU_CLOCKS_BU_ADJ_LSI32K(PCC_Init->LSI32KCalibrationValue); // Поправочный коэффициент LSI32K
|
||||
|
||||
/* Опорный источник для монитора частоты */
|
||||
errors.FreqMonRef = HAL_PCC_FreqMonRefSet(PCC_Init->FreqMon.Force32KClk);
|
||||
|
||||
/* Настройка источника тактирования системы */
|
||||
errors.SetOscSystem = HAL_PCC_SetOscSystem(PCC_Init->FreqMon.OscillatorSystem, PCC_Init->FreqMon.ForceOscSys);
|
||||
|
||||
/* Делители частоты */
|
||||
HAL_PCC_DividerAHB(PCC_Init->AHBDivider);
|
||||
HAL_PCC_DividerAPB_M(PCC_Init->APBMDivider);
|
||||
HAL_PCC_DividerAPB_P(PCC_Init->APBPDivider);
|
||||
|
||||
/* Выбор источника тактирования RTC */
|
||||
errors.RTCClock = HAL_PCC_RTCClock(PCC_Init->RTCClockSelection);
|
||||
|
||||
/* Выбор источника тактирования RTC в составе ядра*/
|
||||
errors.CPURTCClock = HAL_PCC_CPURTCClock(PCC_Init->RTCClockCPUSelection);
|
||||
|
||||
|
||||
|
||||
/* Отключение неиспользуемых источников тактирования */
|
||||
/* Источники 32МГц */
|
||||
/* Внутренний */
|
||||
if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_HSI32M))
|
||||
{
|
||||
WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_HSI32M_EN_S); // Выключить HSI32M
|
||||
}
|
||||
|
||||
// /* Внешний */
|
||||
if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_OSC32M))
|
||||
{
|
||||
WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_OSC32M_EN_S); // Выключить OSC32M
|
||||
}
|
||||
|
||||
/* Источники 32кГц */
|
||||
/* Внутренний */
|
||||
if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_LSI32K))
|
||||
{
|
||||
WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_LSI32K_EN_S); // Выключить LSI32K
|
||||
}
|
||||
|
||||
/* Внешний */
|
||||
if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_OSC32K))
|
||||
{
|
||||
WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_OSC32K_EN_S); // Выключить OSC32K
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получить частоту приоритетного системного источника тактирования в Гц.
|
||||
* @return Частота приоритетного системного источника в Гц.
|
||||
* @warning Система может тактироваться не от приоритетного источника. Например, если источник не был назначен принудительно и сигнал от источника отсутствует.
|
||||
* В таком случае автоматически выбирается источник в соответствии со следующим приоритетом: OSC32M, HSI32M, OSC32K, LSI32K.
|
||||
*/
|
||||
uint32_t HAL_PCC_GetSysClockFreq()
|
||||
{
|
||||
uint32_t system_clock = 0;
|
||||
|
||||
switch (PM->AHB_CLK_MUX & PM_AHB_CLK_MUX_M)
|
||||
{
|
||||
case PM_AHB_CLK_MUX_OSC32M_M:
|
||||
system_clock = OSC_SYSTEM_VALUE;
|
||||
break;
|
||||
case PM_AHB_CLK_MUX_OSC32K_M:
|
||||
system_clock = OSC_CLOCK_VALUE;
|
||||
break;
|
||||
case PM_AHB_CLK_MUX_HSI32M_M:
|
||||
system_clock = HSI_VALUE;
|
||||
break;
|
||||
case PM_AHB_CLK_MUX_LSI32K_M:
|
||||
system_clock = LSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return system_clock;
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
#include "mik32_hal_rtc.h"
|
||||
|
||||
__attribute__((weak)) void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
|
||||
{
|
||||
__HAL_PCC_RTC_CLK_ENABLE();
|
||||
}
|
||||
|
||||
void HAL_RTC_WaitFlag(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
uint32_t retry_limit = 10000;
|
||||
for (uint32_t i = 0; i < retry_limit; i++)
|
||||
{
|
||||
if ((hrtc->Instance->CTRL & RTC_CTRL_FLAG_M) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (hrtc->Instance->CTRL & RTC_CTRL_FLAG_M);
|
||||
|
||||
|
||||
#ifdef MIK32_RTC_DEBUG
|
||||
xprintf("Ожидание установки CTRL.FLAG в 0 превышено\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void HAL_RTC_Disable(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
// Для записи даты нужно сбросить бит EN в регистре CTRL
|
||||
RTC->CTRL &= ~RTC_CTRL_EN_M;
|
||||
HAL_RTC_WaitFlag(hrtc);
|
||||
}
|
||||
|
||||
void HAL_RTC_Enable(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
// Установка бита EN включает модуль RTC
|
||||
RTC->CTRL |= RTC_CTRL_EN_M;
|
||||
HAL_RTC_WaitFlag(hrtc);
|
||||
}
|
||||
|
||||
void HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime)
|
||||
{
|
||||
uint8_t DOW, TH, H, TM, M, TS, S;
|
||||
DOW = sTime->Dow;
|
||||
TH = sTime->Hours / 10;
|
||||
H = sTime->Hours % 10;
|
||||
TM = sTime->Minutes / 10;
|
||||
M = sTime->Minutes % 10;
|
||||
TS = sTime->Seconds / 10;
|
||||
S = sTime->Seconds % 10;
|
||||
|
||||
uint32_t RTC_time = (DOW << RTC_TIME_DOW_S) | // День недели
|
||||
(TH << RTC_TIME_TH_S) | // Десятки часов
|
||||
(H << RTC_TIME_H_S) | // Единицы часов
|
||||
(TM << RTC_TIME_TM_S) | // Десятки минут
|
||||
(M << RTC_TIME_M_S) | // Единицы минут
|
||||
(TS << RTC_TIME_TS_S) | // Десятки секунд
|
||||
(S << RTC_TIME_S_S) | // Единицы секунд
|
||||
(0 << RTC_TIME_TOS_S); // Десятые секунды
|
||||
|
||||
#ifdef MIK32_RTC_DEBUG
|
||||
xprintf("Установка времени RTC\n");
|
||||
#endif
|
||||
|
||||
hrtc->Instance->TIME = RTC_time;
|
||||
HAL_RTC_WaitFlag(hrtc);
|
||||
}
|
||||
|
||||
void HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate)
|
||||
{
|
||||
uint8_t TC, C, TY, Y, TM, M, TD, D;
|
||||
TC = sDate->Century / 10;
|
||||
C = sDate->Century % 10;
|
||||
TY = sDate->Year / 10;
|
||||
Y = sDate->Year % 10;
|
||||
TM = sDate->Month / 10;
|
||||
M = sDate->Month % 10;
|
||||
TD = sDate->Day / 10;
|
||||
D = sDate->Day % 10;
|
||||
|
||||
uint32_t RTC_data = (TC << RTC_DATE_TC_S) | // Десятки века
|
||||
(C << RTC_DATE_C_S) | // Единицы века
|
||||
(TY << RTC_DATE_TY_S) | // Десятки года
|
||||
(Y << RTC_DATE_Y_S) | // Единицы года
|
||||
(TM << RTC_DATE_TM_S) | // Десятки месяца
|
||||
(M << RTC_DATE_M_S) | // Единицы месяца
|
||||
(TD << RTC_DATE_TD_S) | // Десятки числа
|
||||
(D << RTC_DATE_D_S); // Единицы числа
|
||||
|
||||
#ifdef MIK32_RTC_DEBUG
|
||||
xprintf("Установка даты RTC\n");
|
||||
#endif
|
||||
|
||||
hrtc->Instance->DATE = RTC_data;
|
||||
HAL_RTC_WaitFlag(hrtc);
|
||||
}
|
||||
|
||||
void HAL_RTC_Alarm_SetTime(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm)
|
||||
{
|
||||
uint8_t DOW, TH, H, TM, M, TS, S;
|
||||
DOW = sAlarm->AlarmTime.Dow;
|
||||
TH = sAlarm->AlarmTime.Hours / 10;
|
||||
H = sAlarm->AlarmTime.Hours % 10;
|
||||
TM = sAlarm->AlarmTime.Minutes / 10;
|
||||
M = sAlarm->AlarmTime.Minutes % 10;
|
||||
TS = sAlarm->AlarmTime.Seconds / 10;
|
||||
S = sAlarm->AlarmTime.Seconds % 10;
|
||||
|
||||
uint32_t RTC_alarm_time = (DOW << RTC_TIME_DOW_S) | // День недели
|
||||
(TH << RTC_TIME_TH_S) | // Десятки часов
|
||||
(H << RTC_TIME_H_S) | // Единицы часов
|
||||
(TM << RTC_TIME_TM_S) | // Десятки минут
|
||||
(M << RTC_TIME_M_S) | // Единицы минут
|
||||
(TS << RTC_TIME_TS_S) | // Десятки секунд
|
||||
(S << RTC_TIME_S_S) | // Единицы секунд
|
||||
(0 << RTC_TIME_TOS_S); // Десятые секунды
|
||||
|
||||
#ifdef MIK32_RTC_DEBUG
|
||||
xprintf("Установка времени будильника\n");
|
||||
#endif
|
||||
|
||||
hrtc->Instance->TALRM = RTC_alarm_time | sAlarm->MaskAlarmTime;
|
||||
HAL_RTC_WaitFlag(hrtc);
|
||||
}
|
||||
|
||||
void HAL_RTC_Alarm_SetDate(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm)
|
||||
{
|
||||
uint8_t TC, C, TY, Y, TM, M, TD, D;
|
||||
TC = sAlarm->AlarmDate.Century / 10;
|
||||
C = sAlarm->AlarmDate.Century % 10;
|
||||
TY = sAlarm->AlarmDate.Year / 10;
|
||||
Y = sAlarm->AlarmDate.Year % 10;
|
||||
TM = sAlarm->AlarmDate.Month / 10;
|
||||
M = sAlarm->AlarmDate.Month % 10;
|
||||
TD = sAlarm->AlarmDate.Day / 10;
|
||||
D = sAlarm->AlarmDate.Day % 10;
|
||||
|
||||
uint32_t RTC_alarm_data = (TC << RTC_DATE_TC_S) | // Десятки века
|
||||
(C << RTC_DATE_C_S) | // Единицы века
|
||||
(TY << RTC_DATE_TY_S) | // Десятки года
|
||||
(Y << RTC_DATE_Y_S) | // Единицы года
|
||||
(TM << RTC_DATE_TM_S) | // Десятки месяца
|
||||
(M << RTC_DATE_M_S) | // Единицы месяца
|
||||
(TD << RTC_DATE_TD_S) | // Десятки числа
|
||||
(D << RTC_DATE_D_S); // Единицы числа
|
||||
|
||||
#ifdef MIK32_RTC_DEBUG
|
||||
xprintf("Установка даты будильника\n");
|
||||
#endif
|
||||
|
||||
hrtc->Instance->DALRM = RTC_alarm_data | sAlarm->MaskAlarmDate;
|
||||
HAL_RTC_WaitFlag(hrtc);
|
||||
}
|
||||
|
||||
void HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm)
|
||||
{
|
||||
HAL_RTC_Alarm_SetTime(hrtc, sAlarm);
|
||||
HAL_RTC_Alarm_SetDate(hrtc, sAlarm);
|
||||
}
|
||||
|
||||
void HAL_RTC_AlarmDisable(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
hrtc->Instance->TALRM &= ~(RTC_TALRM_CS_M | RTC_TALRM_CM_M | RTC_TALRM_CH_M | RTC_TALRM_CDOW_M);
|
||||
HAL_RTC_WaitFlag(hrtc);
|
||||
|
||||
hrtc->Instance->DALRM &= ~(RTC_DALRM_CD_M | RTC_DALRM_CM_M | RTC_DALRM_CY_M | RTC_DALRM_CC_M);
|
||||
HAL_RTC_WaitFlag(hrtc);
|
||||
}
|
||||
|
||||
void HAL_RTC_ClearAlrmFlag(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/* Сброс флага ALRM в RTC */
|
||||
hrtc->Instance->CTRL &= ~RTC_CTRL_ALRM_M;
|
||||
HAL_RTC_WaitFlag(hrtc);
|
||||
}
|
||||
|
||||
int HAL_RTC_GetAlrmFlag(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
return (hrtc->Instance->CTRL & RTC_CTRL_ALRM_M) >> RTC_CTRL_ALRM_S;
|
||||
}
|
||||
|
||||
RTC_DateTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
uint8_t TC, C, TY, Y, TM, M, TD, D;
|
||||
uint32_t rtc_date_read = hrtc->Instance->DATE;
|
||||
RTC_DateTypeDef sDate = {0};
|
||||
|
||||
TC = (rtc_date_read & RTC_DATE_TC_M) >> RTC_DATE_TC_S;
|
||||
C = (rtc_date_read & RTC_DATE_C_M) >> RTC_DATE_C_S;
|
||||
TY = (rtc_date_read & RTC_DATE_TY_M) >> RTC_DATE_TY_S;
|
||||
Y = (rtc_date_read & RTC_DATE_Y_M) >> RTC_DATE_Y_S;
|
||||
TM = (rtc_date_read & RTC_DATE_TM_M) >> RTC_DATE_TM_S;
|
||||
M = (rtc_date_read & RTC_DATE_M_M) >> RTC_DATE_M_S;
|
||||
TD = (rtc_date_read & RTC_DATE_TD_M) >> RTC_DATE_TD_S;
|
||||
D = (rtc_date_read & RTC_DATE_D_M) >> RTC_DATE_D_S;
|
||||
|
||||
sDate.Century = TC * 10 + C;
|
||||
sDate.Year = TY * 10 + Y;
|
||||
sDate.Month = TM * 10 + M;
|
||||
sDate.Day = TD * 10 + D;
|
||||
|
||||
#ifdef MIK32_RTC_DEBUG
|
||||
xprintf("\n%d%d век\n", TC, C);
|
||||
xprintf("%d%d.%d%d.%d%d\n", TD, D, TM, M, TY, Y);
|
||||
#endif
|
||||
|
||||
return sDate;
|
||||
}
|
||||
|
||||
RTC_TimeTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
RTC_TimeTypeDef sTime;
|
||||
|
||||
sTime.Dow = hrtc->Instance->DOW;
|
||||
sTime.Hours = hrtc->Instance->TH * 10 + hrtc->Instance->H;
|
||||
sTime.Minutes = hrtc->Instance->TM * 10 + hrtc->Instance->M;
|
||||
sTime.Seconds = hrtc->Instance->TS * 10 + hrtc->Instance->S;
|
||||
|
||||
#ifdef MIK32_RTC_DEBUG
|
||||
switch (hrtc->Instance->DOW)
|
||||
{
|
||||
case 1:
|
||||
xprintf("Понедельник\n");
|
||||
break;
|
||||
case 2:
|
||||
xprintf("Вторник\n");
|
||||
break;
|
||||
case 3:
|
||||
xprintf("Среда\n");
|
||||
break;
|
||||
case 4:
|
||||
xprintf("Четверг\n");
|
||||
break;
|
||||
case 5:
|
||||
xprintf("Пятница\n");
|
||||
break;
|
||||
case 6:
|
||||
xprintf("Суббота\n");
|
||||
break;
|
||||
case 7:
|
||||
xprintf("Воскресенье\n");
|
||||
break;
|
||||
}
|
||||
xprintf("%d%d:%d%d:%d%d.%d\n", hrtc->Instance->TH, hrtc->Instance->H, hrtc->Instance->TM,
|
||||
hrtc->Instance->M, hrtc->Instance->TS, hrtc->Instance->S, hrtc->Instance->TOS);
|
||||
#endif
|
||||
|
||||
return sTime;
|
||||
}
|
||||
|
||||
void HAL_RTC_SetInterruptAlarm(RTC_HandleTypeDef *hrtc, uint32_t InterruptEnable)
|
||||
{
|
||||
hrtc->Interrupts.Alarm = InterruptEnable;
|
||||
|
||||
uint32_t config = hrtc->Instance->CTRL;
|
||||
config &= ~RTC_CTRL_INTE_M;
|
||||
config |= InterruptEnable << RTC_CTRL_INTE_S;
|
||||
hrtc->Instance->CTRL = config;
|
||||
|
||||
HAL_RTC_WaitFlag(hrtc);
|
||||
}
|
||||
|
||||
void HAL_RTC_InterruptInit(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
HAL_RTC_SetInterruptAlarm(hrtc, hrtc->Interrupts.Alarm);
|
||||
}
|
||||
|
||||
int HAL_RTC_GetINTE(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
return (hrtc->Instance->CTRL & RTC_CTRL_INTE_M) >> RTC_CTRL_INTE_S;
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
#include "mik32_hal_spi.h"
|
||||
|
||||
/**
|
||||
* @brief Инициализация SPI MSP.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
*/
|
||||
__attribute__((weak)) void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
if (hspi->Instance == SPI_0)
|
||||
{
|
||||
__HAL_PCC_SPI_0_CLK_ENABLE();
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
|
||||
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
|
||||
|
||||
switch (hspi->Init.ChipSelect)
|
||||
{
|
||||
case SPI_CS_0:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_4;
|
||||
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
|
||||
break;
|
||||
|
||||
case SPI_CS_1:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_14;
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
break;
|
||||
|
||||
case SPI_CS_2:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_15;
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
break;
|
||||
|
||||
case SPI_CS_3:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6;
|
||||
HAL_GPIO_Init(GPIO_2, &GPIO_InitStruct);
|
||||
break;
|
||||
}
|
||||
|
||||
/* В режиме ведущего вывод SPIx_N_SS_IN должен быть в режиме SPI с подтяжкой к питанию. */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3;
|
||||
if (hspi->Init.SPI_Mode == HAL_SPI_MODE_MASTER)
|
||||
{
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP;
|
||||
}
|
||||
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
if (hspi->Instance == SPI_1)
|
||||
{
|
||||
__HAL_PCC_SPI_1_CLK_ENABLE();
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
|
||||
switch (hspi->Init.ChipSelect)
|
||||
{
|
||||
case SPI_CS_0:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_4;
|
||||
break;
|
||||
|
||||
case SPI_CS_1:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_5;
|
||||
break;
|
||||
|
||||
case SPI_CS_2:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6;
|
||||
break;
|
||||
|
||||
case SPI_CS_3:
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_7;
|
||||
break;
|
||||
}
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3;
|
||||
if (hspi->Init.SPI_Mode == HAL_SPI_MODE_MASTER)
|
||||
{
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP;
|
||||
}
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Включить модуль SPI.
|
||||
*
|
||||
* Перед включением модуля производится сброс флагов ошибок и очистка буферов TX и RX.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
*/
|
||||
void HAL_SPI_Enable(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
HAL_SPI_ClearError(hspi);
|
||||
__HAL_SPI_ENABLE(hspi);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Выключить модуль SPI.
|
||||
*
|
||||
* После выключения модуля производится сброс флагов ошибок и очистка буферов TX и RX.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
*/
|
||||
void HAL_SPI_Disable(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
__HAL_SPI_DISABLE(hspi);
|
||||
HAL_SPI_ClearError(hspi);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать задержку BTWN.
|
||||
*
|
||||
* Задержка в периодах опорного тактового сигнала между снятием сигнала выбора одного ведомого
|
||||
* устройства и установкой сигнала выбора другого ведомого устройства.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param btwn задержка BTWN в периодах опорного тактового сигнала.
|
||||
* Этот параметр может быть значением в пределах от 0 до 255.
|
||||
*/
|
||||
void HAL_SPI_SetDelayBTWN(SPI_HandleTypeDef *hspi, uint8_t btwn)
|
||||
{
|
||||
hspi->Instance->DELAY &= ~SPI_DELAY_BTWN_M;
|
||||
hspi->Instance->DELAY |= SPI_DELAY_BTWN(btwn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать задержку AFTER.
|
||||
*
|
||||
* Задержка в периодах опорного тактового сигнала между последним битом текущего слова
|
||||
* и первым битом следующего слова.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param after Задержка AFTER в периодах опорного тактового сигнала.
|
||||
* Этот параметр может быть числом в пределах от 0 до 255.
|
||||
*/
|
||||
void HAL_SPI_SetDelayAFTER(SPI_HandleTypeDef *hspi, uint8_t after)
|
||||
{
|
||||
hspi->Instance->DELAY &= ~SPI_DELAY_AFTER_M;
|
||||
hspi->Instance->DELAY |= SPI_DELAY_AFTER(after);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать задержку INIT.
|
||||
*
|
||||
* Дополнительная задержка в периодах опорного тактового сигнала между установкой
|
||||
* сигнала n_ss_out в «0» и передачей первого бита.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param init задержка INIT в периодах опорного тактового сигнала.
|
||||
* Этот параметр может быть числом в пределах от 0 до 255.
|
||||
*/
|
||||
void HAL_SPI_SetDelayINIT(SPI_HandleTypeDef *hspi, uint8_t init)
|
||||
{
|
||||
hspi->Instance->DELAY &= ~SPI_DELAY_INIT_M;
|
||||
hspi->Instance->DELAY |= SPI_DELAY_INIT(init);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать задержку перед передачей.
|
||||
*
|
||||
* Модуль SPI в режиме ведомого устройства начинает передачу только когда тактовый сигнал
|
||||
* sclk_in (внешнего ведущего устройства) не изменяется в течение количества периодов опорного
|
||||
* тактового сигнала SPI заданного в этом поле или когда модуль SPI не активен.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param slave_idle_counter задержку перед передачей в периодах опорного тактового сигнала.
|
||||
* Этот параметр может быть числом в пределах от 0 до 255.
|
||||
*/
|
||||
void HAL_SPI_SetSlaveIdleCounter(SPI_HandleTypeDef *hspi, uint8_t slave_idle_counter)
|
||||
{
|
||||
hspi->Instance->SIC = slave_idle_counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать уровень, при котором TX_FIFO считается незаполненным и формируется
|
||||
* прерывание TX_FIFO_NOT_full (IXR_TXOW).
|
||||
*
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param threshold уровень, при котором TX_FIFO считается не заполненным.
|
||||
*/
|
||||
void HAL_SPI_SetThresholdTX(SPI_HandleTypeDef *hspi, uint32_t threshold)
|
||||
{
|
||||
hspi->Init.ThresholdTX = threshold;
|
||||
hspi->Instance->TX_THR = threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получить идентификационный номер модуля. Ожидаемое ID 0x01090100.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @return идентификационный номер модуля.
|
||||
*/
|
||||
uint32_t HAL_SPI_ReadModuleID(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
return hspi->Instance->ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Инициализировать SPI в соответствии с настройками в @ref SPI_HandleTypeDef.
|
||||
*
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @return Статус HAL.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
HAL_StatusTypeDef error_code = HAL_OK;
|
||||
|
||||
if (hspi == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
HAL_SPI_MspInit(hspi);
|
||||
|
||||
HAL_SPI_ClearError(hspi);
|
||||
|
||||
/* Выключение модуля SPI */
|
||||
HAL_SPI_Disable(hspi);
|
||||
|
||||
uint32_t SPI_config = 0;
|
||||
|
||||
/* Настройка режима ведомого */
|
||||
switch (hspi->Init.SPI_Mode)
|
||||
{
|
||||
case HAL_SPI_MODE_MASTER:
|
||||
SPI_config = SPI_CONFIG_MASTER_M;
|
||||
break;
|
||||
case HAL_SPI_MODE_SLAVE:
|
||||
SPI_config = SPI_CONFIG_SLAVE_M;
|
||||
hspi->Init.ManualCS = SPI_MANUALCS_OFF;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Настройки SPI */
|
||||
SPI_config |= (hspi->Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S) | /* Настройка делителя частоты */
|
||||
(hspi->Init.ManualCS << SPI_CONFIG_MANUAL_CS_S) | /* Настройка режима управления сигналом CS */
|
||||
(hspi->Init.CLKPhase << SPI_CONFIG_CLK_PH_S) | /* Настройка фазы тактового сигнала */
|
||||
(hspi->Init.CLKPolarity << SPI_CONFIG_CLK_POL_S) | /* Настройка полярности тактового сигнала */
|
||||
(hspi->Init.Decoder << SPI_CONFIG_PERI_SEL_S); /* Настройка использования внешнего декодера */
|
||||
//(hspi->Init.DataSize << SPI_CONFIG_DATA_SZ_S); /* Длина передаваемой посылки */
|
||||
|
||||
/* Выбор ведомого в соответствии с режимом ManualCS */
|
||||
if (hspi->Init.ManualCS == SPI_MANUALCS_ON)
|
||||
{
|
||||
/* Ведомое устройство не выбрано. Ручное управление сигналом CS */
|
||||
SPI_config |= SPI_CS_NONE << SPI_CONFIG_CS_S;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Выбор ведомого устройства в автоматическом режиме управления CS */
|
||||
SPI_config |= hspi->Init.ChipSelect << SPI_CONFIG_CS_S;
|
||||
}
|
||||
|
||||
/* Установка выбранных настроек */
|
||||
hspi->Instance->CONFIG = SPI_config;
|
||||
|
||||
HAL_SPI_SetDelayBTWN(hspi, 1);
|
||||
HAL_SPI_SetDelayAFTER(hspi, 0);
|
||||
HAL_SPI_SetDelayINIT(hspi, 0);
|
||||
|
||||
/* уровень при котором регистр TX считается незаполненным и формируется прерывание */
|
||||
if (hspi->Init.ThresholdTX > 8)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
HAL_SPI_SetThresholdTX(hspi, hspi->Init.ThresholdTX);
|
||||
|
||||
hspi->TxCount = 0;
|
||||
hspi->RxCount = 0;
|
||||
|
||||
hspi->State = HAL_SPI_STATE_READY;
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Очистить буфер TX_FIFO.
|
||||
*
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
*/
|
||||
void HAL_SPI_ClearTXFIFO(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Очистить буфер RX_FIFO.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
*/
|
||||
void HAL_SPI_ClearRXFIFO(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_RX_FIFO_M;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Сбросить флаги ошибок, очистить буферы RX и TX.
|
||||
*
|
||||
* @warning Функция выключает модуль SPI.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
**/
|
||||
void HAL_SPI_ClearError(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
/* Сброс ошибок */
|
||||
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
|
||||
|
||||
__HAL_SPI_DISABLE(hspi);
|
||||
HAL_SPI_ClearRXFIFO(hspi);
|
||||
HAL_SPI_ClearTXFIFO(hspi);
|
||||
volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */
|
||||
(void) unused;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Выбрать ведомое устройство.
|
||||
*
|
||||
* В ручном режиме управления сигналом выбора ведомого
|
||||
* @ref SPI_InitTypeDef::ManualCS "SPI_HandleTypeDef.Init.ManualCS" = @ref SPI_MANUALCS_ON при вызове функции выбранный вывод
|
||||
* перейдет в активное состояние (низкий уровень).
|
||||
*
|
||||
* В автоматическом режиме управления сигналом выбора ведомого функция задает один из сигналов
|
||||
* CS0 - CS3, который будет использован во время передачи.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param CS_M ведомое устройство.
|
||||
* Этот параметр должен быть одним из следующих значений:
|
||||
* - @ref SPI_CS_NONE - ведомое устройство не выбрано
|
||||
* - @ref SPI_CS_0 - ведомое устройство 1
|
||||
* - @ref SPI_CS_1 - ведомое устройство 2
|
||||
* - @ref SPI_CS_2 - ведомое устройство 3
|
||||
* - @ref SPI_CS_3 - ведомое устройство 4
|
||||
* Если используется внешний декодер (@ref SPI_InitTypeDef::Decoder "SPI_HandleTypeDef.Init.Decoder" = @ref SPI_DECODER_USE),
|
||||
* @ref SPI_InitTypeDef::ChipSelect "SPI_HandleTypeDef.Init.ChipSelect" отображается на выводах CS0 - CS3.
|
||||
*/
|
||||
void HAL_SPI_CS_Enable(SPI_HandleTypeDef *hspi, uint32_t CS_M)
|
||||
{
|
||||
hspi->Init.ChipSelect = CS_M;
|
||||
CS_M = CS_M << SPI_CONFIG_CS_S;
|
||||
hspi->Instance->CONFIG = (hspi->Instance->CONFIG & ~SPI_CONFIG_CS_M) | CS_M;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Перевести активный сигнал выбора ведомого в неактивное состояние (высокий уровень).
|
||||
*
|
||||
* Функция устанавливает значение @ref SPI_CS_NONE - ведомые устройства не выбраны.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
*/
|
||||
void HAL_SPI_CS_Disable(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
hspi->Init.ChipSelect = SPI_CS_NONE;
|
||||
hspi->Instance->CONFIG = (hspi->Instance->CONFIG & ~SPI_CONFIG_CS_M) | SPI_CONFIG_CS_NONE_M;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Запустить передачу и прием данных.
|
||||
*
|
||||
* Байты поочередно передаются и считываются по одному байту.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param TransmitBytes указатель на буфер передаваемых данных.
|
||||
* @param ReceiveBytes указатель на буфер считываемых данных.
|
||||
* @param DataSize число байт для отправки и приема.
|
||||
* @param Timeout продолжительность тайм-аута.
|
||||
* @return Статус HAL.
|
||||
*
|
||||
* @warning Во время обмена пороговое значение ThresholdTX = 1.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout)
|
||||
{
|
||||
uint32_t txallowed = 1;
|
||||
HAL_StatusTypeDef error_code = HAL_OK;
|
||||
uint32_t timeout_counter = 0;
|
||||
|
||||
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
|
||||
hspi->pRxBuffPtr = (uint8_t *)ReceiveBytes;
|
||||
hspi->RxCount = DataSize;
|
||||
hspi->pTxBuffPtr = (uint8_t *)TransmitBytes;
|
||||
hspi->TxCount = DataSize;
|
||||
|
||||
hspi->Instance->TX_THR = 1;
|
||||
|
||||
/* Включить SPI если выключено */
|
||||
if (!(hspi->Instance->ENABLE & SPI_ENABLE_M))
|
||||
{
|
||||
__HAL_SPI_ENABLE(hspi);
|
||||
}
|
||||
|
||||
while ((hspi->TxCount > 0) || (hspi->RxCount > 0))
|
||||
{
|
||||
/* Проверка флага TX_FIFO_NOT_FULL */
|
||||
if ((hspi->Instance->INT_STATUS & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M) && (hspi->TxCount > 0) && (txallowed == 1))
|
||||
{
|
||||
hspi->Instance->TXDATA = *(hspi->pTxBuffPtr);
|
||||
hspi->pTxBuffPtr++;
|
||||
hspi->TxCount--;
|
||||
/* Следующие данные - прием (Rx). Tx не разрешен */
|
||||
txallowed = 0;
|
||||
}
|
||||
|
||||
/* Ожидание когда установится флаг RX_FIFO_NOT_EMPTY */
|
||||
if ((hspi->Instance->INT_STATUS & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M) && (hspi->RxCount > 0))
|
||||
{
|
||||
*(hspi->pRxBuffPtr) = hspi->Instance->RXDATA;
|
||||
hspi->pRxBuffPtr++;
|
||||
hspi->RxCount--;
|
||||
/* Следующие данные - передача (Tx). Tx разрешается */
|
||||
txallowed = 1;
|
||||
}
|
||||
|
||||
if (((timeout_counter++) >= Timeout) || (Timeout == 0U))
|
||||
{
|
||||
error_code = HAL_TIMEOUT;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
__HAL_SPI_DISABLE(hspi);
|
||||
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */
|
||||
volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */
|
||||
(void) unused;
|
||||
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Запустить передачу и прием данных с учетом порогового значения @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX".
|
||||
*
|
||||
* Сначала полностью заполняется буфер TX. Затем начинается передача, состоящая из цикличного считывания
|
||||
* и отправки @ref SPI_BUFFER_SIZE - @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX" + 1 байт. Если во
|
||||
* время ожидания байта в буфере RX опустошился буфер TX ниже порогового значения ThresholdTX,
|
||||
* то в буфер TX записывается 1 байт. За одну итерацию цикла в буфер TX записывается и считывается из буфера RX не более
|
||||
* @ref SPI_BUFFER_SIZE - @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX" + 1 байт.
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param TransmitBytes указатель на буфер передаваемых данных.
|
||||
* @param ReceiveBytes указатель на буфер считываемых данных.
|
||||
* @param DataSize число байт для отправки и приема.
|
||||
* @param Timeout продолжительность тайм-аута.
|
||||
* @return Статус HAL.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout)
|
||||
{
|
||||
uint32_t tx_offset = 0; /* Номер отправляемого байта */
|
||||
uint32_t rx_offset = 0; /* Номер считываемого байта */
|
||||
uint32_t tx_counter = 0; /* Количество записанных байт в буфер TX за итерацию */
|
||||
uint32_t write_read_bytes = SPI_BUFFER_SIZE - hspi->Init.ThresholdTX + 1; /* Число байт для записи и чтения в итерации */
|
||||
uint32_t status_tx = 0; /* Регистр состояний флагов SPI во время записи в TXDATA */
|
||||
uint32_t timeout_counter = Timeout;
|
||||
HAL_StatusTypeDef error_code = HAL_OK;
|
||||
|
||||
/* Очистка ошибок */
|
||||
HAL_SPI_ClearError(hspi);
|
||||
|
||||
/* Первая запись буфера до полного заполнения */
|
||||
while (!(hspi->Instance->INT_STATUS & SPI_INT_STATUS_TX_FIFO_FULL_M))
|
||||
{
|
||||
hspi->Instance->TXDATA = TransmitBytes[tx_offset];
|
||||
tx_offset++;
|
||||
|
||||
/* Количество записанных байт не должно быть больше буфера */
|
||||
if (tx_offset >= SPI_BUFFER_SIZE)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Включить SPI */
|
||||
__HAL_SPI_ENABLE(hspi);
|
||||
|
||||
while ((tx_offset < DataSize) || (rx_offset < DataSize))
|
||||
{
|
||||
/* Чтение (8 - Threshold + 1) байт. */
|
||||
if (rx_offset < DataSize)
|
||||
{
|
||||
for (uint32_t rx_counter = 0; (rx_counter < write_read_bytes) && (rx_offset < DataSize); rx_counter++)
|
||||
{
|
||||
timeout_counter = Timeout;
|
||||
while (!((status_tx = hspi->Instance->INT_STATUS) & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M))
|
||||
{
|
||||
|
||||
if (!(timeout_counter--))
|
||||
{
|
||||
error_code = HAL_TIMEOUT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Если буфер RX пуст, а буфер TX опустошился ниже порогового значения, то в буфер TX записывается байт. */
|
||||
if (((tx_counter != 0) || ((status_tx = hspi->Instance->INT_STATUS) & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M)) && (tx_offset < DataSize) && (tx_counter < write_read_bytes))
|
||||
{
|
||||
if (status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
hspi->Instance->TXDATA = TransmitBytes[tx_offset++];
|
||||
tx_counter++;
|
||||
}
|
||||
}
|
||||
ReceiveBytes[rx_offset++] = hspi->Instance->RXDATA;
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_offset < DataSize)
|
||||
{
|
||||
timeout_counter = Timeout;
|
||||
/* Ожидание опустошение буфера ниже */
|
||||
while ((tx_counter == 0) && (!((status_tx = hspi->Instance->INT_STATUS) & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M)))
|
||||
{
|
||||
if (!(timeout_counter--))
|
||||
{
|
||||
error_code = HAL_TIMEOUT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
for (; (tx_counter < write_read_bytes) && (tx_offset < DataSize); tx_counter++)
|
||||
{
|
||||
hspi->Instance->TXDATA = TransmitBytes[tx_offset++];
|
||||
}
|
||||
tx_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
__HAL_SPI_DISABLE(hspi);
|
||||
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */
|
||||
if ((status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M)))
|
||||
{
|
||||
if (status_tx & SPI_INT_STATUS_RX_OVERFLOW_M)
|
||||
{
|
||||
hspi->ErrorCode |= HAL_SPI_ERROR_OVR;
|
||||
}
|
||||
else
|
||||
{
|
||||
hspi->ErrorCode |= HAL_SPI_ERROR_MODF;
|
||||
}
|
||||
|
||||
error_code = HAL_ERROR;
|
||||
}
|
||||
status_tx = hspi->Instance->INT_STATUS;
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Запустить передачу и прием данных с прерываниями.
|
||||
*
|
||||
* Во время передачи используются следующие прерывания:
|
||||
* - RX_OVERFLOW: прерывание при переполнении буфера RX_FIFO
|
||||
* - MODE_FAIL: напряжение на выводе n_ss_in не соответствую режиму работы SPI
|
||||
* - TX_FIFO_NOT_FULL: регистр TX_FIFO не заполнен (опустошился ниже значения @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX")
|
||||
* - RX_FIFO_NOT_EMPTY: буфер RX_FIFO не пустой
|
||||
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля SPI.
|
||||
* @param TransmitBytes указатель на буфер передаваемых данных.
|
||||
* @param ReceiveBytes указатель на буфер считываемых данных.
|
||||
* @param Size число байт для отправки и приема.
|
||||
* @return Статус HAL.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_SPI_Exchange_IT(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size)
|
||||
{
|
||||
HAL_StatusTypeDef error_code = HAL_OK;
|
||||
|
||||
if ((TransmitBytes == NULL) || (ReceiveBytes == NULL) || (Size == 0))
|
||||
{
|
||||
error_code = HAL_ERROR;
|
||||
return error_code;
|
||||
}
|
||||
if (hspi->Init.ThresholdTX == 0)
|
||||
{
|
||||
error_code = HAL_ERROR;
|
||||
return error_code;
|
||||
}
|
||||
|
||||
hspi->State = HAL_SPI_STATE_BUSY;
|
||||
|
||||
hspi->pTxBuffPtr = TransmitBytes;
|
||||
hspi->TxCount = Size;
|
||||
hspi->pRxBuffPtr = ReceiveBytes;
|
||||
hspi->RxCount = Size;
|
||||
|
||||
/* Очистка ошибок */
|
||||
HAL_SPI_ClearError(hspi);
|
||||
|
||||
/* Первая запись буфера до полного заполнения */
|
||||
for (uint32_t i = 0; i < SPI_BUFFER_SIZE; i++)
|
||||
{
|
||||
hspi->Instance->TXDATA = *(hspi->pTxBuffPtr);
|
||||
hspi->pTxBuffPtr++;
|
||||
hspi->TxCount--;
|
||||
}
|
||||
|
||||
|
||||
/* Включить SPI если выключено */
|
||||
if (!(hspi->Instance->ENABLE & SPI_ENABLE_M))
|
||||
{
|
||||
__HAL_SPI_ENABLE(hspi);
|
||||
}
|
||||
|
||||
HAL_SPI_InterruptEnable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M /* Прерывания ошибок */
|
||||
| SPI_INT_STATUS_TX_FIFO_NOT_FULL_M | SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M); /* Прерывания опустошения буфера TX и наличие байтов в буфере RX */
|
||||
|
||||
return error_code;
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
#include <mik32_hal_spifi.h>
|
||||
|
||||
__attribute__((weak)) void HAL_SPIFI_MspInit()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
__HAL_PCC_SPIFI_CLK_ENABLE();
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
|
||||
HAL_GPIO_Init(GPIO_2, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP;
|
||||
HAL_GPIO_Init(GPIO_2, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
void HAL_SPIFI_MemoryMode_Init(SPIFI_MemoryModeConfig_HandleTypeDef *spifi)
|
||||
{
|
||||
HAL_SPIFI_MspInit();
|
||||
|
||||
spifi->Instance->STAT |= SPIFI_CONFIG_STAT_RESET_M;
|
||||
spifi->Instance->CLIMIT = spifi->CacheLimit; // Граница кеширования
|
||||
if (spifi->CacheEnable)
|
||||
{
|
||||
spifi->Instance->CTRL |= SPIFI_CONFIG_CTRL_CACHE_EN_M;
|
||||
}
|
||||
else
|
||||
{
|
||||
spifi->Instance->CTRL &= ~SPIFI_CONFIG_CTRL_CACHE_EN_M;
|
||||
}
|
||||
|
||||
// Настройка команды чтения
|
||||
spifi->Instance->MCMD = ((spifi->Command.InterimLength << SPIFI_CONFIG_MCMD_INTLEN_S) |
|
||||
(spifi->Command.FieldForm << SPIFI_CONFIG_MCMD_FIELDFORM_S) |
|
||||
(spifi->Command.FrameForm << SPIFI_CONFIG_MCMD_FRAMEFORM_S) |
|
||||
(spifi->Command.OpCode << SPIFI_CONFIG_MCMD_OPCODE_S));
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_SendCommand(
|
||||
SPIFI_HandleTypeDef *spifi,
|
||||
SPIFI_CommandTypeDef *cmd,
|
||||
uint32_t address,
|
||||
uint16_t bufferSize,
|
||||
uint8_t *readBuffer,
|
||||
uint8_t *writeBuffer,
|
||||
uint32_t timeout)
|
||||
{
|
||||
return HAL_SPIFI_SendCommand_LL(
|
||||
spifi,
|
||||
cmd->Direction |
|
||||
SPIFI_CONFIG_CMD_INTLEN(cmd->InterimLength) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(cmd->FieldForm) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(cmd->FrameForm) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(cmd->OpCode),
|
||||
address,
|
||||
bufferSize,
|
||||
readBuffer,
|
||||
writeBuffer,
|
||||
cmd->InterimData,
|
||||
timeout);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_SendCommand_LL(
|
||||
SPIFI_HandleTypeDef *spifi,
|
||||
uint32_t cmd,
|
||||
uint32_t address,
|
||||
uint16_t bufferSize,
|
||||
uint8_t *readBuffer,
|
||||
uint8_t *writeBuffer,
|
||||
uint32_t interimData,
|
||||
uint32_t timeout)
|
||||
{
|
||||
spifi->Instance->STAT |= SPIFI_CONFIG_STAT_INTRQ_M;
|
||||
spifi->Instance->ADDR = address;
|
||||
spifi->Instance->IDATA = interimData;
|
||||
spifi->Instance->CMD = cmd | SPIFI_CONFIG_CMD_DATALEN(bufferSize);
|
||||
|
||||
if (cmd & SPIFI_CONFIG_CMD_DOUT_M)
|
||||
{
|
||||
if ((bufferSize > 0) && (writeBuffer == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
for (int i = 0; i < bufferSize; i++)
|
||||
{
|
||||
spifi->Instance->DATA8 = writeBuffer[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((bufferSize > 0) && (readBuffer == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
for (int i = 0; i < bufferSize; i++)
|
||||
{
|
||||
readBuffer[i] = (uint8_t)spifi->Instance->DATA8;
|
||||
}
|
||||
}
|
||||
HAL_StatusTypeDef waitStatus = HAL_SPIFI_WaitCommandProcessing(spifi, timeout);
|
||||
if ((waitStatus == HAL_OK) && (cmd & SPIFI_CONFIG_CMD_POLL_M))
|
||||
{
|
||||
if (SPIFI_CONFIG->DATA8 == (cmd & SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE_M))
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
return HAL_ERROR;
|
||||
}
|
||||
return waitStatus;
|
||||
}
|
||||
|
||||
bool HAL_SPIFI_IsMemoryModeEnabled(SPIFI_HandleTypeDef *spifi)
|
||||
{
|
||||
return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_MCINIT_M) != 0;
|
||||
}
|
||||
|
||||
void HAL_SPIFI_Reset(SPIFI_HandleTypeDef *spifi)
|
||||
{
|
||||
spifi->Instance->STAT = SPIFI_CONFIG_STAT_RESET_M;
|
||||
}
|
||||
|
||||
bool HAL_SPIFI_IsReady(SPIFI_HandleTypeDef *spifi)
|
||||
{
|
||||
return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_RESET_M) == 0;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,495 @@
|
||||
#include "mik32_hal_timer32.h"
|
||||
|
||||
__attribute__((weak)) void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
|
||||
if (htimer32->Instance == TIMER32_0)
|
||||
{
|
||||
__HAL_PCC_TIMER32_0_CLK_ENABLE();
|
||||
}
|
||||
|
||||
if (htimer32->Instance == TIMER32_1)
|
||||
{
|
||||
__HAL_PCC_TIMER32_1_CLK_ENABLE();
|
||||
if (htimer32->Clock.Source == TIMER32_SOURCE_TX_PAD)
|
||||
{
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_4;
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
|
||||
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
|
||||
}
|
||||
}
|
||||
|
||||
if (htimer32->Instance == TIMER32_2)
|
||||
{
|
||||
__HAL_PCC_TIMER32_2_CLK_ENABLE();
|
||||
if (htimer32->Clock.Source == TIMER32_SOURCE_TX_PAD)
|
||||
{
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_4;
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
if (timerChannel->TimerInstance == TIMER32_1)
|
||||
{
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
|
||||
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
|
||||
|
||||
}
|
||||
|
||||
if (timerChannel->TimerInstance == TIMER32_2)
|
||||
{
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
|
||||
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer)
|
||||
{
|
||||
if ((timer->Instance != TIMER32_0) && (timer->Instance != TIMER32_1) && (timer->Instance != TIMER32_2))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
HAL_TIMER32_MspInit(timer);
|
||||
|
||||
HAL_Timer32_Top_Set(timer, timer->Top);
|
||||
HAL_Timer32_Prescaler_Set(timer, timer->Clock.Prescaler);
|
||||
HAL_Timer32_CountMode_Set(timer, timer->CountMode);
|
||||
HAL_Timer32_Source_Set(timer, timer->Clock.Source);
|
||||
HAL_Timer32_InterruptFlags_Clear(timer);
|
||||
HAL_Timer32_State_Set(timer, timer->State);
|
||||
HAL_Timer32_InterruptMask_Set(timer, 0);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state)
|
||||
{
|
||||
timer->State = state;
|
||||
if (state == TIMER32_STATE_DISABLE)
|
||||
{
|
||||
timer->Instance->ENABLE &= ~TIMER32_ENABLE_TIM_EN_M;
|
||||
}
|
||||
else
|
||||
{
|
||||
timer->Instance->ENABLE |= TIMER32_ENABLE_TIM_EN_M;
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top)
|
||||
{
|
||||
timer->Top = top;
|
||||
timer->Instance->TOP = top;
|
||||
}
|
||||
|
||||
void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler)
|
||||
{
|
||||
timer->Clock.Prescaler = prescaler;
|
||||
timer->Instance->PRESCALER = prescaler;
|
||||
}
|
||||
|
||||
void HAL_Timer32_Source_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_SourceTypeDef source)
|
||||
{
|
||||
timer->Clock.Source = source;
|
||||
|
||||
uint32_t timer_cfg_mux_tim32_s = 0;
|
||||
switch ((uint32_t)timer->Instance)
|
||||
{
|
||||
case (uint32_t)TIMER32_0:
|
||||
timer_cfg_mux_tim32_s = MUX_TIM32_0;
|
||||
break;
|
||||
case (uint32_t)TIMER32_1:
|
||||
timer_cfg_mux_tim32_s = MUX_TIM32_1;
|
||||
break;
|
||||
case (uint32_t)TIMER32_2:
|
||||
timer_cfg_mux_tim32_s = MUX_TIM32_2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t timer_cfg_reg = PM->TIMER_CFG & (~PM_TIMER_CFG_MUX_TIMER_M(timer_cfg_mux_tim32_s));
|
||||
uint32_t timer_control_reg = timer->Instance->CONTROL & (~TIMER32_CONTROL_CLOCK_M);
|
||||
|
||||
/* В начале настройки переключается на hclk */
|
||||
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_PRESCALER_M;
|
||||
|
||||
switch (source)
|
||||
{
|
||||
// case TIMER32_SOURCE_PRESCALER:
|
||||
// timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_PRESCALER_M;
|
||||
// break;
|
||||
case TIMER32_SOURCE_TIM1_SYS_CLK:
|
||||
|
||||
timer_cfg_reg |= TIMER32_TIM1_SYS_CLK << timer_cfg_mux_tim32_s;
|
||||
PM->TIMER_CFG = timer_cfg_reg;
|
||||
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM1_M;
|
||||
break;
|
||||
case TIMER32_SOURCE_TIM1_HCLK:
|
||||
timer_cfg_reg |= TIMER32_TIM1_HCLK << timer_cfg_mux_tim32_s;
|
||||
PM->TIMER_CFG = timer_cfg_reg;
|
||||
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM1_M;
|
||||
break;
|
||||
case TIMER32_SOURCE_TIM2_OSC32K:
|
||||
timer_cfg_reg |= TIMER32_TIM2_OSC32K << timer_cfg_mux_tim32_s;
|
||||
PM->TIMER_CFG = timer_cfg_reg;
|
||||
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM2_M;
|
||||
break;
|
||||
case TIMER32_SOURCE_TIM2_LSI32K:
|
||||
timer_cfg_reg |= TIMER32_TIM2_LSI32K << timer_cfg_mux_tim32_s;
|
||||
PM->TIMER_CFG = timer_cfg_reg;
|
||||
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM2_M;
|
||||
break;
|
||||
case TIMER32_SOURCE_TX_PAD:
|
||||
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TX_PIN_M;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_Timer32_InterruptMask_Set(TIMER32_HandleTypeDef *timer, uint32_t intMask)
|
||||
{
|
||||
timer->InterruptMask |= intMask;
|
||||
timer->Instance->INT_MASK |= intMask;
|
||||
}
|
||||
|
||||
void HAL_Timer32_InterruptMask_Clear(TIMER32_HandleTypeDef *timer, uint32_t intMask)
|
||||
{
|
||||
timer->InterruptMask &= ~intMask;
|
||||
timer->Instance->INT_MASK &= ~intMask;
|
||||
}
|
||||
|
||||
void HAL_Timer32_CountMode_Set(TIMER32_HandleTypeDef *timer, uint8_t countMode)
|
||||
{
|
||||
timer->CountMode = countMode;
|
||||
|
||||
uint32_t timer32_control_temp = timer->Instance->CONTROL;
|
||||
timer32_control_temp &= ~TIMER32_CONTROL_MODE_M;
|
||||
timer32_control_temp |= countMode << TIMER32_CONTROL_MODE_S;
|
||||
timer->Instance->CONTROL = timer32_control_temp;
|
||||
}
|
||||
|
||||
void HAL_Timer32_InterruptFlags_ClearMask(TIMER32_HandleTypeDef *timer, uint32_t clearMask)
|
||||
{
|
||||
timer->Instance->INT_CLEAR = clearMask;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
if (timerChannel->TimerInstance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
HAL_TIMER32_Channel_MspInit(timerChannel);
|
||||
|
||||
timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]);
|
||||
|
||||
HAL_Timer32_Channel_PWM_Invert_Set(timerChannel, timerChannel->PWM_Invert);
|
||||
HAL_Timer32_Channel_Mode_Set(timerChannel, timerChannel->Mode);
|
||||
HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, timerChannel->CaptureEdge);
|
||||
HAL_Timer32_Channel_OCR_Set(timerChannel, timerChannel->OCR);
|
||||
HAL_Timer32_Channel_ICR_Clear(timerChannel);
|
||||
HAL_Timer32_Channel_Noise_Set(timerChannel, timerChannel->Noise);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_DeInit(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
if (timerChannel->TimerInstance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
HAL_Timer32_Channel_Disable(timerChannel);
|
||||
HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, 0);
|
||||
HAL_Timer32_Channel_ICR_Clear(timerChannel);
|
||||
HAL_Timer32_Channel_Mode_Set(timerChannel, 0);
|
||||
HAL_Timer32_Channel_Noise_Set(timerChannel, 0);
|
||||
HAL_Timer32_Channel_OCR_Set(timerChannel, 0);
|
||||
HAL_Timer32_Channel_PWM_Invert_Set(timerChannel, 0);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_Enable(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
if (timerChannel->TimerInstance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
timerChannel->State = TIMER32_STATE_ENABLE;
|
||||
timerChannel->Instance->CNTRL |= TIMER32_CH_CNTRL_ENABLE_M;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_Disable(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
if (timerChannel->TimerInstance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
timerChannel->State = TIMER32_STATE_DISABLE;
|
||||
timerChannel->Instance->CNTRL &= ~TIMER32_CH_CNTRL_ENABLE_M;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_PWM_Invert_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_PWMInvertTypeDef PWM_Invert)
|
||||
{
|
||||
if (timerChannel->TimerInstance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
timerChannel->PWM_Invert = PWM_Invert;
|
||||
|
||||
uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_INVERTED_PWM_M);
|
||||
timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (PWM_Invert << TIMER32_CH_CNTRL_INVERTED_PWM_S);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_Mode_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_ModeTypeDef mode)
|
||||
{
|
||||
if (timerChannel->TimerInstance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
timerChannel->Mode = mode;
|
||||
|
||||
uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_MODE_M);
|
||||
timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (mode << TIMER32_CH_CNTRL_MODE_S);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_CaptureEdge_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef captureEdge)
|
||||
{
|
||||
if (timerChannel->TimerInstance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
timerChannel->CaptureEdge = captureEdge;
|
||||
|
||||
uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_CAPTURE_EDGE_M);
|
||||
timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (captureEdge << TIMER32_CH_CNTRL_CAPTURE_EDGE_S);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_OCR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t OCR)
|
||||
{
|
||||
if (timerChannel->TimerInstance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
timerChannel->OCR = OCR;
|
||||
timerChannel->Instance->OCR = OCR;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t ICR)
|
||||
{
|
||||
if (timerChannel->TimerInstance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
timerChannel->Instance->ICR = ICR;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Clear(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
if (timerChannel->TimerInstance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
timerChannel->Instance->ICR = 0;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Channel_Noise_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint8_t noise)
|
||||
{
|
||||
if (timerChannel->TimerInstance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
timerChannel->Noise = noise;
|
||||
|
||||
uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_NOISE_M);
|
||||
timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (noise << TIMER32_CH_CNTRL_NOISE_S);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
void HAL_Timer32_Start(TIMER32_HandleTypeDef *timer)
|
||||
{
|
||||
timer->State = TIMER32_STATE_ENABLE;
|
||||
timer->Instance->ENABLE |= TIMER32_ENABLE_TIM_EN_M;
|
||||
}
|
||||
|
||||
void HAL_Timer32_Stop(TIMER32_HandleTypeDef *timer)
|
||||
{
|
||||
timer->State = TIMER32_STATE_DISABLE;
|
||||
timer->Instance->ENABLE &= ~TIMER32_ENABLE_TIM_EN_M;
|
||||
}
|
||||
|
||||
void HAL_Timer32_Base_Start_IT(TIMER32_HandleTypeDef *timer)
|
||||
{
|
||||
/* Включить прерывание по переполнению */
|
||||
HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_OVERFLOW_M);
|
||||
|
||||
HAL_Timer32_Start(timer);
|
||||
}
|
||||
|
||||
void HAL_Timer32_Base_Stop_IT(TIMER32_HandleTypeDef *timer)
|
||||
{
|
||||
/* Включить прерывание по переполнению */
|
||||
HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_OVERFLOW_M);
|
||||
|
||||
HAL_Timer32_Stop(timer);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_PWM_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
if (timer->Instance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
if (timerChannel->Mode != TIMER32_CHANNEL_MODE_PWM)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Включить прерывание по переполнению */
|
||||
HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_OVERFLOW_M);
|
||||
/* Включить канал */
|
||||
HAL_Timer32_Channel_Enable(timerChannel);
|
||||
/* Запустить счет */
|
||||
HAL_Timer32_Start(timer);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
void HAL_Timer32_PWM_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
/* Включить прерывание по переполнению */
|
||||
HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_OVERFLOW_M);
|
||||
/* Включить канал */
|
||||
HAL_Timer32_Channel_Disable(timerChannel);
|
||||
/* Запустить счет */
|
||||
HAL_Timer32_Stop(timer);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Compare_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
if (timer->Instance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
if (timerChannel->Mode != TIMER32_CHANNEL_MODE_COMPARE)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Включить прерывание по переполнению */
|
||||
HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_OC_M(timerChannel->ChannelIndex));
|
||||
/* Включить канал */
|
||||
HAL_Timer32_Channel_Enable(timerChannel);
|
||||
/* Запустить счет */
|
||||
HAL_Timer32_Start(timer);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
void HAL_Timer32_Compare_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
/* Включить прерывание по переполнению */
|
||||
HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_OC_M(timerChannel->ChannelIndex));
|
||||
/* Включить канал */
|
||||
HAL_Timer32_Channel_Disable(timerChannel);
|
||||
/* Запустить счет */
|
||||
HAL_Timer32_Stop(timer);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_Timer32_Capture_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
if (timer->Instance == TIMER32_0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
if (timerChannel->Mode != TIMER32_CHANNEL_MODE_CAPTURE)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Включить прерывание по переполнению */
|
||||
HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_IC_M(timerChannel->ChannelIndex));
|
||||
/* Включить канал */
|
||||
HAL_Timer32_Channel_Enable(timerChannel);
|
||||
/* Запустить счет */
|
||||
HAL_Timer32_Start(timer);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
void HAL_Timer32_Capture_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
|
||||
{
|
||||
/* Включить прерывание по переполнению */
|
||||
HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_IC_M(timerChannel->ChannelIndex));
|
||||
/* Включить канал */
|
||||
HAL_Timer32_Channel_Disable(timerChannel);
|
||||
/* Запустить счет */
|
||||
HAL_Timer32_Stop(timer);
|
||||
}
|
||||
|
||||
void HAL_Timer32_Start_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask)
|
||||
{
|
||||
/* Включить прерывание по переполнению */
|
||||
HAL_Timer32_InterruptMask_Set(timer, intMask);
|
||||
/* Запустить счет */
|
||||
HAL_Timer32_Start(timer);
|
||||
}
|
||||
|
||||
void HAL_Timer32_Stop_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask)
|
||||
{
|
||||
/* Включить прерывание по переполнению */
|
||||
HAL_Timer32_InterruptMask_Clear(timer, intMask);
|
||||
/* Запустить счет */
|
||||
HAL_Timer32_Stop(timer);
|
||||
}
|
||||
@@ -0,0 +1,364 @@
|
||||
#ifndef MIK32V0
|
||||
#include "mik32_hal_tsens.h"
|
||||
|
||||
/**
|
||||
* @brief Функция включения тактирования аналогового блока (включающего термосенсор).
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
*/
|
||||
__attribute__((weak)) void HAL_TSENS_MspInit(TSENS_HandleTypeDef *htsens)
|
||||
{
|
||||
__HAL_PCC_ANALOG_REGS_CLK_ENABLE();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Функция начальной инициализации термосенсора.
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
* @return Статус HAL.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TSENS_Init(TSENS_HandleTypeDef *htsens)
|
||||
{
|
||||
HAL_StatusTypeDef errorCode = HAL_OK;
|
||||
HAL_TSENS_MspInit(htsens);
|
||||
/* Включение, тактирование температурного сенсора, отключение режима сброса. */
|
||||
ANALOG_REG->TSENS_CFG = (1<<TSENS_CFG_NRST_S)|
|
||||
(1<<TSENS_CFG_NPD_CLK_S)|
|
||||
(1<<TSENS_CFG_NPD_S);
|
||||
|
||||
// Установка источника тактирования термосенсора.
|
||||
if ((errorCode = HAL_TSENS_ClockSource(htsens, htsens->Clock)) != HAL_OK)
|
||||
{
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
// Подбор делителя для заданной частоты термосенсора.
|
||||
if ((errorCode = HAL_TSENS_Clock(htsens, htsens->Frequency)) != HAL_OK)
|
||||
{
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Функция установки источника тактирования термосенсора.
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
* @param clk_source источник тактирования термосенсора.
|
||||
* - @ref HAL_TSENS_SYS_CLK - системная тактовая частота
|
||||
* - @ref HAL_TSENS_HCLK - частота шины АНВ
|
||||
* - @ref HAL_TSENS_OSC32M - внешний генератор 32МГц
|
||||
* - @ref HAL_TSENS_HSI32M - внутренний генератор 32МГц
|
||||
* - @ref HAL_TSENS_OSC32K - внешний генератор 32кГц
|
||||
* - @ref HAL_TSENS_LSI32K - внутренний генератор 32кГц
|
||||
* @return Статус HAL.
|
||||
* HAL_OK, если источник тактирования установлен успешно
|
||||
* HAL_ERROR, если входной параметр некорректен.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TSENS_ClockSource(TSENS_HandleTypeDef *htsens, HAL_TSENS_ClockTypeDef clk_source)
|
||||
{
|
||||
switch (clk_source)
|
||||
{
|
||||
case HAL_TSENS_SYS_CLK:
|
||||
case HAL_TSENS_HCLK:
|
||||
case HAL_TSENS_OSC32M:
|
||||
case HAL_TSENS_HSI32M:
|
||||
case HAL_TSENS_OSC32K:
|
||||
case HAL_TSENS_LSI32K:
|
||||
break;
|
||||
default:
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
htsens->Clock = clk_source;
|
||||
ANALOG_REG->TSENS_CFG = (ANALOG_REG->TSENS_CFG & (~TSENS_CFG_CLK_MUX_M)) | (clk_source << TSENS_CFG_CLK_MUX_S);
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция установки делителя частоты для термосенсора.
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
* @param clk_div делитель частоты термосенсора.
|
||||
* Этот параметр может принимать значения от 0 до 1023.
|
||||
* @return Статус HAL.
|
||||
* HAL_OK, если делитель частоты установлен успешно;
|
||||
* HAL_ERROR, если делитель частоты слишком мал или слишком велик для получения частоты термосенсора 0 - 100 кГц.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TSENS_ClockDivider(TSENS_HandleTypeDef *htsens, uint16_t clk_div)
|
||||
{
|
||||
if (clk_div >= 1024) return HAL_ERROR;
|
||||
|
||||
clk_div &= 0x3FF;
|
||||
uint32_t divider;
|
||||
uint32_t systemFreq = HAL_PCC_GetSysClockFreq();
|
||||
uint32_t tsensFreq = 0;
|
||||
switch (htsens->Clock)
|
||||
{
|
||||
case HAL_TSENS_SYS_CLK:
|
||||
divider = (clk_div + 1) << 1;
|
||||
tsensFreq = systemFreq / divider;
|
||||
if ((tsensFreq > 100000UL)||(tsensFreq == 0)) return HAL_ERROR;
|
||||
break;
|
||||
case HAL_TSENS_HCLK:
|
||||
divider = ((uint32_t)PM->DIV_AHB + 1) * ((clk_div + 1) << 1);
|
||||
tsensFreq = systemFreq / divider;
|
||||
if ((tsensFreq > 100000UL)||(tsensFreq == 0)) return HAL_ERROR;
|
||||
break;
|
||||
case HAL_TSENS_OSC32M:
|
||||
if (clk_div < (OSC_SYSTEM_VALUE/200000 - 1)) return HAL_ERROR;
|
||||
tsensFreq = OSC_SYSTEM_VALUE/((1 + clk_div) << 1);
|
||||
break;
|
||||
case HAL_TSENS_HSI32M:
|
||||
if (clk_div < (HSI_VALUE/200000 - 1)) return HAL_ERROR;
|
||||
tsensFreq = HSI_VALUE/((1 + clk_div) << 1);
|
||||
break;
|
||||
case HAL_TSENS_OSC32K:
|
||||
case HAL_TSENS_LSI32K:
|
||||
tsensFreq = OSC_CLOCK_VALUE/((1 + clk_div) << 1);
|
||||
break;
|
||||
default:
|
||||
return HAL_ERROR;
|
||||
}
|
||||
ANALOG_REG->TSENS_CFG = (ANALOG_REG->TSENS_CFG & (~TSENS_CFG_DIV_M)) | (clk_div << TSENS_CFG_DIV_S);
|
||||
htsens->Frequency = tsensFreq;
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция установки тактовой частоты для термосенсора.
|
||||
*
|
||||
* Функция подбирает делитель для получения наиболее близкой частоты термосенсора к заданной.
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
* @param f_enter тактовая частота термосенсора.
|
||||
* @return Статус HAL.
|
||||
* HAL_OK, если частота установлена успешно
|
||||
* HAL_ERROR, если введенная частота не попадает в область допустимых значений частот 0 - 100 кГц или если невозможно подобрать делитель.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TSENS_Clock(TSENS_HandleTypeDef *htsens, uint32_t f_enter)
|
||||
{
|
||||
if ((f_enter > 100000UL)||(f_enter == 0)) return HAL_ERROR;
|
||||
uint32_t f_real;
|
||||
uint32_t systemFreq = HAL_PCC_GetSysClockFreq();
|
||||
switch (htsens->Clock)
|
||||
{
|
||||
case HAL_TSENS_SYS_CLK:
|
||||
f_real = systemFreq; /* Примечание: надо проверить какой источник и входимость в диапазон */
|
||||
break;
|
||||
case HAL_TSENS_HCLK:
|
||||
f_real = systemFreq / (PM->DIV_AHB + 1); /* Примечание: надо проверить какой источник и входимость в диапазон */
|
||||
break;
|
||||
case HAL_TSENS_OSC32M:
|
||||
f_real = OSC_SYSTEM_VALUE;
|
||||
break;
|
||||
case HAL_TSENS_HSI32M:
|
||||
f_real = HSI_VALUE;
|
||||
break;
|
||||
case HAL_TSENS_OSC32K:
|
||||
f_real = OSC_CLOCK_VALUE;
|
||||
break;
|
||||
case HAL_TSENS_LSI32K:
|
||||
f_real = LSI_VALUE;
|
||||
break;
|
||||
default:
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
uint32_t divider = (f_real / f_enter) >> 1;
|
||||
if (divider == 0) return HAL_ERROR;
|
||||
|
||||
uint32_t pre_result = f_real / (divider << 1);
|
||||
while ((pre_result > 100000) && (divider <= 0x400))
|
||||
{
|
||||
divider += 1;
|
||||
if (divider > 0x400)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
pre_result = f_real / (divider << 1);
|
||||
}
|
||||
|
||||
divider -= 1;
|
||||
|
||||
/* Запись данных */
|
||||
ANALOG_REG->TSENS_CFG = (ANALOG_REG->TSENS_CFG & (~TSENS_CFG_DIV_M)) | (divider<<TSENS_CFG_DIV_S);
|
||||
htsens->Frequency = f_real / ((1 + divider) << 1);
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция установки сырого значения нижнего порога температуры.
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
* @param low_tres сырое значение нижнего порога температуры.
|
||||
* Этот параметр может принимать значение от 225 до 603.
|
||||
* @return Статус HAL.
|
||||
* HAL_OK, если нижнее пороговое значение установлено успешно;
|
||||
* HAL_ERROR, если значение low_tres не попадает в диапазон [225, 603].
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TSENS_SetLowThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t low_tres)
|
||||
{
|
||||
if (low_tres > 603 || low_tres < 225)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
low_tres &= 0x3FF;
|
||||
htsens->Instance->TSENS_THRESHOLD = (htsens->Instance->TSENS_THRESHOLD & (~TSENS_TRESHOLD_LOW_M)) | ((uint32_t)low_tres << TSENS_TRESHOLD_LOW_S);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция установки сырого значения верхнего порога температуры.
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
* @param hi_tres сырое значение верхнего порога температуры.
|
||||
* Этот параметр может принимать значение от 225 до 603.
|
||||
* @return Статус HAL.
|
||||
* HAL_OK, если верхнее пороговое значение установлено успешно;
|
||||
* HAL_ERROR, если значение hi_tres не попадает в диапазон [225, 603].
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TSENS_SetHiThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t hi_tres)
|
||||
{
|
||||
if (hi_tres > 603 || hi_tres < 225)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
hi_tres &= 0x3FF;
|
||||
htsens->Instance->TSENS_THRESHOLD = (htsens->Instance->TSENS_THRESHOLD & (~TSENS_TRESHOLD_HI_M)) | ((uint32_t)hi_tres << TSENS_TRESHOLD_HI_S);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция установки значения нижнего порога температуры.
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
* @param low_temp_border значение нижнего порога температуры в градусах Цельсия.
|
||||
* Этот параметр может принимать значение от -40 до 125.
|
||||
* @return Статус HAL.
|
||||
* HAL_OK, если нижнее пороговое значение установлено успешно;
|
||||
* HAL_ERROR, если рассчитанное значение нижнего порога не попадает в диапазон [225, 603].
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TSENS_SetLowThreshold(TSENS_HandleTypeDef *htsens, int low_temp_border)
|
||||
{
|
||||
return HAL_TSENS_SetLowThresholdRaw(htsens, TSENS_CELSIUS_TO_VALUE(low_temp_border));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция установки значения верхнего порога температуры.
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
* @param hi_temp_border значение верхнего порога температуры в градусах Цельсия.
|
||||
* Этот параметр может принимать значение от -40 до 125.
|
||||
* @return Статус HAL.
|
||||
* HAL_OK, если верхнее пороговое значение установлено успешно;
|
||||
* HAL_ERROR, если рассчитанное значение верхнего порога не попадает в диапазон [225, 603].
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TSENS_SetHiThreshold(TSENS_HandleTypeDef *htsens, int hi_temp_border)
|
||||
{
|
||||
return HAL_TSENS_SetHiThresholdRaw(htsens, TSENS_CELSIUS_TO_VALUE(hi_temp_border));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция чтения и перевода в градусы Цельсия данных термосенсора.
|
||||
*
|
||||
* Функция используется для получения значения температуры в непрерывном режиме измерения (Continuous).
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
* @return температура в градусах Цельсия, увеличенная в 100 раз.
|
||||
*/
|
||||
uint32_t HAL_TSENS_GetTemperature(TSENS_HandleTypeDef *htsens)
|
||||
{
|
||||
return TSENS_VALUE_TO_CELSIUS(__HAL_TSENS_READ_MEASUREMENT(htsens));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Запустить непрерывное измерение температуры.
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
*/
|
||||
void HAL_TSENS_ContinuousStart(TSENS_HandleTypeDef *htsens)
|
||||
{
|
||||
__HAL_TSENS_RELEASE_RESET(htsens);
|
||||
__HAL_TSENS_CONTINUOUS_START(htsens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Запустить одиночное измерение температуры.
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
* @param timeout значение таймаута. Если значение 0, то ожидание флага конца преобразования никогда не прервется.
|
||||
* @return Структура со статусом HAL и измеренным значением температуры.
|
||||
* @ref TSENS_ValueTypeDef.statusHAL статус HAL
|
||||
* @ref TSENS_ValueTypeDef.value значение температуры в градусах Цельсия. Значение в 100 раз больше.
|
||||
*/
|
||||
TSENS_ValueTypeDef HAL_TSENS_SingleStart(TSENS_HandleTypeDef *htsens, uint32_t timeout)
|
||||
{
|
||||
uint32_t timeoutCounter = timeout;
|
||||
|
||||
__HAL_TSENS_RELEASE_RESET(htsens);
|
||||
__HAL_TSENS_SINGLE_START(htsens);
|
||||
while (!__HAL_TSENS_GET_EOC(htsens))
|
||||
{
|
||||
if ((timeoutCounter-- == 0) && (timeout != 0))
|
||||
{
|
||||
return (TSENS_ValueTypeDef) {.statusHAL = HAL_TIMEOUT, .value = 0};
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t rawValue = __HAL_TSENS_READ_MEASUREMENT(htsens);
|
||||
|
||||
return (TSENS_ValueTypeDef) {.statusHAL = HAL_OK, .value = TSENS_VALUE_TO_CELSIUS(rawValue)};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Запустить непрерывное измерение температуры с использованием прерываний.
|
||||
*
|
||||
* Включаются все прерывания датчика температуры (окончание преобразование, выход измеренного значения температуры за пороговые значения).
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
*/
|
||||
void HAL_TSENS_ContinuousStart_IT(TSENS_HandleTypeDef *htsens)
|
||||
{
|
||||
__HAL_TSENS_IRQ_CLEAR(htsens, TSENS_CLEAR_IRQ_LOW_CLEAR_M | TSENS_CLEAR_IRQ_HI_CLEAR_M | TSENS_CLEAR_IRQ_EOC_CLEAR_M);
|
||||
__HAL_TSENS_IRQ_ENABLE(htsens, TSENS_IRQ_LOW_MASK_M | TSENS_IRQ_HI_MASK_M | TSENS_IRQ_EOC_MASK_M);
|
||||
__HAL_TSENS_RELEASE_RESET(htsens);
|
||||
__HAL_TSENS_CONTINUOUS_START(htsens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Запустить одиночное измерение температуры с использованием прерываний.
|
||||
*
|
||||
* Включаются все прерывания датчика температуры (окончание преобразование, выход измеренного значения температуры за пороговые значения).
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
*/
|
||||
void HAL_TSENS_SingleStart_IT(TSENS_HandleTypeDef *htsens)
|
||||
{
|
||||
__HAL_TSENS_IRQ_CLEAR(htsens, TSENS_CLEAR_IRQ_LOW_CLEAR_M | TSENS_CLEAR_IRQ_HI_CLEAR_M | TSENS_CLEAR_IRQ_EOC_CLEAR_M);
|
||||
__HAL_TSENS_IRQ_ENABLE(htsens, TSENS_IRQ_LOW_MASK_M | TSENS_IRQ_HI_MASK_M | TSENS_IRQ_EOC_MASK_M);
|
||||
__HAL_TSENS_RELEASE_RESET(htsens);
|
||||
__HAL_TSENS_SINGLE_START(htsens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Прервать измерение температуры и отключить прерывания.
|
||||
*
|
||||
* Функция останавливает измерения, выключает все прерывания термосенсора и очищает флаги прерываний.
|
||||
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля TSENS.
|
||||
*/
|
||||
void HAL_TSENS_Stop_IT(TSENS_HandleTypeDef *htsens)
|
||||
{
|
||||
__HAL_TSENS_FORCE_RESET(htsens);
|
||||
__HAL_TSENS_IRQ_DISABLE(htsens, TSENS_IRQ_LOW_MASK_M | TSENS_IRQ_HI_MASK_M | TSENS_IRQ_EOC_MASK_M);
|
||||
__HAL_TSENS_IRQ_CLEAR(htsens, TSENS_CLEAR_IRQ_LOW_CLEAR_M | TSENS_CLEAR_IRQ_HI_CLEAR_M | TSENS_CLEAR_IRQ_EOC_CLEAR_M);
|
||||
}
|
||||
|
||||
#endif // MIK32V0
|
||||
@@ -0,0 +1,203 @@
|
||||
#include "mik32_hal_wdt.h"
|
||||
|
||||
uint16_t TimeOut = 20;
|
||||
uint16_t WDT_prescale[] = {1, 2, 4, 16, 64, 256, 1024, 4096};
|
||||
|
||||
/**
|
||||
* @brief Инициализация WDT MSP.
|
||||
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля WDT.
|
||||
*
|
||||
* информацию о конфигурации для модуля WDT.
|
||||
*/
|
||||
__attribute__((weak)) void HAL_RTC_MspInit(WDT_HandleTypeDef *hwdt)
|
||||
{
|
||||
__HAL_PCC_WDT_CLK_ENABLE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Расчет начального значения отсчета таймера соответствующее времени до перезагрузки @ref WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.init.ReloadMs".
|
||||
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля WDT.
|
||||
* @return Структура с рассчитанным начальным значением @ref WDT_ClockTypeDef.tick и код подобранного делителя частоты @ref WDT_ClockTypeDef.divIndex.
|
||||
* Значение 0 в @ref WDT_ClockTypeDef.tick означает ошибку при расчете.
|
||||
*/
|
||||
WDT_ClockTypeDef HAL_WDT_MillisInClock(WDT_HandleTypeDef *hwdt)
|
||||
{
|
||||
uint32_t wdtClock = 0;
|
||||
|
||||
if (hwdt->Init.Clock < HAL_WDT_OSC32K)
|
||||
{
|
||||
if (hwdt->Init.ReloadMs > WDT_MAX_VALUE_CLOCK32M)
|
||||
{
|
||||
return (WDT_ClockTypeDef){.tick = 0, .divIndex = 0};
|
||||
}
|
||||
|
||||
wdtClock = WDT_CLOCK32M_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hwdt->Init.ReloadMs > WDT_MAX_VALUE_CLOCK32K)
|
||||
{
|
||||
return (WDT_ClockTypeDef){.tick = 0, .divIndex = 0};
|
||||
}
|
||||
|
||||
wdtClock = WDT_CLOCK32K_VALUE;
|
||||
}
|
||||
|
||||
uint32_t tick = 0;
|
||||
int divIndex = 0;
|
||||
int countDiv = sizeof(WDT_prescale) / sizeof(*WDT_prescale);
|
||||
for (divIndex = 0; divIndex < countDiv; divIndex++)
|
||||
{
|
||||
tick = ((wdtClock / (WDT_prescale[divIndex])) * hwdt->Init.ReloadMs) / 1000;
|
||||
|
||||
if ((tick <= 4095) && (tick != 0))
|
||||
{
|
||||
tick = 4095 - tick;
|
||||
break;
|
||||
}
|
||||
else if (divIndex == (countDiv - 1))
|
||||
{
|
||||
return (WDT_ClockTypeDef){.tick = 0, .divIndex = 0}; /* Не удалось подобрать делитель для заданного времени отсчета WDT */
|
||||
}
|
||||
}
|
||||
|
||||
return (WDT_ClockTypeDef){.tick = tick, .divIndex = divIndex};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Инициализировать WDT в соответствии с настройками в @ref WDT_HandleTypeDef.
|
||||
*
|
||||
* Функция включает тактирование таймера, задает источник тактирование сторожевого таймера WDT, настраивает делитель частоты
|
||||
* таймера и начальное значение отсчета в соответствии с временем указанным в @ref WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.init.ReloadMs".
|
||||
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля WDT.
|
||||
* @return Статус HAL.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_WDT_Init(WDT_HandleTypeDef *hwdt, uint32_t timeout)
|
||||
{
|
||||
if (hwdt->Instance != WDT)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
HAL_RTC_MspInit(hwdt);
|
||||
|
||||
|
||||
if (HAL_WDT_Stop(hwdt, timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
PM->WDT_CLK_MUX = hwdt->Init.Clock;
|
||||
|
||||
WDT_ClockTypeDef wdtClock = HAL_WDT_MillisInClock(hwdt);
|
||||
|
||||
if (wdtClock.tick == 0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
uint32_t conValue = (wdtClock.divIndex << WDT_CON_PRESCALE_S) | WDT_CON_PRELOAD(wdtClock.tick);
|
||||
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
|
||||
hwdt->Instance->CON = conValue;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Перезагрузка значения сторожевого таймера.
|
||||
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля WDT.
|
||||
* @param timeout продолжительность тайм-аута.
|
||||
* @return Статус HAL.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_WDT_Refresh(WDT_HandleTypeDef *hwdt, uint32_t timeout)
|
||||
{
|
||||
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
|
||||
hwdt->Instance->KEY = WDT_KEY_START;
|
||||
|
||||
while (timeout--)
|
||||
{
|
||||
if (!(hwdt->Instance->STA & WDT_STA_LOADING_M))
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Запустить таймер WDT.
|
||||
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля WDT.
|
||||
* @param timeout продолжительность тайм-аута.
|
||||
* @return Статус HAL.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_WDT_Start(WDT_HandleTypeDef *hwdt, uint32_t timeout)
|
||||
{
|
||||
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
|
||||
hwdt->Instance->KEY = WDT_KEY_START;
|
||||
|
||||
while (timeout--)
|
||||
{
|
||||
if (hwdt->Instance->STA & WDT_STA_ENABLED_M)
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Остановить таймер.
|
||||
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля WDT.
|
||||
* @param timeout продолжительность тайм-аута.
|
||||
* @return Статус HAL.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_WDT_Stop(WDT_HandleTypeDef *hwdt, uint32_t timeout)
|
||||
{
|
||||
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
|
||||
hwdt->Instance->KEY = WDT_KEY_STOP;
|
||||
|
||||
while (timeout--)
|
||||
{
|
||||
if (!(hwdt->Instance->STA & WDT_STA_ENABLED_M))
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать делитель частоты WDT.
|
||||
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля WDT.
|
||||
* @param prescale делитель частоты WDT.
|
||||
*/
|
||||
void HAL_WDT_SetPrescale(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale prescale)
|
||||
{
|
||||
uint32_t conValue = (hwdt->Instance->CON & (~WDT_CON_PRESCALE_M)) | ((prescale << WDT_CON_PRESCALE_S) & WDT_CON_PRESCALE_M);
|
||||
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
|
||||
hwdt->Instance->CON = conValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Задать начальное значение таймера при запуске или перезапуске.
|
||||
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
|
||||
* информацию о конфигурации для модуля WDT.
|
||||
* @param preload начальное значение таймера при запуске или перезапуске.
|
||||
*/
|
||||
void HAL_WDT_SetPreload(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale preload)
|
||||
{
|
||||
uint32_t conValue = (hwdt->Instance->CON & (~WDT_CON_PRELOAD_M)) | WDT_CON_PRELOAD(preload);
|
||||
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
|
||||
hwdt->Instance->CON = conValue;
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,103 @@
|
||||
#ifndef MIK32_HAL_SPIFI_W25
|
||||
#define MIK32_HAL_SPIFI_W25
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mik32_hal_def.h"
|
||||
#include "mik32_hal_spifi.h"
|
||||
|
||||
typedef enum __HAL_SPIFI_W25_SREGTypeDef
|
||||
{
|
||||
W25_SREG1 = 1,
|
||||
W25_SREG2 = 2,
|
||||
} HAL_SPIFI_W25_SREGTypeDef;
|
||||
|
||||
typedef struct __SPIFI_W25_ManufacturerDeviceIDTypeDef
|
||||
{
|
||||
uint8_t Manufacturer;
|
||||
|
||||
uint8_t Device;
|
||||
|
||||
} W25_ManufacturerDeviceIDTypeDef;
|
||||
|
||||
#define SPIFI_W25_SREG1_BUSY_S 0
|
||||
#define SPIFI_W25_SREG1_BUSY_M (1 << SPIFI_W25_SREG1_BUSY_S)
|
||||
#define SPIFI_W25_SREG1_WRITE_ENABLE_S 1
|
||||
#define SPIFI_W25_SREG1_WRITE_ENABLE_M (1 << SPIFI_W25_SREG1_WRITE_ENABLE_S)
|
||||
#define SPIFI_W25_SREG1_BLOCK_PROTECT_0_S 2
|
||||
#define SPIFI_W25_SREG1_BLOCK_PROTECT_0_M (1 << SPIFI_W25_SREG1_BLOCK_PROTECT_0_S)
|
||||
#define SPIFI_W25_SREG1_BLOCK_PROTECT_1_S 3
|
||||
#define SPIFI_W25_SREG1_BLOCK_PROTECT_1_M (1 << SPIFI_W25_SREG1_BLOCK_PROTECT_1_S)
|
||||
#define SPIFI_W25_SREG1_BLOCK_PROTECT_2_S 4
|
||||
#define SPIFI_W25_SREG1_BLOCK_PROTECT_2_M (1 << SPIFI_W25_SREG1_BLOCK_PROTECT_2_S)
|
||||
#define SPIFI_W25_SREG1_TOP_BOTTOM_PROTECT_S 5
|
||||
#define SPIFI_W25_SREG1_TOP_BOTTOM_PROTECT_M (1 << SPIFI_W25_SREG1_TOP_BOTTOM_PROTECT_S)
|
||||
#define SPIFI_W25_SREG1_SECTOR_PROTECT_S 6
|
||||
#define SPIFI_W25_SREG1_SECTOR_PROTECT_M (1 << SPIFI_W25_SREG1_SECTOR_PROTECT_S)
|
||||
#define SPIFI_W25_SREG1_STATUS_REGISTER_PROTECT_0_S 7
|
||||
#define SPIFI_W25_SREG1_STATUS_REGISTER_PROTECT_0_M (1 << SPIFI_W25_SREG1_STATUS_REGISTER_PROTECT_0_S)
|
||||
|
||||
#define SPIFI_W25_SREG2_STATUS_REGISTER_PROTECT_1_S 0
|
||||
#define SPIFI_W25_SREG2_STATUS_REGISTER_PROTECT_1_M (1 << SPIFI_W25_SREG2_STATUS_REGISTER_PROTECT_1_S)
|
||||
#define SPIFI_W25_SREG2_QUAD_ENABLE_S 1
|
||||
#define SPIFI_W25_SREG2_QUAD_ENABLE_M (1 << SPIFI_W25_SREG2_QUAD_ENABLE_S)
|
||||
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_1_S 3
|
||||
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_1_M (1 << SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_1_S)
|
||||
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_2_S 4
|
||||
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_2_M (1 << SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_2_S)
|
||||
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_3_S 5
|
||||
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_3_M (1 << SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_3_S)
|
||||
#define SPIFI_W25_SREG2_COMPLEMENT_PROTECT_S 6
|
||||
#define SPIFI_W25_SREG2_COMPLEMENT_PROTECT_M (1 << SPIFI_W25_SREG2_COMPLEMENT_PROTECT_S)
|
||||
#define SPIFI_W25_SREG2_SUSPEND_STATUS_S 7
|
||||
#define SPIFI_W25_SREG2_SUSPEND_STATUS_M (1 << SPIFI_W25_SREG2_SUSPEND_STATUS_S)
|
||||
|
||||
void HAL_SPIFI_W25_WriteEnable(SPIFI_HandleTypeDef *spifi);
|
||||
|
||||
uint8_t HAL_SPIFI_W25_ReadSREG(SPIFI_HandleTypeDef *spifi, HAL_SPIFI_W25_SREGTypeDef SREG);
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_W25_WriteSREG(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2);
|
||||
|
||||
void HAL_SPIFI_W25_WriteSREG_Volatile(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2);
|
||||
|
||||
#include "xprintf.h"
|
||||
|
||||
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_W25_WaitBusy(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
|
||||
{
|
||||
while (timeout-- != 0)
|
||||
{
|
||||
if ((HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG1) & 1) == 0)
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_W25_WaitBusy_Polling(SPIFI_HandleTypeDef *spifi, uint32_t timeout);
|
||||
|
||||
void HAL_SPIFI_W25_PageProgram(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes);
|
||||
|
||||
void HAL_SPIFI_W25_SectorErase4K(SPIFI_HandleTypeDef *spifi, uint32_t address);
|
||||
|
||||
void HAL_SPIFI_W25_ReadData(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes);
|
||||
|
||||
W25_ManufacturerDeviceIDTypeDef HAL_SPIFI_W25_ReadManufacturerDeviceID(SPIFI_HandleTypeDef *spifi);
|
||||
|
||||
void HAL_SPIFI_W25_PageProgram_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes);
|
||||
|
||||
void HAL_SPIFI_W25_ReadData_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes);
|
||||
|
||||
void HAL_SPIFI_W25_ReadData_Quad_IO(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes);
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_W25_QuadEnable(SPIFI_HandleTypeDef *spifi);
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_W25_QuadDisable(SPIFI_HandleTypeDef *spifi);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MIK32_HAL_W25
|
||||
@@ -0,0 +1,59 @@
|
||||
#ifndef MIK32_HAL_SSD130
|
||||
#define MIK32_HAL_SSD130
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef SSD1306_128x64
|
||||
#define SSD1306_128x32
|
||||
#endif
|
||||
|
||||
#define BRIGHTNESS_FULL 0xFF
|
||||
#define BRIGHTNESS_HAL 0x7F
|
||||
|
||||
#define START_PAGE 0
|
||||
#define END_PAGE 7
|
||||
#define START_COLUMN 0
|
||||
#define END_COLUMN 127
|
||||
|
||||
/* Десятые часов */
|
||||
#define START_COLUMN_TH 0
|
||||
#define END_COLUMN_TH 24
|
||||
/* Единицы часов */
|
||||
#define START_COLUMN_H 25
|
||||
#define END_COLUMN_H 49
|
||||
|
||||
/* Разделитель - двоеточие */
|
||||
#define START_COLUMN_COLON 50
|
||||
#define END_COLUMN_COLON 74
|
||||
|
||||
/* Десятые минут */
|
||||
#define START_COLUMN_TM 75
|
||||
#define END_COLUMN_TM 99
|
||||
/* Единицы минут */
|
||||
#define START_COLUMN_M 100
|
||||
#define END_COLUMN_M 124
|
||||
|
||||
#define SYMBOL_COLON 58
|
||||
#define SYMBOL_SMILE 13
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mik32_hal_i2c.h"
|
||||
|
||||
/* COM (СЛЕДУЮЩИЙ БАЙТ будет командой), DAT (СЛЕДУЮЩИЙ БАЙТ будет данными) и DATS (ВСЕ СЛЕДУЮЩИЕ БАЙТЫ будут данными) */
|
||||
#define DATS 0b01000000
|
||||
#define DAT 0b11000000
|
||||
#define COM 0b10000000
|
||||
|
||||
|
||||
HAL_StatusTypeDef HAL_SSD1306_Init(I2C_HandleTypeDef *hi2c, uint8_t brightness);
|
||||
HAL_StatusTypeDef HAL_SSD1306_SetBorder(I2C_HandleTypeDef *hi2c, uint8_t start_col, uint8_t end_col, uint8_t start_page, uint8_t end_page);
|
||||
HAL_StatusTypeDef HAL_SSD1306_CLR_SCR(I2C_HandleTypeDef *hi2c);
|
||||
HAL_StatusTypeDef HAL_SSD1306_Write(I2C_HandleTypeDef *hi2c, uint8_t symbol);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Whitespace-only changes.
@@ -0,0 +1,257 @@
|
||||
#include "mik32_hal_spifi_w25.h"
|
||||
|
||||
#define SPIFI_W25_WRITE_SREG_BUSY 10000
|
||||
#define SPIFI_W25_PROGRAM_BUSY 100000
|
||||
|
||||
typedef enum __HAL_SPIFI_W25_OPCodesTypeDef
|
||||
{
|
||||
// Standard SPI Instructions
|
||||
WRITE_ENABLE = 0x06,
|
||||
VOLATILE_SR_WRITE_ENABLE = 0x50,
|
||||
WRITE_DISABLE = 0x04,
|
||||
READ_SREG1 = 0x05,
|
||||
READ_SREG2 = 0x35,
|
||||
WRITE_SREG = 0x01,
|
||||
PAGE_PROGRAM = 0x02,
|
||||
SECTOR_ERASE_4K = 0x20,
|
||||
BLOCK_ERASE_32K = 0x52,
|
||||
BLOCK_ERASE_64K = 0xD8,
|
||||
CHIP_ERASE = 0x60,
|
||||
ERASE_PROGRAM_SUSPEND = 0x75,
|
||||
ERASE_PROGRAM_RESUME = 0x7A,
|
||||
POWER_DOWN = 0xB9,
|
||||
READ_DATA = 0x03,
|
||||
FAST_READ = 0x0B,
|
||||
RELEASE_POWERDOWN_ID = 0xAB,
|
||||
MANUFACTURER_DEVICE_ID = 0x90,
|
||||
JEDEC_ID = 0x9F,
|
||||
READ_UNIQUE_ID = 0x4B,
|
||||
READ_SFDP_REGISTERS = 0x5A,
|
||||
ERASE_SECURITY_REGISTERS = 0x44,
|
||||
PROGRAM_SECURITY_REGISTERS = 0x42,
|
||||
READ_SECURITY_REGISTERS = 0x48,
|
||||
ENABLE_QPI = 0x38,
|
||||
ENABLE_RESET = 0x66,
|
||||
RESET = 0x99,
|
||||
|
||||
// Quad SPI Instructions
|
||||
QUAD_PAGE_PROGRAM = 0x32,
|
||||
FAST_READ_QUAD_OUTPUT = 0x6B,
|
||||
FAST_READ_QUAD_IO = 0xEB,
|
||||
WORD_READ_QUAD_IO = 0xE7,
|
||||
OCTAL_WORD_READ_QUAD_IO = 0xE3,
|
||||
SET_BURST_WITH_WRAP = 0x77,
|
||||
MANUFACTURER_DEVICE_ID_BY_QUAD_IO = 0x94,
|
||||
} HAL_SPIFI_W25_OPCodesTypeDef;
|
||||
|
||||
#define HAL_SPIFI_W25_SREG2_BUSY 2
|
||||
|
||||
const uint32_t cmd_write_enable =
|
||||
SPIFI_DIRECTION_INPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(0) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(WRITE_ENABLE);
|
||||
|
||||
const uint32_t cmd_volatile_sr_write_enable =
|
||||
SPIFI_DIRECTION_INPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(0) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(VOLATILE_SR_WRITE_ENABLE);
|
||||
|
||||
const uint32_t cmd_read_sreg1 =
|
||||
SPIFI_DIRECTION_INPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(0) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(READ_SREG1);
|
||||
|
||||
const uint32_t cmd_read_sreg2 =
|
||||
SPIFI_DIRECTION_INPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(0) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(READ_SREG2);
|
||||
|
||||
const uint32_t cmd_write_sreg =
|
||||
SPIFI_DIRECTION_OUTPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(0) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(WRITE_SREG);
|
||||
|
||||
const uint32_t cmd_page_program =
|
||||
SPIFI_DIRECTION_OUTPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(0) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(PAGE_PROGRAM);
|
||||
|
||||
const uint32_t cmd_sector_erase_4k =
|
||||
SPIFI_DIRECTION_INPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(0) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(SECTOR_ERASE_4K);
|
||||
|
||||
const uint32_t cmd_read_data =
|
||||
SPIFI_DIRECTION_INPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(0) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(READ_DATA);
|
||||
|
||||
const uint32_t cmd_manufacturer_device_id =
|
||||
SPIFI_DIRECTION_INPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(0) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(MANUFACTURER_DEVICE_ID);
|
||||
|
||||
const uint32_t cmd_quad_page_program =
|
||||
SPIFI_DIRECTION_OUTPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(0) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_DATA_PARALLEL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(QUAD_PAGE_PROGRAM);
|
||||
|
||||
const uint32_t cmd_fast_read_quad_output =
|
||||
SPIFI_DIRECTION_INPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(1) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_DATA_PARALLEL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(FAST_READ_QUAD_OUTPUT);
|
||||
|
||||
const uint32_t cmd_fast_read_quad_io =
|
||||
SPIFI_DIRECTION_INPUT |
|
||||
SPIFI_CONFIG_CMD_INTLEN(3) |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_OPCODE_SERIAL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(FAST_READ_QUAD_IO);
|
||||
|
||||
const uint32_t cmd_read_sreg1_polling =
|
||||
SPIFI_DIRECTION_INPUT |
|
||||
SPIFI_CONFIG_CMD_POLL_INDEX(0) |
|
||||
SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE(0) |
|
||||
SPIFI_CONFIG_CMD_POLL_M |
|
||||
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
|
||||
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
|
||||
SPIFI_CONFIG_CMD_OPCODE(READ_SREG1);
|
||||
|
||||
void HAL_SPIFI_W25_WriteEnable(SPIFI_HandleTypeDef *spifi)
|
||||
{
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd_write_enable, 0, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT);
|
||||
}
|
||||
|
||||
void HAL_SPIFI_W25_VolatileSRWriteEnable(SPIFI_HandleTypeDef *spifi)
|
||||
{
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd_volatile_sr_write_enable, 0, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT);
|
||||
}
|
||||
|
||||
uint8_t HAL_SPIFI_W25_ReadSREG(SPIFI_HandleTypeDef *spifi, HAL_SPIFI_W25_SREGTypeDef sreg)
|
||||
{
|
||||
uint8_t byte = 0;
|
||||
|
||||
uint32_t cmd = cmd_read_sreg1;
|
||||
if (sreg == W25_SREG1)
|
||||
{
|
||||
cmd = cmd_read_sreg1;
|
||||
}
|
||||
else if (sreg == W25_SREG2)
|
||||
{
|
||||
cmd = cmd_read_sreg2;
|
||||
}
|
||||
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd, 0, 1, &byte, 0, 0, HAL_SPIFI_TIMEOUT);
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_W25_WriteSREG(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2)
|
||||
{
|
||||
uint8_t data[2] = {sreg1, sreg2};
|
||||
|
||||
HAL_SPIFI_W25_WriteEnable(spifi);
|
||||
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd_write_sreg, 0, 2, 0, data, 0, HAL_SPIFI_TIMEOUT);
|
||||
return HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_WRITE_SREG_BUSY);
|
||||
}
|
||||
|
||||
void HAL_SPIFI_W25_WriteSREG_Volatile(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2)
|
||||
{
|
||||
uint8_t data[2] = {sreg1, sreg2};
|
||||
|
||||
HAL_SPIFI_W25_VolatileSRWriteEnable(spifi);
|
||||
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd_write_sreg, 0, 2, 0, data, 0, HAL_SPIFI_TIMEOUT);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_W25_WaitBusy_Polling(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
|
||||
{
|
||||
return HAL_SPIFI_SendCommand_LL(spifi, cmd_read_sreg1_polling, 0, 0, 0, 0, 0, timeout);
|
||||
}
|
||||
|
||||
void HAL_SPIFI_W25_PageProgram(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes)
|
||||
{
|
||||
HAL_SPIFI_W25_WriteEnable(spifi);
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd_page_program, address, dataLength, 0, dataBytes, 0, HAL_SPIFI_TIMEOUT);
|
||||
HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_PROGRAM_BUSY);
|
||||
}
|
||||
|
||||
void HAL_SPIFI_W25_SectorErase4K(SPIFI_HandleTypeDef *spifi, uint32_t address)
|
||||
{
|
||||
HAL_SPIFI_W25_WriteEnable(spifi);
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd_sector_erase_4k, address, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT);
|
||||
HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_PROGRAM_BUSY);
|
||||
}
|
||||
|
||||
void HAL_SPIFI_W25_ReadData(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes)
|
||||
{
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd_read_data, address, dataLength, dataBytes, 0, 0, HAL_SPIFI_TIMEOUT);
|
||||
}
|
||||
|
||||
W25_ManufacturerDeviceIDTypeDef HAL_SPIFI_W25_ReadManufacturerDeviceID(SPIFI_HandleTypeDef *spifi)
|
||||
{
|
||||
uint8_t data[2] = {0};
|
||||
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd_manufacturer_device_id, 0, 2, data, 0, 0, HAL_SPIFI_TIMEOUT);
|
||||
|
||||
return (W25_ManufacturerDeviceIDTypeDef){
|
||||
.Manufacturer = data[0],
|
||||
.Device = data[1],
|
||||
};
|
||||
}
|
||||
|
||||
void HAL_SPIFI_W25_PageProgram_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes)
|
||||
{
|
||||
HAL_SPIFI_W25_WriteEnable(spifi);
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd_quad_page_program, address, dataLength, 0, dataBytes, 0, HAL_SPIFI_TIMEOUT);
|
||||
HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_PROGRAM_BUSY);
|
||||
}
|
||||
|
||||
void HAL_SPIFI_W25_ReadData_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes)
|
||||
{
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd_fast_read_quad_output, address, dataLength, dataBytes, 0, 0, HAL_SPIFI_TIMEOUT);
|
||||
}
|
||||
|
||||
void HAL_SPIFI_W25_ReadData_Quad_IO(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes)
|
||||
{
|
||||
HAL_SPIFI_SendCommand_LL(spifi, cmd_fast_read_quad_io, address, dataLength, dataBytes, 0, 0, HAL_SPIFI_TIMEOUT);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_W25_QuadEnable(SPIFI_HandleTypeDef *spifi)
|
||||
{
|
||||
uint8_t sreg1 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG1);
|
||||
uint8_t sreg2 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG2);
|
||||
|
||||
return HAL_SPIFI_W25_WriteSREG(spifi, sreg1, sreg2 | HAL_SPIFI_W25_SREG2_BUSY);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_SPIFI_W25_QuadDisable(SPIFI_HandleTypeDef *spifi)
|
||||
{
|
||||
uint8_t sreg1 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG1);
|
||||
uint8_t sreg2 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG2);
|
||||
|
||||
return HAL_SPIFI_W25_WriteSREG(spifi, sreg1, sreg2 & (~HAL_SPIFI_W25_SREG2_BUSY));
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
#include "mik32_hal_ssd1306.h"
|
||||
|
||||
// Адрес ведомого
|
||||
uint16_t slave_address = 0b00111100;
|
||||
|
||||
|
||||
uint8_t data_test[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
/*Символы для SSD1306 128x32*/
|
||||
|
||||
/* Символ ":)" */
|
||||
uint8_t data_symbol_smile[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0,
|
||||
0x00, 0x01, 0x02, 0x07, 0x0F, 0x1E, 0x3C, 0x38, 0x38, 0x78, 0x70, 0x70, 0x70, 0x70, 0x70, 0x78, 0x38, 0x38, 0x3C, 0x1E, 0x0F, 0x07, 0x02, 0x01, 0x00
|
||||
};
|
||||
|
||||
/* Символ ":" */
|
||||
uint8_t data_symbol_colon[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Символ "0" */
|
||||
uint8_t data_symbol_null[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Символ "1" */
|
||||
uint8_t data_symbol_one[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Символ "2" */
|
||||
uint8_t data_symbol_two[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xFC, 0xFC, 0xFC, 0xFC, 0x1F, 0x1F, 0x1F, 0x1F, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xF1, 0xF1, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Символ "3" */
|
||||
uint8_t data_symbol_three[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x00, 0x00,
|
||||
0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Символ "4" */
|
||||
uint8_t data_symbol_four[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFC, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xE3, 0xE3, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Символ "5" */
|
||||
uint8_t data_symbol_five[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0x00, 0x00,
|
||||
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFE, 0xFE, 0xFE, 0xFE, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x01, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Символ "6" */
|
||||
uint8_t data_symbol_six[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x7F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x3F, 0x38, 0x38, 0x38, 0xF8, 0xF8, 0xF8, 0xF8, 0xC0, 0xC0, 0xC0, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Символ "7" */
|
||||
uint8_t data_symbol_seven[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x8F, 0x8F, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x7F, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Символ "8" */
|
||||
uint8_t data_symbol_eight[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3F, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0xF8, 0xF8, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFC, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0x1F, 0x1F, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Символ "9" */
|
||||
uint8_t data_symbol_nine[] = {
|
||||
DATS,
|
||||
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0x03, 0x03, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0x1F, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
|
||||
HAL_StatusTypeDef HAL_SSD1306_Init(I2C_HandleTypeDef *hi2c, uint8_t brightness)
|
||||
{
|
||||
// for (volatile int i = 0; i < 1000; i++);
|
||||
uint8_t Set_MUX_Ratio, Set_COM_Pins;
|
||||
#ifdef SSD1306_128x64
|
||||
Set_MUX_Ratio = 0x3F;
|
||||
Set_COM_Pins = 0x12;
|
||||
#endif
|
||||
|
||||
#ifdef SSD1306_128x32
|
||||
Set_MUX_Ratio = 0x1F;
|
||||
Set_COM_Pins = 0x02;
|
||||
#endif
|
||||
|
||||
/* Массив для стандартной инициализации */
|
||||
uint8_t data_init[] = {
|
||||
COM, 0xA8, COM, Set_MUX_Ratio, // Set MUX Ratio // 0x3F - 128x64; 0x1F - 128x32
|
||||
COM, 0xD3, COM, 0x00, // Set Display Offset
|
||||
COM, 0x40, // Set Display Start Line
|
||||
COM, 0xA1, // Set Segment re-map
|
||||
COM, 0xC8, // Set COM Output Scan Direction
|
||||
COM, 0xDA, COM, Set_COM_Pins,// Set COM Pins hardware configuration. 0x12 - 128x64; 0x02 - 128x32
|
||||
COM, 0x81, COM, brightness, // Set Contrast Control
|
||||
COM, 0xA4, // Disable Entire Display On
|
||||
COM, 0xA6, // Set Normal Display
|
||||
COM, 0xD5, COM, 0x80, // Set Osc Frequency
|
||||
COM, 0x8D,COM, 0x14, // Enable charge pump regulator
|
||||
COM, 0xAF // Display On
|
||||
};
|
||||
|
||||
/* Oled_init - инициализация экрана в стандартном режиме */
|
||||
return HAL_I2C_Master_Transmit(hi2c, slave_address, data_init, sizeof(data_init), I2C_TIMEOUT_DEFAULT);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_SSD1306_SetBorder(I2C_HandleTypeDef *hi2c, uint8_t start_col, uint8_t end_col, uint8_t start_page, uint8_t end_page)
|
||||
{
|
||||
uint8_t data_SetBorder[] = {
|
||||
COM, 0x21, // установка адреса колонок
|
||||
COM, start_col, // номер стартовой колонки
|
||||
COM, end_col, // номер конечной колонки
|
||||
|
||||
COM, 0x22, // установка адреса страницы
|
||||
COM, start_page, // номер стартовой страницы
|
||||
COM, end_page, // номер конечной страницы
|
||||
};
|
||||
|
||||
/* set_border - установка границ вывода на дисплей */
|
||||
return HAL_I2C_Master_Transmit(hi2c, slave_address, data_SetBorder, sizeof(data_SetBorder), I2C_TIMEOUT_DEFAULT);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_SSD1306_CLR_SCR(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
uint8_t data_CLR_SCR[517] = {COM, 0x20, COM, 0x00, // Horizontal Addressing Mode
|
||||
DATS};
|
||||
int counter = 5;
|
||||
for (int page = 0; page < 4; page++)
|
||||
{
|
||||
for(int col = 0; col < 128; col++)
|
||||
{
|
||||
data_CLR_SCR[counter] = (uint8_t)0;
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
/* CLR_SCR - очищение всего экрана в горизонтальном режиме*/
|
||||
return HAL_I2C_Master_Transmit(hi2c, slave_address, data_CLR_SCR, sizeof(data_CLR_SCR), I2C_TIMEOUT_DEFAULT);
|
||||
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_SSD1306_Write(I2C_HandleTypeDef *hi2c, uint8_t symbol)
|
||||
{
|
||||
// for (volatile int i = 0; i < 1000; i++);
|
||||
HAL_StatusTypeDef error_code = HAL_OK;
|
||||
switch (symbol)
|
||||
{
|
||||
case 0:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_null, sizeof(data_symbol_null), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
case 1:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_one, sizeof(data_symbol_one), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
case 2:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_two, sizeof(data_symbol_two), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
case 3:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_three, sizeof(data_symbol_three), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
case 4:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_four, sizeof(data_symbol_four), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
case 5:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_five, sizeof(data_symbol_five), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
case 6:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_six, sizeof(data_symbol_six), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
case 7:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_seven, sizeof(data_symbol_seven), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
case 8:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_eight, sizeof(data_symbol_eight), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
case 9:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_nine, sizeof(data_symbol_nine), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
case SYMBOL_SMILE:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_smile, sizeof(data_symbol_smile), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
default:
|
||||
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_colon, sizeof(data_symbol_colon), I2C_TIMEOUT_DEFAULT);
|
||||
break;
|
||||
}
|
||||
|
||||
return error_code;
|
||||
|
||||
}
|
||||
Whitespace-only changes.
Reference in new issue
Block a user