mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
--- a/targets/TARGET_Cypress/TARGET_PSOC6/pwmout_api.c	Thu Nov 08 11:46:34 2018 +0000
+++ b/targets/TARGET_Cypress/TARGET_PSOC6/pwmout_api.c	Wed Feb 20 22:31:08 2019 +0000
@@ -1,6 +1,8 @@
 /*
  * mbed Microcontroller Library
  * Copyright (c) 2017-2018 Future Electronics
+ * Copyright (c) 2018-2019 Cypress Semiconductor Corporation
+ * SPDX-License-Identifier: Apache-2.0
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -86,10 +88,10 @@
         period /= 2;
         prescaler += 1;
     }
+
     if (period > MAX_16_BIT_PERIOD) {
         // We have reached the prescaler limit, set period to max value.
         error("Can't configure required PWM period.");
-        period = MAX_16_BIT_PERIOD;
     }
 
     obj->prescaler = prescaler;
@@ -120,12 +122,12 @@
 /*
  * Callback handler to restart the timer after deep sleep.
  */
-#if DEVICE_SLEEP && DEVICE_LOWPOWERTIMER
-static cy_en_syspm_status_t pwm_pm_callback(cy_stc_syspm_callback_params_t *callback_params)
+#if DEVICE_SLEEP && DEVICE_LPTICKER
+static cy_en_syspm_status_t pwm_pm_callback(cy_stc_syspm_callback_params_t *callback_params, cy_en_syspm_callback_mode_t mode)
 {
     pwmout_t *obj = (pwmout_t *)callback_params->context;
 
-    switch (callback_params->mode) {
+    switch (mode) {
         case CY_SYSPM_BEFORE_TRANSITION:
             /* Disable timer before transition */
             Cy_TCPWM_PWM_Disable(obj->base, obj->counter_id);
@@ -145,7 +147,7 @@
 
     return CY_SYSPM_SUCCESS;
 }
-#endif // DEVICE_SLEEP && DEVICE_LOWPOWERTIMER
+#endif // DEVICE_SLEEP && DEVICE_LPTICKER
 
 
 void pwmout_init(pwmout_t *obj, PinName pin)
@@ -156,59 +158,75 @@
 
     MBED_ASSERT(obj);
     MBED_ASSERT(pin != (PinName)NC);
-    // Allocate and setup clock.
+
+    // Allocate and setup clock (same clock for all PWMs)
     if (pwm_clock_divider == CY_INVALID_DIVIDER) {
+
         pwm_clock_divider = cy_clk_allocate_divider(CY_SYSCLK_DIV_8_BIT);
         if (pwm_clock_divider == CY_INVALID_DIVIDER) {
             error("PWM clock divider allocation failed.");
-            return;
         }
-        Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT,
-                                   pwm_clock_divider,
-                                   (CY_CLK_PERICLK_FREQ_HZ / PWMOUT_BASE_CLOCK_HZ) - 1);
+
+        /* Configure divider */
+        Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, pwm_clock_divider,
+                                   (cy_PeriClkFreqHz / PWMOUT_BASE_CLOCK_HZ) - 1);
         Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, pwm_clock_divider);
     }
 
+    /* Find instance using pins */
     pwm_cnt = pinmap_peripheral(pin, PinMap_PWM_OUT);
     if (pwm_cnt != (uint32_t)NC) {
-        if (cy_reserve_io_pin(pin)) {
-            error("PWMOUT pin reservation conflict.");
-        }
-        obj->base = (TCPWM_Type*)CY_PERIPHERAL_BASE(pwm_cnt);
-        obj->pin = pin;
+
+        obj->pin  = pin;
+        obj->base = (TCPWM_Type *)CY_PERIPHERAL_BASE(pwm_cnt);
         if (obj->base == TCPWM0) {
+            /* TCPWM0 is used */
             obj->counter_id = ((PWMName)pwm_cnt - PWM_32b_0) / (PWM_32b_1 - PWM_32b_0);
             abs_cnt_num = obj->counter_id;
         } else {
-            // TCPWM1 is used.
+            /* TCPWM1 is used */
             obj->counter_id = ((PWMName)pwm_cnt - PWM_16b_0) / (PWM_16b_1 - PWM_16b_0);
             abs_cnt_num = obj->counter_id + 8;
         }
-        if (cy_reserve_tcpwm(abs_cnt_num)) {
-            error("PWMOUT Timer/Counter reservation conflict.");
+
+        /* Check if resource severed */
+        if (0 != cy_reserve_tcpwm(abs_cnt_num)) {
+            Cy_TCPWM_PWM_Disable(obj->base, obj->counter_id);
+            Cy_TCPWM_PWM_DeInit(obj->base, obj->counter_id, &pwm_config);
+        } else {
+            if (cy_reserve_io_pin(pin)) {
+                error("PWMOUT pin reservation conflict.");
+            }
+
+#if DEVICE_SLEEP && DEVICE_LPTICKER
+            /* Register callback once */
+            obj->pm_callback_handler.callback = pwm_pm_callback;
+            obj->pm_callback_handler.type     = CY_SYSPM_DEEPSLEEP;
+            obj->pm_callback_handler.skipMode = 0;
+            obj->pm_callback_handler.callbackParams = &obj->pm_callback_params;
+            obj->pm_callback_params.base    = obj->base;
+            obj->pm_callback_params.context = obj;
+            if (!Cy_SysPm_RegisterCallback(&obj->pm_callback_handler)) {
+                error("PM callback registration failed!");
+            }
+#endif // DEVICE_SLEEP && DEVICE_LPTICKER
         }
 
-        // Configure clock.
+        /* Configure pin */
         pwm_function = pinmap_function(pin, PinMap_PWM_OUT);
+        pin_function(pin, pwm_function);
+
+        /* Connect clock */
         obj->clock = CY_PIN_CLOCK(pwm_function);
         Cy_SysClk_PeriphAssignDivider(obj->clock, CY_SYSCLK_DIV_8_BIT, pwm_clock_divider);
+
+        /* Configure hardarwe */
         Cy_TCPWM_PWM_Init(obj->base, obj->counter_id, &pwm_config);
-        pin_function(pin, pwm_function);
+
         // These will be properly configured later on.
-        obj->period = 0;
+        obj->period      = 0;
         obj->pulse_width = 0;
-        obj->prescaler = 0;
-#if DEVICE_SLEEP && DEVICE_LOWPOWERTIMER
-        obj->pm_callback_handler.callback = pwm_pm_callback;
-        obj->pm_callback_handler.type = CY_SYSPM_DEEPSLEEP;
-        obj->pm_callback_handler.skipMode = CY_SYSPM_SKIP_CHECK_READY | CY_SYSPM_SKIP_CHECK_FAIL;
-        obj->pm_callback_handler.callbackParams = &obj->pm_callback_params;
-        obj->pm_callback_params.base = obj->base;
-        obj->pm_callback_params.context = obj;
-        if (!Cy_SysPm_RegisterCallback(&obj->pm_callback_handler)) {
-            error("PM callback registration failed!");
-        }
-#endif // DEVICE_SLEEP && DEVICE_LOWPOWERTIMER
+        obj->prescaler   = 0;
 
     } else {
         error("PWM OUT pinout mismatch.");
@@ -217,7 +235,9 @@
 
 void pwmout_free(pwmout_t *obj)
 {
-    // TODO: Not implemented yet.
+    /* Does nothing because it is not called in the MBED PWMOUT driver
+    * destructor. The pwmout_init handles multiple calls of constructor.
+    */
 }
 
 void pwmout_write(pwmout_t *obj, float percent)