Hallo, ich versuche gerade meine i2c lese routine fehler tolerant zu machen. Genauer, nachdem ein Fehler passiert ist muss ein weiter Versuch möglich sein. Also im prinzip ein read von i2c, da passiert ein Fehler, zB timeout Overrun/Underrun. Dann putzen der Fehler/Register, zur not ReInit der HW. Im moment ist es so das ich auf einen Bus ohne Device aber mit pullups ein start schicke, das geht ok. Dann schicke ich die 7bit HW Adresse 0xE0 mit Read, also 0xE1. Danach warte ich bis die Adresse anliegt. deviceAdress=0xE0; /* Send START condition */ i2c_send_start_and_wait_for_rdy(); /* Send slave address */ i2c_send_7bit_address(I2C2, deviceAdress, I2C_READ); /* Waiting for address is transferred. */ WAIT_EVENT_TO(!(I2C_SR1(I2C2) & I2C_SR1_ADDR)); Dies timed natürlich aus da kein Device angeschlossen ist. Soweit so gut. Jetzt wird die oben gezeigte Routine nochmal gerufen und diesmal gibts einen Hardfault. Was auf SCL und SDA passiert sieht man in der angehängten Graphik. Ich vermute mal das man nach so einem Fehler die HW irgendwie zurücksetzen. Hat hierzu jemand einen Rat oder selbst schon Erfahrungen gemacht? Gruss Michael
Hier noch der Code den ich verwende. Im Prinzip ist es das OptimizedI2C/examples/src/I2CRoutines.c aber nur der Pollingmode. Mit der Readroutine kann ich einen SE95D/LM75 ohne Probleme back2back lesen. Kommentare, Anregungen sind Willkommen. Gruss Michael
>Ich vermute mal das man nach so einem Fehler die HW irgendwie >zurücksetzen. > >Hat hierzu jemand einen Rat oder selbst schon Erfahrungen gemacht? Wenn du kein ACK vom Chip bekommst dann versuch erst mal sauber mit einem I2C Stop raus zu gehen.
Da gibts nen Interrupt "I2C-Error-Int". Dort kannst du das "AF"-Flag (AdressFault) in SR1 abfragen. Ich habe darauf hin SR1=0; und CR1 |= CR1_STOP; gemacht. Danach kann ich wieder normal mit de Bus reden. Ebenso verfahre ich mit BERR und ARLO.
Hallo, also jetzt hab ich das setzen von SR1=0 und STOP probiert, immernoch ein Hardfault beim 2ten versuch. MSG:SR1 = 0x400 SR2 = 0x3 SR1 steht nach dem ersten versuch auf AF und und im SR2 BUSY und MSL. Hat vielleicht nochjemand eine Idee? Gruss Michael
Hallo, sieht so als ob das Problem mit FreeRTOS zusammen hängt. Evt so was wie nested IRQ? Ich werd mal weiter suchen... Wie kann man den im hardfault Falle sehen warum es einen Hardfault gab? Gruss Michael
Nun hab ich den Grund für den Hardfault gefunden. Stack war zu klein ;-) Um das Problem zu finden hab ich etwas gegoogled und code für einen hard fault handler gefunden den ich hier in etwas abgeänderter Form poste. Hab den Assembler code in inline assembler umgeschrieben.... termf ist meine printf routine aufs terminal. Damit läst sich das jetzt prima debuggen. Bit 10 im CFSR war bei mir gesetzt was auf einen dangeling pointer hinweist. comipliert mit FreeRTOS, für den STM32 stack muss man das include und register access ändern. Gruss Michael
Hier noch ein snippet von dem Hardfault print out: [Hard fault handler - all numbers in hex] R0 = 1 R1 = 74 R2 = 74 R3 = 1 R12 = a5a5a5a5 LR [R14] = 8002b25 subroutine call return address PC [R15] = 8002160 program counter PSR = 21000000 BFAR = e000ed38 CFSR = 400 HFSR = 40000000 DFSR = 0 AFSR = 0 SCB_SHCSR = 0
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.