Hallo,
auch ich habe noch eine Frage:

Zitat Zitat von linux_80 Beitrag anzeigen
Den Ausgangspuffer nur so gross, wie die Anzahl Bytes die auf einmal zum Master übertragen werden sollen. Damit es keine "alten" Daten gibt. Dann Regelmässig diese mit den entsprehenden Daten füllen, aber nur überschreiben, wenn der Master nicht grad am lesen des Puffers ist.
Aber es wird doch nur das erste Byte aus dem Array gesendet, oder habe ich im Assemblercode (der mir zugegebenermaßen nicht wirklich vertraut ist) irgendwas übersehen?

Code:
'// ----- Master write data mode ------
'// Check reply and goto USI_SLAVE_SEND_DATA if OK, else reset USI.
'case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA:
Isr_ovf_check_rep_from_send_data:     'r24 = Usi_twi_overflow_state
cpi r24, Usi_check_reply_from_send_data        'case Usi_check_reply_from_send_data ?
brNe Isr_ovf_slave_send_data          'no -> jmp to next case

     'if ( USIDR ) // If NACK, the master does not want more data.
      in r24, USIDR
      !and r24, r24
      breq Isr_ovf_req_rep_from_send_data_1    'jmp slave_send_data if Master send a ACK (send next byte)

      'SET_USI_TO_TWI_START_CONDITION_MODE()
   Isr_ovf_set_usi_start_cond_mode:
      ldi r24, Usicr_start_mode
      !out USICR, r24    'USICR = Usicr_start_mode
      ldi r24, Usisr_send_or_read_data
      !out USISR, r24    'USISR = Usisr_send_or_read_data

      LDI r24, Usi_start_condition_mode
      sts {Usi_twi_overflow_state}, r24        'USI_TWI_Overflow_State = Usi_start_condition_mode

      rjmp ISR_OVF_end   'break

'case USI_SLAVE_SEND_DATA
Isr_ovf_slave_send_data:              'r24 = Usi_twi_overflow_state
cpi r24, Usi_send_data   'case Usi_send_data ?
brNe Isr_ovf_req_rep_from_send_data   'no -> jmp to next case

Isr_ovf_req_rep_from_send_data_1:
      '// Get data from Buffer
      lds r24, {Twi_txhead}           '// Pointer  Twi_txhead
      Loadadr Twi_txbuf(1) , Z        'R31:R30
      ldi r31, &H00      'paranoia
      add r30, r24       'add index
      adc r31, r1        'add carry
      ld r24, Z
      !out USIDR, r24    'USIDR = TWI_TxBuf[Twi_txhead]

      '//incr and mask pointer
      lds r24, {Twi_txhead}
      subi r24, &HFF     ' incr Twi_txhead
      andi r24, Twi_tx_buffer_mask    ' mask pointer
      sts {Twi_txhead}, r24           'Twi_txhead = ( Twi_txhead + 1 ) & TWI_TX_BUFFER_MASK

      ldi r24, Usi_request_reply_from_send_data
      sts {Usi_twi_overflow_state}, r24        'USI_TWI_Overflow_State = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA

      'SET_USI_TO_SEND_DATA()'
      SBI DDR_USI, PIN_SDA            'DDR_USI  |=  (1<<PORT_USI_SDA) // Set SDA as output
      ldi r24, Usisr_send_or_read_data
      !out USISR, r24    'USISR=Usisr_send_or_read_data
      rjmp ISR_OVF_end   'break

'// Set Usi To Sample Reply From Master. Next Usi_slave_check_reply_from_send_data
'case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA:
Isr_ovf_req_rep_from_send_data:       'r24 = Usi_twi_overflow_state
cpi r24, Usi_request_reply_from_send_data      'case Usi_request_reply_from_send_data ?
brNe Isr_ovf_slave_request_data       'no -> jmp to next case

      ldi r24, Usi_check_reply_from_send_data
      sts {Usi_twi_overflow_state}, r24        'Usi_twi_overflow_state = Usi_slave_check_reply_from_send_data

      'SET_USI_TO_READ_ACK()'
      CBI DDR_USI, PIN_SDA            'DDR_USI  &= ~(1<<PORT_USI_SDA) // Set SDA as input
      !out USIDR, r1     'USIDR = 0
      ldi r24, Usisr_send_or_read_ack
      !out USISR, r24    'USISR = Usisr_send_or_read_ack
      rjmp ISR_OVF_end   'break
Code:
Loadadr Twi_txbuf(1) , Z
bedeutet doch, dass immer nur das erste Byte gelesen und gesendet wird (wegen TWI_txbuf(1)).
Könnte man da nicht eine Variable einsetzen, die im Array hochzählt, z.B. TWI_txhead ?
TWI_txhead wird doch immer wieder um 1 erhöht. Ich verstehe aber nicht was danach geschieht.
Danach wird doch gesendet, und das ACK oder NACK abgewartet?
Der Slave reagiert aber nicht darauf sondern beendet die ISR, indem er nach ISR_OVF_end springt.

Hab ich das so richtig verstanden und wie sähe es aus, wenn man nach erfolgreichem Abfragen des ACK
wieder in die Senderoutine springt, nur mit erhöhtem Pointer/TWI_txhead?

Leider kenne ich mich nicht so gut mit Assembler aus, es wäre nett wenn mir jemand ein paar Tipps geben könnte.
Paul