changeset 152:3ff923cfab5f main

Pretty good TWI master support.
author Bob Cook <bob@bobcookdev.com>
date Sat, 14 Jul 2012 23:22:25 -0700
parents 1f998d3a559a
children cf96319a494f
files main/packages/avr/device/twi_master.cpp main/packages/avr/device/twi_master.h main/packages/avr/device/twi_status.h
diffstat 3 files changed, 409 insertions(+), 209 deletions(-) [+]
line wrap: on
line diff
--- a/main/packages/avr/device/twi_master.cpp	Sat Jul 07 14:52:52 2012 -0700
+++ b/main/packages/avr/device/twi_master.cpp	Sat Jul 14 23:22:25 2012 -0700
@@ -7,7 +7,7 @@
 //    
 //  This file provides the interface for the TWI library, using master mode.
 //
-//  Copyright (C) 2008 Bob Cook
+//  Copyright (C) 2012 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
@@ -27,7 +27,7 @@
 //  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 //  THE SOFTWARE.
 //
-//  This implementation was heavily inspired by the "i2cmaster.c" from Peter Fleury.
+//  This implementation was heavily inspired by the Atmel technote AVR315.
 //
 // ----------------------------------------------------------------------------------------
 
@@ -64,190 +64,280 @@
 #if defined( PRJ_TWI_MASTER_ENABLE )
 
 // ----------------------------------------------------------------------------------------
-//  twi_master_init
-//
+
+static twi_status_t g_twim_status = twi_status_no_state;
+
+static volatile uint8_t  g_twim_target_addr;
+static volatile uint8_t* g_twim_buffer_ptr;
+static volatile uint8_t  g_twim_buf_length;
+static volatile bool     g_twim_txrx_ok;
+
+// ----------------------------------------------------------------------------------------
+
+inline static bool twim_is_busy()
+{
+    // when the interrupt is enabled, the TWI h/w is busy
+    return ( TWCR & ( 1 << TWIE ) );
+}
+
+// ----------------------------------------------------------------------------------------
+
+void twim_init()
+{
+    //--    Initialize the TWI h/w registers.
+    
+    TWBR = static_cast< uint8_t >( ( ( PRJ_CPU_FREQ / PRJ_TWI_BUS_FREQ ) - 16 ) / 2 );
 
-void twi_master_init()
+    TWCR = 0
+         | ( 0 << TWINT )       // reset the interrupt flag
+         | ( 0 << TWEA  )       // temporarily disconnected from the bus
+         | ( 0 << TWSTA )       // no need to trigger a start condition yet
+         | ( 0 << TWSTO )       // no need to trigger a stop condition yet
+         | ( 1 << TWEN  )       // enable the TWI functions
+         | ( 0 << TWIE  )       // no interrupts enabled yet
+         ;
+
+    TWSR = 0;   // no prescalar
+
+    //--    Set the SDA and SCL pins as inputs, with pull-ups enabled.
+    
+    HW_TWI_DDR  &= ~( ( 1 << HW_TWI_SDA_PIN ) | ( 1 << HW_TWI_SCL_PIN ) );
+    HW_TWI_PORT |=  ( ( 1 << HW_TWI_SDA_PIN ) | ( 1 << HW_TWI_SCL_PIN ) );
+
+    //--    Initialize our state variables.
+    
+    g_twim_status  = twi_status_no_state;
+    g_twim_txrx_ok = false;
+}
+
+// ----------------------------------------------------------------------------------------
+
+void twim_stop()
 {
-    TWSR = 0; // no prescalar
-    TWBR = ( ( PRJ_CPU_FREQ / PRJ_TWI_BUS_FREQ ) - 16 ) / 2;
+    TWCR = 0;   // disable the TWI functions
+}
+
+// ----------------------------------------------------------------------------------------
+
+bool twim_write( uint8_t device, uint8_t data )
+{
+    return twim_write( device, &data, 1 );
 }
 
 // ----------------------------------------------------------------------------------------
-//  twi_master_start
-//
 
