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
LED dimm with gpio-pwm
- aheitz
- Posts: 2
- Joined: Thu Dec 25, 2014 10:22 am
- Vonger
- Posts: 896
- Joined: Sun Oct 19, 2014 6:00 am
- aheitz
- Posts: 2
- Joined: Thu Dec 25, 2014 10:22 am
Re: LED dimm with gpio-pwm
I tried gpio 20, 21 and 12 and i had the same behaviour.
I started and stopped wit this script:
First:
To start:
And finally to stop:
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?
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
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:
I guess that means there is an IRQ conflict.
In other DTS files for the RT5350 I see the following entries:
I did not try to add these entries to the dts file yet.
Vonger, do you think this is needed?
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
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.
- Ton
- Posts: 22
- Joined: Sun Nov 16, 2014 4:35 pm
Re: LED dimm with gpio-pwm
I added the
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.
- 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
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
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
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
- Ton
- Posts: 22
- Joined: Sun Nov 16, 2014 4:35 pm
Re: LED dimm with gpio-pwm
Hi Jonas,
I have a vocore available, but how to dump the registers? Is there a tool?
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
Hi Ton,
no, you need to write a c program.
What you need:
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
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
- Ton
- Posts: 22
- Joined: Sun Nov 16, 2014 4:35 pm
Re: LED dimm with gpio-pwm
Hi Jonas,
These are the registers:
0124 is a running timer, D04 and D08 are running as well.
All values seem ok.
Code to generate the dump:
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);
}
Who is online
Users browsing this forum: No registered users and 79 guests