Hi all,
I am trying to toggle an output-GPIO (PI0) as fast as possible by using a kernel-module (see below code) that directly writes to the corresponding GPIO-register (physical address: 0x01c20800 + 0x130). But due some unknown reason, the toggle only works reliable if I use a delay greater 20 microseconds between setting and resetting the line. I expected to achieve some nano-seconds as minimal delay. For this reason, I think there is something wrong with my GPIO-configuration.
Now, have somebody tried to speed up the GPIO-toggling on that way? or give me a hint for solving this issue? Thanks in advance.
BR,
Luis
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/platform_device.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Luis");
#define MY_GPIO_CLK (49)
#define SW_PA_PORTC_IO_BASE 0x01c20800
#define CSP_PIN_PHY_ADDR_SIZE 0x1000
static int write_delay = 0;
static void __iomem *my_io = NULL;
static struct gpio my_gpios[] = {
{ MY_GPIO_CLK, GPIOF_OUT_INIT_LOW, "clock" },
};
static void sunxi_gpio_write_raw(u32 value)
{
u32 val;
if (write_delay) {
ndelay(write_delay);
}
iowrite32(value, my_io + 0x130);
val = ioread32(my_io + 0x130);
if (value != val) {
printk(KERN_ERR "Failed iowrite32() | %i %i\n", value, val);
}
}
static int wago_write_byte(u8 data)
{
uint pos;
write_delay = 200;
for (pos = 0; pos < 2; pos++) {
//gpio_set_value(MY_GPIO_CLK, 1);
sunxi_gpio_write_raw(1);
//gpio_set_value(MY_GPIO_CLK, 0);
sunxi_gpio_write_raw(0);
}
return 0;
}
static __init int wago_init(void)
{
int err;
my_io = ioremap_nocache(SW_PA_PORTC_IO_BASE, CSP_PIN_PHY_ADDR_SIZE);
if (NULL == my_io) {
printk(KERN_ERR "Failed to ioremap()\n");
return -EIO;
}
err = gpio_request_array(my_gpios, ARRAY_SIZE(my_gpios));
if (err) {
iounmap(my_io);
printk(KERN_ERR "Couldn't request GPIOs, %i\n", err);
return err;
}
wago_write_byte(0xaa);
printk(KERN_INFO "WAGO module loaded " __TIME__ "\n");
return 0;
}
static __exit void wago_exit(void)
{
gpio_free_array(my_gpios, ARRAY_SIZE(my_gpios));
iounmap(my_io);
}
module_init(wago_init);
module_exit(wago_exit);
Don't expect more than about 4MHz as there appear to be weird internal interlocks in the chip itself.
John
Quote from: JohnS on July 27, 2015, 05:58:41 PM
Don't expect more than about 4MHz as there appear to be weird internal interlocks in the chip itself.
Thanks for the info, but at this moment I have about 50kHz. I would be happy to see 2MHz as I need it for generating a bus clock.
I haven't tested with another GPIO than PI0. Could be a problem of this specific line? I will test it at this evening.
Luis
It seems to me it will never be a sensible way to create a clock, let alone quite a fast one. I'd use an existing peripheral type.
John