-bool twi_master_start( const uint8_t address )
+bool twim_write( uint8_t device, uint8_t data1, uint8_t data2 )
 {
-    //--    Send START condition.
-
-    TWCR = ( 1 << TWINT ) | ( 1 << TWSTA ) | ( 1 << TWEN );
-
-    //--    Wait until transmission completed.
-
-    while ( ! ( TWCR & ( 1 << TWINT ) ) );
-
-    //--    Check status.
-
-    uint8_t status = TW_STATUS & 0xF8;
+    uint8_t buf[ 2 ] = { data1, data2 };
+    return twim_write( device, buf, 2 );
+}
 
-    if ( ( status != TW_START) && ( status != TW_REP_START ) )
-    {
-        return false;
-    }
-
-    //--    Send device address.
-
-    TWDR = address;
-    TWCR = ( 1 << TWINT ) | ( 1 << TWEN );
-
-    //--    Wail until transmission completed and ACK/NACK has been received.
+// ----------------------------------------------------------------------------------------
 
-    while ( ! ( TWCR & ( 1 << TWINT ) ) );
-
-    //--    Check status.
-
-    status = TW_STATUS & 0xF8;
-
-    if ( ( status != TW_MT_SLA_ACK ) && ( status != TW_MR_SLA_ACK ) )
-    {
-        return false;
-    }
-
-    return true;
+bool twim_write( uint8_t device, uint8_t data1, uint8_t data2, uint8_t data3 )
+{
+    uint8_t buf[ 3 ] = { data1, data2, data3 };
+    return twim_write( device, buf, 3 );
 }
 
 // ----------------------------------------------------------------------------------------
-//  twi_master_start_repeated
-//
+
+bool twim_write( uint8_t device, const uint8_t* data, uint8_t len )
+{
+    while ( twim_is_busy() ) ;  // wait for idle
+
+    g_twim_target_addr = ( device << 1 ); // low bit is clear for write
+    g_twim_buffer_ptr  = const_cast< uint8_t* >( data );
+    g_twim_buf_length  = len;
+
+    g_twim_status  = twi_status_no_state;
+    g_twim_txrx_ok = false;
+
+    TWCR = 0
+         | ( 1 << TWINT )       // interrupt triggered
+         | ( 0 << TWEA  )       // not listening on the bus
+         | ( 1 << TWSTA )       // start condition
+         | ( 0 << TWSTO )       // no stop condition
+         | ( 1 << TWEN  )       // enable the TWI functions
+         | ( 1 << TWIE  )       // interrupts enabled
+         ;
+
+    while ( twim_is_busy() ) ;  // wait for idle
+
+    return g_twim_txrx_ok;
+}
 
-bool twi_master_start_repeated( const uint8_t address )
+// ----------------------------------------------------------------------------------------
+
+bool twim_read( uint8_t device, uint8_t* data, uint8_t len )
 {
-    return twi_master_start( address );
+    while ( twim_is_busy() ) ;  // wait for idle
+
+    g_twim_target_addr = ( device << 1 ) | 0x01; // low bit is set for read
+    g_twim_buffer_ptr  = data;
+    g_twim_buf_length  = len;
+
+    g_twim_status  = twi_status_no_state;
+    g_twim_txrx_ok = false;
+
+    TWCR = 0
+         | ( 1 << TWINT )       // interrupt triggered
+         | ( 0 << TWEA  )       // not listening on the bus
+         | ( 1 << TWSTA )       // start condition
+         | ( 0 << TWSTO )       // no stop condition
+         | ( 1 << TWEN  )       // enable the TWI functions
+         | ( 1 << TWIE  )       // interrupts enabled
+         ;
+
+    while ( twim_is_busy() ) ;  // wait for idle
+
+    return g_twim_txrx_ok;
 }
 
 // ----------------------------------------------------------------------------------------
-//  twi_master_start_wait
+//  This is nearly identical to "Figure 7. TWI interrupt service routine" from Atmel
+//  technical note 315, except that the target device address is not stored in the data
+//  buffer (and thus gets special treatment).
 //
 
