Forum: Mikrocontroller und Digitale Elektronik TWI Zugriff vor Interrupt blockiert TWI in ISR


von Thomas A. (tha)


Lesenswert?

Hallo,

ich benutze gerade einen xmega32A4U und erzeuge über den RTC jede 
sekunde
einen Interrupt. In der ISR soll dann ein TWI Zugriff erfolgen, z.B. 
eine
LED ein/ausschalten.
Wenn ich in der ISR keinen TWI Zugriff habe,z.b. nur eine Ausgabe über 
den
UART sieht man wie der Interrupt jede Sekunde kommt und abgearbeitet 
wird.
Sobald aber ein TWI Zugriff in der ISR ist scheint der TWI Bus zu 
blockieren.

Ich habe mir den TWI Bus mit dem I2C Sniffer (von Peter Dannegger)
angesehen und es scheint so als ob ein TWI Zugriff durch den Interrupt
unterbrochen wurde und ich in der ISR einen neuen starte.

s40a0Fas41a00a00aFFaFEnp
s40a0Fa

Für den TWi benutze ich den std Treiber von ATMEL, z.b. für den write
access: twi_master_write(TWI_PORT, &packet_transmit);

ISR(RTC_OVF_vect)
{
  static int timer=0;

  timer++;
  if(timer==2) set_uif_LED(LED_MS, ON);
}

void set_uif_LED(uint8_t led, uint8_t onoff)
{
  uint8_t value=0;

  switch(led)
  {
    case LED_MS:
      value=read_I2C(UIF_ADDR,UIF_LED_ADDR);
      if(onoff) value&=~(0x1<<led);
      else value|=(0x1<<led);
      write_I2C(UIF_ADDR,UIF_LED_ADDR,value);
      break;

    default:
      break;
  }
  return;
}

Ist der TWI Access nicht vor Interrupt Unterbrechnungen geschützt? Bzw.
wird der TWI access nicht beendet?

Ich hatte auch schon versucht die Interrupts mit sei() und cli() während
der twi_master_write/twi_master_read zu sperren aber das hat leider auch
nicht funktioniert.

Hat vielleicht jemand eine Lösung für mein Problem bzw. ein Ähnliches?

von Peter D. (peda)


Lesenswert?

Von einer Ressource darf immer nur eine Instanz laufen.
Entweder der Interrupt macht alle I2C-Zugriffe oder keinen.
Das gleich gilt z.B für das SPI oder ein LCD usw.


Peter

von Thomas A. (tha)


Lesenswert?

Danke für die schnelle Antwort Peter,
ich wollte eine abgespeckte Form von einem task scheduler schreiben um 
z.B. neben bei eine
LED blinken zu lassen. Prinzipiell müsste es doch klappen wenn man den 
I2C Zugriff
immer bis zum Ende durchführt bevor in die ISR gesprungen wird.
Hast du vielleicht eine Idee wie man eine LED neben dem normalen 
Programmablauf
blinken lassen kann?

Danke für die Hilfe, Thomas

von Peter D. (peda)


Lesenswert?

Thomas A. schrieb:
> immer bis zum Ende durchführt bevor in die ISR gesprungen wird.

Der Witz an einer ISR ist ja, sie wird nicht angesprungen, sie passiert 
zufällig an einer beliebigen Stelle.
Du darfst eben nicht 2 Instanzen benutzen, d.h. Dein Programmablaufplan 
ist falsch.

Eine Lösung ist, Du schreibst quasi einen I2C Device-Treiber.
D.h. das I2C läuft als Interrupt und kann mindestens 2 Puffer verwalten. 
Einen Puffer kann dann das Main befüllen und den anderen ein anderer 
Interrupt.


Peter

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.