ready to alpha

подготовка к альфа-тестированию
This commit is contained in:
khristolyubov committed 2024-08-19 22:44:04 +07:00
commit e36b851783
164 files changed
+27352

No files matched your search

+1
View File
@@ -0,0 +1 @@
.vscode
+1
View File
@@ -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.