-void twi_master_start_wait( const uint8_t address )
+ISR( TWI_vect )
 {
-    for ( ;; )
+    switch ( static_cast< twi_status_t >( TWSR ) )
     {
-        //--    Send START condition.
-        
-        TWCR = (1 << TWINT ) | ( 1 << TWSTA ) | ( 1 << TWEN );
-    
-        //--    Wait until transmission completed.
-
-        while ( ! ( TWCR & ( 1 << TWINT ) ) );
-    
-        //--    Check status.
-
-        uint8_t status = TW_STATUS & 0xf8;
-
-        if ( ( status != TW_START) && ( status != TW_REP_START ) ) 
-        {
-            continue;   // loop around, try again
-        }
-    
-        //--    Send device address.
+        case twi_status_start:
+        case twi_status_rep_start:
+            // transmit the target device identifier
+            TWDR = g_twim_target_addr;
+            TWCR = 0
+                 | ( 1 << TWINT )       // interrupt triggered
+                 | ( 0 << TWEA  )       // not listening on the bus
+                 | ( 0 << TWSTA )       // no start condition
+                 | ( 0 << TWSTO )       // no stop condition
+                 | ( 0 << TWWC  )       // clear write collision flag
+                 | ( 1 << TWEN  )       // enable the TWI functions
+                 | ( 1 << TWIE  )       // interrupts enabled
+                 ;
+            break;
 
-        TWDR = address;
-        TWCR = ( 1 << TWINT ) | ( 1 << TWEN );
-    
-        //--    Wait until transmission completed.
-
-        while ( ! ( TWCR & ( 1 << TWINT ) ) );
-    
-        //--    Check status.
-
-        status = TW_STATUS & 0xf8;
-
-        if ( ( status == TW_MT_SLA_NACK ) || ( status ==TW_MR_DATA_NACK ) ) 
-        {
-            //--    Device busy, send stop condition to terminate write operation.
+        case twi_status_mtx_adr_ack:
+        case twi_status_mtx_data_ack:
+            if ( g_twim_buf_length )
+            {
+                // send the next data byte
+                TWDR = *g_twim_buffer_ptr++;
+                --g_twim_buf_length;
+                TWCR = 0
+                     | ( 1 << TWINT )       // interrupt triggered
+                     | ( 0 << TWEA  )       // not listening on the bus
+                     | ( 0 << TWSTA )       // no start condition
+                     | ( 0 << TWSTO )       // no stop condition
+                     | ( 0 << TWWC  )       // clear write collision flag
+                     | ( 1 << TWEN  )       // enable the TWI functions
+                     | ( 1 << TWIE  )       // interrupts enabled
+                     ;
+            }
+            else
+            {
+                // successful end of message
+                g_twim_txrx_ok = true;
+                // trigger STOP condition
+                TWCR = 0
+                     | ( 1 << TWINT )       // interrupt triggered
+                     | ( 0 << TWEA  )       // not listening on the bus
+                     | ( 0 << TWSTA )       // no start condition
+                     | ( 1 << TWSTO )       // stop condition
+                     | ( 0 << TWWC  )       // clear write collision flag
+                     | ( 1 << TWEN  )       // enable the TWI functions
+                     | ( 0 << TWIE  )       // interrupts disabled
+                     ;
+            }
+            break;
 
-            TWCR = ( 1 << TWINT ) | ( 1 << TWEN ) | ( 1 << TWSTO );
-            
-            //--    Wait until stop condition is executed and bus released.
-
-            while ( TWCR & ( 1 << TWSTO ) );
-            
-            continue;
-        }
-
-        //--    Success!
-
-        return;
-     }
-}
+        case twi_status_mrx_data_ack:
+            *g_twim_buffer_ptr++ = TWDR;
+            --g_twim_buf_length;
+            // fall through intentionally
 
