/* Reflow Oven Controller * * Copyright (C) 2020 Mario Hüttel * * This file is part of the Reflow Oven Controller Project. * * The reflow oven controller is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * The Reflow Oven Control Firmware is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the reflow oven controller project. * If not, see . */ #include #include #include #include static inline void rotary_encoder_setup_pins(void) { rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(ROTARY_ENCODER_RCC_MASK)); ROTARY_ENCODER_PORT->MODER &= MODER_DELETE(ROTARY_ENCODER_PIN1) & MODER_DELETE(ROTARY_ENCODER_PIN2); ROTARY_ENCODER_PORT->MODER |= ALTFUNC(ROTARY_ENCODER_PIN1) | ALTFUNC(ROTARY_ENCODER_PIN2); SETAF(ROTARY_ENCODER_PORT, ROTARY_ENCODER_PIN1, ROTARY_ENCODER_PORT_ALTFUNC); SETAF(ROTARY_ENCODER_PORT, ROTARY_ENCODER_PIN2, ROTARY_ENCODER_PORT_ALTFUNC); } void rotary_encoder_setup(void) { rcc_manager_enable_clock(&RCC->APB1ENR, BITMASK_TO_BITNO(ROTARY_ENCODER_TIMER_RCC_MASK)); rotary_encoder_setup_pins(); ROTARY_ENCODER_TIMER->ARR = 0xFFFF; ROTARY_ENCODER_TIMER->CNT = 0; ROTARY_ENCODER_TIMER->CR2 = 0; ROTARY_ENCODER_TIMER->SMCR = TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1; ROTARY_ENCODER_TIMER->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; ROTARY_ENCODER_TIMER->CCER = TIM_CCER_CC1P | TIM_CCER_CC2P; ROTARY_ENCODER_TIMER->PSC = 0; ROTARY_ENCODER_TIMER->CR1 = TIM_CR1_CEN; } uint32_t rotary_encoder_get_abs_val(void) { return (uint32_t)ROTARY_ENCODER_TIMER->CNT; } int32_t rotary_encoder_get_change_val(void) { static uint32_t last_val = 0; uint32_t val; int32_t diff; val = rotary_encoder_get_abs_val(); diff = val - last_val; if (val > last_val) { if (diff > (0xFFFF/2)) diff = -(last_val + 0x10000-val); } else { if (ABS(diff) > (0xFFFF/2)) diff = 0x10000 - last_val + val; } last_val = val; return diff; } void rotary_encoder_stop(void) { ROTARY_ENCODER_TIMER->CR1 = 0; ROTARY_ENCODER_TIMER->CR2 = 0; ROTARY_ENCODER_TIMER->ARR = 0; rcc_manager_disable_clock(&RCC->APB1ENR, BITMASK_TO_BITNO(ROTARY_ENCODER_TIMER_RCC_MASK)); rcc_manager_disable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(ROTARY_ENCODER_RCC_MASK)); } void rotary_encoder_zero(void) { ROTARY_ENCODER_TIMER->CNT = 0UL; }