Double edge PWM output on p25 forces p26 (input) low ?

18 Jul 2012

Sorry, wrong port pin in header: pin 24 is reading low not p26.

I am trying to use pins p21,p22,p23,p24 and p26 as inputs using the standard setup DigitalIn(pin)

I also enabled PullUp mode for these pins but when I enable the double edge PWM output (VGA library) on p25 then p24 always reads '0' (low)

A small program without the VGA/PWM stuff works OK, in the VGA code I can only find one f_pinsel function for the PWM output pin setting (Port2 bit1) so what might be causing this ?

19 Jul 2012

How do you instantiate all stuff? Instantiating the digitalins after the VGA library might overwrite the 'damage' done by the VGA library. Quick scan of the VGA library gives me the idea it is not the most subtle library in existence, first thing it does when initializing is powering down all peripherals, and then only powers up what it requires. GPIO is included in that list, but it makes you wonder what other unnecesary stuff it does (at least I don't see why it would do that), that could interfere with your program.

Since the VGA library uses for every function his own custom library (might be faster, but confuses me), it would take me too much time to find everything out. You can try outputting LPC_PINCON->PINSEL4 to your PC over USB serial. Bit 4 and 5 should be zero if it is configured as GPIO. (But defining the DigitalIn after the VGA should already make sure that is correct, can't harm to check it though).

Aditionally you can check with a multimeter what the state of p24 actually is.

19 Jul 2012

Erik - wrote:

How do you instantiate all stuff? Instantiating the digitalins after the VGA library might overwrite the 'damage' done by the VGA library.

I tried both ways, simply initializing them at the beginning of the main program, just after including the headers and just before using them inside the main routine. Made no difference.

Quote:

Quick scan of the VGA library gives me the idea it is not the most subtle library in existence, first thing it does when initializing is powering down all peripherals, and then only powers up what it requires. GPIO is included in that list, but it makes you wonder what other unnecesary stuff it does (at least I don't see why it would do that), that could interfere with your program.

I know all about that, I am partly responsible for the VGA library :-) I disabled all the 'powerdown' stuff just to be sure. The other pins from port 2 are also used by my program (it is a keyboard scanning matrix using p21-p26 (excl. p25 of course) as inputs. They are all declared as simple inputs but only p24 reads as 0

Quote:

Since the VGA library uses for every function his own custom library (might be faster, but confuses me), it would take me too much time to find everything out.

Ivo made the fastlib library so it generates during compiling a most efficient way of controlling the hardware (note: not the easiest..)

Quote:

You can try outputting LPC_PINCON->PINSEL4 to your PC over USB serial. Bit 4 and 5 should be zero if it is configured as GPIO. (But defining the DigitalIn after the VGA should already make sure that is correct, can't harm to check it though).

I will try and tinker some more tonight. The pin 'should' be available if not configured in one of the special modes. For instance: I already found out that you can do I2S with only the data output enabled so the other pins normally used for I2S output (word select and clock) can be used for (in my case) a PS2 keyboard.

Quote:

Aditionally you can check with a multimeter what the state of p24 actually is.

I did and as far as I could measure the port seems to be configured as output sinking a few milliamps from my multimeter to ground (reads as 60 mV on the diode test position so it is not an input) It might have soemthing to doo with the fact that the PWM is configured for double edge PWM but then I would have expected that pin 26 was 'occupied' and not pin 24

19 Jul 2012

Well this seemed to do the trick:

In init hsync I added:

/ create HSYNC output with PWM
static void init_hsync(void) {
....
    fl_select_clock_pwm1(FL_CLOCK_DIV1);
    fl_pinsel(2, 1, FL_FUNC_ALT1, FL_FLOATING, FL_FLOATING);    // PWM1.2, no pullup/down


    fl_pinsel(2, 0, FL_FUNC_DEFAULT, FL_PULLUP, FL_FLOATING);    // p26 normal mode with pullup
    fl_pinsel(2, 2, FL_FUNC_DEFAULT, FL_PULLUP, FL_FLOATING);    // p24 normal mode with pullup
    fl_pinsel(2, 3, FL_FUNC_DEFAULT, FL_PULLUP, FL_FLOATING);    // p23 normal mode with pullup
    fl_pinsel(2, 4, FL_FUNC_DEFAULT, FL_PULLUP, FL_FLOATING);    // p22 normal mode with pullup
    fl_pinsel(2, 5, FL_FUNC_DEFAULT, FL_PULLUP, FL_FLOATING);    // p21 normal mode with pullup
    fl_gpio_set_direction(2, 1<<0, FL_INPUT);                    // set to input mode
    fl_gpio_set_direction(2, 1<<2, FL_INPUT);                    // set to input mode
    fl_gpio_set_direction(2, 1<<3, FL_INPUT);                    // set to input mode
    fl_gpio_set_direction(2, 1<<4, FL_INPUT);                    // set to input mode
    fl_gpio_set_direction(2, 1<<5, FL_INPUT);                    // set to input mode

And now it works OK.

It seems as soon as the alternate function for the PWM pin 25 is written pin 24 get switched to output.. Not sure why that happens, I will contact Ivo about this.

19 Jul 2012

Quote:

Ivo made the fastlib library so it generates during compiling a most efficient way of controlling the hardware (note: not the easiest..)

Oh I got that, I can imagine that especially for something like this you can use all the speed you can get, but it just makes it a bit harder to understand if you are not into it.

Anyway because I am a bit bored I decided to compile for myself. After some issues (had to change file name to cpp, and obviously my debug serial port wont do much with all peripherals turned off), it ran, and I noticed exactly the same as you had. After some checking of registers pretty much everything seemed fine, and obviously I missed the issue. So then I started turning stuff off in the VGA library, and indeed the hsync function was the issue, to be exact the fl_pinsel.

After that it was looking a bit more, and as you have quite often (well at least I have it), in the end it was pretty obvious. The call of fl_pinsel is wrong. The error is that the library uses FL_FLOATING as parameter for the opendrain state. That definition is (I think, but pretty sure) only intended to be used by the pull up/down state. FL_FLOATING has as value 2, open drain is 1 bit per pin, so the function sets the value 10 in location 1 of the register (where it intends to write 0 to disable open drain), which overflows into location 2, setting it to open drain mode. Now port 2 bit 2 is open drain, which is p24.

So the solution is simply replacing:

fl_pinsel(2, 1, FL_FUNC_ALT1, FL_FLOATING, FL_FLOATING);    // PWM1.2, no pullup/down

With either:

fl_pinsel(2, 1, FL_FUNC_ALT1, FL_FLOATING, FL_DISABLE );    // PWM1.2, no pullup/down

or

fl_pinsel(2, 1, FL_FUNC_ALT1, FL_FLOATING, FL_IGNORE);    // PWM1.2, no pullup/down
20 Jul 2012

Quote:

FL_FLOATING has as value 2, open drain is 1 bit per pin, so the function sets the value 10 in location 1 of the register (where it intends to write 0 to disable open drain), which overflows into location 2, setting it to open drain mode. Now port 2 bit 2 is open drain, which is p24.

Ouch, overlooked that one :-) Thanks for testing, it proves again how flexible (and thus complex) the mbed's IO really is.