Jump to content
43oh

Recommended Posts

I'm trying to use Energia for a project and I'm having problems with PWM. My understanding is that the following code should continually toggle the green led between full on and pwm with a value of 14. This is on a 2553 on a Rev. 1.4 Launchpad with the crystal installed.

 

void setup() {
 pinMode(GREEN_LED, OUTPUT);
}

void loop(){
digitalWrite(GREEN_LED, HIGH);
delay(2000);  
analogWrite(GREEN_LED,14);
delay(2000);
}

When the code runs the led is full on. After 2 seconds it goes dim with the pwm. After 2 more seconds I expected the led to go to full brightness as the code loops, but it remains dim. The problem also exists using analogWrite(GREEN_LED, 255) instead of digitalWrite(GREEN_LED, HIGH).

 

Am I missing something here, or is there a bug in Energia?

Link to post
Share on other sites

This is confirmed to be a bug. digitalWrite leaves the pin in PWM mode. A digitalWrite drives the line high and then PWM takes over again immediately after that. Thank you for the report. WIll file a bug and post the patch in this thread.

 

A way around this is:

 

void setup() {
 pinMode(GREEN_LED, OUTPUT);
}

void loop(){
analogWrite(GREEN_LED,254); // write with 255 does a digitalWrite(, HIGH) so will not work
delay(2000);  
analogWrite(GREEN_LED,14);
delay(2000);
}

Link to post
Share on other sites

Bug is fixed. Pull request with fix has been posted for review:

https://github.com/energia/Energia/pull/64/files

 

--- a/hardware/msp430/cores/msp430/wiring_digital.c
+++ b/hardware/msp430/cores/msp430/wiring_digital.c
@@ -79,9 +79,17 @@ void digitalWrite(uint8_t pin, uint8_t val)
       uint8_t bit = digitalPinToBitMask(pin);
       uint8_t port = digitalPinToPort(pin);
       volatile uint16_t *out;
+       volatile uint16_t *sel;

       if (port == NOT_A_PORT) return;

+       /*
+        * Clear bit in PxSEL register to select GPIO function. Other functions like analogWrite(...) 
+        * will set this bit so need to clear it.
+        */
+       sel = portSelRegister(port);    /* get the port function select register address */
+       *sel &= ~bit;                   /* clear bit in pin function select register */
+
       out = portOutputRegister(port);

       if (val == LOW) {

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...