Forum: Mikrocontroller und Digitale Elektronik Probleme mit NXP LPC845 und die USART Ports


von Waffel (Gast)


Lesenswert?

Moin,

ich habe ein kleines Problem mit NXP Controllern. Mein LPC845 will zum 
Verrecken nicht auf den USART Ports 3 und 4 kommunizieren. Sobald ich 
dort einmal sende, hängt sich der ganze MC auf. Ich habe dazu mal das 
Beispiel verändert:
1
    BOARD_InitBootPins();
2
    BOARD_InitBootClocks();
3
    BOARD_InitBootPeripherals();
4
5
    /* Init FSL debug console. */
6
    BOARD_InitDebugConsole();
7
8
    PRINTF("Init...\n\r");
9
10
    callbackUserData[0] = 0;
11
    callbackUserData[1]  = 1;
12
    callbackUserData[2] = 2;
13
    callbackUserData[3]  = 3;
14
15
    PRINTF("Create Handles\n\r");
16
  USART_TransferCreateHandle(baseAddress[1],  &usart[1],  USARTUserCallback1, NULL);
17
  USART_TransferCreateHandle(baseAddress[2], &usart[2], USARTUserCallback2, NULL);
18
  USART_TransferCreateHandle(baseAddress[3],  &usart[3],  USARTUserCallback3, NULL);
19
20
    PRINTF("Init finished\n\r");
21
22
    uint8_t string[] = "Hello World";
23
    usart_transfer_t test_data;
24
    test_data.data = string;
25
    test_data.dataSize = sizeof(string);
26
    PRINTF("sending test.\n\r");
27
28
    USART_TransferSendNonBlocking (baseAddress[1], &usart[1], &test_data);
29
    USART_TransferSendNonBlocking (baseAddress[2], &usart[2], &test_data);
30
    USART_TransferSendNonBlocking (baseAddress[3], &usart[3], &test_data);
31
32
    PRINTF("test Send.\n\r");

Das Letzte was ausgegeben wird ist "sending test" und der Interupt 
USARTUserCallback1 feuert. Die USARTs sind über das Treiber-Tool 
configuriert.

von Harald A. (embedded)


Lesenswert?

Bist Du da mal im Single Step durchgegangen? Irgendwann müsste er ja 
dann im Nirwana landen, daraus kann man meistens Rückschlüsse ziehen.

Wie sieht die Funktion USARTUserCallback aus?

von Johannes S. (Gast)


Lesenswert?

Fehlt da nicht ein USART_Init?

von Waffel (Gast)


Lesenswert?

USART3_init ist autogeneriert in der peripherals.c :
1
const usart_config_t USART3_config = {
2
  .baudRate_Bps = 9600,
3
  .syncMode = kUSART_SyncModeDisabled,
4
  .parityMode = kUSART_ParityDisabled,
5
  .stopBitCount = kUSART_OneStopBit,
6
  .bitCountPerChar = kUSART_8BitsPerChar,
7
  .loopback = false,
8
  .enableRx = true,
9
  .enableTx = true,
10
  .clockPolarity = kUSART_RxSampleOnFallingEdge,
11
  .enableContinuousSCLK = false
12
};
13
14
void USART3_init(void) {
15
  /* USART3 peripheral initialization */
16
  USART_Init(USART3_PERIPHERAL, &USART3_config, USART3_CLOCK_SOURCE);
17
}

Harald A. schrieb:
> Wie sieht die Funktion USARTUserCallback aus?

Die sehe alle gleich aus im Test, 0 und 1 feuern. 2 und 3 nicht.
[c]
void USARTUserCallback2(USART_Type *base, usart_handle_t *handle, 
status_t status, void *userData)
{
  uint8_t usartId = *(uint8_t*)userData;
  PRINTF("Int2 %d on %d\n\r", status, usartId);
}
[c]

von Johannes S. (Gast)


Lesenswert?

Das PRINTF im callback sieht gefährlich aus. Wenn das im ISR context 
selber Interrupts benutzt kann das ein Problem sein.

von Harald A. (embedded)


Lesenswert?

>
> Die sehe alle gleich aus im Test, 0 und 1 feuern. 2 und 3 nicht.
> [c]
> void USARTUserCallback2(USART_Type *base, usart_handle_t *handle,
> status_t status, void *userData)
> {
>   uint8_t usartId = *(uint8_t*)userData;
>   PRINTF("Int2 %d on %d\n\r", status, usartId);
> }

Wenn im User Callback PRINTF aufgerufen wird, wo landet denn die PRINTF 
Ausgabe? Auf dem UART?

von Waffel (Gast)


Lesenswert?

Die Ausgabe geht auf USART0 - Das ist aber nicht das Problem, bei USART0 
und 1 funktioniert das ja. Ich hab das auch ohne die Ausgabe schon 
versucht, mit einem Breakpoint im Callback. Das macht keinen 
Unterschied.

