LED dimm with gpio-pwm

aheitz
 
Posts: 2
Joined: Thu Dec 25, 2014 10:22 am

LED dimm with gpio-pwm

Sat Dec 27, 2014 10:03 am

Hello,

I Compiled the pwm Module into the vocore Image from this description:
http://vonger.cn/?topic=pwm-is-running-at-gpios.
And i simple connect an LED to gpio17 but the LED is flickering iregulary. Does anyone have an idea where the reason could be?

Greetings Andreas

Vonger
 
Posts: 896
Joined: Sun Oct 19, 2014 6:00 am

Re: LED dimm with gpio-pwm

Sun Dec 28, 2014 12:45 pm

do you try another GPIO?

aheitz
 
Posts: 2
Joined: Thu Dec 25, 2014 10:22 am

Re: LED dimm with gpio-pwm

Sun Dec 28, 2014 4:25 pm

I tried gpio 20, 21 and 12 and i had the same behaviour.
I started and stopped wit this script:
First:
Code: Select all
mount -t configfs none /config

To start:
Code: Select all
GPIO=12
mkdir /config/gpio_pwm/$GPIO
echo 1 > /sys/class/pwm/gpio_pwm\:$GPIO/export
echo 10000000 > /sys/class/pwm/gpio_pwm\:$GPIO/period_ns
echo 5000000 > /sys/class/pwm/gpio_pwm\:$GPIO/duty_ns
echo 1 > /sys/class/pwm/gpio_pwm\:$GPIO/run

And finally to stop:
Code: Select all
echo 0 > /sys/class/pwm/gpio_pwm\:$GPIO/run
echo 1 > /sys/class/pwm/gpio_pwm\:$GPIO/unexport
rm -rf /config/gpio_pwm/$GPIO

I want to use the PWM for control 8 - 10 Power LED with an MOSFET for switching the Power LEDs.
For testing i use an LED and 330 Ohm Resitor direct on the GPIO. Do you think that it is possible to use the VoCore for this?

Ton
 
Posts: 22
Joined: Sun Nov 16, 2014 4:35 pm

Re: LED dimm with gpio-pwm

Mon Dec 29, 2014 4:13 pm

I have the same problem. It looks as if there is another (1 hz?) signal superimposed over the generated pwm signal.

In DMESG I see this:

Code: Select all


[    0.000000] genirq: Flags mismatch irq 7. 00014600 (timer) vs. 00014600 (systick)



I guess that means there is an IRQ conflict.

In other DTS files for the RT5350 I see the following entries:


Code: Select all

 timer@100 {
           compatible = "ralink,rt5350-timer", "ralink,rt2880-timer";
           reg = <0x100 0x20>;
           interrupt-parent = <&intc>;
           interrupts = <1>;
   };


   systick@d00 {
           compatible = "ralink,rt5350-systick", "ralink,cevt-systick";
           reg = <0xd00 0x10>;

           interrupt-parent = <&cpuintc>;
           interrupts = <7>;
   };


I did not try to add these entries to the dts file yet.

Vonger, do you think this is needed?

Greenwire-Elektronik
 
Posts: 101
Joined: Thu Dec 04, 2014 6:31 am

Re: LED dimm with gpio-pwm

Mon Dec 29, 2014 9:40 pm

I just checked with the datasheet - there is no hardware solution for GPIO PWM, this means it is a pure software solution. You can probably check the files which have to handle it. If i find some spare minutes tomorrow, i will have a deeper look into it.
Buy now - breakout board for VoCore to easy adapting your idea!

Follow us on Twitter or facebook!

Ton
 
Posts: 22
Joined: Sun Nov 16, 2014 4:35 pm

Re: LED dimm with gpio-pwm

Thu Jan 01, 2015 11:28 am

I added the
Code: Select all
timer@100 {
      .....see above
   };
systick@d00 {
      .....see above
   };

part to the DTS file. Building goes ok, but no difference, still an unregular signal on the LED,
and still genirq: Flags mismatch irq 7 in DMESG.

Greenwire-Elektronik
 
Posts: 101
Joined: Thu Dec 04, 2014 6:31 am

Re: LED dimm with gpio-pwm

Thu Jan 01, 2015 4:31 pm

Ton,

you do not have to rebuild - the quoted part is automatically imported for vocore.dts caused by row 3 (/include/ "rt5350.dtsi").
The important line out of
https://github.com/openwrt-mirror/openw ... t5350.dtsi
is row 190
interrupts = <7>


