Atxmega TWI Daten in Bausteinregister schreiben

OP #1771586
Lesenswert?

Hallo,

ich arbeite zur Zeit an einem Projekt mit dem Atxmega 128A1. Mit diesem 
versuche ich einen Zooming ADC der Firma Semtech (SX8723) anzusteuern.
Dazu benutze ich die TWI Funktionen die Atmel in AVR1308 bereitstellt.

mit der Funktion
1
uint8_t TWI_MasterWriteRead(uint16 sx8723_Register, uint8_t write_bytes ,uint8_t read_bytes)

ist das Auslesen eines Registers auch kein Problem
es erfolgt mit der Funktion
1
TWI_MasterWriteRead(sx8723_Register, 1,1)

 in der Reihenfolge

[Adresse Baustein][Register Adresse][D-Ack][Adresse Baustein][Antwort 
des SX][D-NACK]

soweit kein Problem ich schreibe das Register und lese nach der zweiten 
Adresse dessen Inhalt.

will ich jetzt jedoch Daten in ein Register des SX schreiben habe ich 
mit den mitgelieferten Funktionen nur die Möglichkeit
1
TWI_MasterWriteRead(sx8723_Register, 2,0)

das heißt 2 Byte schreiben
sieht dann auf dem TWI Bus folgendermaßen aus

[Adresse Baustein][Register Adresse][D-Ack][Daten an den SX][D-ACK]

der Baustein benötigt aber zum Schreiben der Daten das Format

[Adresse Baustein][Ack][Register Adresse][D-Ack][Start][Adresse 
Baustein][Ack][Daten an den SX][ACK]

Habe noch zwei Bilder angehangen
Bild 1: so sieht meine Übertragung zur Zeit aus
Bild 2: So ist es beim SX vorgesehen
zip: AVR1308 Application Note

Die Funktion TWI_MasterWriteRead
sieht folgendermaßen aus:
1
bool TWI_MasterWriteRead(TWI_Master_t *twi,
2
                         uint8_t address,
3
                         uint8_t *writeData,
4
                         uint8_t bytesToWrite,
5
                         uint8_t bytesToRead)
6
{
7
  /*Parameter sanity check. */
8
  if (bytesToWrite > TWIM_WRITE_BUFFER_SIZE) {
9
    return false;
10
  }
11
  if (bytesToRead > TWIM_READ_BUFFER_SIZE) {
12
    return false;
13
  }
14

15
  /*Initiate transaction if bus is ready. */
16
  if (twi->status == TWIM_STATUS_READY) {
17

18
    twi->status = TWIM_STATUS_BUSY;
19
    twi->result = TWIM_RESULT_UNKNOWN;
20

21
    twi->address = address<<1;
22

23
    /* Fill write data buffer. */
24
    for (uint8_t bufferIndex=0; bufferIndex < bytesToWrite; bufferIndex++) {
25
      twi->writeData[bufferIndex] = writeData[bufferIndex];
26
    }
27

28
    twi->bytesToWrite = bytesToWrite;
29
    twi->bytesToRead = bytesToRead;
30
    twi->bytesWritten = 0;
31
    twi->bytesRead = 0;
32

33
    /* If write command, send the START condition + Address +
34
     * 'R/_W = 0'
35
     */
36
    if (twi->bytesToWrite > 0) {
37
      uint8_t writeAddress = twi->address & ~0x01;
38
      twi->interface->MASTER.ADDR = writeAddress;
39
    }
40

41
    /* If read command, send the START condition + Address +
42
     * 'R/_W = 1'
43
     */
44
    else if (twi->bytesToRead > 0) {
45
      uint8_t readAddress = twi->address | 0x01;
46
      twi->interface->MASTER.ADDR = readAddress;
47
    }
48
    return true;
49
  } else {
50
    return false;
51
  }
52
}
Angehängte Dateien:
OP #1773973
Lesenswert?

Hab jetzt eine "Lösung" gefunden

