diff --git a/app/app_hal.c b/app/app_hal.c new file mode 100644 index 000000000..96ef17538 --- /dev/null +++ b/app/app_hal.c @@ -0,0 +1,59 @@ +/* +Flipper devices inc. + +GPIO and HAL implementations +*/ + +#include "main.h" +#include "gpio.h" + +void app_gpio_init(GpioPin gpio, GpioMode mode) { + if(gpio.pin != 0) { + GPIO_InitTypeDef GPIO_InitStruct; + + GPIO_InitStruct.Pin = gpio.pin; + GPIO_InitStruct.Pull = GPIO_NOPULL; + + switch(mode) { + case GpioModeInput: + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + break; + + case GpioModeOutput: + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; + break; + + case GpioModeOpenDrain: + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; + break; + } + + HAL_GPIO_Init(gpio.port, &GPIO_InitStruct); + } +} + +// TODO delay from timer +void delay_us(uint32_t time) { + time *= 11.8; + + while(time--) {} +} + +void pwm_set(float value, float freq, TIM_HandleTypeDef* tim, uint32_t channel) { + tim->Init.CounterMode = TIM_COUNTERMODE_UP; + tim->Init.Period = (uint32_t)((SystemCoreClock/tim->Init.Prescaler)/freq); + tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + HAL_TIM_PWM_Init(tim); + + TIM_OC_InitTypeDef sConfigOC; + + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = (uint16_t)(291 * value); + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + HAL_TIM_PWM_ConfigChannel(tim, &sConfigOC, channel); + HAL_TIM_PWM_Start(tim, channel); +} \ No newline at end of file diff --git a/app/app_hal.h b/app/app_hal.h new file mode 100644 index 000000000..3a33aaedd --- /dev/null +++ b/app/app_hal.h @@ -0,0 +1,100 @@ +/* +Flipper devices inc. + +GPIO and HAL implementations +*/ + +#pragma once + +#include +#include "main.h" + +typedef enum { + GpioModeInput, + GpioModeOutput, + GpioModeOpenDrain +} GpioMode; + +typedef struct { + GPIO_TypeDef* port; + uint32_t pin; +} GpioPin; + +void app_gpio_init(GpioPin gpio, GpioMode mode); + +inline void app_gpio_write(GpioPin gpio, bool state) { + if(gpio.pin != 0) { + if(state) { + gpio.port->BSRR = (uint32_t)gpio.pin; + } else { + gpio.port->BRR = (uint32_t)gpio.pin; + } + } +} + +inline bool app_gpio_read(GpioPin gpio) { + if(gpio.pin != 0) { + return (gpio.port->IDR & gpio.pin) != 0x00u; + } + + return false; +} + +void delay_us(uint32_t time); + +void pwm_set(float value, float freq, TIM_HandleTypeDef* tim, uint32_t channel); + +extern TIM_HandleTypeDef htim8; + +inline void app_tim_ic_init(bool both) { + HAL_TIM_OC_Stop(&htim8, TIM_CHANNEL_2); + + TIM_IC_InitTypeDef sConfigIC = {0}; + sConfigIC.ICPolarity = both ? TIM_INPUTCHANNELPOLARITY_BOTHEDGE : TIM_INPUTCHANNELPOLARITY_FALLING; + sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; + sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; + sConfigIC.ICFilter = 0; + HAL_TIM_IC_ConfigChannel(&htim8, &sConfigIC, TIM_CHANNEL_2); + + HAL_TIM_IC_Start_IT(&htim8, TIM_CHANNEL_2); +} + +inline void app_tim_pulse(uint32_t width) { + htim8.State = HAL_TIM_STATE_BUSY; + + __HAL_TIM_DISABLE(&htim8); + + __HAL_TIM_SET_COUNTER(&htim8, 0); + + TIM_OC_InitTypeDef sConfigOC; + sConfigOC.OCMode = TIM_OCMODE_INACTIVE; + sConfigOC.Pulse = (uint16_t)(width); + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + // HAL_TIM_OC_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_2); + + htim8.Lock = HAL_LOCKED; + + /* Configure the TIM Channel 2 in Output Compare */ + TIM_OC2_SetConfig(htim8.Instance, &sConfigOC); + + htim8.Lock = HAL_UNLOCKED; + + // TIM_CCxChannelCmd(htim8.Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + /* Reset the CCxE Bit */ + htim8.Instance->CCER &= ~(TIM_CCER_CC1E << (TIM_CHANNEL_2 & 0x1FU)); + + /* Set or reset the CCxE Bit */ + htim8.Instance->CCER |= (uint32_t)(TIM_CCx_ENABLE << (TIM_CHANNEL_2 & 0x1FU)); + + __HAL_TIM_MOE_ENABLE(&htim8); + __HAL_TIM_ENABLE(&htim8); + + htim8.State = HAL_TIM_STATE_READY; +} + +inline void app_tim_stop() { + HAL_TIM_OC_Stop(&htim8, TIM_CHANNEL_2); + HAL_TIM_IC_Stop(&htim8, TIM_CHANNEL_2); +} \ No newline at end of file