/******************************************************************************* * COPYRIGHT (C) 2021 CMS Technologies Ltd. * * * ******************************************************************************** * FileName : tima.c * * Author : * * Version : 1.0 * * Date : 2021.08.13 * * Description : * * Function List : * ********************************************************************************/ #include "tima.h" #include "cgc.h" #define g_ta0_value 0xffff /** * @brief This function starts TMA counter. * @param None * @retval None */ void TMA_Start(void) { TMA->TACR0 |= TMA_COUNT_START; } /** * @brief This function stops TMA counter. * @param None * @retval None */ void TMA_Stop(void) { TMA->TACR0 &= (uint8_t)~TMA_COUNT_START; INTC_DisableIRQ(TMA_IRQn);/* disable INTTMA interrupt */ INTC_ClearPendingIRQ(TMA_IRQn);/* clear INTTMA interrupt flag */ } /** * @brief Clear the specified TMA flag is set. * @param TMA_FLAG: specifies the flag to check. * This parameter can be one of the following values: * @arg TMA_FLAG_UNDERFLOW: Transmission running status flag * @arg TMA_FLAG_ACTIVE_EDGE_RECEIVED: Transmission register save valid data flag * @arg TMA_FLAG_STATUS_COUNT: Transmission frame data error flag * @retval None. */ void TMA_ClearFlag(uint8_t TMA_FLAG) { /* Check the parameters */ assert_param(IS_TMA_FLAG(TMA_FLAG)); TMA->TACR0 &= ~TMA_FLAG; } /** * @brief Checks whether the specified TMA flag is set or not. * @param TMA_FLAG: specifies the flag to check. * This parameter can be one of the following values: * @arg TMA_FLAG_UNDERFLOW: Transmission running status flag * @arg TMA_FLAG_ACTIVE_EDGE_RECEIVED: Transmission register save valid data flag * @arg TMA_FLAG_STATUS_COUNT: Transmission frame data error flag * @retval The new state of USART_FLAG (SET or RESET). */ FlagStatus TMA_GetStaus(uint8_t TMA_FLAG) { FlagStatus bitstatus = RESET; /* Check the parameters */ assert_param(IS_TMA_FLAG(TMA_FLAG)); if ((TMA->TACR0 & TMA_FLAG) != (uint16_t)RESET) { bitstatus = SET; } else { bitstatus = RESET; } return bitstatus; } /** * @brief Initializes the TIEMRA peripheral according to the specified * parameters in the TIMA_InitStruct . * @param TIMA_InitStruct: pointer to a TMA_InitTypeDef structure that contains * the configuration information for the specified TIEMRA peripheral. * @retval none */ void TMA_Init(TMA_InitTypeDef *TIMA_InitStruct) { CGC_PER1PeriphClockCmd(CGC_PER1Periph_TMA,ENABLE); TMA->TACR0 &= (uint8_t)~0x01; //TMA STOP INTC_DisableIRQ(TMA_IRQn); /* disable INTTMA interrupt */ INTC_ClearPendingIRQ(TMA_IRQn); /* clear INTTMA interrupt flag */ TMA->TAMR0 = TIMA_InitStruct->TMA_Clk | TIMA_InitStruct->TMA_Mode; if(TIMA_InitStruct->TMA_Mode == TMA_Mode_Square) { TMA->TAIOC0 = TIMA_InitStruct->TMA_Polarity | 0x04; //0x00:ban TAO OUTPUT } else if(TIMA_InitStruct->TMA_Mode == TMA_Mode_PluseWidth || TIMA_InitStruct->TMA_Mode == TMA_Mode_PlusePeriod) { if(TIMA_InitStruct->TMA_Pulse ==TMA_Pulse_Width_Low || TIMA_InitStruct->TMA_Pulse ==TMA_Pulse_Rising) TMA->TAIOC0 = TMA_Polarity_0; if(TIMA_InitStruct->TMA_Pulse ==TMA_Pulse_Width_High ||TIMA_InitStruct->TMA_Pulse ==TMA_Pulse_Falling ) TMA->TAIOC0 = TMA_Polarity_1; } else if(TIMA_InitStruct->TMA_Mode == TMA_Mode_EventCount) { assert_param(IS_TMA_EDGE(TIMA_InitStruct->TMA_EventPara.TIMA_Edge)); assert_param(IS_TMA_CTRL(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl)); if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl & 0x000f) { TMA->TAIOC0 = TMA_EVENT_ENABLE_INTP4; } else if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl & 0x0ff0) { TMA->TAIOC0 = TMA_EVENT_ENABLE_TIMEROUTSIGNAL; } else { TMA->TAIOC0 = TMA_EVENT_ENABLE_ALWAYS; } if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl == TMA_INTP4_LOW_LEVEL) { TMA->TAISR0 = TMA_PWM_POLARITY_L; } if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl == TMM_TMIOD1_LOW_LEVEL) { TMA->TAISR0 = TMA_PWM_POLARITY_L | TMA_PWM_TMIOD1; } if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl == TMM_TMIOC1_LOW_LEVEL) { TMA->TAISR0 = TMA_PWM_POLARITY_L | TMA_PWM_TMIOC1; } if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl == TIM_TO02_LOW_LEVEL) { TMA->TAISR0 = TMA_PWM_POLARITY_L | TMA_PWM_TO02; } if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl == TIM_TO03_LOW_LEVEL) { TMA->TAISR0 = TMA_PWM_POLARITY_L | TMA_PWM_TO03; } if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl == TMA_INTP4_HIGH_LEVEL) { TMA->TAISR0 = TMA_PWM_POLARITY_H; } if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl == TMM_TMIOD1_HIGH_LEVEL) { TMA->TAISR0 = TMA_PWM_POLARITY_H | TMA_PWM_TMIOD1; } if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl == TMM_TMIOC1_HIGH_LEVEL) { TMA->TAISR0 = TMA_PWM_POLARITY_H | TMA_PWM_TMIOC1; } if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl == TIM_TO02_HIGH_LEVEL) { TMA->TAISR0 = TMA_PWM_POLARITY_H | TMA_PWM_TO02; } if(TIMA_InitStruct->TMA_EventPara.TMA_Ctrl == TIM_TO03_HIGH_LEVEL) { TMA->TAISR0 = TMA_PWM_POLARITY_H | TMA_PWM_TO03; } if(TIMA_InitStruct->TMA_EventPara.TIMA_Edge == TMA_RISING_EDGE) { TMA->TAMR0 |= TMA_TAIO_POLARITY_ONE; TMA->TAIOC0 |= TMA_Polarity_0; } else if(TIMA_InitStruct->TMA_EventPara.TIMA_Edge == TMA_FALLING_EDGE) { TMA->TAMR0 |= TMA_TAIO_POLARITY_ONE; TMA->TAIOC0 |= TMA_Polarity_1; } else { TMA->TAMR0 |= TMA_TAIO_POLARITY_BOTH; } } if(TIMA_InitStruct->TMA_Clk == TMA_FIL) { CGC->OSMC = 0x10U; /* WUTMMCK0 = 1 */ } TMA->TA0 = TIMA_InitStruct->TMA_Period - 1; } uint32_t TMA_GetPulseWidth(void) { uint32_t width;// period; static uint32_t tempwidth = g_ta0_value, tma_underflow_count=0; while(INTC_GetPendingIRQ(TMA_IRQn) == 0); INTC_ClearPendingIRQ(TMA_IRQn); /* clear INTTMA interrupt flag */ if (TMA_GetStaus(TMA_FLAG_UNDERFLOW)) { TMA->TACR0 &= (uint8_t)~TMA_FLAG_UNDERFLOW; tma_underflow_count += 1U; } if(TMA_GetStaus(TMA_FLAG_ACTIVE_EDGE_RECEIVED)) //active edge ocuurs { TMA->TACR0 &= ~TMA_FLAG_ACTIVE_EDGE_RECEIVED; if (tma_underflow_count == 0U) { width = tempwidth - TMA->TA0; tempwidth = TMA->TA0; } else { width = tempwidth + (0xffff + 1) * tma_underflow_count - TMA->TA0; tempwidth = TMA->TA0; tma_underflow_count = 0; } } return width; } uint32_t TMA_GetPulsePeriod(void) { uint32_t width=0, tmp; static uint32_t tempwidth = g_ta0_value, tma_underflow_count=0; static uint8_t time =0; while(INTC_GetPendingIRQ(TMA_IRQn) == 0); INTC_ClearPendingIRQ(TMA_IRQn); /* clear INTTMA interrupt flag */ if (TMA_GetStaus(TMA_FLAG_UNDERFLOW)) { TMA_ClearFlag(TMA_FLAG_UNDERFLOW); tma_underflow_count += 1U; } if(TMA_GetStaus(TMA_FLAG_ACTIVE_EDGE_RECEIVED)) //active edge ocuurs { time++; TMA_ClearFlag(TMA_FLAG_ACTIVE_EDGE_RECEIVED); if(time == 1) { tmp = TMA->TA0; // dummy read to update readbuf } else { if(tma_underflow_count == 0) { width = tempwidth - TMA->TA0; } else { width = tempwidth - TMA->TA0 + 1U + (tempwidth + 1) * tma_underflow_count; } time = 0; } } return width; }