So the problem is narrowed down for the system tick. I assume the PWM function (which i previously stated is not directly implemented in hardware) is realized with the free running counter - see Chapter 3.6 especially the register offset 0x0h and 0x4h. I think kernel is loading 0x4h with the given value (your time value divided by the system tick time) and after this enabling 0x0h:CNT_EN. After the specific time, the interrupt 7 will be generated.
So far so good.
Let's cut to the error message.
The systemtick is handled by a driver generated through this patch:
https://github.com/openwrt-mirror/openw ... ling.patch
The patch leads to:
https://github.com/torvalds/linux/blob/ ... t-rt3352.c
This file configures systemtick to irq 7 and to external timer interrupt (EXT_STK_EN=1).

I haven't found something exactly sticking to the problem, so i just searched in the kernel sources for the error message prefix "Flags mismatch irq".
I found the file which seems to manage interrupts and generate the messages:
https://github.com/torvalds/linux/blob/ ... q/manage.c
There is more or less just one case which can lead to this message, it begins around row 1050 and i checks for interrupt sharing and level (i think).

I have the feeling that the normal timer interrupt is somehow interfering with that systemtick.
Next step would be register dumping and going through it step by step. i have not vocore to hand though, so i cannot do it - Ton?
What could be needed: All registers from the interrupt controller (0x10000200h base), from the timer (0x10000100h base) and the systemtick (0x10000d00h base). Best time slot to dump is after configuring but not starting the PWM.

So far sorry for not have a solution in hand, but i think this might give new ideas.

Best Regards,

Jonas
Buy now - breakout board for VoCore to easy adapting your idea!

Follow us on Twitter or facebook!

Ton
 
Posts: 22
Joined: Sun Nov 16, 2014 4:35 pm

Re: LED dimm with gpio-pwm

Sat Jan 03, 2015 1:14 pm

Hi Jonas,

I have a vocore available, but how to dump the registers? Is there a tool?

Greenwire-Elektronik
 
Posts: 101
Joined: Thu Dec 04, 2014 6:31 am

Re: LED dimm with gpio-pwm

Sat Jan 03, 2015 3:38 pm

Hi Ton,

no, you need to write a c program.
What you need:

Code: Select all
int* memaccess;
int fd = open("/dev/mem", O_RDWR);
int dumpvalue;

...

if (fd == -1) {
printf("Error getting mem access\n");
return -1;
}
else
memaccess = (unsigned int*) mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x10000000);
close(fd);

dumpvalue=memaccess[OFFSET>>2]; //OFFSET means the address offset from 0x10000000 in hex, for gpio register GPIO21_00_EDGE it would be 0x604.


This would dump the content of GPIO21_00_EDGE into dumpvalue. It is a lot of copy paste for those dumps i admit.

Rgds

Jonas
Buy now - breakout board for VoCore to easy adapting your idea!

Follow us on Twitter or facebook!

Ton
 
Posts: 22
Joined: Sun Nov 16, 2014 4:35 pm

Re: LED dimm with gpio-pwm

Sun Jan 04, 2015 1:59 pm

Hi Jonas,

These are the registers:

Code: Select all
Before PWM:

 0100 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0110 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0114 - 0000FFFF - 0000_0000_0000_0000_1111_1111_1111_1111
 0118 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0120 - 0000D692 - 0000_0000_0000_0000_1101_0110_1001_0010
 0124 - 0000D148 - 0000_0000_0000_0000_1101_0001_0100_1000
 0128 - 000000BF - 0000_0000_0000_0000_0000_0000_1011_1111
 0200 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0204 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0220 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0230 - 00000008 - 0000_0000_0000_0000_0000_0000_0000_1000
 0234 - 80061042 - 1000_0000_0000_0110_0001_0000_0100_0010
 0238 - 80061042 - 1000_0000_0000_0110_0001_0000_0100_0010
 0D00 - 00000003 - 0000_0000_0000_0000_0000_0000_0000_0011
 0D04 - 0000B514 - 0000_0000_0000_0000_1011_0101_0001_0100
 0D08 - 0000B380 - 0000_0000_0000_0000_1011_0011_1000_0000
root@Vocore2:~#

