Forum: Mikrocontroller und Digitale Elektronik STM32F072 GPIO von Output nach Input umschalten = Prozessor tot


von K. H. (hegy)


Lesenswert?

Hallo,

wir haben ein Problem mit der Pinrichtungsumschaltung von Ausgang nach 
Eingang beim STM32F072. Die GPIO-Pins
PB8  = Data0
PA3  = Data1
PA2  = Data2
PA1  = Data3
PF0  = Data4
PC15 = Data5
PC14 = Data6
PC13 = Data7

werden der Reihenfolge (von oben nach unten) nach über das 
MODER-Register umgeschaltet. Schon beim ersten Pin scheint es 
prozessorintern zu Problemen zu kommen, weil danach der Debugger (über 
ST-Link) an einer Adresse hängt, die jenseits von gut und böse ist. 
Fehlermeldung direkt beim Start:
> Program received signal SIGTRAP, Trace/breakpoint trap.
> 0x1FFFCC28 in ?? ()

Am Anfang sind die Pins alle auf Ausgang eingestellt und haben 
irgendwelche Werte geschrieben. Um was einzulesen, werden die dann 
mittels der Fkt.
1
MW_GPIO::PinChangeDirection(bool in_out)

umgeschaltet. Diese Fkt. ist eine Kurzform aus der 
stm32f0xx_hal_gpio.cpp, HAL_GPIO_Init().

Ein Reset hilft danach nicht, der Prozessor ist definitiv im Eimer, weil 
die 2 an PB3 und PB4 angeschlossenen LED's nicht mehr blinken sondern 
nur noch bestenfalls glimmen.

Am anderen Ende der GPIO-Pins ist übrigens ein TRF7960 (RFID 
Reader/Writer) angeschlossen ohne irgendwelche Widerstände o. ä. 
dazwischen und die Pins
stehen zu dem Umschaltzeitpunkt auf Input. Es wird also Input <---> 
Output(STM32) auf Input <---> Input umgeschaltet. Wenn alle GPIO's auf 
Input umgeschaltet sind, wird das andere Ende auf Output umgeschaltet 
(Output <---> Input).

Irgend eine Idee, warum das den Prozessor killt?
1
uint32_t MW_GPIO::PinChangeDirection(bool in_out)
2
{
3
#define GPIO_MODER_MODER0  ((uint32_t)0x00000003)
4
#define GPIO_MODE          ((uint32_t)0x00000003)
5
6
    uint32_t position = 0x00;
7
    uint32_t iocurrent = 0x00;
8
    uint32_t temp = 0x00;
9
10
    while(Pin->Pin >> position)
11
    {
12
        iocurrent = Pin->Pin & (1 << position);  // get current I/O-position
13
14
        if(iocurrent) // position found, exmpl: iocurrent = 8 -> position = 3 (2^3 = 1 << 3 = 8)
15
        {
16
            // Configure IO Direction mode (Input, Output, Alternate or Analog)
17
            // GPIOx->MODERnn[1:0], nn = 0...15:
18
            // 00 = Input  (+ OTYPER | OSPEEDR | PUPDR) [default]
19
            // 01 = Output (+ OTYPER | OSPEEDR | PUPDR)
20
            // 10 = alternate function
21
            // 11 = in/out analog
22
            temp = Port->MODER >> (position * 2); // for debug
23
            if( ((Port->MODER >> (position * 2)) & 0x03) >= 0b10) // check if selected pin is not in alternative of analog mode
24
                return 0xFFFF;
25
            temp = 0;
26
            CLEAR_BIT(temp, GPIO_MODER_MODER0 << (position * 2));
27
            SET_BIT(temp, (in_out & GPIO_MODE) << (position * 2));
28
            Port->MODER = temp;
29
        }
30
31
        position++;
32
    }
33
34
    return 0;
35
}

von Nop (Gast)


Lesenswert?

Mußt mal prüfen, ich hab mir mal einen STM32 gebrickt, weil ich den 
JTAG-Port aus Versehen umgestellt habe, so daß der Programmer nicht mehr 
drankam.

