реклама на сайте
подробности

 
 
 
Closed TopicStart new topic
> GPIO в AM1808
_galb_
сообщение Aug 22 2012, 08:54
Сообщение #1





Группа: Участник
Сообщений: 12
Регистрация: 22-08-12
Пользователь №: 73 215



Доброго времени суток всем!

У меня есть отладочная плата с процессором AM1808 (http://www.starterkit.ru/html/index.php?name=shop&op=view&id=70&word=AM1808). На процессоре установлен Linux (2.6.37). Не получается завести GPIO sad.gif Вот что я делаю:

CODE
#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
#

Может, кто-нибудь подскажет, что я делаю не так?.. Или ещё что-то необходимо сделать?
Go to the top of the page
 
+Quote Post
Dron_Gus
сообщение Aug 22 2012, 10:06
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



А почему не использовать gpiolib?


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 22 2012, 10:27
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(_galb_ @ Aug 22 2012, 12:54) *
после подгрузки модуля вижу следующее (с добавлением некоторые отладочных сообщений):

Не совсем понятно, что Вы хотите увидеть и какой вывод делаете из увиденного.
ID читается, регистры пишутся, что не так?
Go to the top of the page
 
+Quote Post
_galb_
сообщение Aug 22 2012, 10:40
Сообщение #4





Группа: Участник
Сообщений: 12
Регистрация: 22-08-12
Пользователь №: 73 215



Цитата(aaarrr @ Aug 22 2012, 17:27) *
Не совсем понятно, что Вы хотите увидеть и какой вывод делаете из увиденного.
ID читается, регистры пишутся, что не так?


не происходит изменения состояния выводов, когда я отправляю туда что-нибудьsm.gif проверка чтения RevID как раз и была нужна для того, чтоб убедиться, правильным ли методом я обращаюсь к регистрам

Цитата(Dron_Gus @ Aug 22 2012, 17:06) *
А почему не использовать gpiolib?


функции gpoilib предназначены для работы из userspace, или я ошибаюсь?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 22 2012, 10:55
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(_galb_ @ Aug 22 2012, 14:40) *
не происходит изменения состояния выводов, когда я отправляю туда что-нибудьsm.gif

То есть выводы остаются в режиме входа с "1" за счет pull-up?
Просто я, например, не представляю как можно зафиксировать цикл из 1000 переключений.
Go to the top of the page
 
+Quote Post
_galb_
сообщение Aug 22 2012, 11:04
Сообщение #6





Группа: Участник
Сообщений: 12
Регистрация: 22-08-12
Пользователь №: 73 215



Цитата(aaarrr @ Aug 22 2012, 17:55) *
То есть выводы остаются в режиме входа с "1" за счет pull-up?
Просто я, например, не представляю как можно зафиксировать цикл из 1000 переключений.


Ну хорошо, если вместо этого цикла я вставлю

GPIO_CLR_DATA01 = 0xffffffff; // pin low

то на пине всё равно висит "1" - не работает...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 22 2012, 11:13
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Вместо int следует использовать volatile int - все же с регистрами работаем.
Ошибок с адресами вроде не видно.
Go to the top of the page
 
+Quote Post
_galb_
сообщение Aug 22 2012, 11:37
Сообщение #8





Группа: Участник
Сообщений: 12
Регистрация: 22-08-12
Пользователь №: 73 215



может быть, есть важные моменты при сборке ядра linux (кроме разрешения GPIO)?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 22 2012, 12:01
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(_galb_ @ Aug 22 2012, 15:37) *
может быть, есть важные моменты при сборке ядра linux (кроме разрешения GPIO)?

Нет: питание GPIO включено, PINMUX настроен. Более ничего и не требуется.
Go to the top of the page
 
+Quote Post
Dron_Gus
сообщение Aug 22 2012, 12:38
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



Цитата(_galb_ @ Aug 22 2012, 14:40) *
функции gpoilib предназначены для работы из userspace, или я ошибаюсь?

Нет. Их используют в ядре. Смотрите drivers/gpio/. И конкретно gpiolib.c.
Из юзерспейса проще всего пользоваться /sys/class/gpio/


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 22 2012, 12:44
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Dron_Gus @ Aug 22 2012, 16:38) *
Нет. Их используют в ядре. Смотрите drivers/gpio/. И конкретно gpiolib.c.
Из юзерспейса проще всего пользоваться /sys/class/gpio/

Чтобы всем этим добром пользоваться, нужно будет пересобирать ядро с модификацией PINMUX'ов для нужных пинов.
Go to the top of the page
 
+Quote Post
_galb_
сообщение Aug 31 2012, 07:53
Сообщение #12





Группа: Участник
Сообщений: 12
Регистрация: 22-08-12
Пользователь №: 73 215



Цитата(aaarrr @ Aug 22 2012, 19:44) *
Чтобы всем этим добром пользоваться, нужно будет пересобирать ядро с модификацией PINMUX'ов для нужных пинов.


Сработало!!! Огромное спасибо aaarrr'у за помощь!;) Напишу, как было дело, вдруг кому-нибудь понадобитсяsm.gif

Итак, для того, чтобы подёргать пином GPIO, надо:

1. Добавить конфигурационную строчку для соответствующего пина в структуру mux_config da850_pins (файл arch/arm/mach-davinci/da850.c). В моём случае это
Код
        ...
    MUX_CFG(DA850, GPIO6_11,        13,     16,     15,     8,      false)
        ...

где:
13 - номер регистра PINMUX, в котором выбирается режим работы пина;
16 - смещение поля PRU0_R30[29]/UHPI_HCNTL0/UPP_CHA_CLOCK/GP6[11] в регистре PINMUX13;
15 - маска для режима работы пина (вроде бы, везде = 15);
8 - выбор функции GP6[11];

2. В файле arch/arm/linux-davinci/include/mach/mux.h добавить в enum davinci_da850_index необходимый пин:
Код
        ...
    DA850_GPIO6_11,
        ...

Причём надо, чтобы позиции в enum'е и структуре из п.1 совпадали, иначе съедут все привязки.

3. В файле board-l138-owlboardplus.c в функции owlboardplus_init проинициализировать нужный пин:
Код
    ret = davinci_cfg_reg(DA850_GPIO6_11);

Здесь в качестве аргумента функции следует указать значение из enum'а (файла mux.h)

4. Пересобрать ядро. При этом в файле .config должны быть сделаны соответствующие настройки, чтоб функциями GPIO можно было пользоваться.

5. Теперь в модуле ядра можно использовать функции gpio! К примеру:
CODE
#include <linux/kernel.h>
#include <linux/module.h>

#include <asm/gpio.h>
#include <mach/mux.h>

#define MYPIN0 GPIO_TO_PIN(6, 11)

MODULE_LICENSE("GPL");

static int My_module_init(void) {
int ret = 0;

printk(KERN_ALERT "My module initialization.\n");

ret = gpio_request(MYPIN0, "My pin 0");
if (ret) {
printk(KERN_WARNING "Unable to request MYPIN0, error %d\n", ret);
return ret;
}

gpio_direction_output(MYPIN0, 0);

gpio_set_value(MYPIN0, 0);
gpio_set_value(MYPIN0, 1);
gpio_set_value(MYPIN0, 0);

return 0;
}

static void My_module_exit(void) {
gpio_free(MYPIN0);
printk(KERN_ALERT "My module exit.\n");
}

module_init(My_module_init);
module_exit(My_module_exit);

Go to the top of the page
 
+Quote Post

Closed TopicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 17:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01464 секунд с 7
ELECTRONIX ©2004-2016