After:

 0100 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0110 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0114 - 0000FFFF - 0000_0000_0000_0000_1111_1111_1111_1111
 0118 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0120 - 0000D692 - 0000_0000_0000_0000_1101_0110_1001_0010
 0124 - 0000D351 - 0000_0000_0000_0000_1101_0011_0101_0001
 0128 - 000000BF - 0000_0000_0000_0000_0000_0000_1011_1111
 0200 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0204 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0220 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0230 - 00000008 - 0000_0000_0000_0000_0000_0000_0000_1000
 0234 - 80061042 - 1000_0000_0000_0110_0001_0000_0100_0010
 0238 - 80061042 - 1000_0000_0000_0110_0001_0000_0100_0010
 0D00 - 00000003 - 0000_0000_0000_0000_0000_0000_0000_0011
 0D04 - 00000B09 - 0000_0000_0000_0000_0000_1011_0000_1001
 0D08 - 00000AEC - 0000_0000_0000_0000_0000_1010_1110_1100
root@Vocore2:~#


Another vocore: (Standard .dts file)

 0100 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0110 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0114 - 0000FFFF - 0000_0000_0000_0000_1111_1111_1111_1111
 0118 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0120 - 0000D692 - 0000_0000_0000_0000_1101_0110_1001_0010
 0124 - 0000CD16 - 0000_0000_0000_0000_1100_1101_0001_0110
 0128 - 000000BF - 0000_0000_0000_0000_0000_0000_1011_1111
 0200 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0204 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0220 - 00000000 - 0000_0000_0000_0000_0000_0000_0000_0000
 0230 - 00000008 - 0000_0000_0000_0000_0000_0000_0000_1000
 0234 - 80061042 - 1000_0000_0000_0110_0001_0000_0100_0010
 0238 - 80061042 - 1000_0000_0000_0110_0001_0000_0100_0010
 0D00 - 00000003 - 0000_0000_0000_0000_0000_0000_0000_0011
 0D04 - 00000C25 - 0000_0000_0000_0000_0000_1100_0010_0101
 0D08 - 00000B62 - 0000_0000_0000_0000_0000_1011_0110_0010
root@Vocore1:~/dumpert#


0124 is a running timer, D04 and D08 are running as well.

All values seem ok.

Code to generate the dump:


Code: Select all
/*
 * Simple Q&D dumper for some RT5350 registers
 * Ton Augustin - 2015
 *
 */
 
 
#include <sys/mman.h>
#include <stdio.h>      // printf
#include <string.h>     // strcat
#include <stdlib.h>     // strtol
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


const char *int32_to_binary(unsigned int x)
{
  static char b[50];
  b[0] = '\0';
  unsigned int z;
  int hick;
  hick = 0;
  for (z = 0x80000000; z > 0; z >>= 1)
  {
    strcat(b, ((x & z) == z) ? "1" : "0");
    hick++;
    if((hick == 4)&&(z != 1)) {
        strcat(b, "_");
        hick = 0;
    };
  }

  return b;
}


main() {

int* memaccess;
int fd = open("/dev/mem", O_RDWR);
int dumpvalue;


if (fd == -1) {
   printf("Error getting mem access\n");
   return -1;
}
memaccess = (unsigned int*) mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x10000000);

void writevalues( int offst) {
   dumpvalue=memaccess[offst>>2]; //OFFSET means the address offset from 0x10000000 in hex, for gpio register GPIO21_00_EDGE it would be 0x604.
   printf(" %04X - %08X - %s\n", offst, dumpvalue, int32_to_binary((unsigned int)dumpvalue));
}


//timer 0x100
writevalues(0x00 + 0x100);
writevalues(0x10 + 0x100);
writevalues(0x14 + 0x100);
writevalues(0x18 + 0x100);
writevalues(0x20 + 0x100);
writevalues(0x24 + 0x100);
writevalues(0x28 + 0x100);

//int 0x200
writevalues(0x00 + 0x200);
writevalues(0x04 + 0x200);
writevalues(0x20 + 0x200);
writevalues(0x30 + 0x200);
writevalues(0x34 + 0x200);
writevalues(0x38 + 0x200);

//sys 0xD00
writevalues(0x00 + 0xD00);
writevalues(0x04 + 0xD00);
writevalues(0x08 + 0xD00);

close(fd);

}

Next
Return to VoCore & VoCore+Dock

Who is online

Users browsing this forum: No registered users and 34 guests