galb
Пункты: 97
Регистрация: 22.08.2012
Доброго времени суток всем!
У меня есть отладочная плата с процессором AM1808 (http://www.starterkit.ru/html/index.php?name=shop&op=view&id=70&word=AM1808). На процессоре установлен Linux (2.6.37). Не получается завести GPIO :( Вот что я делаю:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <mach/da8xx.h>
#include <mach/mux.h>
#define GPIO_BA 0x01E26000 // GPIO Base Address
#define MDCTL3_GPIO_CTRL 0x01E27A0C
#define MDSTAT3_GPIO_STAT 0x01E2780C
#define PINMUX13_ADDR 0x01C14154
#define REV_ID_ADDR 0x01C14000
#define MAP_BASE GPIO_BA
#define MAP_SIZE 4096Ul
#define MAP_MASK (MAP_SIZE - 1)
#define GPIO_BINTEN *(int*)(mapped_base+0x08)
#define GPIO_DIR01 *(int*)(mapped_base+0x88)
#define GPIO_OUT_DATA01 *(int*)(mapped_base+0x8C)
#define GPIO_SET_DATA01 *(int*)(mapped_base+0x90)
#define GPIO_CLR_DATA01 *(int*)(mapped_base+0x94)
MODULE_LICENSE("GPL");
static int My_module_init(void)
{
int *mapped_base, *mapped_base1, *mapped_base2, *mapped_base3;
int RevID_val = 0;
int tmp1 = 0, tmp2 = 0;
int k;
printk(KERN_ALERT "module initialization.\n");
// Прочитаем статус модуля GPIO
mapped_base1 = ioremap_nocache(MDSTAT3_GPIO_STAT, 16);
printk(KERN_ALERT "MDSTAT3_GPIO_STAT mapped 0x%08x\n", mapped_base1);
tmp2 = *(int*)mapped_base1;
printk(KERN_ALERT "MDSTAT3_GPIO_STAT has %08X\n", tmp2);
// Тактируем GPIO
mapped_base = ioremap_nocache(MDCTL3_GPIO_CTRL, 16);
printk(KERN_ALERT "MDCTL3_GPIO_CTRL mapped 0x%08x\n", mapped_base);
*(int*)mapped_base = 0x80000003;
tmp1 = *(int*)mapped_base;
printk(KERN_ALERT "In MDCTL3_GPIO_CTRL was written %08X\n", tmp1);
// Настраиваем GP6[12], GP6[11], GP6[9], GP6[8] на вывод
mapped_base2 = ioremap_nocache(PINMUX13_ADDR, 16);
printk(KERN_ALERT "PINMUX13_ADDR mapped 0x%08x\n", mapped_base2);
*(int*)mapped_base2 = 0x88088000;
tmp1 = *(int*)mapped_base2;
printk(KERN_ALERT "In PinMux13 was written %08X\n", tmp1);
mapped_base = ioremap_nocache(MAP_BASE & ~MAP_MASK, MAP_SIZE);
if (mapped_base == (void *)-1) printk(KERN_ALERT "Memory mapping error.\n");
mapped_base+=(MAP_BASE & MAP_MASK);
printk(KERN_ALERT "Target address mapped 0x%08x-->0x%08x\n",(int) MAP_BASE,(int)mapped_base);
GPIO_DIR01 = 0x0; // set pin fuction is output
tmp1 = GPIO_DIR01;
printk(KERN_ALERT "GPIO_DIR01<-%08X, tmp1);
for (k =0; k<1000; k++)
{
GPIO_SET_DATA01 = 0xffffffff; // pin high
GPIO_CLR_DATA01 = 0xffffffff; // pin low
}
iounmap(MDSTAT3_GPIO_STAT);
iounmap(MDCTL3_GPIO_CTRL);
iounmap(PINMUX13_ADDR);
iounmap(REV_ID_ADDR);
iounmap(MAP_BASE & ~MAP_MASK);
return 0;
}
static void My_module_exit(void) {
printk(KERN_ALERT "module exit.\n");
}
module_init(My_module_init);
module_exit(My_module_exit);
после подгрузки модуля вижу следующее (с добавлением некоторые отладочных сообщений):
# insmod main.ko
[ 87.361992] module initialization.
[ 87.365819] MDSTAT3_GPIO_STAT mapped 0xfee2780c
[ 87.377593] MDSTAT3_GPIO_STAT has 00001E03
[ 87.383010] MDCTL3_GPIO_CTRL mapped 0xfee27a0c
[ 87.387521] In MDCTL3_GPIO_CTRL was written 80000003
[ 87.394612] MDSTAT3_GPIO_STAT now is 00001E03
[ 87.405230] PINMUX13_ADDR mapped 0xfec14154
[ 87.410760] In PinMux13 was written 88088000
[ 87.415130] Original REVID = 0x4E840102, readed RevID_val = 0x4e840102
[ 87.438598] Target address mapped 0x01e26000-->0xfee26000
[ 87.444099] GPIO_DIR01<-00000000
[ 87.451297] GPIO_OUT_DATA01=00000000
[ 87.454937] GPIO_SET_DATA01=FFFFFFFF
[ 87.465286] GPIO_CLR_DATA01=00000000
#
Может, кто-нибудь подскажет, что я делаю не так?.. Или ещё что-то необходимо сделать?
sasamy
Пункты: 83534
Регистрация: 14.08.2009
Цитата
Или ещё что-то необходимо сделать?
Задаться вопросом - для чего это нужно в первую очередь. В ядре есть стандартный интерфейс GPIO.
galb
Пункты: 97
Регистрация: 22.08.2012
Цитата
Задаться вопросом - для чего это нужно в первую очередь. В ядре есть стандартный интерфейс GPIO.
Например, чтобы получить максимальную частоту сигнала с GPIO, Через регистры должно быть быстрее, чем при использовании функций
Jury093
Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата Например, чтобы получить максимальную частоту сигнала с GPIO, Через регистры должно быть быстрее, чем при использовании функций
для этого надо иметь сильную мотивацию и уверенность, что вы напишите код лучше существующего..
из минусов - ловля блох при отладке, хлопоты при переходе на более новые ядра, ну и возможная несовместимость кода для своего подсемейства АРМов и т.б. другой архитектуры..
сверять циферки неохота, я бы опирался на ман по АРМу:
Код 20.2.9 Initialization
The following steps are required to configure the GPIO module after a hardware reset:
1. Perform the necessary device pin multiplexing setup (see your device-specific data manual).
2. Program the Power and Sleep Controller (PSC) to enable the GPIO module. For details on the PSC,
see the Power and Sleep Controller (PSC) chapter.
3. Program the direction, data, and interrupt control registers to set the configuration of the desired GPIO
pins (described in this chapter).
The GPIO module is now ready to perform data transactions
проверьте базовые адреса регистров.. для верификации можно прочитать что-то типа
Код Table 20-3. Revision ID Register (REVID) Field Descriptions
там должно читаться
44830105h
в свое время я на nuk950 рулил из ядра пинами через регистры - никаких трудностей не было, все работало..
На любой вопрос есть любой ответ.