#include "api_rt_pwm.h" #include "api_rt_dbg.h" #include "board_config.h" #include "gd32f30x.h" #include #include "api_rt_adc.h" ApiRtPwm_Handle Pwms[1]; /* ========================================================================== */ /* ============================ Api RT Functions ============================ */ /* ========================================================================== */ void iRtPwm_Init() { Pwms[0].PwmBase = TIMER0; for (int i = 0; i < 6; i++) { Pwms[0].CompareValues[i] = HW_INIT_HHPWM_PERIOD; Pwms[0].ActiveCompareValues[i] = HW_INIT_HHPWM_PERIOD; } Pwms[0].OutputEnable = 0; #if API_FUNCTION_PWM_SYNC_MULTI_SAMPLING Pwms[0].SyncSamplingEnable = 1; Pwms[0].SyncSamplingUpTickCount = 1; Pwms[0].SyncSamplingUpTick[0] = HW_INIT_HHPWM_PERIOD; Pwms[0].SyncSamplingDownTickCount = 1; Pwms[0].SyncSamplingDownTick[0] = HW_SAMPLE_BEFORE_UPDATE_CNTS; #endif } void iRtPwm_ActivateCompareValues(uint8_t devIndex) { ASSERT_LESS(devIndex, 1); for (int i = 0; i < 6; i++) { Pwms[devIndex].ActiveCompareValues[i] = Pwms[devIndex].CompareValues[i]; } } /* ========================================================================== */ /* ============================== API Functions ============================= */ /* ========================================================================== */ uint32_t iPwm_GetClock(uint8_t devIndex) { return HW_TIM_CLOCK_HZ; } void iPwm_EnableCount(uint8_t devIndex) { uint32_t base = Pwms[devIndex].PwmBase; TIMER_CTL0(base) |= (uint32_t)BIT(0); } void iPwm_DisableCount(uint8_t devIndex) { uint32_t base = Pwms[devIndex].PwmBase; TIMER_CTL0(base) &= ~(uint32_t)BIT(0); } uint32_t iPwm_GetCountMax(uint8_t devIndex) { uint32_t base = Pwms[devIndex].PwmBase; uint32_t count_value = 0U; count_value = TIMER_CAR(base); return count_value; } void iPwm_SetCountMax(uint8_t devIndex, uint32_t countMax) { uint32_t base = Pwms[devIndex].PwmBase; TIMER_CAR(base)= countMax; } uint32_t iPwm_GetCount(uint8_t devIndex) { uint32_t base = Pwms[devIndex].PwmBase; uint32_t count_value = 0U; count_value = TIMER_CNT(base); return count_value; } void iPwm_SetCount(uint8_t devIndex, uint32_t count) { uint32_t base = Pwms[devIndex].PwmBase; TIMER_CNT(base)= count; } ApiPwm_CountMode iPwm_GetCountMode(uint8_t devIndex) { uint32_t base = Pwms[devIndex].PwmBase; ApiPwm_CountMode mode = ApiPwm_CountUp; if ((TIMER_CTL0(base) & (uint16_t)0x0060) == (uint16_t)0x0000) { if ((TIMER_CTL0(base) & (uint16_t)0x0010) != 0) { mode = ApiPwm_CountUp; } #if API_FUNCTION_PWM_COUNTDOWN == SUPPORT else { mode = ApiPwm_CountDown; } #endif } else { mode = ApiPwm_CountUpDown; } return mode; } void iPwm_SetCountMode(uint8_t devIndex, ApiPwm_CountMode mode) { uint32_t base = Pwms[devIndex].PwmBase; switch (mode) { case ApiPwm_CountUp: TIMER_CTL0(base) &= ~((uint16_t)0x0060); TIMER_CTL0(base) &= ~(uint16_t)0x0010; break; #if FUNCTION_PWM_COUNTDOWN == SUPPORT case ApiPwm_CountDown: TIMER_CTL0(base) &= ~((uint16_t)0x0060); TIMER_CTL0(base) |= (uint16_t)0x0010; break; #endif case ApiPwm_CountUpDown: TIMER_CTL0(base) |= ((uint16_t)0x0060); break; default: break; } } ApiPwm_CompareMode iPwm_GetCompareMode(uint8_t devIndex, uint8_t channelIndex) { uint32_t base = Pwms[devIndex].PwmBase; uint8_t conf = 0; switch (channelIndex) { case 0: conf = TIMER_CHCTL0(base) & (uint32_t)0x000000F0UL; break; case 1: conf = (TIMER_CHCTL0(base) & (uint32_t)0x0000F000UL) >> 16; break; case 2: conf = TIMER_CHCTL1(base) & (uint32_t)0x000000F0UL; break; case 3: conf = (TIMER_CHCTL1(base) & (uint32_t)0x0000F000UL) >> 16; break; default: break; } ApiPwm_CompareMode mode = ApiPwm_NoAction; switch (conf >> 4) { case 0x00: mode = ApiPwm_NoAction; break; case 0x01: mode = ApiPwm_UpMatchSet; #if FUNCTION_PWM_COUNTDOWN if (iPwm_GetCountMode(devIndex) == Pwm_CountDown) mode = ApiPwm_DownMatchSet; #endif break; case 0x02: mode = ApiPwm_UpMatchClear; #if FUNCTION_PWM_COUNTDOWN if (iPwm_GetCountMode(devIndex) == Pwm_CountDown) mode = ApiPwm_DownMatchClear; #endif break; case 0x03: mode = ApiPwm_UpMatchToggle; #if FUNCTION_PWM_COUNTDOWN if (iPwm_GetCountMode(devIndex) == Pwm_CountDown) mode = ApiPwm_DownMatchToggle; #endif break; case 0x04: mode = ApiPwm_ForceClear; break; case 0x05: mode = ApiPwm_ForceSet; break; case 0x06: mode = ApiPwm_HigherClear; break; case 0x07: mode = ApiPwm_HigherSet; break; default: mode = ApiPwm_NoAction; break; } return mode; } void iPwm_SetCompareMode(uint8_t devIndex, uint8_t channelIndex, ApiPwm_CompareMode mode) { uint32_t base = Pwms[devIndex].PwmBase; uint8_t conf = 0; switch (mode) { case ApiPwm_NoAction: conf = 0x00; break; case ApiPwm_UpMatchSet: conf = 0x01; break; case ApiPwm_UpMatchClear: conf = 0x02; break; case ApiPwm_UpMatchToggle: conf = 0x03; break; case ApiPwm_ForceClear: conf = 0x04; break; case ApiPwm_ForceSet: conf = 0x05; break; case ApiPwm_HigherClear: conf = 0x06; break; case ApiPwm_HigherSet: conf = 0x07; break; default: break; } #if API_FUNCTION_PWM_COUNTDOWN if (iPwm_GetCountMode(devIndex) == ApiPwm_CountDown) { switch (mode) { case ApiPwm_DownMatchSet: conf = 0x01; break; case ApiPwm_DownMatchClear: conf = 0x02; break; case ApiPwm_DownMatchToggle: conf = 0x03; break; } } #endif switch (channelIndex) { case 0: TIMER_CHCTL0(base) &= ~((uint32_t)0x000000F0UL); TIMER_CHCTL0(base) |= (((uint32_t)conf) << 4); break; case 1: TIMER_CHCTL0(base) &= ~((uint32_t)0x0000F000UL); TIMER_CHCTL0(base) |= (((uint32_t)conf) << (4 + 8)); break; case 2: TIMER_CHCTL0(base) &= ~((uint32_t)0x000000F0UL); TIMER_CHCTL0(base) |= (((uint32_t)conf) << 4); break; case 3: TIMER_CHCTL0(base) &= ~((uint32_t)0x0000F000UL); TIMER_CHCTL0(base) |= (((uint32_t)conf) << (4 + 8)); break; } } uint32_t iPwm_GetCompareValue(uint8_t devIndex, uint8_t channelIndex) { uint32_t base = Pwms[devIndex].PwmBase; uint32_t value = 0; switch (channelIndex) { case 0: value = TIMER_CH0CV(base); break; case 1: value = TIMER_CH1CV(base); break; case 2: value = TIMER_CH2CV(base); break; case 3: value = TIMER_CH3CV(base); break; default: break; } return value; } void iPwm_SetCompareValue(uint8_t devIndex, uint8_t channelIndex, uint32_t value) { ASSERT_LESS(devIndex, 1); ASSERT_LESS(channelIndex, 3); Pwms[devIndex].CompareValues[channelIndex] = value; } void iPwm_SetCompareValueDelay(uint8_t devIndex, uint8_t channelIndex, uint32_t value) { ASSERT_LESS(devIndex, 1); ASSERT_LESS(channelIndex, 3); Pwms[devIndex].CompareValues[channelIndex + 3] = value; } void iPwm_SetCompareGroupValues16(uint8_t devIndex, uint16_t* values) { for (int i = 0; i < 6; i++) { Pwms[devIndex].CompareValues[i] = values[i]; } } void iPwm_SetCompareValueImmediate(uint8_t devIndex, uint8_t channelIndex, uint32_t value) { ASSERT_LESS(devIndex, 1); ASSERT_LESS(channelIndex, 4); uint32_t base = Pwms[devIndex].PwmBase; switch (channelIndex) { case 0: TIMER_CH0CV(base) = value; break; case 1: TIMER_CH1CV(base) = value; break; case 2: TIMER_CH2CV(base) = value; break; case 3: TIMER_CH3CV(base) = value; break; default: break; } } int8_t iPwm_GetEnableState(uint8_t devIndex) { ASSERT_LESS(devIndex, 1); return Pwms[devIndex].OutputEnable; } void iPwm_EnableOutput(uint8_t devIndex) { ASSERT_LESS(devIndex, 1); uint32_t base = Pwms[devIndex].PwmBase; TIMER_CCHP(base) |= (uint32_t)0x00008000UL; Pwms[devIndex].OutputEnable = 1; } void iPwm_DisableOutput(uint8_t devIndex) { ASSERT_LESS(devIndex, 1); uint32_t base = Pwms[devIndex].PwmBase; TIMER_CCHP(base) &= ~((uint32_t)0x00008000UL); Pwms[devIndex].OutputEnable = 0; } // // int8_t Pwm_GetChannelEnableState(uint8_t devIndex, uint8_t channelIndex) // // { // // } // // void Pwm_EnableChannelOutput(uint8_t devIndex, uint8_t channelIndex) // // { // // ASSERT_LESS(devIndex, 1); // // ASSERT_LESS(channelIndex, 4); // // TIM_TypeDef *base = Pwms[devIndex].PwmBase; // // if (channelIndex < 64) // // { // // base->CCER |= ((uint32_t)0x01) << (channelIndex * 4); // // } // // else // // { // // base->CCER |= ((uint32_t)0x04) << ((channelIndex - 64) * 4); // // } // // } // // void Pwm_DisableChannelOutput(uint8_t devIndex, uint8_t channelIndex) // // { // // ASSERT_LESS(devIndex, 1); // // ASSERT_LESS(channelIndex, 4); // // TIM_TypeDef *base = Pwms[devIndex].PwmBase; // // if (channelIndex < 64) // // { // // base->CCER &= ~(((uint32_t)0x01) << (channelIndex * 4)); // // } // // else // // { // // base->CCER &= ~(((uint32_t)0x04) << ((channelIndex - 64) * 4)); // // } // // } //void iPwm_EnableDeviceInterrupt(uint8_t devIndex, ApiPwm_DeviceInterrupt interrupt) //{ // ASSERT_LESS(devIndex, 1); // // switch (interrupt) // { // case ApiPwm_CountZeroInt: // Pwms[devIndex].CountZeroISR.Enable = 1; // break; // case ApiPwm_CountMaxInt: // Pwms[devIndex].CountMaxISR.Enable = 1; // break; // case ApiPwm_BreakInt: // Pwms[devIndex].BreakISR.Enable = 1; // break; // default: // break; // } //} // //void iPwm_DisableDeviceInterrupt(uint8_t devIndex, ApiPwm_DeviceInterrupt interrupt) //{ // ASSERT_LESS(devIndex, 1); // // switch (interrupt) // { // case ApiPwm_CountZeroInt: // Pwms[devIndex].CountZeroISR.Enable = 0; // break; // case ApiPwm_CountMaxInt: // Pwms[devIndex].CountMaxISR.Enable = 0; // break; // case ApiPwm_BreakInt: // Pwms[devIndex].BreakISR.Enable = 0; // break; // default: // break; // } //} // //void iPwm_EnableChannelInterrupt(uint8_t devIndex, uint8_t channelIndex, ApiPwm_ChannelInterrupt interrupt) //{ // ASSERT_LESS(devIndex, 1); // ASSERT_LESS(channelIndex, 4); // // Pwms[devIndex].ChannelISR[channelIndex].Enable = 1; //} // //void iPwm_DisableChannelInterrupt(uint8_t devIndex, uint8_t channelIndex, ApiPwm_ChannelInterrupt interrupt) //{ // ASSERT_LESS(devIndex, 1); // ASSERT_LESS(channelIndex, 4); // // Pwms[devIndex].ChannelISR[channelIndex].Enable = 0; //} // //void iPwm_BindDeviceInterrupt(uint8_t devIndex, ApiPwm_DeviceInterrupt interrupt, void (*action)()) //{ // ASSERT_LESS(devIndex, 1); // // switch (interrupt) // { // case ApiPwm_CountZeroInt: // Pwms[devIndex].CountZeroISR.Action = action; // break; // case ApiPwm_CountMaxInt: // Pwms[devIndex].CountMaxISR.Action = action; // break; // case ApiPwm_BreakInt: // Pwms[devIndex].BreakISR.Action = action; // break; // default: // break; // } //} // //void iPwm_BindChannelInterrupt(uint8_t devIndex, uint8_t channelIndex, ApiPwm_DeviceInterrupt interrupt, void (*action)()) //{ // ASSERT_LESS(devIndex, 1); // ASSERT_LESS(channelIndex, 4); // // Pwms[devIndex].ChannelISR[channelIndex].Action = action; //} // //int8_t iPwm_GetBreakState(uint8_t devIndex) //{ // ASSERT_LESS(devIndex, 1); // // TIM_TypeDef *base = Pwms[devIndex].PwmBase; // // return (base->SR & ((uint32_t)0x00000080UL)) ? 1 : 0; //} // //void iPwm_ClearBreak(uint8_t devIndex) //{ // ASSERT_LESS(devIndex, 1); // // TIM_TypeDef *base = Pwms[devIndex].PwmBase; // // base->SR &= ~((uint32_t)0x00000080UL); //} // #if API_FUNCTION_PWM_SYNC_MULTI_SAMPLING void iPwm_EnableSyncMultiSampling(uint8_t devIndex) { Pwms[devIndex].SyncSamplingEnable = 1; } void iPwm_DisableSyncMultiSampling(uint8_t devIndex) { Pwms[devIndex].SyncSamplingEnable = 0; Pwms[devIndex].SyncSamplingUpTickCount = 1; Pwms[devIndex].SyncSamplingUpTick[0] = TIMER_CAR(Pwms[devIndex].PwmBase)>> 1; Pwms[devIndex].SyncSamplingDownTickCount = 1; Pwms[devIndex].SyncSamplingDownTick[0] = TIMER_CAR(Pwms[devIndex].PwmBase)>> 1; } void iPwm_SyncMultiSamplingCountUp(uint8_t devIndex, uint32_t samplingTicks[], uint8_t samplingCounts) { if (Pwms[devIndex].SyncSamplingEnable == 1) { Pwms[devIndex].SyncSamplingUpTickCount = samplingCounts; for (int i = 0; i < samplingCounts; i++) { Pwms[devIndex].SyncSamplingUpTick[i] = samplingTicks[i]; } } } void iPwm_SyncMultiSamplingCountDown(uint8_t devIndex, uint32_t samplingTicks[], uint8_t samplingCounts) { if (Pwms[devIndex].SyncSamplingEnable == 1) { Pwms[devIndex].SyncSamplingDownTickCount = samplingCounts; for (int i = 0; i < samplingCounts; i++) { Pwms[devIndex].SyncSamplingDownTick[i] = samplingTicks[i]; } } } #endif