mbed library sources. Supersedes mbed-src. Add PORTG support for STM32L476JG (SensorTile kit)

Dependents:   SensorTileTest

Fork of mbed-dev by mbed official

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Fri Apr 08 18:00:11 2016 +0100
Parent:
107:414e9c822e99
Child:
109:5e8787d2b815
Commit message:
Synchronized with git revision f28131a577669d25a5a37e7e5901bbad47cd4af6

Full URL: https://github.com/mbedmicro/mbed/commit/f28131a577669d25a5a37e7e5901bbad47cd4af6/

* [LPC812] Fixed PwmOut SCT bugs

* Fixed 0% duty cycle output
* Fixed pulse width 0 output
* Remove unused comment-out code
* Correct cast type for GCC toolchain

* [LPC812] Fix incorrect duty cycle

* The new PWM period now update existing PWM channels, so duty cycle is
kept
* Remove comment and unused code

Changed in this revision

targets/hal/TARGET_NXP/TARGET_LPC81X/pwmout_api.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/hal/TARGET_NXP/TARGET_LPC81X/pwmout_api.c	Tue Apr 05 18:15:12 2016 +0100
+++ b/targets/hal/TARGET_NXP/TARGET_LPC81X/pwmout_api.c	Fri Apr 08 18:00:11 2016 +0100
@@ -37,7 +37,6 @@
 // Find available output channel 0..3
 // Also need one Match register per channel
     for (i = 0; i < CONFIG_SCT_nOU; i++) {
-//    for (i = 0; i < 4; i++) {
         if ((sct_used & (1 << i)) == 0)
             return i;
     }
@@ -47,7 +46,7 @@
 // Any Port pin may be used for PWM.
 // Max number of PWM outputs is 4
 void pwmout_init(pwmout_t* obj, PinName pin) {
-    MBED_ASSERT(pin != (uint32_t)NC);
+    MBED_ASSERT(pin != (PinName)NC);
 
     int sct_n = get_available_sct();
     if (sct_n == -1) {
@@ -72,8 +71,6 @@
       LPC_SYSCON->PRESETCTRL |=  (1 << 8);
 
       // Two 16-bit counters, autolimit (ie reset on Match_0)
-      //pwm->CONFIG &= ~(0x1);
-      //pwm->CONFIG |= (1 << 17);
       pwm->CONFIG |= ((0x3 << 17) | 0x01);
 
       // halt and clear the counter
@@ -90,9 +87,6 @@
       //    - clearing bit 2 of the CTRL register
       pwm->CTRL_U &= ~(1 << 2);
       
-      // Not using IRQs 
-      //NVIC_SetVector(PWM_IRQn, (uint32_t)pwm_irq_handler);
-      //NVIC_EnableIRQ(PWM_IRQn);    
     }
 
     // LPC81x has only one SCT and 4 Outputs
@@ -157,6 +151,14 @@
     // Match_0 is PWM period. Compute new endtime of pulse for current channel
     uint32_t t_off = (uint32_t)((float)(obj->pwm->MATCHREL[0].U) * value);
     obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U = t_off; // New endtime
+
+    if (value == 0.0f) { // duty is 0%
+        // Set CLR event to be same as SET event, makes output to be 0 (low)
+        obj->pwm->OUT[(obj->pwm_ch)].CLR = (1 << 0);
+    } else {
+        // Use normal CLR event (current SCT ch + 1)
+        obj->pwm->OUT[(obj->pwm_ch)].CLR = (1 << ((obj->pwm_ch) + 1));
+    }
 }
 
 // Get dutycycle (0.0 .. 1.0)
@@ -190,20 +192,26 @@
     uint32_t t_period = obj->pwm->MATCHREL[0].U;  // Current PWM period
     obj->pwm->MATCHREL[0].U = (uint32_t)us;       // New PWM period
 
-    //Keep the dutycycle for the new PWM period
-    //Should really do this for all active channels!!
-    //This problem exists in all mbed libs.
-
-    //Sanity check
+    // Sanity check
     if (t_period == 0) {
-      return;
-//      obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = 0; // New endtime for this channel     
+        return;
     }
-    else {    
-      uint32_t t_off  = obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U;
-      float v = (float)t_off/(float)t_period;
-      obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U = (uint32_t)((float)us * (float)v); // New endtime for this channel
-    }   
+    else {
+        int cnt = sct_used;
+        int ch = 0;
+        // Update match period for exising PWM channels
+        do {
+            // Get current pulse width
+            uint32_t t_off  = obj->pwm->MATCHREL[ch + 1].U;
+            // Get the duty
+            float v = (float)t_off/(float)t_period;
+            // Update pulse width for this channel
+            obj->pwm->MATCHREL[ch + 1].U = (uint32_t)((float)us * (float)v);
+            // Get next used SCT channel
+            cnt = cnt >> 1;
+            ch++;
+        } while (cnt != 0);
+    }
 }
 
 
@@ -219,7 +227,13 @@
 
 //Set pulsewidth
 void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
-
+    if (us == 0) {  // pulse width is 0
+        // Set CLR event to be same as SET event, makes output to be 0 (low)
+        obj->pwm->OUT[(obj->pwm_ch)].CLR = (1 << 0);
+    } else {
+        // Use normal CLR event (current SCT ch + 1)
+        obj->pwm->OUT[(obj->pwm_ch)].CLR = (1 << ((obj->pwm_ch) + 1));
+    }
 //Should add Sanity check to make sure pulsewidth < period!
     obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U = (uint32_t)us; // New endtime for this channel
 }