123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510 |
- /**************************************************************************//**
- *
- * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2020-5-4 Philo First version
- *
- ******************************************************************************/
- #include <rtconfig.h>
- #if defined(BSP_USING_EPWM_CAPTURE)
- #if ((BSP_USING_EPWM0_CAPTURE_CHMSK+BSP_USING_EPWM1_CAPTURE_CHMSK)!=0)
- #include <rtdevice.h>
- #include "NuMicro.h"
- #define EPWM_CH0CH1_POS (0)
- #define EPWM_CH2CH3_POS (2)
- #define EPWM_CH4CH5_POS (4)
- /* Private typedef --------------------------------------------------------------*/
- typedef struct nu_capture
- {
- struct rt_inputcapture_device parent;
- EPWM_T *epwm;
- uint8_t u8Channel;
- IRQn_Type irq;
- uint32_t u32CurrentRisingCnt;
- uint32_t u32CurrentFallingCnt;
- rt_bool_t input_data_level;
- } nu_capture_t;
- /* Private functions ------------------------------------------------------------*/
- static rt_err_t nu_capture_init(struct rt_inputcapture_device *inputcapture);
- static rt_err_t nu_capture_open(struct rt_inputcapture_device *inputcapture);
- static rt_err_t nu_capture_close(struct rt_inputcapture_device *inputcapture);
- static rt_err_t nu_capture_get_pulsewidth(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us);
- /* Public functions -------------------------------------------------------------*/
- /* Private variables ------------------------------------------------------------*/
- #if (BSP_USING_EPWM0_CAPTURE_CHMSK!=0)
- static const char *nu_epwm0_device_name[EPWM_CHANNEL_NUM] = { "epwm0i0", "epwm0i1", "epwm0i2", "epwm0i3", "epwm0i4", "epwm0i5"};
- static const IRQn_Type nu_epwm0_irq[EPWM_CHANNEL_NUM / 2] = { EPWM0P0_IRQn, EPWM0P1_IRQn, EPWM0P2_IRQn};
- static nu_capture_t nu_epwm0_capture[EPWM_CHANNEL_NUM] = {0};
- #endif
- #if (BSP_USING_EPWM1_CAPTURE_CHMSK!=0)
- static const char *nu_epwm1_device_name[EPWM_CHANNEL_NUM] = {"epwm1i0", "epwm1i1", "epwm1i2", "epwm1i3", "epwm1i4", "epwm1i5", };
- static const IRQn_Type nu_epwm1_irq[EPWM_CHANNEL_NUM / 2] = {EPWM1P0_IRQn, EPWM1P1_IRQn, EPWM1P2_IRQn };
- static nu_capture_t nu_epwm1_capture[EPWM_CHANNEL_NUM] = {0};
- #endif
- static struct rt_inputcapture_ops nu_capture_ops =
- {
- .init = nu_capture_init,
- .open = nu_capture_open,
- .close = nu_capture_close,
- .get_pulsewidth = nu_capture_get_pulsewidth,
- };
- /* Functions define ------------------------------------------------------------*/
- static rt_err_t CalPulseWidth(nu_capture_t *nu_capture)
- {
- rt_bool_t bWrapAroundFlag = RT_FALSE;
- /* Check rising/falling capture counter is overflow or not */
- if (EPWM_GetWrapAroundFlag(nu_capture->epwm, nu_capture->u8Channel))
- {
- EPWM_ClearWrapAroundFlag(nu_capture->epwm, nu_capture->u8Channel);
- bWrapAroundFlag = RT_TRUE;
- }
- /* Read the capture counter value if falling/rising edge */
- if (EPWM_GetCaptureIntFlag(nu_capture->epwm, nu_capture->u8Channel) == 1)//Rising edge
- {
- EPWM_ClearCaptureIntFlag(nu_capture->epwm, nu_capture->u8Channel, EPWM_CAPTURE_INT_RISING_LATCH);
- if (bWrapAroundFlag)
- {
- nu_capture->u32CurrentRisingCnt = 0x10000;
- }
- nu_capture->u32CurrentRisingCnt += EPWM_GET_CAPTURE_RISING_DATA(nu_capture->epwm, nu_capture->u8Channel);
- }
- else if (EPWM_GetCaptureIntFlag(nu_capture->epwm, nu_capture->u8Channel) == 2)//Falling edge
- {
- EPWM_ClearCaptureIntFlag(nu_capture->epwm, nu_capture->u8Channel, EPWM_CAPTURE_INT_FALLING_LATCH);
- if (bWrapAroundFlag)
- {
- nu_capture->u32CurrentFallingCnt = 0x10000;
- }
- nu_capture->u32CurrentFallingCnt += EPWM_GET_CAPTURE_FALLING_DATA(nu_capture->epwm, nu_capture->u8Channel);
- }
- else
- {
- EPWM_ClearCaptureIntFlag(nu_capture->epwm, nu_capture->u8Channel, EPWM_CAPTURE_INT_RISING_LATCH);
- EPWM_ClearCaptureIntFlag(nu_capture->epwm, nu_capture->u8Channel, EPWM_CAPTURE_INT_FALLING_LATCH);
- return -(RT_ERROR);
- }
- return RT_EOK;
- }
- #if (BSP_USING_EPWM0_CAPTURE_CHMSK&(0x3<<EPWM_CH0CH1_POS))
- void EPWM0P0_IRQHandler(void)
- {
- /* enter interrupt */
- rt_interrupt_enter();
- /* Avoid excessive iteration by monitoring enabled channels */
- #if (BSP_USING_EPWM0_CAPTURE_CHMSK&(0x1<<EPWM_CH0CH1_POS))
- uint8_t const start = 0 + EPWM_CH0CH1_POS;
- #else /* Only channel 1 */
- uint8_t const start = 1 + EPWM_CH0CH1_POS;
- #endif
- #if (BSP_USING_EPWM0_CAPTURE_CHMSK&(0x2<<EPWM_CH0CH1_POS))
- uint8_t const end = 2 + EPWM_CH0CH1_POS;
- #else /* Only channel 0 */
- uint8_t const end = 1 + EPWM_CH0CH1_POS;
- #endif
- /* 2 channel using same irq */
- for (uint8_t i = start; i < end ; i++)
- {
- if (EPWM_GetCaptureIntFlag(nu_epwm0_capture[i].epwm, nu_epwm0_capture[i].u8Channel) != 0)
- {
- /* Calculate pulse width */
- if (CalPulseWidth(&nu_epwm0_capture[i]) == RT_EOK)
- {
- rt_hw_inputcapture_isr(&nu_epwm0_capture[i].parent, nu_epwm0_capture[i].input_data_level);
- }
- }
- }
- /* leave interrupt */
- rt_interrupt_leave();
- }
- #endif
- #if (BSP_USING_EPWM0_CAPTURE_CHMSK&(0x3<<EPWM_CH2CH3_POS))
- void EPWM0P1_IRQHandler(void)
- {
- /* enter interrupt */
- rt_interrupt_enter();
- /* Avoid excessive iteration by monitoring enabled channels */
- #if (BSP_USING_EPWM0_CAPTURE_CHMSK&(0x1<<EPWM_CH2CH3_POS))
- uint8_t const start = 0 + EPWM_CH2CH3_POS;
- #else /* Only channel 3 */
- uint8_t const start = 1 + EPWM_CH2CH3_POS;
- #endif
- #if (BSP_USING_EPWM0_CAPTURE_CHMSK&(0x2<<EPWM_CH2CH3_POS))
- uint8_t const end = 2 + EPWM_CH2CH3_POS;
- #else /* Only channel 2 */
- uint8_t const end = 1 + EPWM_CH2CH3_POS;
- #endif
- /* 2 channel using same irq */
- for (uint8_t i = start; i < end ; i++)
- {
- if (EPWM_GetCaptureIntFlag(nu_epwm0_capture[i].epwm, nu_epwm0_capture[i].u8Channel) != 0)
- {
- /* Calculate pulse width */
- if (CalPulseWidth(&nu_epwm0_capture[i]) == RT_EOK)
- {
- rt_hw_inputcapture_isr(&nu_epwm0_capture[i].parent, nu_epwm0_capture[i].input_data_level);
- }
- }
- }
- /* leave interrupt */
- rt_interrupt_leave();
- }
- #endif
- #if (BSP_USING_EPWM0_CAPTURE_CHMSK&(0x3<<EPWM_CH4CH5_POS))
- void EPWM0P2_IRQHandler(void)
- {
- /* enter interrupt */
- rt_interrupt_enter();
- /* Avoid excessive iteration by monitoring enabled channels */
- #if (BSP_USING_EPWM0_CAPTURE_CHMSK&(0x1<<EPWM_CH4CH5_POS))
- uint8_t const start = 0 + EPWM_CH4CH5_POS;
- #else /* Only channel 5 */
- uint8_t const start = 1 + EPWM_CH4CH5_POS;
- #endif
- #if (BSP_USING_EPWM0_CAPTURE_CHMSK&(0x2<<EPWM_CH4CH5_POS))
- uint8_t const end = 2 + EPWM_CH4CH5_POS;
- #else /* Only channel 4 */
- uint8_t const end = 1 + EPWM_CH4CH5_POS;
- #endif
- /* 2 channel using same irq */
- for (uint8_t i = start; i < end ; i++)
- {
- if (EPWM_GetCaptureIntFlag(nu_epwm0_capture[i].epwm, nu_epwm0_capture[i].u8Channel) != 0)
- {
- /* Calculate pulse width */
- if (CalPulseWidth(&nu_epwm0_capture[i]) == RT_EOK)
- {
- rt_hw_inputcapture_isr(&nu_epwm0_capture[i].parent, nu_epwm0_capture[i].input_data_level);
- }
- }
- }
- /* leave interrupt */
- rt_interrupt_leave();
- }
- #endif
- #if (BSP_USING_EPWM1_CAPTURE_CHMSK&(0x3<<EPWM_CH0CH1_POS))
- void EPWM1P0_IRQHandler(void)
- {
- /* enter interrupt */
- rt_interrupt_enter();
- /* Avoid excessive iteration by monitoring enabled channels */
- #if (BSP_USING_EPWM1_CAPTURE_CHMSK&(0x1<<EPWM_CH0CH1_POS))
- uint8_t const start = 0 + EPWM_CH0CH1_POS;
- #else /* Only channel 1 */
- uint8_t const start = 1 + EPWM_CH0CH1_POS;
- #endif
- #if (BSP_USING_EPWM1_CAPTURE_CHMSK&(0x2<<EPWM_CH0CH1_POS))
- uint8_t const end = 2 + EPWM_CH0CH1_POS;
- #else /* Only channel 0 */
- uint8_t const end = 1 + EPWM_CH0CH1_POS;
- #endif
- /* 2 channel using same irq */
- for (uint8_t i = start; i < end ; i++)
- {
- if (EPWM_GetCaptureIntFlag(nu_epwm1_capture[i].epwm, nu_epwm1_capture[i].u8Channel) != 0)
- {
- /* Calculate pulse width */
- if (CalPulseWidth(&nu_epwm1_capture[i]) == RT_EOK)
- {
- rt_hw_inputcapture_isr(&nu_epwm1_capture[i].parent, nu_epwm1_capture[i].input_data_level);
- }
- }
- }
- /* leave interrupt */
- rt_interrupt_leave();
- }
- #endif
- #if (BSP_USING_EPWM1_CAPTURE_CHMSK&(0x3<<EPWM_CH2CH3_POS))
- void EPWM1P1_IRQHandler(void)
- {
- /* enter interrupt */
- rt_interrupt_enter();
- /* Avoid excessive iteration by monitoring enabled channels */
- #if (BSP_USING_EPWM1_CAPTURE_CHMSK&(0x1<<EPWM_CH2CH3_POS))
- uint8_t const start = 0 + EPWM_CH2CH3_POS;
- #else /* Only channel 3 */
- uint8_t const start = 1 + EPWM_CH2CH3_POS;
- #endif
- #if (BSP_USING_EPWM1_CAPTURE_CHMSK&(0x2<<EPWM_CH2CH3_POS))
- uint8_t const end = 2 + EPWM_CH2CH3_POS;
- #else /* Only channel 2 */
- uint8_t const end = 1 + EPWM_CH2CH3_POS;
- #endif
- /* 2 channel using same irq */
- for (uint8_t i = start; i < end ; i++)
- {
- if (EPWM_GetCaptureIntFlag(nu_epwm1_capture[i].epwm, nu_epwm1_capture[i].u8Channel) != 0)
- {
- /* Calculate pulse width */
- if (CalPulseWidth(&nu_epwm1_capture[i]) == RT_EOK)
- {
- rt_hw_inputcapture_isr(&nu_epwm1_capture[i].parent, nu_epwm1_capture[i].input_data_level);
- }
- }
- }
- /* leave interrupt */
- rt_interrupt_leave();
- }
- #endif
- #if (BSP_USING_EPWM1_CAPTURE_CHMSK&(0x3<<EPWM_CH4CH5_POS))
- void EPWM1P2_IRQHandler(void)
- {
- /* enter interrupt */
- rt_interrupt_enter();
- /* Avoid excessive iteration by monitoring enabled channels */
- #if (BSP_USING_EPWM1_CAPTURE_CHMSK&(0x1<<EPWM_CH4CH5_POS))
- uint8_t const start = 0 + EPWM_CH4CH5_POS;
- #else /* Only channel 5 */
- uint8_t const start = 1 + EPWM_CH4CH5_POS;
- #endif
- #if (BSP_USING_EPWM1_CAPTURE_CHMSK&(0x2<<EPWM_CH4CH5_POS))
- uint8_t const end = 2 + EPWM_CH4CH5_POS;
- #else /* Only channel 4 */
- uint8_t const end = 1 + EPWM_CH4CH5_POS;
- #endif
- /* 2 channel using same irq */
- for (uint8_t i = start; i < end ; i++)
- {
- if (EPWM_GetCaptureIntFlag(nu_epwm1_capture[i].epwm, nu_epwm1_capture[i].u8Channel) != 0)
- {
- /* Calculate pulse width */
- if (CalPulseWidth(&nu_epwm1_capture[i]) == RT_EOK)
- {
- rt_hw_inputcapture_isr(&nu_epwm1_capture[i].parent, nu_epwm1_capture[i].input_data_level);
- }
- }
- }
- /* leave interrupt */
- rt_interrupt_leave();
- }
- #endif
- static rt_err_t nu_capture_get_pulsewidth(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us)
- {
- rt_err_t ret = RT_EOK;
- nu_capture_t *nu_capture;
- nu_capture = (nu_capture_t *)inputcapture;
- if (nu_capture->u32CurrentFallingCnt)
- {
- *pulsewidth_us = nu_capture->u32CurrentFallingCnt;
- nu_capture->input_data_level = RT_FALSE;
- nu_capture->u32CurrentFallingCnt = 0;
- }
- else if (nu_capture->u32CurrentRisingCnt)
- {
- *pulsewidth_us = nu_capture->u32CurrentRisingCnt;
- nu_capture->input_data_level = RT_TRUE;
- nu_capture->u32CurrentRisingCnt = 0;
- }
- else
- {
- ret = RT_ERROR;
- }
- return -(ret);
- }
- static rt_err_t nu_epwm_init(nu_capture_t *nu_capture)
- {
- rt_err_t ret = RT_ERROR;
- static rt_bool_t bEPWM0Inited = RT_FALSE;
- static rt_bool_t bEPWM1Inited = RT_FALSE;
- if (nu_capture->epwm == EPWM0)
- {
- if (bEPWM0Inited == RT_FALSE)
- {
- /* Enable EPWM0 clock */
- SYS_UnlockReg();
- CLK_EnableModuleClock(EPWM0_MODULE);
- CLK_SetModuleClock(EPWM0_MODULE, CLK_CLKSEL2_EPWM0SEL_PLL, 0);
- SYS_LockReg();
- bEPWM0Inited = RT_TRUE;
- }
- ret = RT_EOK;
- }
- else if (nu_capture->epwm == EPWM1)
- {
- if (bEPWM1Inited == RT_FALSE)
- {
- /* Enable EPWM1 clock */
- SYS_UnlockReg();
- CLK_EnableModuleClock(EPWM1_MODULE);
- CLK_SetModuleClock(EPWM1_MODULE, CLK_CLKSEL2_EPWM1SEL_PLL, 0);
- SYS_LockReg();
- bEPWM1Inited = RT_TRUE;
- }
- ret = RT_EOK;
- }
- return -(ret);
- }
- static rt_err_t nu_capture_init(struct rt_inputcapture_device *inputcapture)
- {
- rt_err_t ret = RT_EOK;
- nu_capture_t *nu_capture;
- RT_ASSERT(inputcapture != RT_NULL);
- nu_capture = (nu_capture_t *) inputcapture;
- if (nu_epwm_init(nu_capture) != RT_EOK)
- {
- rt_kprintf("Failed to initialize EPWM%d.\n", nu_capture->epwm);
- ret = RT_ERROR;
- }
- return -(ret);
- }
- static rt_err_t nu_capture_open(struct rt_inputcapture_device *inputcapture)
- {
- rt_err_t ret = RT_EOK;
- nu_capture_t *nu_capture;
- RT_ASSERT(inputcapture != RT_NULL);
- nu_capture = (nu_capture_t *) inputcapture;
- /* Set capture time as 1000 nanosecond */
- EPWM_ConfigCaptureChannel(nu_capture->epwm, nu_capture->u8Channel, 1000, 0);
- /* Enable capture rising/falling edge interrupt */
- EPWM_EnableCaptureInt(nu_capture->epwm, nu_capture->u8Channel, EPWM_CAPTURE_INT_FALLING_LATCH | EPWM_CAPTURE_INT_RISING_LATCH);
- /* Enable EPWM NVIC interrupt */
- NVIC_EnableIRQ(nu_capture->irq);
- /* Enable Capture Function for EPWM */
- EPWM_EnableCapture(nu_capture->epwm, 0x1 << nu_capture->u8Channel);
- /* Enable rising/falling capture reload */
- nu_capture->epwm->CAPCTL |= (0x1 << (EPWM_CAPCTL_RCRLDEN0_Pos + nu_capture->u8Channel))
- | (0x1 << (EPWM_CAPCTL_FCRLDEN0_Pos + nu_capture->u8Channel));
- /* Set counter type as down count */
- EPWM_SET_ALIGNED_TYPE(nu_capture->epwm, 0x1 << nu_capture->u8Channel, EPWM_UP_COUNTER);
- /* Enable EPWM Timer */
- EPWM_Start(nu_capture->epwm, 0x1 << nu_capture->u8Channel);
- return ret;
- }
- static rt_err_t nu_capture_close(struct rt_inputcapture_device *inputcapture)
- {
- rt_err_t ret = RT_EOK;
- nu_capture_t *nu_capture;
- RT_ASSERT(inputcapture != RT_NULL);
- nu_capture = (nu_capture_t *) inputcapture;
- /* Disable capture rising/falling edge interrupt */
- EPWM_DisableCaptureInt(nu_capture->epwm, nu_capture->u8Channel, EPWM_CAPTURE_INT_FALLING_LATCH | EPWM_CAPTURE_INT_RISING_LATCH);
- /* Disable EPWM NVIC interrupt */
- NVIC_DisableIRQ(nu_capture->irq);
- /* Enable EPWM Timer */
- EPWM_Stop(nu_capture->epwm, 0x1 << nu_capture->u8Channel);
- return ret;
- }
- /* Init and register epwm capture */
- int nu_epwm_capture_device_init(void)
- {
- /* Init EPWM0 6 channel and EPWM1 6 channel */
- #if (BSP_USING_EPWM0_CAPTURE_CHMSK!=0)
- for (int i = 0; i < EPWM_CHANNEL_NUM; i++)
- {
- if (BSP_USING_EPWM0_CAPTURE_CHMSK & (0x1 << i))
- {
- nu_epwm0_capture[i].epwm = EPWM0;
- nu_epwm0_capture[i].u8Channel = i;
- nu_epwm0_capture[i].irq = nu_epwm0_irq[i / 2];
- nu_epwm0_capture[i].u32CurrentRisingCnt = 0;
- nu_epwm0_capture[i].u32CurrentFallingCnt = 0;
- nu_epwm0_capture[i].parent.ops = &nu_capture_ops;
- /* register inputcapture device */
- rt_device_inputcapture_register(&nu_epwm0_capture[i].parent, nu_epwm0_device_name[i], &nu_epwm0_capture[i]);
- }
- }
- #endif //#if (BSP_USING_EPWM0_CAPTURE_CHMSK!=0)
- #if (BSP_USING_EPWM1_CAPTURE_CHMSK!=0)
- for (int i = 0; i < EPWM_CHANNEL_NUM; i++)
- {
- if (BSP_USING_EPWM1_CAPTURE_CHMSK & (0x1 << i))
- {
- nu_epwm1_capture[i].epwm = EPWM1;
- nu_epwm1_capture[i].u8Channel = i;
- nu_epwm1_capture[i].irq = nu_epwm1_irq[i / 2];
- nu_epwm1_capture[i].u32CurrentRisingCnt = 0;
- nu_epwm1_capture[i].u32CurrentFallingCnt = 0;
- nu_epwm1_capture[i].parent.ops = &nu_capture_ops;
- /* register inputcapture device */
- rt_device_inputcapture_register(&nu_epwm1_capture[i].parent, nu_epwm1_device_name[i], &nu_epwm1_capture[i]);
- }
- }
- #endif //#if (BSP_USING_EPWM1_CAPTURE_CHMSK!=0)
- return 0;
- }
- INIT_DEVICE_EXPORT(nu_epwm_capture_device_init);
- #endif //#if ((BSP_USING_EPWM0_CAPTURE_CHMSK+BSP_USING_EPWM1_CAPTURE_CHMSK)!=0)
- #endif //#if defined(BSP_USING_EPWM_CAPTURE)
|