adriendesp commented on code in PR #12679:
URL: https://github.com/apache/nuttx/pull/12679#discussion_r1677508808


##########
arch/arm/src/xmc4/xmc4_pwm.c:
##########
@@ -0,0 +1,1364 @@
+/*****************************************************************************
+ * arch/arm/src/xmc4/xmc4_pwm.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Included Files
+ *****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "arm_internal.h"
+#include "chip.h"
+#include "xmc4_pwm.h"
+#include "xmc4_gpio.h"
+#include "xmc4_clockconfig.h"
+#include "hardware/xmc4_ccu4.h"
+#include "hardware/xmc4_scu.h"
+#include "hardware/xmc4_pinmux.h"
+
+/*****************************************************************************
+ * Pre-processor Definitions
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Private Types
+ *****************************************************************************/
+
+/* This structure represents the state of one PWM timer */
+
+struct xmc4_pwm_s
+{
+  const struct pwm_ops_s *ops; /* PWM operations */
+  uint8_t module;              /* CCU4x Module number {0,...,4} */
+  uint8_t slice;               /* CC4y Slice number {0,...,4} */
+  uint8_t prescaler;           /* Clock division for f_tclk */
+  uint32_t frequency;          /* Current frequency setting */
+  ub16_t duty;                 /* Current duty setting */
+  uint32_t base;               /* The base address of the CCU4x module */
+  uint32_t f_tclk;             /* The frequency of the module clock */
+  uint32_t outgpio;            /* The output pin config (set in board.h) */
+};
+
+/*****************************************************************************
+ * Private Function Prototypes
+ *****************************************************************************/
+
+/* PWM Register access */
+
+static inline void xmc4_pwm_putreg32(struct xmc4_pwm_s *priv,
+                                     uint32_t offset,
+                                     uint32_t value);
+static inline uint32_t xmc4_pwm_getreg32(struct xmc4_pwm_s *priv,
+                                         uint32_t offset);
+static void xmc4_pwm_modifyreg32(struct xmc4_pwm_s *priv,
+                                 uint32_t offset,
+                                 uint32_t clearbits,
+                                 uint32_t setbits);
+
+/* PWM driver methods */
+
+static int pwm_setup(struct pwm_lowerhalf_s *dev);
+static int pwm_shutdown(struct pwm_lowerhalf_s *dev);
+static int pwm_start(struct pwm_lowerhalf_s *dev,
+                     const struct pwm_info_s *info);
+static int pwm_stop(struct pwm_lowerhalf_s *dev);
+static int pwm_ioctl(struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg);
+
+/* PWM helper method */
+
+static int pwm_set_period_match(struct xmc4_pwm_s *priv, uint16_t period_val);
+static int pwm_set_compare_match(struct xmc4_pwm_s *priv,
+                                 uint16_t compare_val);
+static int pwm_set_passive_level(struct xmc4_pwm_s *priv, uint8_t level);
+static int pwm_shadow_transfert(struct xmc4_pwm_s *priv);
+static int pwm_enable_slice_clock(struct xmc4_pwm_s *priv);
+static int pwm_disable_slice_clock(struct xmc4_pwm_s *priv);
+static int pwm_start_slice_timer(struct xmc4_pwm_s *priv);
+static int pwm_stop_slice_timer(struct xmc4_pwm_s *priv);
+static bool pwm_is_slice_timer_running(struct xmc4_pwm_s *priv);
+static int pwm_set_slice_prescaler(struct xmc4_pwm_s *priv,
+                                   uint8_t prescaler);
+static int pwm_start_module_prescaler(struct xmc4_pwm_s *priv);
+static int pwm_stop_module_prescaler(struct xmc4_pwm_s *priv);
+static int pwm_enable_module(struct xmc4_pwm_s *priv);
+static int pwm_disable_module(struct xmc4_pwm_s *priv);
+static bool pwm_is_module_used(struct xmc4_pwm_s *priv);
+static int pwm_get_config(struct xmc4_pwm_s *priv,
+                          const struct pwm_info_s *info,
+                          uint8_t *prescaler,
+                          uint16_t *period,
+                          uint16_t *compare);
+static int pwm_timer(struct xmc4_pwm_s *priv, const struct pwm_info_s *info);
+
+/*****************************************************************************
+ * Private Data
+ *****************************************************************************/
+
+static const struct pwm_ops_s g_pwmops =
+    {
+        .setup = pwm_setup,
+        .shutdown = pwm_shutdown,
+        .start = pwm_start,
+        .stop = pwm_stop,
+        .ioctl = pwm_ioctl,
+};
+
+#ifdef CONFIG_XMC4_CCU40
+#ifdef CONFIG_XMC4_CCU40_CC40
+static struct xmc4_pwm_s g_pwm00 =
+    {
+        .ops = &g_pwmops,
+        .module = 0,
+        .slice = 0,
+        .base = XMC4_CCU40_BASE,
+        .outgpio = GPIO_CCU40_OUT0,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU40_CC41
+static struct xmc4_pwm_s g_pwm01 =
+    {
+        .ops = &g_pwmops,
+        .module = 0,
+        .slice = 1,
+        .base = XMC4_CCU40_BASE,
+        .outgpio = GPIO_CCU40_OUT1,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU40_CC42
+static struct xmc4_pwm_s g_pwm02 =
+    {
+        .ops = &g_pwmops,
+        .module = 0,
+        .slice = 2,
+        .base = XMC4_CCU40_BASE,
+        .outgpio = GPIO_CCU40_OUT2,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU40_CC43
+static struct xmc4_pwm_s g_pwm03 =
+    {
+        .ops = &g_pwmops,
+        .module = 0,
+        .slice = 3,
+        .base = XMC4_CCU40_BASE,
+        .outgpio = GPIO_CCU40_OUT3,
+};
+#endif
+#endif /* CONFIG_XMC4_CCU40 */
+
+#ifdef CONFIG_XMC4_CCU41
+#ifdef CONFIG_XMC4_CCU41_CC40
+static struct xmc4_pwm_s g_pwm10 =
+    {
+        .ops = &g_pwmops,
+        .module = 1,
+        .slice = 0,
+        .base = XMC4_CCU41_BASE,
+        .outgpio = GPIO_CCU41_OUT0,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU41_CC41
+static struct xmc4_pwm_s g_pwm11 =
+    {
+        .ops = &g_pwmops,
+        .module = 1,
+        .slice = 1,
+        .base = XMC4_CCU41_BASE,
+        .outgpio = GPIO_CCU41_OUT1,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU41_CC42
+static struct xmc4_pwm_s g_pwm12 =
+    {
+        .ops = &g_pwmops,
+        .module = 1,
+        .slice = 2,
+        .base = XMC4_CCU41_BASE,
+        .outgpio = GPIO_CCU41_OUT2,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU41_CC43
+static struct xmc4_pwm_s g_pwm13 =
+    {
+        .ops = &g_pwmops,
+        .module = 1,
+        .slice = 3,
+        .base = XMC4_CCU41_BASE,
+        .outgpio = GPIO_CCU41_OUT3,
+};
+#endif
+#endif /* CONFIG_XMC4_CCU41 */
+
+#ifdef CONFIG_XMC4_CCU42
+#ifdef CONFIG_XMC4_CCU42_CC40
+static struct xmc4_pwm_s g_pwm20 =
+    {
+        .ops = &g_pwmops,
+        .module = 2,
+        .slice = 0,
+        .base = XMC4_CCU42_BASE,
+        .outgpio = GPIO_CCU42_OUT0,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU42_CC41
+static struct xmc4_pwm_s g_pwm21 =
+    {
+        .ops = &g_pwmops,
+        .module = 2,
+        .slice = 1,
+        .base = XMC4_CCU42_BASE,
+        .outgpio = GPIO_CCU42_OUT1,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU42_CC42
+static struct xmc4_pwm_s g_pwm22 =
+    {
+        .ops = &g_pwmops,
+        .module = 2,
+        .slice = 2,
+        .base = XMC4_CCU42_BASE,
+        .outgpio = GPIO_CCU42_OUT2,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU42_CC43
+static struct xmc4_pwm_s g_pwm23 =
+    {
+        .ops = &g_pwmops,
+        .module = 2,
+        .slice = 3,
+        .base = XMC4_CCU42_BASE,
+        .outgpio = GPIO_CCU42_OUT3,
+};
+#endif
+#endif /* CONFIG_XMC4_CCU42 */
+
+#ifdef CONFIG_XMC4_CCU43
+#ifdef CONFIG_XMC4_CCU43_CC40
+static struct xmc4_pwm_s g_pwm30 =
+    {
+        .ops = &g_pwmops,
+        .module = 3,
+        .slice = 0,
+        .base = XMC4_CCU43_BASE,
+        .outgpio = GPIO_CCU43_OUT0,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU43_CC41
+static struct xmc4_pwm_s g_pwm31 =
+    {
+        .ops = &g_pwmops,
+        .module = 3,
+        .slice = 1,
+        .base = XMC4_CCU43_BASE,
+        .outgpio = GPIO_CCU43_OUT1,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU43_CC42
+static struct xmc4_pwm_s g_pwm32 =
+    {
+        .ops = &g_pwmops,
+        .module = 3,
+        .slice = 2,
+        .base = XMC4_CCU43_BASE,
+        .outgpio = GPIO_CCU43_OUT2,
+};
+#endif
+
+#ifdef CONFIG_XMC4_CCU43_CC43
+static struct xmc4_pwm_s g_pwm33 =
+    {
+        .ops = &g_pwmops,
+        .module = 3,
+        .slice = 3,
+        .base = XMC4_CCU43_BASE,
+        .outgpio = GPIO_CCU43_OUT3,
+};
+#endif
+#endif /* CONFIG_XMC4_CCU43 */
+
+/*****************************************************************************
+ * Private Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Name: xmc4_pwm_putreg32
+ *
+ * Description:
+ *   Put a 32-bit register value by offset
+ *
+ *****************************************************************************/
+
+static inline void xmc4_pwm_putreg32(struct xmc4_pwm_s *priv,
+                                     uint32_t offset,
+                                     uint32_t value)
+{
+  putreg32(value, priv->base + offset);
+}
+
+/*****************************************************************************
+ * Name: xmc4_pwm_getreg32
+ *
+ * Description:
+ *   Get a 32-bit register value by offset
+ *
+ *****************************************************************************/
+
+static inline uint32_t xmc4_pwm_getreg32(struct xmc4_pwm_s *priv,
+                                         uint32_t offset)
+{
+  return getreg32(priv->base + offset);
+}
+
+/*****************************************************************************
+ * Name: xmc4_pwm_modifyreg32
+ *
+ * Description:
+ *   Modify a 32-bit register value by offset
+ *
+ *****************************************************************************/
+
+static void xmc4_pwm_modifyreg32(struct xmc4_pwm_s *priv,
+                                 uint32_t offset,
+                                 uint32_t clearbits,
+                                 uint32_t setbits)
+{
+  modifyreg32(priv->base + offset, clearbits, setbits);
+}
+
+/*****************************************************************************
+ * Name: pwm_set_period_match
+ *
+ * Description:
+ *   Set the period match register (CC4yPRS.PRS).
+ *   Must call pwm_shadow_transfert() after.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_set_period_match(struct xmc4_pwm_s *priv, uint16_t period_val)
+{
+  DEBUGASSERT(priv != NULL);
+
+  uint32_t cc4yprs_offset =
+      (uint32_t)(XMC4_CCU4_CC40PRS_OFFSET + 0x0100 * priv->slice);
+
+  xmc4_pwm_putreg32(priv, cc4yprs_offset, period_val);
+
+  pwminfo("PWM CCU4%d,CC4%d period is : %" PRId16 "\n",
+          priv->module, priv->slice, period_val);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_set_compare_match
+ *
+ * Description:
+ *   Set the comapre match register (CC4yCRS.CRS).
+ *   Must call pwm_shadow_transfert() after.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_set_compare_match(struct xmc4_pwm_s *priv,
+                                  uint16_t compare_val)
+{
+  DEBUGASSERT(priv != NULL);
+
+  uint32_t cc4ycrs_offset =
+      (uint32_t)(XMC4_CCU4_CC40CRS_OFFSET + 0x0100 * priv->slice);
+
+  xmc4_pwm_putreg32(priv, cc4ycrs_offset, compare_val);
+
+  pwminfo("PWM CCU4%d,CC4%d compare is : %" PRId16 "\n",
+          priv->module, priv->slice, compare_val);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_set_passive_level
+ *
+ * Description:
+ *   Set the passive level of the PWM slice.
+ *   Must call pwm_shadow_transfert() after.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_set_passive_level(struct xmc4_pwm_s *priv, uint8_t level)
+{
+  DEBUGASSERT(priv != NULL);
+
+  uint32_t passive_level = (uint32_t)(level == 1);
+
+  uint32_t cc4ypsl_offset =
+      (uint32_t)(XMC4_CCU4_CC40PSL_OFFSET + 0x0100 * priv->slice);
+
+  xmc4_pwm_putreg32(priv, cc4ypsl_offset, passive_level);
+
+  pwminfo("PWM CCU4%d,CC4%d passive level is : %" PRId8 "\n",
+          priv->module, priv->slice, passive_level);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_shadow_transfert
+ *
+ * Description:
+ *   Enable the transfert of the CRS, PRS and PSL registers for the next
+ *   period. Must be called if one of these register is changed.
+ *   Must call pwm_shadow_transfert() after.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_shadow_transfert(struct xmc4_pwm_s *priv)
+{
+  DEBUGASSERT(priv != NULL);
+
+  uint32_t shadow_transfert_mask = 1 << (priv->slice * 4);
+
+  xmc4_pwm_modifyreg32(priv, XMC4_CCU4_GCSS_OFFSET, 0,
+                       shadow_transfert_mask);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_enable_slice_clock
+ *
+ * Description:
+ *   Enable the prescaller clock for the given slice.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_enable_slice_clock(struct xmc4_pwm_s *priv)
+{
+  DEBUGASSERT(priv != NULL);
+
+  uint32_t mask = (1 << priv->slice);
+
+  xmc4_pwm_modifyreg32(priv, XMC4_CCU4_GIDLC_OFFSET, 0, mask);
+
+  pwminfo("PWM CCU4%d,CC4%d clock is enabled.\n", priv->module, priv->slice);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_disable_slice_clock
+ *
+ * Description:
+ *   Disable the prescaller clock for the given slice.
+ *
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_disable_slice_clock(struct xmc4_pwm_s *priv)
+{
+  DEBUGASSERT(priv != NULL);
+
+  uint32_t mask = (1 << priv->slice);
+
+  xmc4_pwm_modifyreg32(priv, XMC4_CCU4_GIDLS_OFFSET, 0, mask);
+
+  pwminfo("PWM CCU4%d,CC4%d clock is disabled.\n",
+          priv->module, priv->slice);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_start_slice_timer
+ *
+ * Description:
+ *   Start the timer counter for the given slice.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_start_slice_timer(struct xmc4_pwm_s *priv)
+{
+  DEBUGASSERT(priv != NULL);
+
+  uint32_t cc4ytcset_offset =
+      (uint32_t)(XMC4_CCU4_CC40TCSET_OFFSET + 0x0100 * priv->slice);
+
+  xmc4_pwm_putreg32(priv, cc4ytcset_offset,
+                    (uint32_t)CCU4_CC4_TCSET_TRBS_MASK);
+
+  pwminfo("PWM CCU4%d,CC4%d timer is running.\n", priv->module, priv->slice);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_stop_slice_timer
+ *
+ * Description:
+ *   Stop the timer counter for the given slice. Reset the counter.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_stop_slice_timer(struct xmc4_pwm_s *priv)
+{
+  DEBUGASSERT(priv != NULL);
+
+  uint32_t cc4ytcclr_offset =
+      (uint32_t)(XMC4_CCU4_CC40TCCLR_OFFSET + 0x0100 * priv->slice);
+
+  xmc4_pwm_putreg32(priv, cc4ytcclr_offset,
+                    (uint32_t)(CCU4_CC4_TCCLR_TRBC_MASK |
+                    CCU4_CC4_TCCLR_TCC_MASK));
+
+  pwminfo("PWM CCU4%d,CC4%d timer is stopped.\n", priv->module, priv->slice);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_is_slice_timer_running
+ *
+ * Description:
+ *   Get the state (running timer or not) of the slice.
+ *
+ *
+ * Returned Value:
+ *   0 if slice timer is stopped else true if timmer running.
+ *
+ *****************************************************************************/
+
+static bool pwm_is_slice_timer_running(struct xmc4_pwm_s *priv)
+{
+  DEBUGASSERT(priv != NULL);
+
+  uint32_t cc4ytst_offset =
+      (uint32_t)(XMC4_CCU4_CC40TST_OFFSET + 0x0100 * priv->slice);
+
+  bool status = (bool)((xmc4_pwm_getreg32(priv, cc4ytst_offset) &
+                        (uint32_t)CCU4_CC4_TCST_TRB_MASK) ==
+                        (uint32_t)CCU4_CC4_TCST_TRB_MASK);
+
+  pwminfo("PWM CCU4%d,CC4%d timer status is :%d\n",
+            priv->module, priv->slice, status);
+
+  return status;
+}
+
+/*****************************************************************************
+ * Name: pwm_set_slice_prescaler
+ *
+ * Description:
+ *   Set the value of the prescaler [0-14] in CC4yPSC.PSIV.
+ *   Slice must be restarted for effective change.
+ *   Update the value of prescaler in related xmc4_pwm_s.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_set_slice_prescaler(struct xmc4_pwm_s *priv, uint8_t prescaler)
+{
+  DEBUGASSERT(priv != NULL);
+  DEBUGASSERT(prescaler < 15);
+
+  if (prescaler >= 15)
+    {
+      return -EINVAL;
+    }
+
+  uint32_t cc4ypsc_offset =
+      (uint32_t)(XMC4_CCU4_CC40PSC_OFFSET + 0x0100 * priv->slice);
+
+  xmc4_pwm_putreg32(priv, cc4ypsc_offset, (uint32_t)prescaler);
+
+  priv->prescaler = prescaler;
+
+  pwminfo("PWM CCU4%d,CC4%d prescaler is set to :%" PRId8 "\n",
+            priv->module, priv->slice, prescaler);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_start_module_prescaler
+ *
+ * Description:
+ *   Start the CCU4x module prescaler (CCU4xGIDLC.SPRB)
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_start_module_prescaler(struct xmc4_pwm_s *priv)
+{
+  DEBUGASSERT(priv != NULL);
+
+  xmc4_pwm_modifyreg32(priv, XMC4_CCU4_GIDLC_OFFSET, 0, CCU4_GIDLC_SPRB_MASK);
+
+  pwminfo("PWM CCU4%d prescaler is started\n", priv->module);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_stop_module_prescaler
+ *
+ * Description:
+ *   Stop the CCU4x module prescaler (CCU4xGIDLS.CPRB)
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_stop_module_prescaler(struct xmc4_pwm_s *priv)
+{
+  DEBUGASSERT(priv != NULL);
+
+  xmc4_pwm_modifyreg32(priv, XMC4_CCU4_GIDLS_OFFSET, 0, CCU4_GIDLS_CPRB_MASK);
+
+  pwminfo("PWM CCU4%d prescaler is stopped\n", priv->module);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_enable_module
+ *
+ * Description:
+ *   Enable the CCU4x module (ungate and de-assert reset).
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_enable_module(struct xmc4_pwm_s *priv)
+{
+  DEBUGASSERT(priv != NULL);
+
+  if (priv->module == 3)
+    {
+#ifdef XMC4_SCU_GATING
+      /* Check if peripheral is gated */
+
+      if ((getreg32(XMC4_SCU_CGATSTAT1) && SCU_CGAT1_CCU43))
+        {
+          putreg32(SCU_CGAT1_CCU43, XMC4_SCU_CGATCLR1); /* Ungate it */
+        }
+
+#endif
+      /* Check if peripheral rest is asserted */
+
+      if ((getreg32(XMC4_SCU_PRSTAT1) && SCU_PR1_CCU43RS))
+        {
+          putreg32(SCU_PR1_CCU43RS, XMC4_SCU_PRCLR1); /* De-assert reset */
+        }
+    }
+  else
+    {
+      uint32_t scu_ccu4x_mask = (uint32_t)(1 << (priv->module + 2));
+
+#ifdef XMC4_SCU_GATING
+      if ((getreg32(XMC4_SCU_CGATSTAT0) && scu_ccu4x_mask))
+        {
+          putreg32(scu_ccu4x_mask, XMC4_SCU_CGATCLR0);
+        }
+
+#endif
+      if ((getreg32(XMC4_SCU_PRSTAT0) && scu_ccu4x_mask))
+        {
+          putreg32(scu_ccu4x_mask, XMC4_SCU_PRCLR0);
+        }
+    }
+
+  pwminfo("PWM CCU4%d module is enabled\n", priv->module);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_enable_module
+ *
+ * Description:
+ *   Disable the CCU4x module (gate and assert reset).
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ *****************************************************************************/
+
+static int pwm_disable_module(struct xmc4_pwm_s *priv)
+{
+  DEBUGASSERT(priv != NULL);
+
+  if (priv->module == 3)
+    {
+      /* Assert reset */
+
+      putreg32(SCU_PR1_CCU43RS, XMC4_SCU_PRCLR1);
+
+#ifdef XMC4_SCU_GATING
+      /* Gate clock */
+
+      putreg32(SCU_CGAT1_CCU43, XMC4_SCU_CGATSET1);
+#endif
+    }
+  else
+    {
+      uint32_t scu_ccu4x_mask = (uint32_t)(1 << (priv->module + 2));
+
+      putreg32(scu_ccu4x_mask, XMC4_SCU_PRSET0);
+
+#ifdef XMC4_SCU_GATING
+      putreg32(scu_ccu4x_mask, XMC4_SCU_CGATSET0);
+#endif
+    }
+
+  pwminfo("PWM CCU4%d module is disabled\n", priv->module);
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Name: pwm_is_module_used
+ *
+ * Description:
+ *   Get the state (running timer or not) of the slice.
+ *
+ * Returned Value:
+ *   0 if module is idle, else true if one slice or more is running.
+ *
+ *****************************************************************************/
+
+static bool pwm_is_module_used(struct xmc4_pwm_s *priv)
+{
+  DEBUGASSERT(priv != NULL);
+
+  uint32_t idle_status = xmc4_pwm_getreg32(priv, XMC4_CCU4_GSTAT_OFFSET);
+  uint32_t mask = (CCU4_GSTAT_S0I_MASK |
+                   CCU4_GSTAT_S1I_MASK |
+                   CCU4_GSTAT_S2I_MASK |
+                   CCU4_GSTAT_S3I_MASK);
+
+  idle_status &= mask;
+
+  bool is_used = !(idle_status == mask);
+
+  pwminfo("PWM CCU4%d is used ? : %d\n", priv->module, is_used);
+
+  return is_used;
+}
+
+/*****************************************************************************
+ * Name: pwm_get_config
+ *
+ * Description:
+ *   Compute the prescaler value, compare and period match for the given
+ *   info config.
+ *
+ * Input Parameters:
+ *   priv - A reference to the lower half PWM driver state structure
+ *   info - A reference to the characteristics of the pulsed output
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure
+ *
+ *****************************************************************************/
+
+static int pwm_get_config(struct xmc4_pwm_s *priv,

Review Comment:
   Changed to pwm_compute_config()



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to