-// ----------------------------------------------------------------------------------------
-//  twi_master_write
-//
-//      Send a byte to the remote device. Assumes twi_master_start() was successful.
-//
-//      Returns true if the byte was sent successfully.
-//
-
-bool twi_master_write( const uint8_t data )
-{
-    //--    Send.
-
-    TWDR = data;
-    TWCR = ( 1 << TWINT ) | ( 1 << TWEN );
-
-    //--    wait until transmission completed.
-
-    while ( ! ( TWCR & ( 1 << TWINT ) ) );
-
-    //--    Check the result.
-
-    if ( ( TW_STATUS & 0xf8 ) != TW_MT_DATA_ACK )
-    {
-        return false;
-    }
-
-    return true;
-}
+        case twi_status_mrx_adr_ack:
+            if ( g_twim_buf_length > 1 )
+            {
+                // expecting to read more bytes
+                TWCR = 0
+                     | ( 1 << TWINT )       // interrupt triggered
+                     | ( 1 << TWEA  )       // listening on the bus
+                     | ( 0 << TWSTA )       // no start condition
+                     | ( 0 << TWSTO )       // no stop condition
+                     | ( 0 << TWWC  )       // clear write collision flag
+                     | ( 1 << TWEN  )       // enable the TWI functions
+                     | ( 1 << TWIE  )       // interrupts enabled
+                     ;
+            }
+            else
+            {
+                // send NACK, last byte still expected
+                TWCR = 0
+                     | ( 1 << TWINT )       // interrupt triggered
+                     | ( 0 << TWEA  )       // not listening on the bus
+                     | ( 0 << TWSTA )       // no start condition
+                     | ( 0 << TWSTO )       // no stop condition
+                     | ( 0 << TWWC  )       // clear write collision flag
+                     | ( 1 << TWEN  )       // enable the TWI functions
+                     | ( 1 << TWIE  )       // interrupts enabled
+                     ;
+            }   
+            break;
 
-// ----------------------------------------------------------------------------------------
-//  twi_master_read_and_request_more
-//
-//      Read a byte from the remote device, and signal that we intend to receive more
-//      data from the device immediately afterwards.
-//
-
-uint8_t twi_master_read_and_request_more()
-{
-}
-
-// ----------------------------------------------------------------------------------------
-//  twi_master_read_and_stop
-//
-//      Read a byte from the remote device, and signal this is the last read (puts a
-//      stop condition on the bus).
-//
+        case twi_status_mrx_data_nack:
+            // received last byte
+            *g_twim_buffer_ptr++ = TWDR;
+            --g_twim_buf_length;
+            g_twim_txrx_ok = ( g_twim_buf_length == 0 );
+            // trigger a STOP condition
+            TWCR = 0
+                 | ( 1 << TWINT )       // interrupt triggered
+                 | ( 0 << TWEA  )       // not listening on the bus
+                 | ( 0 << TWSTA )       // no start condition
+                 | ( 1 << TWSTO )       // stop condition
+                 | ( 0 << TWWC  )       // clear write collision flag
+                 | ( 1 << TWEN  )       // enable the TWI functions
+                 | ( 0 << TWIE  )       // interrupts disabled
+                 ;
+            break;     
 
-uint8_t twi_master_read_and_stop()
-{
-}
-
-// ----------------------------------------------------------------------------------------
-//  twi_master_send_stop
-//
+        case twi_status_abb_lost:
+            // trigger another START condition
+            TWCR = 0
+                 | ( 1 << TWINT )       // interrupt triggered
+                 | ( 0 << TWEA  )       // not listening on the bus
+                 | ( 1 << TWSTA )       // start condition
+                 | ( 0 << TWSTO )       // no stop condition
+                 | ( 0 << TWWC  )       // clear write collision flag
+                 | ( 1 << TWEN  )       // enable the TWI functions
+                 | ( 1 << TWIE  )       // interrupts enabled
+                 ;
+            break;
 
-void twi_master_send_stop()
-{
-    /* send stop condition */
-    TWCR = ( 1 << TWINT ) | ( 1 << TWEN ) | ( 1 << TWSTO );
-    
-    // wait until stop condition is executed and bus released
-    while(TWCR & (1<<TWSTO));
+        case twi_status_mtx_adr_nack:
+        case twi_status_mrx_adr_nack:
+        case twi_status_mtx_data_nack:
+        //    case TWI_NO_STATE              // No relevant state information available; TWINT = <93>0<94>
+        case twi_status_bus_error:
+        default:    
+            g_twim_status = static_cast< twi_status_t >( TWSR );
+            // reset interface
+            TWCR = 0
+                 | ( 0 << TWINT )       // clear interrupt flag
+                 | ( 0 << TWEA  )       // not listening on the bus
+                 | ( 0 << TWSTA )       // no start condition
+                 | ( 0 << TWSTO )       // no stop condition
+                 | ( 0 << TWWC  )       // clear write collision flag
+                 | ( 1 << TWEN  )       // enable the TWI functions
+                 | ( 0 << TWIE  )       // interrupts disabled
+                 ;
+            break;
+    }
 }
 