Geholfen hat es, den Programmer anzuschließen, den Resetknopf auf dem 
Board zu drücken und zu halten, beim Programmer "Start" zu klicken und 
dann erst den Resetknopf loszulassen.

Der Programmer hat dadurch die Resetleitung gezogen, bevor die 
fehlerhafte Firmware loslaufen konnte (weil die ja wegen des Knopfes 
noch im Reset war).

von K. H. (hegy)


Lesenswert?

Mit "Prozessor tot" meinte ich, dass der Prozesser echt tot ist. Die 
angeschlossenen LED's blinken nicht mehr, ich kann den µP nicht mehr 
flashen, debuggen ist auch nicht mehr möglich und und über andere Pins 
bekomme ich keine Meldungen mehr.
Der Fehler tritt ja nur 1x auf, dann ist der µP förmlich zerschossen. 
Also ich flashe den µP und das Programm läuft normal bis zu einem 
bestimmten Punkt im Programm (die Fkt. von oben) und damit ist Schluss. 
Da hilft auch kein Reset und flashen kann ich nicht, weil ST-Link keine 
Verbindung aufbauen kann. Aber das ist das Ergebnis, ich will die 
Ursache wissen bzw. wie kann ich den STM32F072 dazu bringen, einen 8-Bit 
breiten Datenbus bidirektional zu machen?

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Hast Du an BOOT0 oder den BOOT1 Option herumgemacht? 0x1FFFCC28 hoert 
sich sehr nach Bootloader an!

Falls Du nicht irgendwelche unerlaubten Spannungen auf Deinem Board 
hast, halte ich es für sehr unwahrscheinlich, das der Baustein tot ist.

von Ralph S. (jjflash)


Lesenswert?

... hast du schon das ST-Link Utility unter Windows ausprobiert und dort 
"Connect under reset" versucht ?

Target -> Settings  dort: Connection Mode: Connect under Reset

Reset aktiviert halten und connect starten.

Wenn das funktioniert alle eventuell gesetzten Lockbits deaktivieren.

von K. H. (hegy)


Lesenswert?

Der Fehler ist gefunden! Wie Nop (Gast) schon schrieb, ich habe durch 
einen Bug im Code alle Portpins auf Input umgeschaltet und das war es 
dann. Deswegen konnte der ST-Link wohl nicht mehr verbinden und direkt 
nach dem Reset wurden alle Portpins kaputtkonfiguriert. Erst durch 
Dauerreset und dann verbinden und Flash-Erase ging es wieder.

Wo der Fehler liegt:
1
        if(iocurrent) // position found, exmpl: iocurrent = 8 -> position = 3 (2^3 = 1 << 3 = 8)
2
        {
3
            // Configure IO Direction mode (Input, Output, Alternate or Analog)
4
            // GPIOx->MODERnn[1:0], nn = 0...15:
5
            // 00 = Input  (+ OTYPER | OSPEEDR | PUPDR) [default]
6
            // 01 = Output (+ OTYPER | OSPEEDR | PUPDR)
7
            // 10 = alternate function
8
            // 11 = in/out analog
9
            temp = Port->MODER >> (position * 2); // for debug
10
            if( ((Port->MODER >> (position * 2)) & 0x03) >= 0b10) // check if selected pin is not in alternative of analog mode
11
                return 0xFFFF;
12
            temp = 0;
13
            CLEAR_BIT(temp, GPIO_MODER_MODER0 << (position * 2));
14
            SET_BIT(temp, (in_out & GPIO_MODE) << (position * 2));
15
            Port->MODER = temp;
16
        }

In Zeile 12 (temp = 0;) wird durch das stumpfe schreiben von 0 auf alle 
Portpins werden diese zum Eingang umgebaut. Also Zeile raus und es sieht 
wohl so aus, als wäre das Problem gelöst. Jetzt nur noch herausfinden, 
wie man den beknakkten TRF7960 zum Antworten bekommt, also Register oder 
von einer bestimmten Adresse was lesen.....

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.