Forum: Mikrocontroller und Digitale Elektronik [AVR] USI I2C Slave - USI_START_VECTOR busy wait.


von Jens R. (Firma: esolutions GmbH) (jens_r38)


Lesenswert?

Hallo,

ich implementiere gerade einen I2C Slave (USI) und weil ich das Rad 
nicht neu erfinden will, habe ich mir die

AVR312 - Using the USI module as a I2C slave

heruntergeladen.

Im Interrupt USI_START_VECTOR macht Atmel einen busy wait:
1
#pragma vector=USI_START_VECTOR
2
__interrupt void USI_Start_Condition_ISR(void)
3
{
4
    unsigned char tmpUSISR;                                         // Temporary variable to store volatile
5
    tmpUSISR = USISR;                                               // Not necessary, but prevents warnings
6
// Set default starting conditions for new TWI package
7
    USI_TWI_Overflow_State = USI_SLAVE_CHECK_ADDRESS;
8
    DDR_USI  &= ~(1<<PORT_USI_SDA);                                 // Set SDA as input
9
10
    // -----------------------------------
11
    // BUSY - WAIT im Interrupt 
12
    while ( (PIN_USI & (1<<PORT_USI_SCL)) & !(tmpUSISR & (1<<USIPF)) );
13
    // Wait for SCL to go low to ensure the "Start Condition" has completed.
14
    // -----------------------------------
15
                                                                       // If a Stop condition arises then leave the interrupt to prevent waiting forever.
16
    USICR   =   (1<<USISIE)|(1<<USIOIE)|                            // Enable Overflow and Start Condition Interrupt. (Keep StartCondInt to detect RESTART)
17
                (1<<USIWM1)|(1<<USIWM0)|                            // Set USI in Two-wire mode.
18
                (1<<USICS1)|(0<<USICS0)|(0<<USICLK)|                // Shift Register Clock Source = External, positive edge
19
                (0<<USITC);
20
    USISR  =    (1<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Clear flags
21
                (0x0<<USICNT0);                                     // Set USI to sample 8 bits i.e. count 16 external pin toggles.
22
}

Wenn ich mich da nicht täusche, dann verstöst das gegen die Haager 
Landkriegsordnung....

Im Notfall, wenn es keine bessere Lösung gibt, dann müsste man noch 
einen Interrupt auf diesen Flankenwechsel implementieren...

Oder hat jemand eine bessere Idee? Und/Oder vielleicht eine Lösung?

Schöne Grüße
Jens Riebold

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Jens Riebold schrieb:
> Wenn ich mich da nicht täusche, dann verstöst das gegen die Haager
> Landkriegsordnung....

Nur wenn man päpstlicher als der Papst sein will, oder neben dem USI 
andere sehr zeitkritische Interrupts hat.

Es gibt mit den 14-Pin ATtiny441/841 mittlerweile Tinys, die einen 
vollständigen I2C-Slave enthalten. Nicht so eine Krücke wie das USI. 
Entspricht dem TWI der Xmegas, auf reinen Slave reduziert.

von Jens R. (Firma: esolutions GmbH) (jens_r38)


Lesenswert?

Leider habe ich schon eine Platine für den ATTiny261 erstellt.

Aufgefallen ist mir nur, dass bei laufender I2C Kommunikation meine 
Software UART Zeichen verliert... Unschön...

von (prx) A. K. (prx)


Lesenswert?

Ach ja, UARTs hat der 841 auch. Gleich 2.

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.