Wpis z mikrobloga

Kurde chciałem sobie uruchomić tylko i wyłacznie przerwanie IDLE na STM32F103 i udało się ale dzieje się coś dziwnego - cały czas jestem przerzucany do procedury obsugi przerwania, mimo, że teoretycznie flaga powinna być wyczyszczona, zgodnie z dokumentacją:

It is cleared by a software sequence (an read to the USARTSR register followed by a read to the USARTDR register). as you can see I do it in my code, but for some reason the flag is not cleared.

Mimo to siedząc w debuggerze widzę, że cały czas jestem przerzucany do procedury.

Tutaj fragment kodu: klik

#programowanie #embedded
  • 44
@zarowka12: Czy przy -O0 też by mogło coś takiego wystąpić? Przekopiowałem procedurę czyszczenia flag z implementacji w LL od STM i nadal to samo. Breakpoint mi łapie bezpośrednio w miejscach gdzie przypisywane są zmienne więc wydaje mi się, że nie zostały wywalone podczas kompilacji.
@a231: @zarowka12:

Dodałem parę linijek kodu, tak aby wartość DR na pewno była brana pod uwagę - więc dorzuciłem ifa, który w zależności od wartości DR zmienia wartość innej zmiennej volatile, ale nic to nie dało. Cały czas widzę, że bit IDLE w SR jest zapalony.
@bielu000: Zastanawiam się jeszcze nad jednym - w libopencm3 nie w przypadku usart1 dla STM32F103 nie ma żadnej funkcji, która włączałaby przerwanie po wykryciu IDLE. W api jest tylko funkcja, w której ciało wygląda tak:
USARTCR1(usart) |= USARTCR1_RXNEIE;
Ale z drugiej strony są definicje, pozwalające ustawić w CR przerwanie na to zdarzenie. Już się zastanawiam czy może to coś jest nie tak w przypadku tego MCU, ale nie mogę
@zarowka12: Chcę właczyć przerwanie opisane dokładnie jako: "Idle line detected" na USART1, żadne inne mnie nie interesuje aktualnie.
Nie wdając się zbytnio w szczegóły - potrzebuję tego do wywołania procedury przetwarzania danych, które zostaną przesłane przez USART i które DMA skopiuje do mi bufora. Dane te mogą być zmiennej długości więc przerwania HT oraz TC z DMA nie do końca mi leżą.
@zarowka12: Właśnie trafiłem na ten artykuł, prześledzę go i spróbuję zrobić tak jak tam jest. [[maybeunused]] to po prostu atrybut, który mówi kompilatorowi aby mimo, że zmienna jest nieużywana to nie wywalał błędu przy kompilacji. Aktualnie w usart1isr mam skopiowany kod z procedury z LLUSARTClearFlag_IDLE. Niestety nic to nie zmienia. To raczej niemożliwe, aby z chipem było coś nie tak prawda?
@bielu000: chipa bym nie podejrzewał. Podejrzewam makra USART1SR i USART1DR. Do jakich adresów się odnoszą? Skąd wziąłeś funkcję LLUSARTClearFlag_IDLE? Taka funkcja jest w HAL-u, ale tam używane są struktury z CMSIS zamiast makr, jest też volatile.
@zarowka12: Tak aktualnie wygląda moja procedura obsługi przerwania klik
- zwykły kod
- przpuszczony przez preprocesor, więc widać na co się rozwijają makra

Muszę to porównać z adresami ze struktur z CMSIS.

Funkcję LLUSARTClearFlag_IDLE wziąłem z kodu źródłowego HAL od STM, tak aby mieć u siebie dokładnie to co oni w tej procedurze.
@bielu000: jak zaglądam do HAL-a, to ta funkcja wygląda tak:
_STATICINLINE void LLUSARTClearFlagIDLE(USARTTypeDef *USARTx)
{
_IO uint32t tmpreg;
tmpreg = USARTx->SR;
(void) tmpreg;
tmpreg = USARTx->DR;
(void) tmpreg;
}
Niemniej wychodzi na to samo i wygląda poprawnie, bo SR jest pod adresem 0x40013800, a DR jest pod 0x40013804.
Tak więc nie wiem czemu to u Ciebie nie działa. Może jednak coś Ci wysyła
@zarowka12: Właśnie w tym momencie skończyłem przeglądać kod HAL i też podliczylem te wartości i wyszło mi to samo. UART jest podpięty do konwertera FTDI FT232RL i nic czego jestem świadom nie jest przez niego aktualnie wysyłane.
@zarowka12: Assembler też wygląda ok, jest read zarówno z SR jak i DR. Nie mam pomysłu co to może być. Jutro spróbuje szukać dalej. Mógłbym pewnie wymyślić jakiś workaround na to, ale bez sensu skoro powinno to działać.
@zarowka12: Wywiązałem pewną dyskusję na stacku odnośnie tego tematu. Ale czegoś nie rozumiem - czy jeżeli nie wysyłam żadnych danych przez UART, czy flaga IDLE w SR powinna być cały czas zapalona, czy nie?
@zarowka12 Bo jeżeli tak to zastanawiam się jeszcze nad jedną rzeczą
- wyłaczyć przerwanie IDLE
- włączyć przerwanie RX
- po pierwszym otrzymanym bajcie w isr właczyć przerwanie IDLE, wyłaczyć RX
- po przerwaniu IDLE wyłaczyć... przerwanie IDLE i włączyć ponownie RX.

Tylko nie wiem czy to nie jest workaround.
@zarowka12: Dlatego też nie chce go robić, to tylko takie moje przemyślenie było.
Ale wracając jeszcze do pytania, tak aby miał pewność, że dobrze rozumiem.
Wlączam przerwanie na IDLE Line Detected, nie wysyłam żadnych danych - czy w tej sytuacji procedura obsługi tego przerawnia powinna być wywoływana (raz, cały czas), czy to przerwanie powinno zostać dopiero wywołane w momencie po otrzymaniu jakichś danych, gdzie nic już więcej nie jest otrzymywane przez