-
 // ----------------------------------------------------------------------------------------
 #endif  // #if defined( PRJ_TWI_MASTER_ENABLE )
 
--- a/main/packages/avr/device/twi_master.h	Sat Jul 07 14:52:52 2012 -0700
+++ b/main/packages/avr/device/twi_master.h	Sat Jul 14 23:22:25 2012 -0700
@@ -7,7 +7,7 @@
 //    
 //  This file provides the interface for the TWI library, using master mode.
 //
-//  Copyright (C) 2010 Bob Cook
+//  Copyright (C) 2012 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
@@ -34,6 +34,8 @@
 
 #include <stdint.h>
 
+#include "twi_status.h"
+
 // ----------------------------------------------------------------------------------------
 //  definitions from "project_defs.h"
 //
@@ -48,77 +50,44 @@
 // ----------------------------------------------------------------------------------------
 
 // ----------------------------------------------------------------------------------------
-//  twi_master_init
+//  twim_init
 //
 //      Initialize the TWI h/w for master mode; call this once, before doing any i/o.
 //
 
-void twi_master_init();
-
-// ----------------------------------------------------------------------------------------
-//  twi_master_start
-//
-//      Issue a start condition and send the address of the device to communicate with.
-//
-//      Returns true if the device is now accessible.
-//
-
-bool twi_master_start( const uint8_t address );
+void twim_init();
 
 // ----------------------------------------------------------------------------------------
-//  twi_master_start_repeated
+//  twim_stop
 //
-//      Similar to twi_master_start() except this is a repeated start.
-//
-//      Returns true if the device is now accessible.
+//      Stop the TWI h/w.
 //
 
-bool twi_master_start_repeated( const uint8_t address );
-
-// ----------------------------------------------------------------------------------------
-//  twi_master_start_wait
-//
-//      Similar to twi_master_start() except it waits for the bus and device to become 
-//      accessible.
-//
-
-void twi_master_start_wait( const uint8_t address );
+void twim_stop();
 
 // ----------------------------------------------------------------------------------------
-//  twi_master_write
-//
-//      Send a byte to the remote device. Assumes twi_master_start() was successful.
-//
-//      Returns true if the byte was sent successfully.
+//  twim_write
 //
-
-bool twi_master_write( const uint8_t data );
-
-// ----------------------------------------------------------------------------------------
-//  twi_master_read_and_request_more
-//
-//      Read a byte from the remote device, and signal that we intend to receive more
-//      data from the device immediately afterwards.
+//      Send one or more bytes to the specified remote device. Will block until all data
+//      is sent to the device, or an error occurs. Returns true if data is successfully
+//      written, false on error.
 //
 
-uint8_t twi_master_read_and_request_more();
+bool twim_write( uint8_t device, uint8_t data );
+bool twim_write( uint8_t device, uint8_t data1, uint8_t data2 );
+bool twim_write( uint8_t device, uint8_t data1, uint8_t data2, uint8_t data3 );
+bool twim_write( uint8_t device, const uint8_t* data, uint8_t len );
 
 // ----------------------------------------------------------------------------------------
-//  twi_master_read_and_stop
+//  twim_read
 //
-//      Read a byte from the remote device, and signal this is the last read (puts a
-//      stop condition on the bus).
+//      Read the specified number of byte(s) from the specified remote device. Will block
+//      until all data is read from the device, or an error occurs. Returns true if data
+//      is successfully read, false on error.
 //
 
-uint8_t twi_master_read_and_stop();
+bool twim_read( uint8_t device, uint8_t* data, uint8_t len );
 
-// ----------------------------------------------------------------------------------------
-//  twi_master_send_stop
-//
-//      Send a stop condition on the bus.
-//
-
-void twi_master_send_stop();
 
 #endif  // #if !defined( BCDRL_AVR_DEVICE_TWI_MASTER_H )
 // ----------------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/packages/avr/device/twi_status.h	Sat Jul 14 23:22:25 2012 -0700
