AT91 TWI NACK wird gesetzt

OP #929438
Lesenswert?

Hallo,

ich hab gerade ein paar Schwierigkeiten mit TWI bei den Atmel-ICs 
(AT91SAM9260). Die Seite mit der Zusammenfassung von einigen Buggs hab 
ich mir angeschaut.
http://www.mikrocontroller.net/articles/AT91-TWI

Im Moment versuche ich aus einem Eeprom Daten auszulesen. Jedoch bekomm 
ich keine Rückmeldung nachdem ich die Kommunikation gestartet habe. -> 
daher wird nach einer Weile das NACK Bit gesetzt im Status-Register.

Meine Init-Function lautet:
1
    /* Configure TWI PIOs */
2
    AT91F_TWI_CfgPIO ();
3

4
    /* Configure PMC by enabling TWI clock */
5
    AT91F_TWI_CfgPMC ();
6

7
    /* Reset the TWI */
8
    AT91C_BASE_TWI->TWI_CR = AT91C_TWI_SWRST;
9

10
    /* Configure TWI in master mode */
11
    AT91F_TWI_Configure (AT91C_BASE_TWI);
12

13
    /* Set TWI Clock Waveform Generator Register */
14
    AT91F_SetTwiClock();
15

16
  //TWI NACK Bug workaround
17
    AT91F_AIC_ConfigureIt (   AT91C_BASE_AIC,
18
                              AT91C_ID_TWI,
19
                              7,
20
                              AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE,
21
                              (void (*)(void))dummy_irq);
22
    *AT91C_TWI_IER = (1<<0);
23
    *AT91C_TWI_CR = AT91C_TWI_MSEN;

Read-Function:
1
void AT91F_AT24C_ReadPage (struct at24c *ptAt24c,
2
                            char *Buffer,
3
                            unsigned int NumOfBytes,
4
                            unsigned int PageNumber,
5
                            unsigned int AddressOffSet)
6
{
7
  unsigned int WordAddress;
8
  unsigned int SlaveAddress;
9
  unsigned int Count ;
10
  unsigned int status=0;
11
  unsigned int timeout = 0;
12

13

14
  /* Addr: 1010 101(R/W) */
15
  SlaveAddress = (0xAA<<16);
16

17
  /* pagenbr = 2, pagesize = 256; offset am anfang 0 */
18
  WordAddress = (PageNumber*ptAt24c->PageSize) + AddressOffSet ;
19

20

21
   /* Enable Master Mode of the TWI */
22
   //AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN ;
23

24
   /* Set the TWI Master Mode Register */
25
   AT91C_BASE_TWI->TWI_MMR =  SlaveAddress | AT91C_TWI_MREAD | AT91C_TWI_IADRSZ_2_BYTE;
26
   //AT91C_BASE_TWI->TWI_MMR =  SlaveAddress | AT91C_TWI_MREAD;
27

28

29
   /* Set the internal address to access the wanted page */
30
   AT91C_BASE_TWI->TWI_IADR = WordAddress ;
31

32
   /* Send the Start + slave address + Internal Address */
33
   AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
34

35

36
   while(!(*AT91C_AIC_IPR & (1<<AT91C_ID_TWI))){                                 //TX Complete TWI irq polling
37
    timeout++;
38
    if(timeout >= 10000000){
39
//      twi_stop();
40
      return;                                                     //Exit on TXCOMP timeout
41
    }
42
  }
43
  twi_nack_wait();
44

45
  status = AT91C_BASE_TWI->TWI_SR;
46
  if(status & AT91C_TWI_NACK){                                           //Slave exist and send ACK?
47
//    twi_stop();
48
    return;      //Exit on NACK  -> jedes pkt muss ackd werden 
49
  }
50

51
 //.....

Bei der letzten Status-Abfrage ist bei mir stets das NACK Bit im 
Zusammenhang mit dem TXCOMP gesetzt. Zusätzlich sind TXRDY und SVREAD 
gesetzt - aber nicht RXRDY.

Vielleicht hat jmd. von euch einen Rat für mich.

Bernd
OP #933876
Lesenswert?

>Du hast das AT91F_TWI_Open(); mit AT91F_SetTwiClock(); vertauscht.

wie meinst du das genau? in TWI_Open steht doch alles drinnen u.a. auch 
das setzen der clock?

>Des weiteren musst du darauf achten, dass die Interrupte aktiv sind

die interrupts sind aktiv.... sowohl fürs senden als auch fürs 
empfangne....

>Ich weis gerade leider nicht, wie identisch das TWI vom SAM7 zum RM9
>ist.

soweit ich das überblicke ist da kein großer / wenn überhaupt ein 
unterschied vorhanden. Beim Versuch vom Beschreiben eines Eeproms wird 
auch das Startbyte und die Adresse vom Eeprom geschickt, allerdings 
kommt danach kein ACK vom Eeprom an...


Gruß
Bernd
OP #933986
Lesenswert?

>Hast du mal versucht ein "twi scan" laufen zu lassen?

einen Scan hab ich noch nicht laufen lassen - werd ich morgn mal 
ausprobieren... Die Adresse für den EEPROM AT24HC02B lautet 1010 A2 A1 
A0 R/W, wobei A2 = A0 = 1 und A1 = 0 ist. somit schreibe ich 0x55 ins 
Register rein.

>Evtl. kannst du mal ins irc kommen, bin gerade da und hab ein System zum
>Testen ;)