in dem ich den in der AppNote gegebenen Code für meinen Bedarf angepasst 
habe.
1
bool TWI_MasterWriteRegisterData(TWI_Master_t *twi,uint8_t address,uint8_t *writeRegister,uint8_t *writeData,uint8_t bytesToWrite)
2
{
3
  
4
  /*Parameter sanity check. */
5
  if (bytesToWrite > TWIM_WRITE_BUFFER_SIZE) {
6
    return false;
7
  }
8

9
  /*Initiate transaction if bus is ready. */
10
  if (twi->status == TWIM_STATUS_READY) {
11

12
    twi->status = TWIM_STATUS_BUSY;
13
    twi->result = TWIM_RESULT_UNKNOWN;
14

15
    twi->address = address<<1;
16

17
    /* Fill write data buffer. */
18
    for (uint8_t bufferIndex=0; bufferIndex < bytesToWrite; bufferIndex++) 
19
      {
20
        twi->writeData[bufferIndex] = writeRegister[bufferIndex];
21
      }
22

23
    twi->bytesToWrite = bytesToWrite;
24
    twi->bytesToRead = 0;
25
    twi->bytesWritten = 0;
26
    twi->bytesRead = 0;
27

28
    /* If write command, send the START condition + Address +
29
     * 'R/_W = 0'
30
     */
31
    if (twi->bytesToWrite > 0) 
32
    {
33
      uint8_t writeAddress = twi->address & ~0x01;
34
      twi->interface->MASTER.ADDR = writeAddress;
35
    }
36
  
37
    while (twi->status != TWIM_STATUS_READY)
38
    {}
39

40
    for (uint8_t bufferIndex=0; bufferIndex < bytesToWrite; bufferIndex++) 
41
    {
42
      twi->writeData[bufferIndex] = writeData[bufferIndex];
43
    }
44

45
    twi->bytesToWrite = bytesToWrite;
46
    twi->bytesToRead = 0;
47
    twi->bytesWritten = 0;
48
    twi->bytesRead = 0;
49

50
    if (twi->bytesToWrite > 0) 
51
    {
52
      uint8_t writeAddress = twi->address & ~0x01;
53
      twi->interface->MASTER.ADDR = writeAddress;
54
    }
55
    while (twi->status != TWIM_STATUS_READY)
56
    {}
57
    return true;
58
  } 
59
  else 
60
  {
61
    return false;
62
  }
63
}

Leider entspricht das noch nicht ganz dem im Datenblatt vom SX8723 
geforderten Aufbau, da nach dem Address Ack noch ein Start Kommando 
gesendet wird was eigentlich entfallen sollte. Hat jemand eine Idee wie 
ich das machen kann?
Im Anhang seht ihr die momentane Übertragung.

Gruß Andi
Angehängte Dateien:
Gast #1773999
Lesenswert?

Moin,

Andi M. schrieb:
> Dazu benutze ich die TWI Funktionen die Atmel in AVR1308 bereitstellt.

Andi M. schrieb:
> mit den mitgelieferten Funktionen nur die Möglichkeit :
> TWI_MasterWriteRead(sx8723_Register, 2,0)

Andi M. schrieb:
> zip: AVR1308 Application Note

dir ist schon klar das "Application Note" ein allgemeines Beispiel 
darstellt das zeigt dass es geht, aber nicht auf deine speziellen 
Bedürfnisse eingeht?

MfG
OP #1774053
Lesenswert?

ja das ist es aber es passte in dem Fall halt schon ziemlich gut zu dem 
was ich wollte. Bis auf den kleinen Unterschied und ich wollte jetzt 
wissen ob es so wie ich es angepasst hab vernünftig ist oder ob man es 
noch "schöner" machen kann.

bzw. wie ich das mit der Stop Kondition noch verhindern kann
#1774574
Lesenswert?

Wo ist das Problem?
Du rufst die Funktion zweimal auf.
Zuerst  rufst Du die TWI_MasterWriteRegisterData auf.
und schreibst Du die Slave Adresse und Memory Adresse.
Dann wird im nächsten Funktionsaufruf Slave Adresse und Data 
geschrieben.
Wenn ich das richtig sehe sollte das Klappen.

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