Przerwanie Uart TX w ARM

Dec 04, 2008 6 Replies

Witajcie Zaczynam zabawê z ARM LPC2148. Nie mogê sobie poradziæ z transmisj± przez UART w trybie przerwañ. Do tej pory w 8051 czy AVR robi³em bufor nadawczy i odbiorczy. Wysy³aj±c kilka znaków wpisywa³em do bufora i inicjowa³em transmisjê a w obs³udze przerwania z bufora by³y pobierane kolejne znaki a¿ do opró¿nienia. Analogicznie z odbiorem - przychodzi³o do bufora a w wolnej chwili odczytywa³em to co przysz³o.



W ARM poradzi³em sobie z transmisj± przychodz±c± ale ju¿ drugi dzieñ siedzê i nie mogê uzyskaæ przerwania od wys³ania znaku. Je¿eli pierwszy bajt danych wrzucê "rêcznie" do U0THR to wychodzi na zewn±trz, ale nie jest poprawnie zg³aszane przerwanie.



W U0IER mam w³±czone zezwolenia na przerwania od nadawania i odbioru: UIER_ERB | UIER_THRE



Zainstalowa³em sobie ewaluacyjn± wersjê CrossStudio i debugujê rejestry. Po wys³aniu znaku widzê w U0IIR InterruptPending = 0 (jest przerwanie), Interrupt_Identification = 1 (THRE), czyli niby wszystko OK, ale nie ustawia siê bit przerwania od UARTA w VICIRQStatus (= 0). Doszed³em do etapu ¿e wchodzê do obs³ugi przerwania, dochodzê do makra IS_ENTRY i po przej¶ciu kasuj± mi siê flagi w U0IIR i nie ma ¶ladu po przerwaniu. Oczywi¶cie nie moze byæ poprawnie obs³u¿one. Je¿eli przychodzi znak z zewn±trz, jest odpowiednia flaga w VICIRQStatus, poprawnie wchodzê do obs³ugi przerwania i odczytujê znak.



Próbowa³em debugowaæ ró¿ne przyk³adowe programy z takim samym efektem.



Konfiguracja UARTa wygl±da tak: Uart0Init(B9600, UART_8N1, UART_FIFO_1) //////////////////////////////////////////////////////////////////////////////// uint16_t Uart0Init(uint16_t baud, uint8_t mode, uint8_t fmode) { U0IER = 0x00; // disable all interrupts U0IIR; // clear interrupt ID U0RBR; // clear receive register U0LSR; // clear line status register



// set the baudrate U0LCR = ULCR_DLAB_ENABLE; // select divisor latches U0DLL = (uint8_t)baud; // set for baud low byte U0DLM = (uint8_t)(baud >> 8); // set for baud high byte



// set the number of characters and other // user specified operating parameters U0LCR = (mode & ~ULCR_DLAB_ENABLE); U0FCR = fmode;



//initialize the interrupt vector VICIntSelect &= ~VIC_BIT(UART0_INT); // UART0 selected as IRQ VICVectCntl0 = VIC_ENABLE | UART0_INT; VICVectAddr0 = (uint32_t)Uart0ISR; // address of the ISR VICIntEnable = VIC_BIT(UART0_INT); // UART0 interrupt enabled



//inicjuj zmienne obs³ugi buforów ko³owych wsk_ob0n = 0; wsk_nb0n = 0; wsk_ob0o = 0; wsk_nb0o = 0;



U0FCR = 1;



//w³acz przerwania U0IER = UIER_ERB | UIER_THRE; return (TRUE); }



wysy³anie znaku mam zrobione tak± procedur±: //////////////////////////////////////////////////////////////////////////////// void PutChar0 (uint8_t ch) { unsigned cpsr;



while (buf0_nad_size == UART0_TX_BUFFER_SIZE); // czekaj az bedzie miejsce w buforze



cpsr = disableIRQ(); // disable global interrupts U0IER &= ~UIER_THRE; //wy³±cz przerwanie wysy³ania restoreIRQ(cpsr); // restore global interrupts



//sprawd¼ czy trwa wysy³anie danych if (uart0_tx_running) { uart0_tx_buf[wsk_nb0n++] = ch; if (wsk_nb0n == UART0_TX_BUFFER_SIZE) wsk_nb0n = 0; buf0_nad_size++; } else { // set running flag and write to output register uart0_tx_running = TRUE; U0THR = (uint8_t)ch; }



cpsr = disableIRQ(); // disable global interrupts U0IER |= UIER_THRE; //w³±cz przerwanie wysy³ania restoreIRQ(cpsr); // restore global interrupts }



Je¿eli mo¿ecie wskazaæ jak±¶ ¶cie¿kê, albo podrzuciæ dzia³aj±cy przyk³ad, bêdê wdziêczny.


Piotr "Pitlab" Laskowski pisze:

Ja się bawiłem LPC2378 i 2364, one są nowsze, mają trochę rozbudowane peryferia, więc to może nie działać... ale poszukaj w dokumentacji :).. te LPC23xx miały wbudowany taki bufor do nadawania i do odbierania... I pierwszy znak jaki wpisywało się do U0THR trafiał od razu do nadajnika, kolejne (jeśli były wpisane do U0THR zanim pierwszy się "nadał") trafiały do kolejki FIFO... natomiast przerwanie było zgłaszane tylko po opróżnieniu FIFO... mówiąc inaczej - jeśli wysyłałeś po 1 znaku - nie było zgłaszane przerwanie... trzeba po prostu zrobić inną filozofię :)... Ewentualnie poszukaj w rejestrach do UARTa jakiś odpowiadających za to "kiedy zgłaszane jest przerwanie"... może tam znajdziesz jednak coś odpowiedniego :).. Ja piszę z pamięci, więc jak będą jakieś nieścisłości, to przepraszam...

Pozdrawiam Konop

O dziêki! to brzmi bardzo rozs±dnie. Tutaj te¿ jest FIFO, chocia¿ jest ustawione na rozmiar jednego znaku, wiêc prawdopodobnie wystarczy wpisaæ 2 znaki. Spróbujê usia¶æ do tego w nocy.

U¿ytkownik "Piotr "Pitlab" Laskowski" snipped-for-privacy@pulapka.wp.pl> napisa³ w wiadomo¶ci news:gh8o4c$91i$ snipped-for-privacy@mx1.internetia.pl...

... ...

Zobacz czy s± jakie¶ erraty do tego uk³adu. Bawi³em siê kiedy¶ starszym LPC (chyba LPC2136) i z erraty wynika³o, ¿e uk³ad zosta³ straszliwie skopany, trzeba by³o robiæ wiele obej¶æ a niektóre rzeczy nie dawa³y siê zrealizowaæ. Lepszym wyborem jest Atmel.

PC

Paweł Cern pisze:

Może masz rację z tym Atmelem, ale trzeba przyznać, że Philips/NXP wiele poprawił :)... pierwsze wersje miały skopane dużo, kolejne trochę mniej.. te 23xx są już chyba OK :)... Tzn. nie słyszałem, żeby ktoś narzekał ;)... no ale rozumiem, pewnie jakbym się zraził na początku, to bym patrzył tak samo, jak Ty ;)

Pozdrawiam! Konop

W³a¶nie przejrza³em erratê, ale nie wspomina o problemach z UARTem. Zrobi³em kilka prób z wysy³aniem paczek danych i widzê ¿e co¶ zaczyna siê dziaæ z przerwaniem. Jeszcze nie jest to czego oczekujê, ale mo¿e jeszcze nie wszystko rozumiem. Dokumentacja jest jednak dosyæ uboga, jest tylko suchy opis rejestrów. Noty aplikacyjne koñcz± siê na wpisaniu pojedyñczego znaku do rejestru wysy³aj±cego bez u¿ycia przerwañ. Jeszcze muszê znale¼æ jak±¶ dokumentacjê do standardowego uarta 550, bo pisz± ¿e zaimplementowany w kontrolerze jest jego odpowiednikiem. Co do Atmela: Rozpisa³em sobie "konkurs u¿yteczno¶ci w moim projekcie" na 3 ARMy od Atmela, NXP i AD. Porównywa³em g³ównie pod k±tem dopasowania peryferiów, bo to jest aplikacja mocno "usprzêtowiona". Seria LPC wyda³a mi siê najodpowiedniejsza z podwójnym UARTem i SPI, pe³niejszym USB, bateryjnym podtrzymaniem zegara. Teraz zdajê sobie sprawê ¿e porównywanie na tym poziomie abstrakcji jest dosyæ pobie¿ne, ale dopóki nie zacznie siê pracy z uk³adem wiêkszo¶ci problemów nie da siê zobaczyæ :-)

Paweł Cern pisze:

Nie mów hop. Atmel także ma pokaźne erraty w prockach serii AT91SAM7 a jeszcze grubsze w AT91SAM9. Do tego dochodzą błędy nie opisane w erratach, na których już w firmie zęby sobie połamaliśmy (np. dziwaczne zachowanie polaryzacji linii zegara SPI przed pierwszym dostępem do danego urządzenia).

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required