/* Reflow Oven Controller * * Copyright (C) 2021 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 hw-version-detect * @{ */ #include #include #include #if HW_REV_DETECT_PIN_LOW > HW_REV_DETECT_PIN_HIGH #error Configuration error for Hardware derection pins. Lowest position must be less than the highest pin position. #endif enum hw_revision get_pcb_hardware_version(void) { uint8_t current_pin; uint16_t port_bitmask = 0U; static enum hw_revision revision = HW_REV_NOT_DETECTED; /* If the revision has been previously detected, * just return it and don't do the whole detection stuff */ if (revision != HW_REV_NOT_DETECTED) return revision; rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(HW_REV_DETECT_RCC_FIELD)); /* Setup the pins as input with pull up */ for (current_pin = HW_REV_DETECT_PIN_LOW; current_pin <= HW_REV_DETECT_PIN_HIGH; current_pin++) { HW_REV_DETECT_GPIO->MODER &= MODER_DELETE(current_pin); HW_REV_DETECT_GPIO->PUPDR &= PUPDR_DELETE(current_pin); HW_REV_DETECT_GPIO->PUPDR |= PULLUP(current_pin); } /* Loop again and read in the pin mask. * Because we use GND-Shorts on the pins to detect the version, the pins are read inverted. */ for (current_pin = HW_REV_DETECT_PIN_LOW; current_pin <= HW_REV_DETECT_PIN_HIGH; current_pin++) { port_bitmask >>= 1; port_bitmask |= (HW_REV_DETECT_GPIO->IDR & (1 << current_pin)) ? 0x0 : 0x80; } /* Resolve the read in bitmask to a hardware version */ switch (port_bitmask) { case 0U: revision = HW_REV_V1_2; break; case 1U: revision = HW_REV_V1_3; break; case 2U: revision = HW_REV_V1_3_1; break; default: revision = HW_REV_ERROR; } rcc_manager_disable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(HW_REV_DETECT_RCC_FIELD)); return revision; } /** @} */