Hejto.pl
Dodaj post

Wpisz coś do wyszukania (minimum 2 znaki)

#baremetal

Gruba ryba

w Programowanie

4piorunów

Uruchamiam STM32F103C8, a konkretnie EXTI na liniach PA0 ... PA4. Siedzą na tych pinach zwykłe przełączniki typu pushbutton. Rozwikłałem reference manual na tyle, że jedno przerwanie działa, ale inne mimo takiej samej składni przy każdym pinie już nie chcą.

GPIO ustawiam:
>GPIOA->CRL &= ~GPIO_CRL_CNF0_0; // floating input to pull-down
>GPIOA->CRL |= GPIO_CRL_CNF0_1;
Puszczam zegar do EXTI (w tym procku AFIO):
>RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
Zdejmuję maskę z interesujących pinów:
>EXTI->IMR |= EXTI_IMR_MR0 | EXTI_IMR_MR1 | EXTI_IMR_MR2 | EXTI_IMR_MR3 | EXTI_IMR_MR4;
Ustawiam reakcję na zbocze narastające:
>EXTI->RTSR |= EXTI_RTSR_TR0 | EXTI_RTSR_TR1 | EXTI_RTSR_TR2 | EXTI_RTSR_TR3 | EXTI_RTSR_TR4;
Dodaję priorytety przerwania i uruchamiam przerwania (tu tylko po jednym żeby nie mnożyć):
>NVIC_SetPriority(EXTI0_IRQn, 1);
>NVIC_EnableIRQ(EXTI0_IRQn);
Przykładowe przerwanie:
>__attribute__((section(".after_vectors"))) void EXTI0_IRQHandler()
>{
>   printf("++ \\r\\n");
>   EXTI->PR |= EXTI_PR_PR0;
>}

Co bym nie robił tak działa tylko jedno przerwanie i to z PA2. Wiązać pinów z EXTI niby nie muszę (po resecie akurat się zgrywają), ale robię to dla pewności, nie widzę już gdzie szukać. W komentarzu dla czytelności wrzucam cały kod okrojony do obsługi EXTI.
Co mogę robić źle albo gdzie szukać? Do debugowania mam UART i LEDa ( ͡° ͜ʖ ͡°)

 

Gruba ryba0piorunów

>static void gpio_init(void)
>{
>   RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN;
>   RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
>
>   // BUT_CANC (PA0)
>   GPIOA->CRL &= ~GPIO_CRL_CNF0_0; // floating input to pull-down
>   GPIOA->CRL |= GPIO_CRL_CNF0_1;
>
>   // (PA1)
>   GPIOA->CRL &= ~GPIO_CRL_CNF1_0; // floating input to pull-down
>   GPIOA->CRL |= GPIO_CRL_CNF1_1;
>
>   // (PA2)
>   GPIOA->CRL &= ~GPIO_CRL_CNF2_0; // floating input to pull-down
>   GPIOA->CRL |= GPIO_CRL_CNF2_1;
>
>   // (PA3)
>   GPIOA->CRL &= ~GPIO_CRL_CNF3_0; // floating input to pull-down
>   GPIOA->CRL |= GPIO_CRL_CNF3_1;
>
>   // (PA4)
>   GPIOA->CRL &= ~GPIO_CRL_CNF4_0; // floating input to pull-down
>   GPIOA->CRL |= GPIO_CRL_CNF4_1;
>}
>
>static void exti_init(void)
>{
>   RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
>   EXTI->IMR |= EXTI_IMR_MR0 | EXTI_IMR_MR1 | EXTI_IMR_MR2 | EXTI_IMR_MR3 | EXTI_IMR_MR4;
>   EXTI->RTSR |= EXTI_RTSR_TR0 | EXTI_RTSR_TR1 | EXTI_RTSR_TR2 | EXTI_RTSR_TR3 | EXTI_RTSR_TR4;
>
>   // connect pin to interrupt
>   AFIO->EXTICR[0] |= AFIO_EXTICR1_EXTI0_PA;
>   AFIO->EXTICR[1] |= AFIO_EXTICR1_EXTI1_PA;
>   AFIO->EXTICR[2] |= AFIO_EXTICR1_EXTI2_PA;
>   AFIO->EXTICR[3] |= AFIO_EXTICR1_EXTI3_PA;
>   AFIO->EXTICR[0] |= AFIO_EXTICR2_EXTI4_PA;
>
>   NVIC_SetPriority(EXTI0_IRQn, 1);
>   NVIC_SetPriority(EXTI1_IRQn, 2);
>   NVIC_SetPriority(EXTI2_IRQn, 2);
>   NVIC_SetPriority(EXTI3_IRQn, 1);
>   NVIC_SetPriority(EXTI4_IRQn, 1);
>   NVIC_EnableIRQ(EXTI0_IRQn);
>   NVIC_EnableIRQ(EXTI1_IRQn);
>   NVIC_EnableIRQ(EXTI2_IRQn);
>   NVIC_EnableIRQ(EXTI3_IRQn);
>   NVIC_EnableIRQ(EXTI4_IRQn);
>}
>
>__attribute__((section(".after_vectors"))) void EXTI0_IRQHandler()
>{
>   EXTI->PR |= EXTI_PR_PR0;
>}
>
>__attribute__((section(".after_vectors"))) void EXTI1_IRQHandler()
>{
>   EXTI->PR |= EXTI_PR_PR1;
>}
>
>__attribute__((section(".after_vectors"))) void EXTI2_IRQHandler()
>{
>   EXTI->PR |= EXTI_PR_PR2;
>}
>
>__attribute__((section(".after_vectors"))) void EXTI3_IRQHandler()
>{
>   EXTI->PR |= EXTI_PR_PR3;
>}
>
>__attribute__((section(".after_vectors"))) void EXTI4_IRQHandler()
>{
>   EXTI->PR |= EXTI_PR_PR4;
>}
Mam nadzieję, że formatowanie przetrwa.

Tytan2piorunów

Nie zeby to cos zmienilo (bo to wszystko sa zera) ale EXTI0...3 sa w AFIO->EXTICR[0] a EXTI4 w AFIO->EXTICR[1].

W ramach debugowania sprobuj wywolac przerwanie programowe ustawiajac bity w rejestrze EXTI->SWIER. To pomoze Ci znalezc czy problem jest po stronie EXTI / NVIC / CPU czy konfiguracji GPIO. Sprawdz tez, prosta petla, czy czytanie pinu GPIO i pokazywanie go na LEDzie dziala dla wszystkich pieciu. Najgorzej jest spedzic wieczor debugujac program jak problem jest sprzetowy.

Gruba ryba0piorunów

@Skylark dzięki. Jutrzejsze popołudnie zapowiada się zatem pod znakiem debugu, oby skutecznego.
EXTICR[0] i EXTICR[1] próbowałem wcześniej, ale też nie chodziło. Nie zapuściłem żadnego SVN, to tak zostało : )
Jak na razie spędziłem kilka dobrych posiedzeń nad szukaniem przyczyny całkowitego niedziałania nawet zwykłego blinky, a wyszło że to był jakiś pokopany CMSIS, choć wprost pobrany ze źródła.

Gruba ryba0piorunów

@Skylark przerwania programowanie wywołują się. Problem polega na tym, że na dwóch pinach zamiast 3V3 z pullupa rezystorem 10k pojawia mi się jedynie 0,7 V. Poprawiałem na nich diody, a że są w obudowie SOD323, to może jedną - dwie odwrotnie wlutowałem. Napięcie pasuje ładnie do złącza p-n.
No albo coś w kodzie, ale przy ctrl+c/v to raczej nie powinno tak się stać.

Pokaż więcej komentarzy (9)