@@ -0,0 +1,141 @@
+// ----------------------------------------------------------------------------------------
+//
+//  avr/device/twi_status.h
+//    
+//  Bob Cook Development, Robotics Library
+//  http://www.bobcookdev.com/rl/
+//    
+//  This file provides the interface for the TWI library, using master mode.
+//
+//  Copyright (C) 2012 Bob Cook
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+// 
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+// 
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+//  Refer to the Atmel datasheets for more details about each status code.
+//
+// ----------------------------------------------------------------------------------------
+
+#if !defined( BCDRL_AVR_DEVICE_TWI_STATUS_H )
+#define BCDRL_AVR_DEVICE_TWI_STATUS_H
+
+// ----------------------------------------------------------------------------------------
+
+typedef enum
+{
+    // ----- common status codes -----
+
+    // START condition has been transmitted
+    twi_status_start = 0x08,
+
+    // Repeated START has been transmitted
+    twi_status_rep_start = 0x10,
+
+    // Arbitration lost in SLA+R or NOT ACK bit
+    twi_status_abb_lost = 0x38,
+
+    // ----- master transmitter status codes -----
+
+    // SLA+W has been tramsmitted and ACK received
+    twi_status_mtx_adr_ack = 0x18,
+
+    // SLA+W has been tramsmitted and NACK received 
+    twi_status_mtx_adr_nack = 0x20,
+
+    // Data byte has been tramsmitted and ACK received
+    twi_status_mtx_data_ack = 0x28,
+
+    // Data byte has been tramsmitted and NACK received
+    twi_status_mtx_data_nack = 0x30,
+
+    // ----- master receiver status codes -----
+
+    // SLA+R has been tramsmitted and ACK received
+    twi_status_mrx_adr_ack = 0x40,
+
+    // SLA+R has been tramsmitted and NACK received
+    twi_status_mrx_adr_nack = 0x48,
+
+    // Data byte has been received and ACK tramsmitted
+    twi_status_mrx_data_ack = 0x50,
+
+    // Data byte has been received and NACK tramsmitted
+    twi_status_mrx_data_nack = 0x58,
+
+    // ----- slave transmitter status codes -----
+
+    // Own SLA+R has been received; ACK has been returned
+    twi_status_stx_adr_ack = 0xa8,
+
+    // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned
+    twi_status_stx_adr_ack_m_arb_lost = 0xb0,
+
+    // Data byte in TWDR has been transmitted; ACK has been received
+    twi_status_stx_data_ack = 0xb8,
+
+    // Data byte in TWDR has been transmitted; NOT ACK has been received
+    twi_status_stx_data_nack = 0xc0,
+
+    // Last data byte in TWDR has been transmitted (TWEA = <93>0<94>); ACK has been received
+    twi_status_stx_data_ack_last_byte = 0xc8,
+
+    // ----- slave receiver status codes -----
+
+    // Own SLA+W has been received ACK has been returned
+    twi_status_srx_adr_ack = 0x60,
+
+    // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned
+    twi_status_srx_adr_ack_m_arb_lost = 0x68,
+
+    // General call address has been received; ACK has been returned
+    twi_status_srx_gen_ack = 0x70,
+
+    // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned
+    twi_status_srx_gen_ack_m_arb_lost = 0x78,
+
+    // Previously addressed with own SLA+W; data has been received; ACK has been returned
+    twi_status_srx_adr_data_ack = 0x80,
+
+    // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned
+    twi_status_srx_adr_data_nack = 0x88,
+
+    // Previously addressed with general call; data has been received; ACK has been returned
+    twi_status_srx_gen_data_ack = 0x90,
+
+    // Previously addressed with general call; data has been received; NOT ACK has been returned
+    twi_status_srx_gen_data_nack = 0x98,
+
+    // A STOP condition or repeated START condition has been received while still addressed as Slave
+    twi_status_srx_stop_restart = 0xa0,
+
+    // ----- miscellaneous status codes -----
+
+    // No relevant state information available; TWINT = <93>0<94>
+    twi_status_no_state = 0xf8,
+
+    // Bus error due to an illegal START or STOP condition
+    twi_status_bus_error = 0x00,
+    
+} twi_status_t;
+
+
+#endif  // #if !defined( BCDRL_AVR_DEVICE_TWI_STATUS_H )
+// ----------------------------------------------------------------------------------------
+//  end of twi_status.h
+// ----------------------------------------------------------------------------------------
+