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

Приветствую!

Среда: простейшая прошивка, написанная с использованием SDK_2.2_MCIM6ULL, скачанного с сайта NXP.

Возникла странная проблема: я настраиваю вход GPIO4[22] на обработку прерывания по спаду сигнала и предполагаю, что обработчик прерывания будет вызываться один раз после одного active-low импульса сигнала длительностью около 200 мкс. Однако по факту вызов обработчика происходит два раза, при этом во время первого вызова состояние пина GPIO4[22], прочитанное с использованием функции GPIO_ReadPinInput(GPIO4, 22), вполне ожидаемо равно 0. При втором (повторном) вызове обработчика состояние пина уже равно 1, что совсем неожиданно, т.к. прерывание должно быть только по спаду сигнала.

Я проверил значения регистров ICR2 - в нем в соответствующих битах установлено значение 11b, в регистре EDGE_SEL все биты равны нулю. В самом обработчике после проверки бита прерывания (GPIO_GetPinsInterruptFlags(GPIO4) & (1U << 22)) выполняется сброс флага прерывания с помощью вызова GPIO_ClearPinsInterruptFlags(GPIO4, 1U << 22). Т.е. сначала читается значение ISR и проверяется наличие бита прерывания, потом сбрасывается значение этого бита для подтверждения обработки прерывания. При этом я проверял, что значение бита в ISR действительно сбрасывается, т.е. на момент выхода из обработчика прерывания значение регистра ISR равно нулю.

Фронты сигнала чистые, длительность менее 10 нс, проверял осциллографом. Включение гистерезиса на входе эффекта не даёт.

В Errata ничего на этот счет нет. При этом проблема не с одним битом GPIO4[22],  но и с GPIO4[23] наблюдается то же самое поведение.

Кто-нибудь сталкивался с подобным поведением i.MX6? Что это может быть за мистика?

 

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


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

Ситуация, очень похожая на мою проблему: https://community.nxp.com/t5/i-MX-Processors/MX6ul-var-dart-dtsi-for-gpio-input-only-on-falling-edge/m-p/655519

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


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

38 minutes ago, makc said:

Ситуация, очень похожая на мою проблему: https://community.nxp.com/t5/i-MX-Processors/MX6ul-var-dart-dtsi-for-gpio-input-only-on-falling-edge/m-p/655519

Очевидно источник прерывания не сбрасывается несмотря на проверку чтением.  
Либо кэширование, либо тормоза на шине периферии.
Как вариант не торопиться и дать задержку в обработчике,  сбрасывать источник после команды барьера, или два раза сбрасывать.  
 

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


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

Делал задержку 10 мкс - не помогает.

Барьеры ставил - без результата.

Отключал кеш и MMU - не помогло.

Ещё одна подобная тема: https://community.nxp.com/t5/i-MX-Processors/Push-button-Interrupt-comes-for-both-edge-even-though-configured/m-p/918781

4 минуты назад, AlexandrY сказал:

Либо кэширование, либо тормоза на шине периферии.

Проверял эту гипотезу путем чтения и последующей записи в регистр DR бита для другого тестового пина. Получил честный меандр. Так что скорее всего дело не в этом. 

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


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

23 часа назад, makc сказал:

Кто-нибудь сталкивался с подобным поведением i.MX6? Что это может быть за мистика?

в качестве гипотезы, раз нет исходников для просмотра - попробуйте все то же самое с пином из банка GPIO3

и возможно забыли разрешить тактирование для GPIO4, т.к. в SDK в примере:

CCM->CCGR3 = 0xFF3CC300U;

под линуксом в imx6ull вроде проблем не было с gpio interrupt, разве что там в конце инита gpio чистят ISR, но у вас стендалоне и это не требуется

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


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

13 минут назад, Jury093 сказал:

в качестве гипотезы, раз нет исходников для просмотра - попробуйте все то же самое с пином из банка GPIO3

Пробовал, там изредка наблюдались подобные проблемы, но намного намного реже. Пробовал и с GPIO1, с которого всё и началось из-за возникновения прерываний по спаду под Linux, в обработчике которых значение линии было равно единице.

17 минут назад, Jury093 сказал:

и возможно забыли разрешить тактирование для GPIO4, т.к. в SDK в примере:

CCM->CCGR3 = 0xFF3CC300U;

Да, в примере такая настройка по-умолчанию. Но при этом вызов функции GPIO_PinInit включает необходимые тактовые сигналы GPIO:

void GPIO_PinInit(GPIO_Type* base, uint32_t pin, const gpio_pin_config_t* Config)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    /* Enable GPIO clock. */
    CLOCK_EnableClock(s_gpioClock[GPIO_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

При этом макрос FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL не определен, а если проследить содержимое массива s_gpioClock, то получается следующее:

...
      kCLOCK_Gpio4          = (3U << 8) | 0x6U,     /*!< CCGR3, CG6  */
...

/*! @brief Clock ip name array for GPIO. */
#define GPIO_CLOCKS                                                  \
    {                                                                \
        kCLOCK_IpInvalid, kCLOCK_Gpio1, kCLOCK_Gpio2,                \
        kCLOCK_Gpio3, kCLOCK_Gpio4, kCLOCK_Gpio5                     \
    }

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Array of GPIO clock name. */
static const clock_ip_name_t s_gpioClock[] = GPIO_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

Поскольку у меня настройка выполняется именно с помощью функции GPIO_PinInit():

	static const gpio_pin_config_t input_pin_config = {
		.direction     = kGPIO_DigitalInput,
		.outputLogic   = 0, // default value
		.interruptMode = kGPIO_IntFallingEdge
	};

	IOMUXC_SetPinMux(IOMUXC_CSI_DATA01_GPIO4_IO22, 0U);
	IOMUXC_SetPinConfig(IOMUXC_CSI_DATA01_GPIO4_IO22,
			    IOMUXC_SW_PAD_CTL_PAD_HYS_MASK);
	GPIO_PinInit(GPIO4, 22, &input_pin_config);

То я полагаю, что необходимый тактовый сигнал включается. Но в понедельник на всякий случай всё же проверю, что в регистре CCM->CCGR3

22 минуты назад, Jury093 сказал:

под линуксом в imx6ull вроде проблем не было с gpio interrupt, разве что там в конце инита gpio чистят ISR, но у вас стендалоне и это не требуется

Судя по вышеприведенным ссылкам проблемы все же есть. И у меня они тоже наблюдались, как я сказал выше. Но на порядки реже, чем в standalone с GPIO4.

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


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

12.03.2021 в 20:30, makc сказал:

Кто-нибудь сталкивался с подобным поведением i.MX6? Что это может быть за мистика?

Делал программный УАРТ, в приемнике так же выставлял прерывание по спаду (фиксирование старт бита), все норм, мистики не заметил. Проц IMX6S.

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


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

На каком GPIO был этот UART? Какие были настройки входного пина в IOMUX?

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


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

2 часа назад, makc сказал:

На каком GPIO был этот UART?

Инициализация:

disable_interrupt(IMX_INT_GPIO4_INT15_0, CPU_0);
  SetPortIN (PORTD,9,IO_IN_PU); 
  gpio_clear_interrupt(PORTD,9);
  gpio_set_interrupt_config(PORTD,9, GPIO_ICR_FALL_EDGE);//---\____
  gpio_set_interrupt_mask(PORTD,9, GPIO_IMR_MASKED);//enable intr
  register_interrupt_routine(IMX_INT_GPIO4_INT15_0,Intr_suart_gpio);
  enable_interrupt(IMX_INT_GPIO4_INT15_0, CPU_0, 0);
 

Что там в IOMUX было не помню, задавалось в SetPortIN ().

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


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

3 часа назад, mantech сказал:

SetPortIN (PORTD,9,IO_IN_PU); 

Я правильно понимаю, что эта строка включает подтяжку на входе?

С подтяжкой я не пробовал тестировать, т.к. у меня она внешняя. Завтра попробую добавить и проверить реакцию.

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


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

1 час назад, makc сказал:

Я правильно понимаю, что эта строка включает подтяжку на входе?

Именно так.

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


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

13.03.2021 в 20:15, Jury093 сказал:

CCM->CCGR3 = 0xFF3CC300U;

Проверил. У меня после инициализации значения другие: CCM->CCGR3 = 0xFF3CF300. Т.е. тактирование разрешено.

11 часов назад, mantech сказал:

Именно так

Установка pull-up не помогла, хотя я не очень-то на это надеялся.

Попробовал сделать loopback на другой паре пинов на GPIO4: один пин формирует меандр с периодом 2 секунды, другой настроен на прерывание по спаду. Все работает как ожидалось, по одному прерыванию на период, четко по переключению из 1 в 0.

Дополнение: проверил в режиме loopback проблеммный вход GPIO4[22] и при генерации 128000 импульсов на другом контакте процессора было получено 128000 прерываний по спаду. Т.е. налицо проблема в источнике сигнала, хотя по виду на осциллографе сигнал был чистым.

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


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

1 час назад, makc сказал:

Проверил. У меня после инициализации значения другие: CCM->CCGR3 = 0xFF3CF300. Т.е. тактирование разрешено.

Установка pull-up не помогла, хотя я не очень-то на это надеялся.

Попробовал сделать loopback на другой паре пинов на GPIO4: один пин формирует меандр с периодом 2 секунды, другой настроен на прерывание по спаду. Все работает как ожидалось, по одному прерыванию на период, четко по переключению из 1 в 0.

Дополнение: проверил в режиме loopback проблеммный вход GPIO4[22] и при генерации 128000 импульсов на другом контакте процессора было получено 128000 прерываний по спаду. Т.е. налицо проблема в источнике сигнала, хотя по виду на осциллографе сигнал был чистым.

да, ff3cf300 - тактирование банка 4 разрешено. ок

т.е. все-таки дребезг, с утра была такая мысль посоветовать чистоту фронтов посмотреть, но в исходном было, что чистый импульс длительностью и решил, что тут все норм.

заработало - поздравляю

ЗЫ у меня под рукой 6ull но у него доступен gpio только с заведомо дребежащим входом и тогда мое моделирование не помогло бы..

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


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

2 часа назад, makc сказал:

Т.е. налицо проблема в источнике сигнала

Что и требовалось доказать - никакой мистики)) А вот где мистика действительно была, так это в аппаратных уартах данного проца, ибо мне так и не удалось запустить его в режиме 9 бита, хотя с четностью все работает, и у приемника бывает зацикливание (начинает принимать постоянно 0 при том, что на входе стоит единица, если до этого длительное время был очень шумный сигнал)...

Изменено пользователем mantech

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


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

1 час назад, Jury093 сказал:

т.е. все-таки дребезг, с утра была такая мысль посоветовать чистоту фронтов посмотреть, но в исходном было, что чистый импульс длительностью и решил, что тут все норм.

tek00000.thumb.png.f366960761731bb3826684fd2692cc78.png

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

1 час назад, Jury093 сказал:

заработало - поздравляю

Не совсем заработало, но пока есть небольшое продвижение. По крайней мере на двух платах эта логика ведет себя абсолютно одинаково.

1 час назад, mantech сказал:

Что и требовалось доказать - никакой мистики))

Только пока непонятно, как всё таки пронаблюдать источник проблемы. См. осциллограмму. По ней совсем не очевидно, что должно быть лишнее прерывание по фронту (нарастанию) сигнала.

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


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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...