diff --git a/cores/arduino/Tone.cpp b/cores/arduino/Tone.cpp index 4977133..81899f3 100644 --- a/cores/arduino/Tone.cpp +++ b/cores/arduino/Tone.cpp @@ -100,7 +100,7 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) HAL_EPIC_MaskLevelSet(HAL_EPIC_TIMER16_1_MASK); pinMode(pin, OUTPUT); - timer_pin_port->CLEAR = timer_pin_mask; + HAL_GPIO_WritePin((GPIO_TypeDef *)timer_pin_port, timer_pin_mask, GPIO_PIN_LOW); HAL_Timer16_Counter_Start_IT(&htimer16_1, frequencyParams.period_ticks); timerIsOn = true; @@ -124,8 +124,9 @@ void noTone(uint8_t pin) { if (timerIsOn) { - timer_pin_port->CLEAR = timer_pin_mask; // pin to 0 - htimer16_1.Instance->CR &= ~TIMER16_CR_ENABLE_M; // disable timer + // pin to 0 + HAL_GPIO_WritePin((GPIO_TypeDef *)timer_pin_port, timer_pin_mask, GPIO_PIN_LOW); + HAL_Timer16_Disable(&htimer16_1); // disable timer HAL_EPIC_MaskLevelClear(HAL_EPIC_TIMER16_1_MASK); pinMode(pin, INPUT); // deinit pin timer_pin = -1; // reset to default @@ -136,12 +137,12 @@ void noTone(uint8_t pin) // irq handler extern "C" void tone_interrupt_handler(void) { - if ((htimer16_1.Instance->ISR & htimer16_1.Instance->IER) & TIMER16_ISR_ARR_MATCH_M) + if(HAL_Timer16_GetInterruptStatus_ARRM(&htimer16_1)) { // timer period has passed, change the pin state if (timer_toggle_count != 0) { - timer_pin_port->OUTPUT_ ^= timer_pin_mask; + HAL_GPIO_TogglePin((GPIO_TypeDef*)timer_pin_port, timer_pin_mask); if (timer_toggle_count > 0) timer_toggle_count--; @@ -149,10 +150,10 @@ extern "C" void tone_interrupt_handler(void) else { // turn off if the specified duration has passed - timer_pin_port->CLEAR = timer_pin_mask; + HAL_GPIO_WritePin((GPIO_TypeDef *)timer_pin_port, timer_pin_mask, GPIO_PIN_LOW); noTone(timer_pin); } } // reset timer interrupt flags - htimer16_1.Instance->ICR = 0xFFFFFFFF; + HAL_Timer16_ClearInterruptMask(&htimer16_1, 0xFFFFFFFF); } \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h index b3a6776..e398583 100644 --- a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h @@ -375,14 +375,85 @@ typedef enum __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(); + +/** + * @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. + */ +static inline __attribute__((always_inline)) GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin) +{ + if ((GPIO_x->SET & pin) != (uint32_t)GPIO_PIN_LOW) + return GPIO_PIN_HIGH; + else + return GPIO_PIN_LOW; +} + +/** + * @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 высокий выходной уровень + */ +static inline __attribute__((always_inline)) 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, к которым применяются указанные настройки. + */ +static inline __attribute__((always_inline)) void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin) +{ + GPIO_x->OUTPUT_ ^= pin; +} + +/** + * @brief Получить состояние линии прерывания. + * @param irqLine номер линии прерывания. + * @return Возвращает 1 если сработало прерывание данной линии, иначе 0. + */ +static inline __attribute__((always_inline)) 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 Логический уровень вывода. + */ +static inline __attribute__((always_inline)) 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(). + * Если после обработки прерывания регистр не был сброшен, + * обработчик будет вызван снова, программа будет бесконечно вызывать обработчик. + */ +static inline __attribute__((always_inline)) void HAL_GPIO_ClearInterrupts() +{ + GPIO_IRQ->CLEAR = 0b11111111; +} #ifdef __cplusplus } diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h index 873a26f..60dcc2c 100644 --- a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h @@ -230,8 +230,6 @@ typedef struct __Timer16_HandleTypeDef 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); @@ -278,6 +276,26 @@ void HAL_Timer16_SetInterruptARRM(Timer16_HandleTypeDef *htimer16); void HAL_Timer16_SetInterruptCMPM(Timer16_HandleTypeDef *htimer16); void HAL_Timer16_InterruptInit(Timer16_HandleTypeDef *htimer16); +/** + * @brief Выключить таймер. + * Может использоваться для отключения таймера или при записи в регистр CFGR. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +static inline void __attribute__((always_inline)) HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16) +{ + htimer16->Instance->CR &= ~TIMER16_CR_ENABLE_M; +} + +/** + * @brief Включить таймер + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +static inline void __attribute__((always_inline)) HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16) +{ + htimer16->Instance->CR |= TIMER16_CR_ENABLE_M; +} + /** * @brief Получить статус прерываний Timer16. * Функция возвращает статус прерываний в соответствии с маской разрешенный прерываний. @@ -291,6 +309,16 @@ static inline __attribute__((always_inline)) uint32_t HAL_Timer16_GetInterruptSt return interrupt_status; } +/** + * @brief Получить статус прерывания по соответствию автозагрузке ARRM + * @param htimer16 Указатель на структуру с настройками Timer16 + * @return Статус прерывания ARRM - true, если прерывание сработало + */ +static inline __attribute__((always_inline)) bool HAL_Timer16_GetInterruptStatus_ARRM(Timer16_HandleTypeDef *htimer16) +{ + return (bool)((htimer16->Instance->ISR & htimer16->Instance->IER) & TIMER16_ISR_ARR_MATCH_M); +} + /** * @brief Очистить флаг прерывания. * @param htimer16 Указатель на структуру с настройками Timer16. diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c index ea3e1ae..ce6ae55 100644 --- a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c @@ -93,58 +93,6 @@ HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, 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 настройка мультиплексора линии прерывания. @@ -222,39 +170,3 @@ HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine) 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; -} diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c index 7bcda80..8756bb7 100644 --- a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c @@ -99,26 +99,6 @@ __attribute__((weak)) void HAL_TIMER16_MspInit(Timer16_HandleTypeDef* htimer16) } } -/** - * @brief Выключить таймер. - * Может использоваться для отключения таймера или при записи в регистр CFGR. - * - * @param htimer16 Указатель на структуру с настройками Timer16. - */ -void HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16) -{ - htimer16->Instance->CR &= ~TIMER16_CR_ENABLE_M; -} - -/** - * @brief Включить таймер - * @param htimer16 Указатель на структуру с настройками Timer16. - */ -void HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16) -{ - htimer16->Instance->CR |= TIMER16_CR_ENABLE_M; -} - /** * @brief Установить активный фронт для подсчёта или задать подрежим энкодера. * Используется при тактировании Timer16 от внешнего источника тактового сигнала на выводе Input1.