SPI не работает должным образом в MODE_0 на Odroid-C1. Подсистема pinctrl ядра Linux.

Я пытаюсь использовать GPS-приемник UBlox NEO-7M на плате Odroid-C1.

По умолчанию модуль GPS работает в первом режиме SPI. Вот почему я использую этот фрагмент кода пользовательского пространства, чтобы выбрать правильный режим SPI.

    int mode = SPI_MODE_0;

    ret = ioctl(spi_fd, SPI_IOC_WR_MODE, &mode);

    if (ret < 0) {
        perror("can't set spi mode");        
        exit(1);
    }   

После этого я пытаюсь прочитать байт за раз и отправить его на стандартный вывод. Однако это не сработает.

Немного подумав, я подключил свой логический анализатор Salaea и получил вот такую ​​картину

режим SPI

Это вообще не кажется правильным. Если я не ошибаюсь, SCL должен снижаться между транзакциями.

Я попытался решить эту проблему, потянув строку SCL в модуле ядра spicc.ko (я использую это ядро с RT-патчем для компиляции модуля. RT-патч на самом деле не имеет никакого значения. Проблема возникает и на ванильном ядре).

Таким образом, главный вопрос заключается в следующем: правильно ли вытаскивать этот штифт?

При дальнейшем изучении кода я заметил, что spicc_set_mode() устанавливает режим, как описано в Техническое описание Amlogic S805 (раздел 15.5.3 описывает схему регистра CONREG). Может быть, этого недостаточно?

В любом случае, каков предполагаемый способ вытащить булавку с помощью интерфейса Linux pinctrl?

Я также пытаюсь понять код spicc. Оно использует

ret = of_property_read_string(pdev->dev.of_node, "pinctrl-names", &prop_name);
if(ret || IS_ERR(prop_name)) {
    dev_err(&pdev->dev, "match pinctrl-names failed!\n");
    return -ENODEV;
}
pdata->pinctrl = devm_pinctrl_get_select(&pdev->dev, prop_name);
if(IS_ERR(pdata->pinctrl)) {
    dev_err(&pdev->dev, "pinmux error\n");
    return -ENODEV;
}
dev_info(&pdev->dev, "pinctrl_name = %s\n", prop_name);

чтобы получить дескриптор pinctrl из Blob дерева устройств, не так ли? Должен ли я редактировать файл .dts, чтобы вытащить булавку, или это можно сделать во время выполнения?

Сначала я пытался использовать его с помощью кода тупой брутальной силы, но это не сработало (pinctrl уже использует этот вывод, как указано в файле .dts в разделе spicc).

static void spicc_sclk_init(void)
{
    int ret;
    int gpio;
    char *owner = "spicc_sclk";
    char *pin_name = "GPIOX_8";

    gpio = amlogic_gpio_name_map_num(pin_name);

    if (gpio < 0) {
        printk(KERN_ERR "amlogic_gpio_name_map_num() failed. gpio: %d\n", gpio);
        goto out_map;
    }

    ret = amlogic_gpio_request(gpio, owner);

    if (ret < 0) {
        printk(KERN_ERR "amlogic_gpio_request_one() failed. ret: %d\n", ret);
        goto out_request;
    }

    ret = amlogic_set_pull_up_down(gpio, 0, owner);

    if (ret < 0) {
        printk(KERN_ERR "amlogic_set_pull_up_down() failed. ret: %d\n", ret);
        goto out_pull_up_down;
    }

out_pull_up_down:
out_request:
out_map:
    ;
}

Есть ли у кого-нибудь предложения, как можно решить эту проблему?

PS: я использую тот же код пользовательского пространства на RPi с тем же UBlox, и код работает, и режимы переключаются, как и ожидалось.

Я попытался подключить другое устройство с SPI-управлением к Odroid-C1 (если это имеет значение, это был Invensense MPU9260), и это сработало. Я предполагаю, что это просто более устойчиво к режиму SPI.


person staroselskii    schedule 06.04.2015    source источник


Ответы (1)


Возможно, в конфигурации ПИН-кода для этого ПИН-кода активировано какое-то внутреннее подтягивание. Вы можете попробовать проверить, работает ли какой-либо из режимов SPI. Еще один момент — проверить, есть ли в системе Pull-UP. И может стоит измерить напряжение в холостом состоянии.

person graugans    schedule 25.06.2015