Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

sam3x8e проблема с прерыванием

Пт окт 28, 2022 07:08:17

добрый день

исходные:
Код:
- arm-toolchain (10.3.1, 11.x, 12.2)
- arm_gdb-12.1_py3.7
- openocd-0.12.0
- atmel ice (отладчик)
- sam3x8e (прототиа arduino-due)
- slackware-14.2 x64

отлаживаю "библиотеку" на си - передача данных по 2м проводам (wiegand):
- импульс D0 -> получили "0"
- импульс D1 -> получили "1"

будет использоваться неск. экземпляров RFID-датчиков, поэтому планирую сделать вообще без "механизмов блокировки".

в прерывании только устанавливаются флаги, все остальное делается в основном цикле.

в силу "обстоятельств" (унаследовано с прототипа) подключение пинов данных D0/D1 - на разных портах (по идее это не проблема, на ардуиновском "тестовом скетче" с таким-же расположением пинов - rfid-карта читается без проблем, но, походу, конечно протестирую еще и "все на одном порту")

текущий код на си. читает карту, но с особенностями.
к основному номеру карты (в старший разряд) добавляется еденица и последний (младший) разряд, соотв. обрезается.

для отладки по шагам вместо "виганда" подключил две кнопки (c rc-цепочкой, сигналы нормальные, дребезг отсутствует, кнопок много, менялись/проверялись)

выяснилось (в отладчике):
- импульс на D0 - прерывание срабатывает 1 раз и далее все "печенькой" :о)
- импульс на D1 - прерывание срабатывает 3 раза

1й раз - все по делу, "на падение сигнала", как и должно быть
2й раз - не по делу, "на подьем" (возвращение кнопки обратно), причем 2раза подряд

и еще для "запуток" - при чтении (без отладчика, напрямую) только одна, самая первая, неправильная 1-ца добавляется в начало (в старший разряд) а далее серийник читается правильно.

порты D0/D1 инициируются на вход, включается подтяжка, ни чего особенного.

код, выкусы (упрощенка) кода:
Код:
//
// структура (выкус)
//
struct struct_Wiegand
{
TPinOut           d0;                   // D0   пин
TPinOut           d1;                   // D1   пин

uint8_t  volatile data_flag[2]; // два флага на сработку D0/D1
...
};

typedef struct struct_Wiegand TWiegand;

extern TWiegand* lst_rfid[RFID_NUM_DEV]; // список указателей на структуры

//
// в теле реализации
//
TWiegand w1={ {PIOA,19}, {PIOC,18}, {PIOA,20}, 0, {0,0}, 0, 0 };
TWiegand* lst_rfid[RFID_NUM_DEV] = { &w1 };

//
// регистрация/добавление обработчиков прерываний
// механизм/список такой-же как в ардуино
//
isr_enb_port (lst_rfid[0]->d0.pio, lst_rfid[0]->d0.pin, isr_rfid0_D0, FALLING); // D0
isr_enb_port (lst_rfid[0]->d1.pio, lst_rfid[0]->d1.pin, isr_rfid0_D1, FALLING); // D1

//
// обработчики
//
void isr_rfid0_D0() { lst_rfid[0]->data_flag[0] ++; }
void isr_rfid0_D1() { lst_rfid[0]->data_flag[1] ++; }

других инициализаций прерываний нет (отрубал все что можно).
если закомментировать строку вызова "добавления прерывания" для D1, то прерывание на D1 не срабатывает

подобрал ссылки "околотемы"
URL1 https://forum.cxem.net/index.php?/topic/216111-прерывание-отрабатывает-два-раза-вместо-одного
URL2
URL3
URL4
URL5
URL6

пока буду изучать ссылки, доки, даташит
пинайте, кидайте помидоры, идеи, ссылки, все что угодно! можно просто побалагурить по теме! :о)
спасибо.

Re: sam3x8e проблема с прерыванием

Пт окт 28, 2022 22:45:29

ни мне бросаться Вам на помощь - опыта мало,
да и С++ не знаю, его листинг скорей угадываю, чем читаю.
из того что Вы привели:
допустим есть массив по адресу w1, его содержимое :
{ {PIOA,19}, {PIOC,18}, {PIOA,20}, 0, {0,0}, 0, 0 }

допустим это обработчики прерываний:
void isr_rfid0_D0() { lst_rfid[0]->data_flag[0] ++; }
void isr_rfid0_D1() { lst_rfid[0]->data_flag[1] ++; }

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

заглянул библиотеку на github, там про данный момент в прерываниях все натурально:
для "0":
_bitCount++; // счетчик импульсов
_cardTemp <<=1; // куда падают битики
для "1":
_bitCount ++;
_cardTemp |= 1;
_cardTemp <<=1;

_cardTemp - содержит принятую инфу.

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

Re: sam3x8e проблема с прерыванием

Сб окт 29, 2022 07:25:06

привет, a797945!

по ходу:
С++
библиотека пишется на Си

обработчики прерываний:

Код:
void isr_rfid0_D0() { lst_rfid[0]->data_flag[0] ++; }
void isr_rfid0_D1() { lst_rfid[0]->data_flag[1] ++; }

у меня "сделано" по другому :))
в обработчике поднимаются "флаги сработки" а в основном цикле идет основная работа по анализу
к стати, ++ в данном случае используется для отладки, от куда я и понял, что прерывание вызывается не один раз
в конечном итоге ++ меняется на установку еденицы
заглянул библиотеку на github

там реализация под "мандарину" на плюсАх (я пишу свою реализацию)
на контроллере EXTI

я тоже глянул "свои" ссылки, там об этом тоже говориться, но, на ск. я понял это под stm
а в даташите на данный чип, в разделе NVIC нет подобного упоминания

п.с.
проблема "более менее" локализована :shock: аж до смешного (но механизм проявления все-равно не понятен)
перевешиваем пины данных D0/D1 на один порт и все пучком...

спасибо

Re: sam3x8e проблема с прерыванием

Сб окт 29, 2022 08:36:58

увлекся писаниной ттолько потом допер, что ++ для отладки :)
EXTI упомянул по аналогии, но именно в сторону "железа" я б и разбирался. Что, на пример, с распределением по портам, что со сбросом флагов и т.д. Т.е. по ближе познакомится с применяемым механизмом.
Заглянул бы в листинг на участок инита прерываний - что компиль грузит в регистры "EXTI"
Ответить