von Harald A. (embedded)


Lesenswert?

Wie ist das denn jetzt? Kannst Du Single Step machen oder hast Du keinen 
Debugger dran? In den ersten USART_TransferSendNonBlocking rein und 
schauen, wo er in die Wüste springt

: Bearbeitet durch User
von Johannes S. (Gast)


Lesenswert?

hier ist der Zeiger auf userdata NULL:
1
USART_TransferCreateHandle(baseAddress[1],  &usart[1],  USARTUserCallback1, NULL);

Im callback wird der Zeiger dereferenziert, gibts da evtl. einen 
hardfault? Statt NULL sollte da doch sicher &userdata[n] rein.

von Waffel (Gast)


Lesenswert?

Dsa Problem ist, dass sich das nicht wirklich debuggen lässt. Gehe ich 
Schritt für Schritt vor, läuft er zumindest bis zum "test send" durch. 
sobald ich dann aber auf "continue" drücke hängts. Das scheint mit dem 
Auslösen des Interupts zu tun zu haben.

von Peter D. (peda)


Lesenswert?

Waffel schrieb:
> Die sehe alle gleich aus im Test

Laß die Prosa sein, die taugt nicht als Quelltext.
Wie wärs, wenn Du mal den echten und vollständigen Testcode als Anhang 
postest.
Und auch nen Link auf die Lib und die Toolchain.

von Waffel (Gast)


Lesenswert?

Peter D. schrieb:
> Und auch nen Link auf die Lib und die Toolchain.

Versuch doch im Gegenzug mal ein wenig netter zu sein. Dein Text kommt 
bei mir schon etwas agressiv an. Der Satz heißt lediglich, dass alle 
vier Interupthandler den gleichen Inhalt haben und sich nur durch eine 
Zahl im Namen unterscheiden. Ich sehe es nicht als zielführend weil 
unübersichtlich, vier mal das gleiche zu posten.

Der restliche Quelltext ist oben zu finden. Die Toolchain ist das 
MCUXpresso IDE von NXP, dass bringt die Libs mit. In diesem Fall ist es 
die fsl_usart (wie im Include des geposteten Quellcode zu sehen) Das 
sind alles die offiziellen standard Tools, die von NXP kommen. Falls dir 
also noch etwas konkretes fehlt, kann ich das gerne posten.

Hier noch das Ergebnis des Konfigurationstools, die entsprechenden 
Einträge der pin_mux.h. Die fehlte noch.
1
    /* USART3_TXD connect to P0_7 */
2
    SWM_SetMovablePinSelect(SWM0, kSWM_USART3_TXD, kSWM_PortPin_P0_7);
3
4
    /* USART3_RXD connect to P0_6 */
5
    SWM_SetMovablePinSelect(SWM0, kSWM_USART3_RXD, kSWM_PortPin_P0_6);
6
7
    /* USART4_TXD connect to P0_22 */
8
    SWM_SetMovablePinSelect(SWM0, kSWM_USART4_TXD, kSWM_PortPin_P0_22);
9
10
    /* USART4_RXD connect to P0_21 */
11
    SWM_SetMovablePinSelect(SWM0, kSWM_USART4_RXD, kSWM_PortPin_P0_21);

von Harald A. (embedded)


Lesenswert?

Waffel schrieb:
> läuft er zumindest bis zum "test send" durch.
> sobald ich dann aber auf "continue" drücke hängts.

Hast Du mal versucht, dass Du einfach weiter beharrlich weiterstepst, 
auch wenn er augenscheinlich durch ist? Das Problem ist ja, dass der 
tatsächliche Int wesentlich später feuert. Falls da am Ende eine 
Sleep-Instruction ist (Programm-Ende) füge einfach ein While(1) oder 
ähnliches ein, wo Du dann auch weitersteppen kannst.
Was sagt denn der Alice Yang aus dem anderen Forum dazu? Der scheint ja 
recht hilfsbereit zu sein...

von Waffel (Gast)


Lesenswert?

So lange du im Step Modus bist, werden die Interupts nicht ausgelöst. Da 
kann man dann ewig durch die main loop laufen. - Das steht als Hinweis 
extra im Datenblatt.

Wenn ich ihn aber laufen lasse, bis er hängt, und dann den Debugger 
einschalte, lande ich immer in PIN_INT6_USART3_IRQHandler - Und sehe da 
auch beim schrittweise durchgehen, das er dort im Kreis läuft. Also 
fürchte ich wirklich, dass ich da auf die Hilfe von NXP angewiesen bin. 
Falls du dich dafür interessierst, weißt du ja jetzt wo die mögliche 
Antwort von der netten Dame findest, die für NXP arbeitet.

