Need to dynamically switch a PwmOut pin to hi-z

24 Feb 2013

I have pin 21 defined as PwmOut on the MBED LPC1768:

PwmOut sidetone(p21)

// and I currently turn the output on and off like this:

sidetone = 0.5;  // turn on
sidetone = 0.0;  // turn off

I also need to switch the output pin to input to obtain a hi-z state on the pin when it is turned off instead of a logic 0. To turn it back on I need to switch it back to the output state as well as setting the duty cycle to 50%.

I assume I should be able to dig into the chip data sheet and figure out how to do this eventually. But I thought I would see if anyone can easily provide any guidance / hints that might save me some time getting oriented to the chip inner details.

Thanks,

Chuck

24 Feb 2013

What might work, besides looking at datasheet, once figured out it is pretty straightforward, is first defining the pin as DigitalInOut, and next as PWM object. When you do it in this order the PWM should set everything right for normal PWM operation. However you can still use DigitalInOut to switch the pin between input (high-Z) and output.

24 Feb 2013

Erik,

I did not realize it was possible to make two different declarations for the same pin, very interesting. I just confirmed that the compiler indeed is happy with both declarations being present so I will go ahead and try this out using the scope to see if this will do it for me.

Thanks.

03 Mar 2013

Follow up / solution:

I did not have any success with the dual declaration, so I dug into the data sheet and the MBED header files and figured out the commands that allowed me to access the registers. I needed to access a few different registers:

I initialized PINSEL4 to the GPIO function and PINMODE4 so no internal pullups/pulldowns are configured and initialized FIODIR to insure the input direction when the GPIO function is selected:

// These operations should initialize the sidetone pin (P2.5, p21, PWM_6)
// so at keyup the external bias resistors provide a level of 3.3V/2

  LPC_PINCON->PINSEL4 &= 0xFBFF;  // clear bit 10  for GPIO Input  <-------
  LPC_GPIO2->FIODIR &= 0xDF;  // will force bit 5 to zero for Hi-Z       <-------
  LPC_PINCON->PINMODE4  |= 0x0800;  // set bit 11  for no pullup or pulldown  (key down)  <-------

Then in my application I used the commands below to switch between the PWM output and the GPIO Hi-z input state:

  if (monEna)
    {
      sidetone = 0.0;
      LPC_PINCON->PINSEL4 &= 0xFBFF;  // clear bit 10  for GPIO Input  <---------
    }

and:

  if (monEna)
    {
      LPC_PINCON->PINSEL4  |= 0x0400;  // set bit 10  for PWM  <--------
      sidetone = 0.5;
    }

Summary: I now at least have a minimal understanding of how to access registers when needed. I don't expect this to be of interest to others, but I wanted to "close" this topic instead of leaving it hanging.