/** ****************************************************************************** * @file ow_port.c * @brief This file includes the driver for port for OneWire purposes ****************************************************************************** */ #include "ow_port.h" #include "onewire.h" #include "tim.h" /** * @brief The internal function is used as gpio pin mode * @param OW OneWire HandleTypedef * @param Mode Input or Output */ void OneWire_Pin_Mode(OneWire_t* OW, PinMode Mode) { #if defined(UART_Driver) #elif defined(CMSIS_Driver) volatile uint32_t *config_reg = (OW->DataPinNumb < 8) ? &(OW->DataPort->CRL) : &(OW->DataPort->CRH); uint32_t pin_pos = (OW->DataPinNumb < 8) ? (OW->DataPinNumb * 4) : ((OW->DataPinNumb - 8) * 4); // —брос текущих 4 бит (CNF + MODE) *config_reg &= ~(0xF << pin_pos); if (Mode == Input) { // ¬ход с подт¤жкой или без Ц например, CNF = 0b01, MODE = 0b00 // «десь устанавливаем вход с подт¤жкой: *config_reg |= (0x8 << pin_pos); // CNF=10, MODE=00 (вход с подт¤жкой) OW->DataPort->ODR |= (1 << OW->DataPinNumb); // ¬ключить подт¤жку вверх } else { // ¬ыход push-pull, 2 ћ√ц Ц MODE = 0b10, CNF = 0b00 *config_reg |= (0x2 << pin_pos); } #elif defined(LL_Driver) if(Mode == Input) { LL_GPIO_SetPinMode(OW->DataPort, OW->DataPin, LL_GPIO_MODE_INPUT); }else{ LL_GPIO_SetPinMode(OW->DataPort, OW->DataPin, LL_GPIO_MODE_OUTPUT); } #else GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = OW->DataPin; if(Mode == Input) { GPIO_InitStruct.Mode = GPIO_MODE_INPUT; }else{ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; } HAL_GPIO_Init(OW->DataPort, &GPIO_InitStruct); #endif } /** * @brief The internal function is used as gpio pin level * @param OW OneWire HandleTypedef * @param Mode Level: Set/High = 1, Reset/Low = 0 */ void OneWire_Pin_Level(OneWire_t* OW, uint8_t Level) { #if defined(UART_Driver) #elif defined(CMSIS_Driver) if (Level != GPIO_PIN_RESET) { OW->DataPort->BSRR = OW->DataPin; } else { OW->DataPort->BSRR = (uint32_t)OW->DataPin << 16u; } #elif defined(LL_Driver) if(Level == 1) { LL_GPIO_SetOutputPin(OW->DataPort, OW->DataPin); }else{ LL_GPIO_ResetOutputPin(OW->DataPort, OW->DataPin); } #else HAL_GPIO_WritePin(OW->DataPort, OW->DataPin, Level); #endif } /** * @brief The internal function is used to read data pin * @retval Pin level status * @param OW OneWire HandleTypedef */ uint8_t OneWire_Pin_Read(OneWire_t* OW) { #if defined(UART_Driver) return 0; #elif defined(CMSIS_Driver) return ((OW->DataPort->IDR & OW->DataPin) != 0x00U) ? 1 : 0; #elif defined(LL_Driver) return ((OW->DataPort->IDR & OW->DataPin) != 0x00U) ? 1 : 0; #else return HAL_GPIO_ReadPin(OW->DataPort, OW->DataPin); #endif } uint32_t tim_1us_period = OW_TIM_1US_PERIOD; void OneWire_Delay_us(uint32_t us) { uint32_t ticks = us * tim_1us_period; uint16_t start = OW_TIM->CNT; uint32_t elapsed = 0; uint16_t prev = start; while (elapsed < ticks) { uint16_t curr = OW_TIM->CNT; uint16_t delta = (uint16_t)(curr - prev); // учЄт переполнени¤ elapsed += delta; prev = curr; } }