Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:0
Поисковых ботовПоисковых ботов:2
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:3
Форум » starterkit.ru » Процессорные модули » SK-MVF6-NANO
GPIO пропуск импульсов
MalVal
Добавлено 19.05.2016 11:57
0
Сообщение: 1
MalVal
0

Пункты: 3131
Регистрация: 04.06.2013
Приветствую!
Помогите разобраться с проблемой, пожалуйста.

Модуль SK-MVF6-NANO установлен в наше устройство. К нему по SPI подключен IMU ADIS16485.
На пин 38 (GPIO/JTDI) подан сигнал DATA-READY от ADIS16485 - сигнал о готовности данных. По этому сигналу мне необходимо получать данные от ADIS16485. Импульс имеет обратную полярность. Ширина импульса порядка 10 мкс (jitter 1.4мкс). Пин 38 подтянут к "+" через резистор 10к. Осциллографом импульс наблюдаю. Причем с той частотой, с которой я конфигурирую ADIS16485.

Ядро Linux-3.1.2. В ядре настроил 38 пин на GPIO:
Код
#define MVF600_PAD02_PTA9_SPI_READY \
IOMUX_PAD(0x0008, 0x0008, 0, 0x0000, 0, \
MVF600_GPIO_GENERAL_CTRL | PAD_CTL_IBE_ENABLE)

В spi_dev.c на этот GPIO повесил прерывание. В нем считаю число полученных импульсов и на каждом 1000-м импульсе вывожу разницу по времени:
Код
static irq_handler_t spidev_irq_handler(unsigned int irq, void *dev_id, struct pt_regs *regs)
{
++nIrqCount;
if (0 == (nIrqCount % 1000))
{
getnstimeofday(&ts_current); // Get the current time as ts_current
ts_diff = timespec_sub(ts_current, ts_last); // Determine the time difference between last 2 presses
ts_last = ts_current; // Store the current time as the last time ts_last

printk(KERN_INFO "%lu %lu.%.9lu\n", nIrqCount , ts_diff.tv_sec, ts_diff.tv_nsec);
//tick = prev_tick;
}
return (irq_handler_t) IRQ_HANDLED; // Announce that the IRQ has been handled correctly
}

Далее настраиваю ADIS16485 на частоту выдачи 60 Гц. И вижу пропуск импульсов:
90000 48.163889943
91000 47.913995563
92000 49.380072441
93000 48.330490609
94000 48.780305261
95000 48.513764441
96000 49.013545033
97000 48.297182426
98000 48.830298125
99000 49.096848850
100000 49.080198033
Частота примерно в три раза меньше. И она плавает.

Пробовал разные частоты, от исходной - 2460Гц, до 6Гц. Всегда наблюдаю пропуск и частоту прерываний примерно в три раза меньше заданной.

Куда копать?
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 19.05.2016 12:30 Редактировалось 19.05.2016 12:32 Сообщение: 2
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Обработчик прерываний от GPIO как настраиваете при регистрации ISR - по уровню или по фронту ?

http://lxr.free-electrons.com/source/include/linux/interrupt.h#L144

unsigned long flags = ?
Спуститься к концу Подняться к началу
Персональная информация
MalVal
Добавлено 19.05.2016 13:08 Сообщение: 3
MalVal
0

Пункты: 3131
Регистрация: 04.06.2013
sasamy,
По восходящему фронту (в доке на ADIS готовность данных).
Попробовал IRQF_TRIGGER_LOW и gpio_set_debounce на 1мс.
Теперь пошли какие-то бешенные частоты.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 19.05.2016 13:45 Редактировалось 19.05.2016 13:48 Сообщение: 4
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Цитата
По восходящему фронту


по фронту должно быть ОК, к сожалению нет такой платы и знаком с процессором поверхностно.
Попробуйте протестировать по-другому

http://www.starterkit.ru/html/index.php?name=forum&op=view&id=16886#16926

только учитывайте что там для imx233 пины написаны.
Спуститься к концу Подняться к началу
Персональная информация
MalVal
Добавлено 19.05.2016 14:01 Редактировалось 19.05.2016 14:03 Сообщение: 5
MalVal
0

Пункты: 3131
Регистрация: 04.06.2013
Тут пришла мысль.
Если по IRQF_TRIGGER_LOW я ловлю дребезг, может просто по прерыванию взводить таймер на 12-15 мкс и по его срабатыванию забрать данные.
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 19.05.2016 14:54 Редактировалось 19.05.2016 14:54 Сообщение: 6
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата
Если по IRQF_TRIGGER_LOW я ловлю дребезг, может

LOW/HIGH - это прерывание по уровню
вам нужно RISING/FALLING - это по фронту..
а перед этив доке на проц прочитать - понимает ли он на прерывание от gpio нужный режим..

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
MalVal
Добавлено 20.05.2016 08:01 Сообщение: 7
MalVal
0

Пункты: 3131
Регистрация: 04.06.2013
В общем, разобрались.
В драйвере GPIO в режиме входа принудительно включаются цифровые фильтры, видимо для устранения дребезга. Отключил - получаю прерывания с установленной частотой.
Конкретнее, файл $KERNEL_PATH/arch/arm/plat-mxc/gpio-mvf.c:
Код
static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
int dir)
{
struct mxc_gpio_port *port =
container_of(chip, struct mxc_gpio_port, chip);
u32 l;
unsigned long flags;
void __iomem *pad_addr;

spin_lock_irqsave(&port->lock, flags);

/*Get the corresponding IOMUX register*/
pad_addr = MVF_IO_ADDRESS(
MVF_IOMUXC_BASE_ADDR + 4 * (chip->base + offset));

if (dir)
l = MVF600_GPIO_GENERAL_CTRL | PAD_CTL_OBE_ENABLE;
else {
l = MVF600_GPIO_GENERAL_CTRL | PAD_CTL_IBE_ENABLE;
// отключаем цифровые фильтры:
/*__raw_writel((1 << offset), port->base_int + GPIO_DFER);
__raw_writel(1, port->base_int + GPIO_DFCR);
__raw_writel(0xFF, port->base_int + GPIO_DFWR);*/
}

/*Note: This will destroy the original IOMUX settings.*/
__raw_writel(l, pad_addr);

spin_unlock_irqrestore(&port->lock, flags);
}


Всем спасибо за подсказки.
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Процессорные модули » SK-MVF6-NANO