/** * Reset 1-wire bus (~1 ms). */ static inline uint8_t reset(void) { uint8_t tmp = 0; uint8_t result = 0; TIM1_SetAutoreload(485); TIM1->CR1 |= TIM1_CR1_CEN; OW_PORT->ODR |= OW_OUT; while (TIM1->CR1 & TIM1_CR1_CEN); OW_PORT->ODR &= ~OW_OUT; TIM1_ClearFlag(TIM1_FLAG_UPDATE); // Wait once again, sample within 100 mks TIM1->CR1 |= TIM1_CR1_CEN; while (TIM1->CR1 & TIM1_CR1_CEN) { tmp = TIM1->CNTRH; if (TIM1->CNTRL >= RESET_TIME) break; } result = (OW_PORT->IDR & OW_IN) == 0; // Wait for the end of reset period. while (TIM1->CR1 & TIM1_CR1_CEN); TIM1_ClearFlag(TIM1_FLAG_UPDATE); TIM1_SetAutoreload(60); return result; }
/** * 1-wire read cycle. * Drive line low for 1 mks, then release line, wait until remote device drives it and measure release time. * * \pre TIM1 is configured to 1 MHz, 60 mks period. * \pre TIM1 counter is set to 0. * \pre TIM1 CC1 is configured to input capture. * \returns 0x80 if 1 was read */ static inline uint8_t read(void) { uint8_t tmp = 0; uint8_t result = 0; TIM1->CR1 |= TIM1_CR1_CEN; OW_PORT->ODR |= OW_OUT; for (;;) { tmp = TIM1->CNTRH; if (TIM1->CNTRL >= READ_PULSE) break; } OW_PORT->ODR &= ~OW_OUT; for (;;) { tmp = TIM1->CNTRH; if (TIM1->CNTRL >= READ_TIME) break; } result = (OW_PORT->IDR & OW_IN) ? 0x80 : 0; while (TIM1->CR1 & TIM1_CR1_CEN); // Wait until the end of time slot. TIM1_ClearFlag(TIM1_FLAG_UPDATE); return result; }
/** * 1-wire write 0 cycle (60 mks). * Drive line low for the whole cycle. * * \pre TIM1 is configured to 1 MHz, 60 mks period. * \pre TIM1 counter is set to 0. */ static inline void write_0(void) { TIM1->CR1 |= TIM1_CR1_CEN; OW_PORT->ODR |= OW_OUT; // Drives line low. while (TIM1->CR1 & TIM1_CR1_CEN); OW_PORT->ODR &= ~OW_OUT; // Release line. TIM1_ClearFlag(TIM1_FLAG_UPDATE); }
/** * @brief Configure TIM1 to to capture the internal clock source (LSI) * @param None * @retval None */ static void TIM1_Config(void) { TIM1_ICInit( TIM1_CHANNEL_1, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV8, 0x0); /* Enable TIM1 */ TIM1_Cmd(ENABLE); /* Clear CC1 Flag*/ TIM1_ClearFlag(TIM1_FLAG_CC1); /* wait a capture on CC1 */ while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1); /* Get CCR1 value*/ ICValue1 = TIM1_GetCapture1(); TIM1_ClearFlag(TIM1_FLAG_CC1); /* wait a capture on cc1 */ while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1); /* Get CCR1 value*/ ICValue2 = TIM1_GetCapture1(); TIM1_ClearFlag(TIM1_FLAG_CC1); }
/** * 1-wire write 1 cycle (60 mks). * Drive line low for ~5 mks, then drive it high. * * \pre TIM1 is configured to 1 MHz, 60 mks period. * \pre TIM1 counter is set to 0. */ static inline void write_1(void) { uint8_t tmp; TIM1->CR1 |= TIM1_CR1_CEN; OW_PORT->ODR |= OW_OUT; // Drives line low. while (TIM1->CR1 & TIM1_CR1_CEN) { tmp = TIM1->CNTRH; if (TIM1->CNTRL >= WRITE1_TIME) { OW_PORT->ODR &= ~OW_OUT; break; } } while (TIM1->CR1 & TIM1_CR1_CEN); // Wait until the end of time slot. TIM1_ClearFlag(TIM1_FLAG_UPDATE); }
/** * @brief Measure the LSI frequency using timer IC1 and update the calibration registers. * @par Parameters: * None * @retval * None * @par Required preconditions: * It is recommanded to use a timer clock frequency of at least 10MHz in order * to obtain a better in the LSI frequency measurement. */ u32 LSIMeasurment(void) { u32 lsi_freq_hz = 0x0; u32 fmaster = 0x0; u16 ICValue1 = 0x0; u16 ICValue2 = 0x0; /* Get master frequency */ fmaster = CLK_GetClockFreq(); /* Enable the LSI measurement: LSI clock connected to timer Input Capture 1 */ AWU->CSR |= AWU_CSR_MSR; #if defined (STM8S903) || defined (STM8S103) /* Measure the LSI frequency with TIMER Input Capture 1 */ /* Capture only every 8 events!!! */ /* Enable capture of TI1 */ TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV8, 0); /* Enable TIM1 */ TIM1_Cmd(ENABLE); /* wait a capture on cc1 */ while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1); /* Get CCR1 value*/ ICValue1 = TIM1_GetCapture1(); TIM1_ClearFlag(TIM1_FLAG_CC1); /* wait a capture on cc1 */ while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1); /* Get CCR1 value*/ ICValue2 = TIM1_GetCapture1(); TIM1_ClearFlag(TIM1_FLAG_CC1); /* Disable IC1 input capture */ TIM1->CCER1 &= (u8)(~TIM1_CCER1_CC1E); /* Disable timer2 */ TIM1_Cmd(DISABLE); #else /* Measure the LSI frequency with TIMER Input Capture 1 */ /* Capture only every 8 events!!! */ /* Enable capture of TI1 */ TIM3_ICInit(TIM3_CHANNEL_1, TIM3_ICPOLARITY_RISING, TIM3_ICSELECTION_DIRECTTI, TIM3_ICPSC_DIV8, 0); /* Enable TIM3 */ TIM3_Cmd(ENABLE); /* wait a capture on cc1 */ while ((TIM3->SR1 & TIM3_FLAG_CC1) != TIM3_FLAG_CC1); /* Get CCR1 value*/ ICValue1 = TIM3_GetCapture1(); TIM3_ClearFlag(TIM3_FLAG_CC1); /* wait a capture on cc1 */ while ((TIM3->SR1 & TIM3_FLAG_CC1) != TIM3_FLAG_CC1); /* Get CCR1 value*/ ICValue2 = TIM3_GetCapture1(); TIM3_ClearFlag(TIM3_FLAG_CC1); /* Disable IC1 input capture */ TIM3->CCER1 &= (u8)(~TIM3_CCER1_CC1E); /* Disable timer3 */ TIM3_Cmd(DISABLE); #endif /* Compute LSI clock frequency */ lsi_freq_hz = (8 * fmaster) / (ICValue2 - ICValue1); /* Disable the LSI measurement: LSI clock disconnected from timer Input Capture 1 */ AWU->CSR &= (u8)(~AWU_CSR_MSR); return (lsi_freq_hz); }