/* 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 . */ /** * @addtogroup digio * @{ */ #include #include #include #include #include static const uint8_t digio_pins[] = {DIGIO_PINS}; static const uint8_t digio_default_io[] = {DIGIO_INOUT_DEFAULT}; static const uint8_t digio_default_altfunc[] = {DIGIO_ALTFUNC_DEFAULT}; static uint16_t loudspeaker_val; static void digio_setup_pin_int(uint8_t bit_no, uint8_t in_out, uint8_t alt_func) { DIGIO_PORT->MODER &= MODER_DELETE(bit_no); switch (in_out) { case 2: DIGIO_PORT->MODER |= ALTFUNC(bit_no); SETAF(DIGIO_PORT, bit_no, alt_func); break; case 1: DIGIO_PORT->MODER |= OUTPUT(bit_no); break; case 0: /* expected fallthrough */ default: break; } } void digio_init(void) { rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(DIGIO_RCC_MASK)); digio_set_default_values(); } void digio_setup_pin(uint8_t num, uint8_t in_out, uint8_t alt_func) { if (num >= COUNT_OF(digio_pins)) return; digio_setup_pin_int(digio_pins[num], in_out, alt_func); } void digio_set(uint8_t num, int val) { uint8_t pin; if (num >= COUNT_OF(digio_pins)) return; pin = digio_pins[num]; /* Check if port is an output. If not, do noting. */ if ((DIGIO_PORT->MODER & (0x3<ODR |= (1<ODR &= ~(1<= COUNT_OF(digio_pins)) return -1; if ((DIGIO_PORT->MODER & (0x3<ODR & (1<IDR & (1<AHB1ENR, BITMASK_TO_BITNO(LED_RCC_MASK)); for (i = 0; i < COUNT_OF(led_pins); i++) { LED_PORT->MODER &= MODER_DELETE(led_pins[i]); LED_PORT->MODER |= OUTPUT(led_pins[i]); } } void led_set(uint8_t num, int val) { if (num >= COUNT_OF(led_pins)) return; if (val) LED_PORT->ODR |= (1<ODR &= ~(1<= COUNT_OF(led_pins)) return -1; return ((LED_PORT->ODR & (1<APB1ENR, BITMASK_TO_BITNO(RCC_APB1ENR_TIM7EN)); TIM7->CR1 = 0UL; TIM7->CR2 = 0UL; TIM7->PSC = 1000; TIM7->DIER = TIM_DIER_UIE; NVIC_EnableIRQ(TIM7_IRQn); #endif } void loudspeaker_setup(void) { rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(LOUDSPEAKER_RCC_MASK)); LOUDSPEAKER_PORT->MODER &= MODER_DELETE(LOUDSPEAKER_PIN); LOUDSPEAKER_PORT->MODER |= OUTPUT(LOUDSPEAKER_PIN); loudspeaker_freq_timer_init(); loudspeaker_set(0U); } /** * @brief Start the beeper * @param val frequency value of the speaker in 'Timer relaod values' * @note If @ref LOUDSPEAKER_MULTIFREQ isn't set, * the speaker output will be set to high and no frequency is generated. * The value of @p val is ignored in this case */ static void loudspeaker_start_beep(uint16_t val) { #if LOUDSPEAKER_MULTIFREQ TIM7->ARR = (val == 1 ? LOUDSPEAKER_MULTIFREQ_DEFAULT : val); TIM7->CNT = 0UL; TIM7->CR1 |= TIM_CR1_CEN; #else (void)val; LOUDSPEAKER_PORT->ODR |= (1<CR1 &= ~TIM_CR1_CEN; __DSB(); TIM7->SR = 0UL; __DSB(); LOUDSPEAKER_PORT->ODR &= ~(1<ODR &= ~(1<SR = 0UL; __DSB(); LOUDSPEAKER_PORT->ODR ^= (1<