was ist denn das irc?

Gruß
Bernd
OP #934466
Lesenswert?

hab dich gestern abend leider nicht mehr erreicht im chat - hab erst 
später nachschauen können...

Den Scan hab ich gerade ausprobiert; mit dem Ergebnis, dass bei vielen 
Werten / Adressen kein NACK ankommt bzw. verlorengeht - und bei 
mehrmaligen Probieren, diese Werte auch etwas variieren.

Die Wartefunktion wird auf jeden Fall durchlaufen und nicht 
weg-optimiert.

Gruß
Bernd
OP #934487
Lesenswert?

ist mir hier am arbeitsrechner grad nicht möglich, dem Chat 
beizutreten... hab zwar die Sicherheitseinstellungen entsprechend 
angepasst aber funktioniert nicht.

Auf jeden Fall hab ich die Waitfunktion nochmals vergrößert (was die 
Zeit angeht) -> und jetzt bekomm ich bei jeder Adresse ein NACK 
geliefert...


Gruß
Bernd
OP #934516
Lesenswert?

Was mich etwas stutzig macht, ist die Frequenz für TWI:
1
#define AT91B_MAIN_OSC         (18432000)                // Exetrnal Main Oscillator MAINCK
2
#define AT91B_PROCESSOR_CLOCK  ((AT91B_MAIN_OSC/14)*74) // Output PLL Clock (100 MHz)
3
#define AT91B_MASTER_CLOCK     (AT91B_PROCESSOR_CLOCK) // Output PLL Clock (100 MHz)
4
#define AT91C_TWI_CLOCK   8000 /* in Hz*/
1
void AT91F_SetTwiClock(void){
2
  int sclock;
3
  /* Here, CKDIV = 1 and CHDIV=CLDIV  ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6)*/
4
 
5
  sclock = (10*AT91B_MASTER_CLOCK /AT91C_TWI_CLOCK);
6
  if (sclock % 10 >= 5)
7
    sclock = (sclock /10) - 5;
8
  else
9
    sclock = (sclock /10)- 6;
10
  sclock = (sclock + (4 - sclock %4)) >> 2;  // div 4
11
  AT91C_BASE_TWI->TWI_CWGR  = ( 1<<16 ) | (sclock << 8) | sclock;
12
}

Mit 8k Hz sehe ich die richtig-losgesendete Adresse an SDA; wenn ich 
jetzt allerdings 100k Hz verwende, sehe ich lediglich noch das Startbyte 
- die Adresse kann nicht mehr dargestellt werden (obwohl der Slave 
ebenfalls bis 400k Hz gehen kann. Definiere ich den Wert der TWI_Clock 
falsch?

Die  Clock des Prozessors müsste ca. den obigen Werten übereinstimmen, 
da ansonsten auch keine Ausgabe über RS232 möglich wäre.


Gruß
Bernd
OP #934542
Lesenswert?

ich arbeite mit dem AT91SAM9260 controller / nicht mit dem RM9200.... 
weiß jetzt nicht genau wie sehr sich da unterschiede auftun im zuge von 
TWI aber ansonsten sind die beiden Controller schon sehr 
unterschiedlich.

Wohnen tue ich in Paderborn.

Gruß
Bernd
Gast #988013
Lesenswert?

Hallo Jens und Bernd,

ich wollte diese Woche mit der Inbetriebnahme des TWIs bei einem SAM9260 
beginnen und habe bei der Recherche den Wiki-Artikel gefunden. Dort 
heisst es, die Lib wuerde noch nicht laufen. Was ist denn das Problem 
bei dem 9260?

Gruss
Th.Kusch

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren