Перейти к содержанию

    

Как в linux переназначить светодиод на другой GPIO?

Есть отладочная плата с Altera SoC у которой светодиод, задействованный в linux (моргает при загрузке/работе HPS), выведен на GPIO53.

Хочу вывести его на другой GPIO. Подскажите, пожалуйста, как его правильно переназначить.

Пробовал вручную править dts, а затем собирать его в dtb, но это не сработало.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
13 минут назад, BSACPLD сказал:

Есть отладочная плата с Altera SoC у которой светодиод, задействованный в linux (моргает при загрузке/работе HPS), выведен на GPIO53.

Хочу вывести его на другой GPIO. Подскажите, пожалуйста, как его правильно переназначить.

Пробовал вручную править dts, а затем собирать его в dtb, но это не сработало.

для начала надо проверить/изменить настройки в QSYS для выбранного пина

если конфигурацию поменяли, то пересобрать настройки в QSYS, потом пересобрать бутлоадер и u-boot, после этого прописать в dts нужную функцию для этого gpio

простейшую проверку выбранного, но ненстроенного пина можно сделать прямо из uboot, записывая командами "запись в память" настроек в блоке регистров (в консоли uboot команда "help")

полистать доку на свой кит - может там где описаны свободные настроеные пины в режиме gpio - задействовать их под класс leds

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если система в QSYS не менялась и есть свободный GPIO, достаточно просто пересобрать dtb?

Просто я пробовал вообще убрать светодиод из dts чтобы его отключить, но даже с пересобранным dtb он продолжил моргать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

UPD.

Нашел в чем была проблема с переназначением светодиода на уже имеющийся GPIO.

В u-boot.scr неправильно указал имя файла.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очередные грабли.

Пересобрал preloader и u-boot.

Подправил dts и сделал из него dtb.

Закинул все это дело на SD карту, но проект заработал не так как я ожидал.

GPIO53, 54, 55, 56 настроены как GPIO. I2C0 отключен.

Светодиоды прописаны следующим образом:

Для HPS.

leds {
		compatible = "gpio-leds";

		hps0 {
			label = "hps_led0";
			gpios = <0x33 0x18 0x0>;
			linux,default-trigger = "heartbeat";
		};

		hps1 {
			label = "hps_led1";
			gpios = <0x33 0x19 0x0>;
			linux,default-trigger = "heartbeat";
		};

		hps2 {
			label = "hps_led2";
			gpios = <0x33 0x1a 0x0>;
			linux,default-trigger = "heartbeat";
		};

		hps3 {
			label = "hps_led3";
			gpios = <0x33 0x1b 0x0>;
			linux,default-trigger = "heartbeat";
		};
	};

Для FPGA.

leds {
			compatible = "gpio-leds";

			fpga0 {
				label = "fpga_led0";
				gpios = <0x31 0x0 0x0>;
				linux,default-trigger = "heartbeat";
			};

			fpga1 {
				label = "fpga_led1";
				gpios = <0x31 0x1 0x0>;
				linux,default-trigger = "heartbeat";
			};

			fpga2 {
				label = "fpga_led2";
				gpios = <0x31 0x2 0x0>;
				linux,default-trigger = "heartbeat";
			};

			fpga3 {
				label = "fpga_led3";
				gpios = <0x31 0x3 0x0>;
				linux,default-trigger = "heartbeat";
			};
		};

По идее все светодиоды должны моргать одновременно, но:

1) 2 и 3 светодиоды на HPS вообще не моргают. Причем это именно те GPIO на которые в изначальном проекте был выведен I2C0. Я его отключил, но они все равно не работают.

2) Светодиоды на HPS и FPGA переключаются по очереди.

Что я делаю не так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
11 часов назад, BSACPLD сказал:

1) 2 и 3 светодиоды на HPS вообще не моргают. Причем это именно те GPIO на которые в изначальном проекте был выведен I2C0. Я его отключил, но они все равно не работают.

2) Светодиоды на HPS и FPGA переключаются по очереди.

Что я делаю не так?

я не понял - кто управляет светиками в фпга части? разделите задачу, для начала

dmesg | grep gpio

нет ли там ругани..

далее, отключите пины в классе leds и попробуйте через класс gpio потестить

echo NN > /sys/class/gpio/export

где NN логический номер требуемого gpio

если заработало, будете разбираться с leds

если нет, то ищите, где ошиблись qsys, preloader, u-boot, что-нить забыли обновить..

с фпга децл посложнее, но тоже решаемо.. loan io кажись..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для настройки GPIO со стороны HPS пользовался этой инструкцией:

https://support.criticallink.com/redmine/boards/45/topics/4148

https://support.criticallink.com/redmine/projects/mityarm-5cs/wiki/Linux_GPIO_Chip_Mapping

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Написал программу для тестирования GPIO.

dts переделал так чтобы система моргала только GPIO53 (linux,default-trigger = "heartbeat").

Остальными GPIO управляет моя программа.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>

int main()
{
    int fd = 0;
    void *fpga_leds = 0;
    void *hps_leds  = 0;

    try
    {
        fd = open( "/dev/mem", O_RDWR | O_SYNC );
        if(fd < 0)
            throw "mem open error";

        printf("fpga_leds\n");

        fpga_leds = (mmap(0, (16/4), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xFF203000));
        if(fpga_leds == MAP_FAILED)
            throw "fpga_leds mmap error";

        for(int i=0 ; i<(16/4) ; i++)
        {
            uint32_t a = *(((uint32_t*)fpga_leds) + i);
            printf("0x%08X\n", a);
        }

        *(((uint32_t*)fpga_leds) + 0) = 0x0000000F;
        usleep(1000000);
        *(((uint32_t*)fpga_leds) + 0) = 0x00000000;
        usleep(1000000);
        *(((uint32_t*)fpga_leds) + 0) = 0x0000000A;
        usleep(500000);
        *(((uint32_t*)fpga_leds) + 0) = 0x00000005;
        usleep(500000);
        *(((uint32_t*)fpga_leds) + 0) = 0x0000000A;
        usleep(500000);
        *(((uint32_t*)fpga_leds) + 0) = 0x00000005;
        usleep(500000);
        *(((uint32_t*)fpga_leds) + 0) = 0x0000000F;

        printf("\n");

        usleep(1000000);

        printf("hps_leds\n");

        hps_leds = (mmap(0, (120/4), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xFF709000));
        if(hps_leds == MAP_FAILED)
            throw "hps_leds mmap error";

        for(int i=0 ; i<(120/4) ; i++)
        {
            uint32_t a = *(((uint32_t*)hps_leds) + i);
            printf("0x%08X\n", a);
        }

        for(int i=0 ; i<32 ; i++)
        {
            *(((uint32_t*)hps_leds) + 0) = 1 << i;
            usleep(500000);
        }

        *(((uint32_t*)fpga_leds) + 0) = 0x00000000;

        *(((uint32_t*)hps_leds) + 0) = 0xFFFFFFFF;
        usleep(500000);

        printf("\n");
    }
    catch(const char* msg)
    {
        printf("\n%s\n", msg);
    }

    if(fd != 0)
        close(fd);

    return 0;
}

GPIO со стороны FPGA отображенные в память процессора работают нормально, а вот со стороны HPS удается зажечь только первые 2 из 4.

И ещё странный эффект. После того как я записываю 1 в GPIO54 он должен непрерывно гореть, но он сбрасывается после того как система моргнет GPIO53.

 

P.S.

Описание регистров и их адреса я брал вот отсюда:

https://www.intel.com/content/www/us/en/programmable/hps/cyclone-v/hps.html#topic/sfo1410069909712.html#sfo1410069909712

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пробовал через loanio. Такой вариант вообще не работает.

Пробовал на GPIO54, 55, 56.

Т.е. сам linux стартует, но переключать пины настроенные как loanio не получается (на oe подавал 1, out выводил на кнопки).

Причем если GPIO54 настроить как gpio, то он начинает работать. 55 и 56 не удалось заставить работать ни как gpio, ни как loanio.

Подозреваю, что дело в некорректной настройке pinmux в preloader.

Пробовал собирать preloader как в 15.1, так и в 18.0. Результат один и тот же.

u-boot также пересобирал.

Где-то читал, что вроде начиная с 13.1 loanio и gpio окончательно поломали. Так ли это?

Во всяком случае очень похоже, т.к. при чтении регистров GENERALIO7 (GPIO55, 0xFFD0849C) и GENERALIO8 (GPIO56, 0xFFD084A0) для варианта gpio возвращается 1, хотя согласно документации там должен быть 0. При этом для GENERALIO6 (GPIO54, 0xFFD08498), который работает, как и положено, возвращается 0.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Заработало :)

Я сам себе злобный буратино :) Копировал preloader не в тот раздел sd карты.

Остался только вопрос почему linux пишет сразу во все gpio хотя я прописал

linux,default-trigger = "heartbeat";

только для GPIO53.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти