Hi,
ich habe folgendes Problem:
Auf meinem Cortex M3 ist I2C2 initialisiert. Der Cortex soll dort auf
den General Call (0x00) lauschen, und immer wenn etwas hereinkommt, die
Daten in den Buffer twi_buf[] schreiben.
Das Lauschen und hineinschreiben funktionierte auch.
Danach habe ich einen Timer initialisiert, der alle 1,8s einen
Interrupt verursacht. In seiner IR prüft er verschiedene Flags ab, und
handelt entsprechend. Eines dieser Flags (hier myUUID ) sollte
eigentlich auf false gesetzt werden, wenn der Cortex eine ganz bestimmte
Nachricht über den General Call erhält, und mann dann twi_buf[]
auswertet.
Die Nachricht erscheint auch auf dem Bus (kann ich mit meinem Advaark
sehen), doch der Cortex "hört" sie nicht, bzw geht erst gar nicht in den
I2C2_EV_IRQHandler hinein. Also wird twi_buf[] nicht beschrieben und
kann auch nicht ausgewertet werden.
Nun dachte ich, vielleicht behindert die Timer NVICdie I2C2
NVICeinstellung, und habe dem I2C2 eine höhere Priorität gegeben, als
dem Timer NVIC. Doch genützt hat das auch nichts.
Hier meine NVIC Einstellungen für den Timer4:
Da myUUID immer true ist, (weil twi_buf[] nicht im I2C2_EV_IRQHandler
beschrieben wird), sendet mein Cortex alle 1,8s TWI_MESSAGE_newID.
Dies sollte er meiner Meinung nach doch auch selbst empfangen, da er
diese Nachricht General Call verschickt.
Aber nichts tut sich, der I2C2_EV_IRQHandler springt nicht an.
Kommentiere ich den Timer und seine NVIC aus, bekommt der Cortex wieder
alles mit, und geht auch schön in seinen I2C2_EV_IRQHandler hinein.
Hat jemand ne Idee?
Gruß
Sylvia
Muss der Timer4 INT nicht auch im NVIC quittiert/zurückgesetzt werden?
Also ich mach das, weiss aber nicht, ob es absolut notwendig ist.
Könnte sonst sein, dass die TIM4 ISR dir die gesamte Rechenzeit
wegfrisst, weil er immer wieder reingeht. Bin mir aber nicht sicher.
Arne schrieb:> Muss der Timer4 INT nicht auch im NVIC quittiert/zurückgesetzt werden?
also in der ISR wird der Interrupt mit
> TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
zurückgesetzt.
was du mit "NVIC quittiert/zurückgesetzt" meinst verstehe ich nicht.....
Im Timer-Interrupt das I2C anzusprechen setzt natürlich voraus, dass die
I2C-Routinen im Hauptprogramm gegen Timer-Interrupts abgesichert sind.
Sonst droht ab und zu Chaos, wenn ein Timer-Interrupt mittendrin
zuschlägt.
Arne schrieb:> Muss der Timer4 INT nicht auch im NVIC quittiert/zurückgesetzt werden?
Bist du sicher, dass du den Cortex-M3 meinst, und nicht den VIC mancher
ARM7? Das Interrupt-Flag des Timers hatten wir heute morgen schon in
einem anderen Thread.
A. K. schrieb:> Im Timer-Interrupt das I2C anzusprechen setzt natürlich voraus, dass die> I2C-Routinen im Hauptprogramm gegen Timer-Interrupts abgesichert sind.
deshalb habe ich ja die Priorität des I2C Interrupt höher gestellt als
die des Timers
A. K. schrieb:> Was das eigentliche Problem angeht: Da habe ich nur Bahnhof verstanden
ist kein Timer im Spiel, kann mein Cortex auf den General Call des I2C
hören,
kommt der Timer dazu, wird der Cortex taub auf dem I2C Ohr
Sylvia H. schrieb:> deshalb habe ich ja die Priorität des I2C Interrupt höher gestellt als> die des Timers
Das nützt nichts, denn wenn im Hauptprogramm und im Timer-Interrupt
nichttriviale I2C-Funktionen oder -Abläufe verwendet werden, dann kann
der Timer immer reinschlüpfen, egal wie die Prioritäten stehen, solange
der Timer höher priorisiert ist als der Teil des Hauptprogramms.
Sylvia H. schrieb:> ist kein Timer im Spiel, kann mein Cortex auf den General Call des I2C> hören, kommt der Timer dazu, wird der Cortex taub auf dem I2C Ohr
Was mir nicht gefällt ist das TWI_Send im Timer-Interrupt. Ich halte
mich gern aus der STM32-Lib raus (hab grad auch weder Doku noch Source
im direkten Zugriff), vermute aber, dass es da drin recht komplex zugeht
und diese Aktion nicht in einem Interrupt-Handler gehört.
Sind die TWI-Funktionen der STM32-Lib überhaupt Interrupt-gesteuert?
A. K. schrieb:> Was mir nicht gefällt ist das TWI_Send im Timer-Interrupt
das gefällt mir auch nicht, ich muss aber einen vorgegebenen Code
benutzen, der für den ATXMEGA geschrieben wurde, und nun für den CORTEX
M3 "Übersetzt" werde soll.
Ich sende mit POLLING und empfange mit INTERRUPT. Die Libs sind für
Polling/Interrupt und dma ausgelegt
Sylvia H. schrieb:> das gefällt mir auch nicht, ich muss aber einen vorgegebenen Code> benutzen, der für den ATXMEGA geschrieben wurde, und nun für den CORTEX> M3 "Übersetzt" werde soll.
Jo, aber trotzdem wäre die korrekte Vorgehensweise, im Hauptprogramm
abhängig von einem Flag zu senden, und das im Timer-Interrupt zu setzen.
Auch beim AVR.
A. K. schrieb:> Jo, aber trotzdem wäre die korrekte Vorgehensweise, im Hauptprogramm> abhängig von einem Flag zu senden, und das im Timer-Interrupt zu setzen.> Auch beim AVR.
habs erledigt, gefällt mir auch besser...
vielleicht stimmt ja auch etwas mit der I2C Senderoutine nicht, es wäre
nicht das erste Mal, das bei den STM Libs was faul ist...
Hier mal die benutzte Senderoutine, damit sie nicht so lang ist, hab ich
für das Posting die Interrupt und DMA Option rausgelöscht...
ich meine, ich komme dem Problem langsam näher:
es scheint nichts mit dem Timer zu tun zu haben, sondern mit dem senden.
Bevor ich die Sache mit dem Timer angefangen hatte, habe ich ja nur
gelauscht, und nichts gesendet. Lauschen hatte ja funktioniert.
Nun aber wird auch gesendet, und da bleibt das Programm nach dem senden
des letzten Byte in der Methode
Status I2C_Master_BufferWrite(I2C_TypeDef* I2Cx, uint8_t* pBuffer,
uint32_t NumByteToWrite, I2C_ProgrammingModel Mode,
uint8_t SlaveAddress)
an genau dieser Stelle hängen (warten auf Event 8):
1
while(NumByteToWrite--){
2
/* Poll on BTF to receive data because in polling mode we can not guarantee the
3
EV8 software sequence is managed before the current byte transfer completes */
4
while((I2Cx->SR1&0x00004)!=0x000004)// HIER HÄNGS!!!
5
;
6
/* Send the current byte */
7
I2Cx->DR=*pBuffer;
8
/* Point to the next byte to be written */
9
pBuffer++;
10
}
Danach kommt ja erst das Senden der Stop Bedingung, d.h. der Bus ist
blokiert.
Wie bekomme ich nun den Bus wieder Frei, wenn mein Partnerboard das
Event 8 nicht sendet?
hab gerade festgestellt, das
> while ((I2Cx->SR1 & 0x00004) != 0x000004) // HIER HÄNGS!!!
nicht das Even 8 sondern das Event 8_2 abfrägt.
Wenn ich das ändere, und auf Event 8 warte, bleibt der Cortex schon nach
dem ersten Byte hängen, mein Partner schickt kein Event 8.
Lasse ich nach Event 8_2 ausschau halten, dann kann man bis zum letzten
byte das Array auf den I2C Bus schicken, aber das letzte Byte wird dann
nicht mehr vom Partnerboard mit Event 8_2 bestätigt.
Woran hängt das ?