Проблема с SPIDEV, деревом устройств и именем.dtbo с Beaglebone Black

У меня странная проблема с деревом устройств. Я обнаружил, что изменение имени.dtbo изменило поведение ядра!

Я изменил BB-SPIDEV1-00A0.dts, указанный в /lib/firmware с Angstrom:

/*
 * Copyright (C) 2013 CircuitCo
 *
 * Virtual cape for SPI1 on connector pins P9.29 P9.31 P9.30 P9.28
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
/dts-v1/;
/plugin/;

/ {
    compatible = "ti,beaglebone", "ti,beaglebone-black";

    /* identification */
    part-number = "BB-SPI1-01";
    version = "00A0";

    /* state the resources this cape uses */
    exclusive-use =
        /* the pin header uses */
        "P9.31",    /* spi1_sclk */
        "P9.29",    /* spi1_d0 */
        "P9.30",    /* spi1_d1 */
        "P9.28",    /* spi1_cs0 */
            "P9.42",    /* spi1_cs1 */
        /* the hardware ip uses */
        "spi1";

    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            /* default state has all gpios released and mode set to uart1 */
            bb_spi1_pins: pinmux_bb_spi1_pins {
                pinctrl-single,pins = <
                    0x190 0x13  /* mcasp0_aclkx.spi1_sclk,  OUTPUT_PULLUP | MODE3 */
                    0x194 0x33  /* mcasp0_fsx.spi1_d0,      INPUT_PULLUP | MODE3 */
                    0x198 0x13  /* mcasp0_axr0.spi1_d1,     OUTPUT_PULLUP | MODE3 */
                    0x19c 0x13  /* mcasp0_ahclkr.spi1_cs0,      OUTPUT_PULLUP | MODE3 */
                    0x164 0x12  /* eCAP0_in_PWM0_out.spi1_cs1   OUTPUT_PULLUP | MODE2 */
                    0x1A0 0x32  /* Other P42 pin, INPUT_PULLUP */
                >;
            };
        };
    };

    fragment@1 {
        target = <&spi1>;   /* spi1 is numbered correctly */
        __overlay__ {
            status = "okay";
            pinctrl-names = "default";
            pinctrl-0 = <&bb_spi1_pins>;

            #address-cells = <1>;
            #size-cells = <0>;

            spi1_0{
                #address-cells = <1>;
                #size-cells = <0>;

                compatible = "spidev";

                reg = <0>;
                spi-max-frequency = <16000000>;
            };


            spi1_1{
                #address-cells = <1>;
                #size-cells = <0>;

                compatible = "spidev";

                reg = <1>;
                spi-max-frequency = <16000000>;
            };
        };
    };
};

Я скомпилировал его с двумя именами: BB-SPIDEV1-00A0.dtbo и BB-SPI1-01-00A0.dtbo

Когда я загружаю один из них в /sys/devices/bone_capemgr.9/slots, spidev ведет себя по-другому!

С BB-SPIDEV1 spidev1.0 хорошо работает без каких-либо проблем. Но выбор чипа spidev1.1 не работает! Вывод 42 находится в неправильном режиме, и вывод не назначен с помощью spi1

С другой стороны, с BB-SPI1-01 (это имя не важно, если другое имя такое же, просто оно должно отличаться от BB-SPIDEV1), вывод 42 хорошо распределен:

root@beaglebone:/sys/kernel/debug/pinctrl/44e10800.pinmux# cat pinmux-pins | grep spi
pin 89 (44e10964): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 100 (44e10990): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 101 (44e10994): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 102 (44e10998): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 103 (44e1099c): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 104 (44e109a0): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins

и в хорошем режиме:

root@beaglebone:/sys/kernel/debug/pinctrl/44e10800.pinmux# cat pins | grep 964
pin 89 (44e10964) 00000012 pinctrl-single 

НО на этот раз spidev1.0 не работает по-своему. Линия MISO (так что вход для BBB), видит только 0, даже если это ложно (я проверил с помощью осциллографа).

Так в чем может быть проблема?

заранее спасибо

2 ответа

Решение

Ну, хорошо, я снова отвечаю на свой вопрос сам. На самом деле проблема была в том, что я не смог использовать второй чип выбора SPI канала 1 (spidev.1.1). Когда я попытался это сделать, появилась проблема с именами dtbo, и я отправил этот вопрос. Однако проблема с именами еще не решена.

Но проблема

НО на этот раз spidev1.0 не работает по-своему. Линия MISO (так что вход для BBB), видит только 0, даже если это ложно (я проверил с помощью осциллографа).

была решена путем изменения режима часов: 0x33 вместо 0x13. Несмотря на то, что это вывод, установка 0x33 меняет вывод на RXACTIVE_PULLUP. Должен быть включен этот способ получения данных.

Странно то, что 0x13 отлично работал с BB-SPIDEV1...

Спасибо TekuConcept за помощь по поводу регистров, если у меня появятся дополнительные моменты, я постараюсь выкопать регистры.

Установите P9_42B в режим 4 с высоким импедансом (0x2C) - в противном случае по умолчанию используется режим 4 Fast-In Pull-Down. Если этот вывод не изменен другим оверлеем, мультиплексирование не требуется для P9_42B.

Регистры SPI1 (а также регистры SPI0, I2C и GPIO2) сообщали мне об ошибках шины, когда я обращался к их регистрам, делая устройства отключенными, несмотря на то, что в соответствующих оверлейных программах их состояние было "хорошо". Итак, я проверил регистр CM_PER и достаточно точно: IDLEST=3 [disabled] а также MODULEMODE=0 [disabled], Хотя эти тесты были проведены в системе Debian, я уверен, что то же самое касается Angstrom и всех других дистрибутивов.

Чтобы включить их, вам нужно получить доступ к адресам памяти для управления питанием и часами через предпочитаемый вами язык:

Через сборку ПРУ:

.origin 0
.entrypoint START

START:
    MOV  r0, 0x44E00050 // CM_PER_SPI1_CLKCTRL Register [reset = 30000h / disabled]
    LBBO r1, r0, 0, 4   // load register value
    CLR  r1.t16         // set IDLEST to FUNC
    CLR  r1.t17
    SET  r1.t1          // set MODULEMODE to ENABLE
    SBBO r1, r0, 0, 4   // store value
    HALT

Через Python:
Beaglebone IO с использованием Python mmap

Через C / C++: (аналогично приведенному выше примеру с Python)
Ссылка от: vabi-robotics.blogspot.com

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <iostream>
#define CM_PER 0x44E00000 //PG 157

using namespace std;

int main(){
    int fd = open("/dev/mem",O_RDWR | O_SYNC);
    ulong* pinconf1 =  (ulong*) mmap(NULL, 0x0FFF, PROT_READ | PROT_WRITE, MAP_SHARED, fd, CM_PER);

    printf("INFO: %X\n", pinconf1[0x50/4]);
    pinconf1[0x50/4] = 0x00000002;
    printf("INFO: %X\n", pinconf1[0x50/4]); // conf. initialized

    return 0;
}

Примечание. Если проблема не в этом, и один канал действительно работает, убедитесь, что канал отключен, прежде чем включать следующий канал. Также убедитесь, что бит MS очищен [ мастер ], бит PIN34 очищен [ SPIEN используется в качестве выбора микросхемы ], а бит SINGLE очищен [используется более одного канала ] в регистре MCSPI_MODULCTRL (SPI1: 0x481A0128)

Другие вопросы по тегам