XMEGA & TWI -> Lese Problem

OP #5049638
Lesenswert?

Moin Moin,

habt ihr ne Idee, wieso ich vom Slave nichts empfange? Senden klappt..
Ist was an der Lese Routine falsch?

Es handelt sich um einen I2C Touch Controller (QT2120 von ATMEL)..
Habe einen Pin als GPIO konfiguriert und dort ne LED angeschlossen. 
Diese kann ich an und aus schalten. Die ID lesen von dem Chip schlägt 
jedoch fehl.
1
uint8_t twi_read(TWI_t *twi, uint8_t slave_addr, uint8_t reg)
2
{
3
  uint8_t ret=0;
4
  
5
//   twi->MASTER.ADDR = (slave_addr<<1);
6
//   while(!(twi->MASTER.STATUS&TWI_MASTER_WIF_bm));
7
//  
8
//   twi->MASTER.ADDR = reg;
9
//   while(!(twi->MASTER.STATUS&TWI_MASTER_WIF_bm));
10
//  
11
//  
12
//   twi->MASTER.ADDR = ((slave_addr<<1)|0x01);
13
//   while(!(twi->MASTER.STATUS & TWI_MASTER_RIF_bm));
14
//  
15
//   ret = twi->MASTER.DATA;
16
//  
17
//   twi->MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc;
18

19

20
  twi->MASTER.ADDR = slave_addr<<1 & ~0x01;
21
  while (!(twi->MASTER.STATUS & TWI_MASTER_WIF_bm) || (twi->MASTER.STATUS & TWI_SLAVE_RXACK_bm));
22
  twi->MASTER.DATA = reg;
23
  while (!(twi->MASTER.STATUS & TWI_MASTER_WIF_bm));
24

25
  twi->MASTER.ADDR = slave_addr | 0x01;
26
  while (!(twi->MASTER.STATUS & TWI_MASTER_RIF_bm));
27
  ret = twi->MASTER.DATA;
28
  TWIC.MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
29

30
  return ret;
31
}
Gast #5049848
Lesenswert?

Bastian W. schrieb:
> und nicht einen weiteren Start.

Nicht ganz:

6.   The host must then send a STOP and a START condition followed by 
the
     slave address again but this time accompanied by the READ bit.


Note:

     Alternatively, instead of step 6, a repeated START can be sent so 
the
     host does not need to relinquish control of the bus.
#5049860
Lesenswert?

jim_quakenbush schrieb:
> Bastian W. schrieb:
>> und nicht einen weiteren Start.
>
> Nicht ganz:
>
> 6.   The host must then send a STOP and a START condition followed by
> the
>      slave address again but this time accompanied by the READ bit.
>
>
> Note:
>
>      Alternatively, instead of step 6, a repeated START can be sent so
> the
>      host does not need to relinquish control of the bus.


Ok die Anmerkung hab ich überlesen.
@TO

Kannst du nach dem lesen wieder schreiben , oder verlierst du danach die 
Abitration ?

Ich hab die TWI Register nicht im Kopf, hast du Automatik für ACK/NACK 
beim lesen an ? Hast du
Bei dem Byte das du gelesen hast ein NACK vor dem Stop gesendet ?

Gruß JackFrost

Hast du einen LA um zu schauen ob das alles richtig gesendet wird ?
Gast #5049920
Lesenswert?

Bastian W. schrieb:
> Kannst du nach dem lesen wieder schreiben , oder verlierst du danach die
> Abitration ?

Ich toggle die LED an einem der GPIOS hin und her. Und danach lese ich. 
Das Schreiben klappt.

Bastian W. schrieb:
> ch hab die TWI Register nicht im Kopf, hast du Automatik für ACK/NACK
> beim lesen an ? Hast du Bei dem Byte das du gelesen hast ein NACK vor
> dem Stop gesendet ?

Ich habe oben im auskommentierten Teil, zum Schluss einen NACK gesendet. 
Hat leider auch nichts gebracht.
#5050137
Lesenswert?

Fabian D. schrieb:
> Ich toggle die LED an einem der GPIOS hin und her. Und danach lese ich.
> Das Schreiben klappt.

Das geht also auch dauerhaft, also nach dem ersten Zyklus lesen geht das 
schreiben wieder ohne Probleme ?

Mit der Funktion lese ich bei einem Atxmega E Daten aus einem FRAM mit 
aus.

Page_adress ist die Slave ID und Adress ist die Addresse der 
Speicherzelle.

Der Block mit dem PortC ist noch nicht dynamisch, da ich da noch keine 
Arbeit reingesteckt hatte. Btw. das ist von einem C++ Projekt. Wenn du 
also nicht TWIC nutzt musst du da noch den Port ändern.
1
void twi_read(TWI_t *twiname, uint8_t *readData,uint8_t page_adress, uint8_t Adress, uint8_t bytes)
2
{
3
  twiname->MASTER.CTRLC &= ~((1<<TWI_MASTER_ACKACT_bp));
4
  twiname->MASTER.ADDR = page_adress;
5
  while (!(twiname->MASTER.STATUS & TWI_MASTER_WIF_bm));
6
  if(twiname->MASTER.STATUS & (1<<TWI_MASTER_ARBLOST_bp))
7
  {
8
    twiname->MASTER.CTRLA = 0;
9
    PORTC.DIRSET = PIN1_bm;
10
    for(uint8_t i=0;i<9;i++)
11
    {
12
      PORTC.OUTSET = PIN1_bm;
13
      _delay_us(20);
14
      PORTC.OUTCLR = PIN1_bm;
15
      _delay_us(20);
16
    }
17
    PORTC.DIRCLR = PIN1_bm;
18
    twiname->MASTER.CTRLA = TWI_MASTER_ENABLE_bm;
19
    twiname->MASTER.STATUS = TWI_MASTER_ARBLOST_bm | TWI_MASTER_BUSERR_bm;
20
    twiname->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
21
    twiname->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
22
    twiname->MASTER.ADDR = page_adress;
23
    while (!(twiname->MASTER.STATUS & TWI_MASTER_WIF_bm));
24
  }
25
  twiname->MASTER.DATA = Adress;
26
  while (!(twiname->MASTER.STATUS & TWI_MASTER_WIF_bm));
27
  page_adress |= 0x01;
28
  twiname->MASTER.ADDR = page_adress;
29
  for(volatile uint8_t j=0 ;j<bytes ;j++){
30
    
31
    while(!(twiname->MASTER.STATUS&TWI_MASTER_RIF_bm));
32
    if(j == (bytes-1))
33
    {
34
      twiname->MASTER.CTRLC = (1<<TWI_MASTER_ACKACT_bp) | TWI_MASTER_CMD_STOP_gc;
35
    }
36
    readData[j] = twiname->MASTER.DATA;
37
  }
38
}

Gruß JackFrost
#5050370
Lesenswert?

Das ist nur der Fall wenn die Abitration nicht da ist. Wenn z.b. Ein 
Reset beim lesen kam, dann ist der Slave noch im Lesemodus und man kann 
keinen Start mehr senden.

Dann wir das TWI Modul deaktiviert und es werden 9 Pulse über SCL 
gesendet.
SDA bleibt dabei High. Damit kommt mit dem letzten Bit wieder ein NACK 
und der Slave legt keine Daten mehr auf SDA.

Gruß JackFrost

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