von Johannes S. (Gast)


Lesenswert?

Läuft das auf dem LPC845-BRK Board? Das habe ich auch und könnte das 
auch testen wenn du das Projekt hier hochlädst.

von Harald A. (embedded)


Lesenswert?

Waffel schrieb:
> So lange du im Step Modus bist, werden die Interupts nicht ausgelöst.

Hm, ich hätte jetzt geschworen, dass ich genau das beim Debugging vom 
artverwandten LPC824 schon erlebt hätte. Kannst Du ergründen, warum er 
dort im Kreis läuft? Musst du vielleicht ein Flag selber zurücksetzen? 
Wenn er dort im Kreis läuft bist du der Lösung doch recht nahe, oder?

Waffel schrieb:
> weißt du ja jetzt wo die mögliche
> Antwort von der netten Dame findest, die für NXP arbeitet.

Natürlich Dame, ich bitte den Fauxpas zu entschuldigen. Ich hatte beim 
Kopieren irgendwie nur den Nachnamen im Blick. Ich hatte nur gesehen, 
dass die um Source bittet. Gibt es denn schon eine Lösung?

von Waffel (Gast)


Lesenswert?

Sie hat noch nicht geantwortet, vermutlich arbeitet die nich am 
Wochenende.

von Peter D. (peda)


Lesenswert?

Waffel schrieb:
> Der Satz heißt lediglich, dass alle
> vier Interupthandler den gleichen Inhalt haben und sich nur durch eine
> Zahl im Namen unterscheiden. Ich sehe es nicht als zielführend weil
> unübersichtlich, vier mal das gleiche zu posten.

Ich schon.
Du wärst nicht der erste, der C&P Fehler macht.
Es hat schon seinen Sinn, wenn man den echten und vollständigen Code 
postet. Schon allein die Typklarheit der "geheimen" Funktionen hilft dem 
Betrachter viel. Er kann ja nicht in Deinen Kopf schauen.
Nach Murphys Gesetz wird immer nur der Schnipsel gepostet, wo der Fehler 
nicht drin ist.
Vollständige Sourcen erlauben jedem, sie schnell mal durch den Compiler 
zu jagen und sich die Warnungen und Fehler anzeigen zu lassen. Schnipsel 
erlauben das nicht.
Du mußt im Forum nicht mit Speicherplatz sparen. Quelltexte werden ja 
nicht als BMP abgespeichert.

von Johannes S. (Gast)


Lesenswert?

Ein Betrunkener geht die ganze Zeit auf dem Boden suchend um eine 
Straßenlaterne! Kommt ein Passant vorbei und fragt: "Suchen sie etwas?" 
"Ja, ich habe meinen Schlüssel verloren!" Der Passant hilft dem 
Betrunkenen zu suchen, doch sie finden den Schlüssel nicht! Nach einer 
Stunde fragt der Passant: "Sind sie sich sicher, dass sie den Schlüssel 
hier verloren haben?" Da antwortet der Betrunkene: "Nein, ich habe ihn 
irgendwo da hinten verloren, aber hier ist der einzige Ort, wo es Licht 
gibt!"

von Waffel (Gast)


Lesenswert?

Danke für die dämlichen Kommentare. Aber das ist man in diesem Forum ja 
leider gewöhnt.

Das Problem ist inzwischen weiter eingegrenzt, auch wenn NXP wenig 
hilfreich war. Das erste Beispielprojekt hat einfach die polling 
Variante benutzt und so die Probleme mit dem Interrupt umgangen. Das 
nächste Beispiel war für ein anderes SDK. - Es gibt scheinbar einen 
Konflikt zwischen dem PINT (Pin-Interrupt) und dem USART Treiber aus dem 
NXP SDK. Die Documentation sagt dazu nichts, genau wie das 
Konfigurationstool keine Fehler meldet. Nachdem ich das PINT 
rausgenommen habe, was ich auch nur zum Debuggen brauchte, funktioniert 
jetzt die USART3 und USART4.

von Harald (Gast)


Lesenswert?

Was mir auch zu dem Thema noch einfällt: Sind das die Routinen, die die 
ROM-API nutzen (weiß jetzt nicht genau, ob der LPC845 auch ROM-API für 
Serial hat)? Falls ja, da muss man doch im Linker einen RAM-Bereich 
reservieren/sperren, damit da nichts überschrieben wird. Die ROM-APIs 
nutzen ja auch RAM... Diese Info ist etwas schwierig zu finden, notfalls 
einem Beispielprojekt kopieren.

von Johannes S. (Gast)


Lesenswert?

tja, aber genau darum ging es: der Fehler war nicht da wo du gesucht 
hast. Und wie sollen andere helfen wenn sie nur die Hälfte der Infos 
bekommen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.