use twi implementation by peterfleury and read rtc
							parent
							
								
									be90944b2f
								
							
						
					
					
						commit
						80ccc8e23c
					
				| @ -1,22 +0,0 @@ | |||||||
| #ifndef _I2C_h |  | ||||||
| #define _I2C_h |  | ||||||
| 
 |  | ||||||
| /** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */ |  | ||||||
| #define I2C_READ    1 |  | ||||||
| 
 |  | ||||||
| /** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */ |  | ||||||
| #define I2C_WRITE   0 |  | ||||||
| #define SCL_CLOCK  96000L //i2c clockspeed
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void i2c_init(void); |  | ||||||
| unsigned char i2c_start(unsigned char address); |  | ||||||
| /*
 |  | ||||||
| void i2c_stop(void); |  | ||||||
| unsigned char i2c_write( unsigned char data ); |  | ||||||
| unsigned char i2c_readAck(void); |  | ||||||
| unsigned char i2c_readNak(void); |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| #endif |  | ||||||
| @ -0,0 +1,178 @@ | |||||||
|  | #ifndef _I2CMASTER_H | ||||||
|  | #define _I2CMASTER_H | ||||||
|  | /************************************************************************* 
 | ||||||
|  | * Title:    C include file for the I2C master interface  | ||||||
|  | *           (i2cmaster.S or twimaster.c) | ||||||
|  | * Author:   Peter Fleury <pfleury@gmx.ch> | ||||||
|  | * File:     $Id: i2cmaster.h,v 1.12 2015/09/16 09:27:58 peter Exp $ | ||||||
|  | * Software: AVR-GCC 4.x | ||||||
|  | * Target:   any AVR device | ||||||
|  | * Usage:    see Doxygen manual | ||||||
|  | **************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  @file | ||||||
|  |  @defgroup pfleury_ic2master I2C Master library | ||||||
|  |  @code #include <i2cmaster.h> @endcode | ||||||
|  |    | ||||||
|  |  @brief I2C (TWI) Master Software Library | ||||||
|  | 
 | ||||||
|  |  Basic routines for communicating with I2C slave devices. This single master  | ||||||
|  |  implementation is limited to one bus master on the I2C bus.  | ||||||
|  | 
 | ||||||
|  |  This I2c library is implemented as a compact assembler software implementation of the I2C protocol  | ||||||
|  |  which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c). | ||||||
|  |  Since the API for these two implementations is exactly the same, an application can be linked either against the | ||||||
|  |  software I2C implementation or the hardware I2C implementation. | ||||||
|  | 
 | ||||||
|  |  Use 4.7k pull-up resistor on the SDA and SCL pin. | ||||||
|  |   | ||||||
|  |  Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module  | ||||||
|  |  i2cmaster.S to your target when using the software I2C implementation !  | ||||||
|  |   | ||||||
|  |  Adjust the  CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion. | ||||||
|  | 
 | ||||||
|  |  @note  | ||||||
|  |     The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted  | ||||||
|  |     to GNU assembler and AVR-GCC C call interface. | ||||||
|  |     Replaced the incorrect quarter period delays found in AVR300 with  | ||||||
|  |     half period delays.  | ||||||
|  |      | ||||||
|  |  @author Peter Fleury pfleury@gmx.ch  http://tinyurl.com/peterfleury
 | ||||||
|  |  @copyright (C) 2015 Peter Fleury, GNU General Public License Version 3 | ||||||
|  |   | ||||||
|  |  @par API Usage Example | ||||||
|  |   The following code shows typical usage of this library, see example test_i2cmaster.c | ||||||
|  | 
 | ||||||
|  |  @code | ||||||
|  | 
 | ||||||
|  |  #include <i2cmaster.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |  #define Dev24C02  0xA2      // device address of EEPROM 24C02, see datasheet
 | ||||||
|  | 
 | ||||||
|  |  int main(void) | ||||||
|  |  { | ||||||
|  |      unsigned char ret; | ||||||
|  | 
 | ||||||
|  |      i2c_init();                             // initialize I2C library
 | ||||||
|  | 
 | ||||||
|  |      // write 0x75 to EEPROM address 5 (Byte Write) 
 | ||||||
|  |      i2c_start_wait(Dev24C02+I2C_WRITE);     // set device address and write mode
 | ||||||
|  |      i2c_write(0x05);                        // write address = 5
 | ||||||
|  |      i2c_write(0x75);                        // write value 0x75 to EEPROM
 | ||||||
|  |      i2c_stop();                             // set stop conditon = release bus
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |      // read previously written value back from EEPROM address 5 
 | ||||||
|  |      i2c_start_wait(Dev24C02+I2C_WRITE);     // set device address and write mode
 | ||||||
|  | 
 | ||||||
|  |      i2c_write(0x05);                        // write address = 5
 | ||||||
|  |      i2c_rep_start(Dev24C02+I2C_READ);       // set device address and read mode
 | ||||||
|  | 
 | ||||||
|  |      ret = i2c_readNak();                    // read one byte from EEPROM
 | ||||||
|  |      i2c_stop(); | ||||||
|  | 
 | ||||||
|  |      for(;;); | ||||||
|  |  } | ||||||
|  |  @endcode | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**@{*/ | ||||||
|  | 
 | ||||||
|  | #if (__GNUC__ * 100 + __GNUC_MINOR__) < 304 | ||||||
|  | #error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include <avr/io.h> | ||||||
|  | 
 | ||||||
|  | /** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */ | ||||||
|  | #define I2C_READ    1 | ||||||
|  | 
 | ||||||
|  | /** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */ | ||||||
|  | #define I2C_WRITE   0 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  @brief initialize the I2C master interace. Need to be called only once  | ||||||
|  |  @return none | ||||||
|  |  */ | ||||||
|  | extern void i2c_init(void); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /** 
 | ||||||
|  |  @brief Terminates the data transfer and releases the I2C bus  | ||||||
|  |  @return none | ||||||
|  |  */ | ||||||
|  | extern void i2c_stop(void); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /** 
 | ||||||
|  |  @brief Issues a start condition and sends address and transfer direction  | ||||||
|  |    | ||||||
|  |  @param    addr address and transfer direction of I2C device | ||||||
|  |  @retval   0   device accessible  | ||||||
|  |  @retval   1   failed to access device  | ||||||
|  |  */ | ||||||
|  | extern unsigned char i2c_start(unsigned char addr); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  @brief Issues a repeated start condition and sends address and transfer direction  | ||||||
|  | 
 | ||||||
|  |  @param   addr address and transfer direction of I2C device | ||||||
|  |  @retval  0 device accessible | ||||||
|  |  @retval  1 failed to access device | ||||||
|  |  */ | ||||||
|  | extern unsigned char i2c_rep_start(unsigned char addr); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  @brief Issues a start condition and sends address and transfer direction  | ||||||
|  |     | ||||||
|  |  If device is busy, use ack polling to wait until device ready  | ||||||
|  |  @param    addr address and transfer direction of I2C device | ||||||
|  |  @return   none | ||||||
|  |  */ | ||||||
|  | extern void i2c_start_wait(unsigned char addr); | ||||||
|  | 
 | ||||||
|  |   | ||||||
|  | /**
 | ||||||
|  |  @brief Send one byte to I2C device | ||||||
|  |  @param    data  byte to be transfered | ||||||
|  |  @retval   0 write successful | ||||||
|  |  @retval   1 write failed | ||||||
|  |  */ | ||||||
|  | extern unsigned char i2c_write(unsigned char data); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  @brief    read one byte from the I2C device, request more data from device  | ||||||
|  |  @return   byte read from I2C device | ||||||
|  |  */ | ||||||
|  | extern unsigned char i2c_readAck(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  @brief    read one byte from the I2C device, read is followed by a stop condition  | ||||||
|  |  @return   byte read from I2C device | ||||||
|  |  */ | ||||||
|  | extern unsigned char i2c_readNak(void); | ||||||
|  | 
 | ||||||
|  | /** 
 | ||||||
|  |  @brief    read one byte from the I2C device | ||||||
|  |   | ||||||
|  |  Implemented as a macro, which calls either @ref i2c_readAck or @ref i2c_readNak | ||||||
|  |   | ||||||
|  |  @param    ack 1 send ack, request more data from device<br> | ||||||
|  |                0 send nak, read is followed by a stop condition  | ||||||
|  |  @return   byte read from I2C device | ||||||
|  |  */ | ||||||
|  | extern unsigned char i2c_read(unsigned char ack); | ||||||
|  | #define i2c_read(ack)  (ack) ? i2c_readAck() : i2c_readNak();  | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**@}*/ | ||||||
|  | #endif | ||||||
| @ -1,41 +1,17 @@ | |||||||
| #include "i2c.h" |  | ||||||
| #include "DS3231.h" | #include "DS3231.h" | ||||||
| #include "pinout.h" | #include "pinout.h" | ||||||
| #include <avr/io.h> | #include <avr/io.h> | ||||||
|  | #include "i2cmaster.h" | ||||||
| 
 | 
 | ||||||
| 
 | uint32_t DS3231_read(){ | ||||||
| 
 |     i2c_start_wait(0xD0); | ||||||
| void DS3231_init(void){ |     i2c_write(0x00); | ||||||
| 	//i2c_start(DS3231_ADDRESS);
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| int DS3231_seconds(void){ |  | ||||||
| 	 |  | ||||||
| 	char ret = i2c_start(DS3231_ADDRESS+I2C_WRITE); |  | ||||||
| 	/*
 |  | ||||||
| 	USART_Transmit_String(" Return "); |  | ||||||
| 	//putchar(ret);
 |  | ||||||
| 	USART_Transmit_String("\n"); |  | ||||||
| 	*/ |  | ||||||
| /*
 |  | ||||||
| 	if(ret){ //failed
 |  | ||||||
| 		  PORTB |= STATUS_LED_B; |  | ||||||
| 		  i2c_stop(); |  | ||||||
| 	}else{ |  | ||||||
| 		// issuing start condition ok, device accessible 
 |  | ||||||
|          i2c_write(0x05);                       // write address = 5
 |  | ||||||
|          i2c_write(0x75);                       // ret=0 -> Ok, ret=1 -> no ACK 
 |  | ||||||
|     i2c_stop(); |     i2c_stop(); | ||||||
| 
 | 
 | ||||||
| 		 i2c_start_wait(DS3231_ADDRESS+I2C_WRITE);     // set device address and write mode
 |     i2c_start_wait(0xD1); | ||||||
|          i2c_write(REG_SECONDS);                       // write address = 5
 |     uint8_t sec = i2c_readAck(); | ||||||
|          i2c_rep_start(DS3231_ADDRESS+I2C_READ);       // set device address and read mode
 |     uint8_t min = i2c_readAck(); | ||||||
|          ret = i2c_readNak();                          // read one byte
 |     uint8_t std = i2c_readNak(); | ||||||
|     i2c_stop(); |     i2c_stop(); | ||||||
| 	} |     return ((uint32_t)std<<16) | ((uint32_t)min<<8) | sec; | ||||||
| 	 |  | ||||||
| 	return ret; |  | ||||||
| 	*/ |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,94 +0,0 @@ | |||||||
| #include "i2c.h" |  | ||||||
| #include "pinout.h" |  | ||||||
| #include <util/twi.h> 			 |  | ||||||
| #include <avr/io.h> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void i2c_init(void) |  | ||||||
| { |  | ||||||
|   /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ |  | ||||||
|    |  | ||||||
|   TWSR = 1;                         /* no prescaler */ |  | ||||||
|   TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  /* must be > 10 for stable operation */ |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| unsigned char i2c_start(unsigned char address){ |  | ||||||
| 	char DATA = 0b10011000; |  | ||||||
| 	//Send START condition
 |  | ||||||
| 	TWCR =  (1<<TWINT)|  |  | ||||||
| 			(1<<TWSTA)| |  | ||||||
| 			(1<<TWEN); |  | ||||||
| 			 |  | ||||||
| 	//Wait for TWINT Flag set. This indicates that the START condition has been transmitted.
 |  | ||||||
| 	while (!(TWCR &(1<<TWINT))); |  | ||||||
| 	 |  | ||||||
| 	//Check value of TWI Status Register. Mask prescaler bits. If status different from START go to ERROR.
 |  | ||||||
| 	if ((TWSR & 0xF8) != TW_START){ |  | ||||||
| 		//ERROR();
 |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	//Load SLA_W into TWDR Register. Clear TWINT bit in TWCR to start transmission of address.
 |  | ||||||
| 	TWDR = address + I2C_WRITE; |  | ||||||
| 	TWCR = (1<<TWINT) | |  | ||||||
| 			(1<<TWEN); |  | ||||||
| 		 |  | ||||||
| 	//Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.	
 |  | ||||||
| 	while (!(TWCR & (1<<TWINT))); |  | ||||||
| 	 |  | ||||||
| 	//Check value of TWI Status Register. Mask prescaler bits. If status different from MT_SLA_ACK go to ERROR.
 |  | ||||||
| 	if ((TWSR & 0xF8) != TW_MT_SLA_ACK){ |  | ||||||
| 	//	 ERROR();
 |  | ||||||
| 	 } |  | ||||||
| 	 |  | ||||||
| 	//Load DATA into TWDR Register. Clear TWINT bit in TWCR to start transmission of data.
 |  | ||||||
| 	TWDR = DATA; |  | ||||||
| 	TWCR = (1<<TWINT) | |  | ||||||
| 			(1<<TWEN); |  | ||||||
| 			 |  | ||||||
| 	//Wait for TWINT Flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received. 
 |  | ||||||
| 	while (!(TWCR &(1<<TWINT))); |  | ||||||
| 	 |  | ||||||
| 	//Check value of TWI Status Register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR.
 |  | ||||||
| 	if ((TWSR & 0xF8) != TW_MT_DATA_ACK){ |  | ||||||
| 	// ERROR();
 |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	//Transmit STOP condition
 |  | ||||||
| 	TWCR = (1<<TWINT)| |  | ||||||
| 			(1<<TWEN) | |  | ||||||
| 			(1<<TWSTO); |  | ||||||
| 	 |  | ||||||
| 	 |  | ||||||
| 	/*
 |  | ||||||
| 	TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); |  | ||||||
| 	while  (!(TWCR & (1<<TWINT))); |  | ||||||
| 	if ((TWSR & 0xF8) != TW_START) |  | ||||||
| 	return 1; |  | ||||||
| 	//ERROR();                                                                //Fehlerbehandlung
 |  | ||||||
| 	TWDR = address + I2C_WRITE; |  | ||||||
| 	TWCR = (1<<TWINT) | (1<<TWEN); |  | ||||||
| 	while (!(TWCR & (1<<TWINT))); |  | ||||||
| 	if ((TWSR & 0xF8) != TW_MT_SLA_ACK) |  | ||||||
|   //ERROR();
 |  | ||||||
|   return 2; |  | ||||||
|   |  | ||||||
| TWDR = address; |  | ||||||
| TWCR = (1<<TWINT) | (1<<TWEN); |  | ||||||
| while (!(TWCR & (1<<TWINT))); |  | ||||||
| if ((TWSR & 0xF8) != TW_MT_DATA_ACK) |  | ||||||
| return 3; |  | ||||||
|   //ERROR();
 |  | ||||||
| TWCR = (1<<TWINT)|(1<<TWEN)| |  | ||||||
| (1<<TWSTO); |  | ||||||
| */ |  | ||||||
| return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @ -0,0 +1,202 @@ | |||||||
|  | /*************************************************************************
 | ||||||
|  | * Title:    I2C master library using hardware TWI interface | ||||||
|  | * Author:   Peter Fleury <pfleury@gmx.ch>  http://jump.to/fleury
 | ||||||
|  | * File:     $Id: twimaster.c,v 1.4 2015/01/17 12:16:05 peter Exp $ | ||||||
|  | * Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 | ||||||
|  | * Target:   any AVR device with hardware TWI  | ||||||
|  | * Usage:    API compatible with I2C Software Library i2cmaster.h | ||||||
|  | **************************************************************************/ | ||||||
|  | #include <inttypes.h> | ||||||
|  | #include <compat/twi.h> | ||||||
|  | 
 | ||||||
|  | #include <i2cmaster.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* define CPU frequency in hz here if not defined in Makefile */ | ||||||
|  | #ifndef F_CPU | ||||||
|  | #define F_CPU 4000000UL | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* I2C clock in Hz */ | ||||||
|  | #define SCL_CLOCK  100000L | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*************************************************************************
 | ||||||
|  |  Initialization of the I2C bus interface. Need to be called only once | ||||||
|  | *************************************************************************/ | ||||||
|  | void i2c_init(void) | ||||||
|  | { | ||||||
|  |   /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ | ||||||
|  |    | ||||||
|  |   TWSR = 0;                         /* no prescaler */ | ||||||
|  |   TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  /* must be > 10 for stable operation */ | ||||||
|  | 
 | ||||||
|  | }/* i2c_init */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*************************************************************************	
 | ||||||
|  |   Issues a start condition and sends address and transfer direction. | ||||||
|  |   return 0 = device accessible, 1= failed to access device | ||||||
|  | *************************************************************************/ | ||||||
|  | unsigned char i2c_start(unsigned char address) | ||||||
|  | { | ||||||
|  |     uint8_t   twst; | ||||||
|  | 
 | ||||||
|  | 	// send START condition
 | ||||||
|  | 	TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); | ||||||
|  | 
 | ||||||
|  | 	// wait until transmission completed
 | ||||||
|  | 	while(!(TWCR & (1<<TWINT))); | ||||||
|  | 
 | ||||||
|  | 	// check value of TWI Status Register. Mask prescaler bits.
 | ||||||
|  | 	twst = TW_STATUS & 0xF8; | ||||||
|  | 	if ( (twst != TW_START) && (twst != TW_REP_START)) return 1; | ||||||
|  | 
 | ||||||
|  | 	// 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 value of TWI Status Register. Mask prescaler bits.
 | ||||||
|  | 	twst = TW_STATUS & 0xF8; | ||||||
|  | 	if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | 
 | ||||||
|  | }/* i2c_start */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*************************************************************************
 | ||||||
|  |  Issues a start condition and sends address and transfer direction. | ||||||
|  |  If device is busy, use ack polling to wait until device is ready | ||||||
|  |   | ||||||
|  |  Input:   address and transfer direction of I2C device | ||||||
|  | *************************************************************************/ | ||||||
|  | void i2c_start_wait(unsigned char address) | ||||||
|  | { | ||||||
|  |     uint8_t   twst; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     while ( 1 ) | ||||||
|  |     { | ||||||
|  | 	    // send START condition
 | ||||||
|  | 	    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); | ||||||
|  |      | ||||||
|  |     	// wait until transmission completed
 | ||||||
|  |     	while(!(TWCR & (1<<TWINT))); | ||||||
|  |      | ||||||
|  |     	// check value of TWI Status Register. Mask prescaler bits.
 | ||||||
|  |     	twst = TW_STATUS & 0xF8; | ||||||
|  |     	if ( (twst != TW_START) && (twst != TW_REP_START)) continue; | ||||||
|  |      | ||||||
|  |     	// send device address
 | ||||||
|  |     	TWDR = address; | ||||||
|  |     	TWCR = (1<<TWINT) | (1<<TWEN); | ||||||
|  |      | ||||||
|  |     	// wail until transmission completed
 | ||||||
|  |     	while(!(TWCR & (1<<TWINT))); | ||||||
|  |      | ||||||
|  |     	// check value of TWI Status Register. Mask prescaler bits.
 | ||||||
|  |     	twst = TW_STATUS & 0xF8; | ||||||
|  |     	if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )  | ||||||
|  |     	{    	     | ||||||
|  |     	    /* device busy, send stop condition to terminate write operation */ | ||||||
|  | 	        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); | ||||||
|  | 	         | ||||||
|  | 	        // wait until stop condition is executed and bus released
 | ||||||
|  | 	        while(TWCR & (1<<TWSTO)); | ||||||
|  | 	         | ||||||
|  |     	    continue; | ||||||
|  |     	} | ||||||
|  |     	//if( twst != TW_MT_SLA_ACK) return 1;
 | ||||||
|  |     	break; | ||||||
|  |      } | ||||||
|  | 
 | ||||||
|  | }/* i2c_start_wait */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*************************************************************************
 | ||||||
|  |  Issues a repeated start condition and sends address and transfer direction  | ||||||
|  | 
 | ||||||
|  |  Input:   address and transfer direction of I2C device | ||||||
|  |   | ||||||
|  |  Return:  0 device accessible | ||||||
|  |           1 failed to access device | ||||||
|  | *************************************************************************/ | ||||||
|  | unsigned char i2c_rep_start(unsigned char address) | ||||||
|  | { | ||||||
|  |     return i2c_start( address ); | ||||||
|  | 
 | ||||||
|  | }/* i2c_rep_start */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*************************************************************************
 | ||||||
|  |  Terminates the data transfer and releases the I2C bus | ||||||
|  | *************************************************************************/ | ||||||
|  | void i2c_stop(void) | ||||||
|  | { | ||||||
|  |     /* send stop condition */ | ||||||
|  | 	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); | ||||||
|  | 	 | ||||||
|  | 	// wait until stop condition is executed and bus released
 | ||||||
|  | 	while(TWCR & (1<<TWSTO)); | ||||||
|  | 
 | ||||||
|  | }/* i2c_stop */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*************************************************************************
 | ||||||
|  |   Send one byte to I2C device | ||||||
|  |    | ||||||
|  |   Input:    byte to be transfered | ||||||
|  |   Return:   0 write successful  | ||||||
|  |             1 write failed | ||||||
|  | *************************************************************************/ | ||||||
|  | unsigned char i2c_write( unsigned char data ) | ||||||
|  | {	 | ||||||
|  |     uint8_t   twst; | ||||||
|  |      | ||||||
|  | 	// send data to the previously addressed device
 | ||||||
|  | 	TWDR = data; | ||||||
|  | 	TWCR = (1<<TWINT) | (1<<TWEN); | ||||||
|  | 
 | ||||||
|  | 	// wait until transmission completed
 | ||||||
|  | 	while(!(TWCR & (1<<TWINT))); | ||||||
|  | 
 | ||||||
|  | 	// check value of TWI Status Register. Mask prescaler bits
 | ||||||
|  | 	twst = TW_STATUS & 0xF8; | ||||||
|  | 	if( twst != TW_MT_DATA_ACK) return 1; | ||||||
|  | 	return 0; | ||||||
|  | 
 | ||||||
|  | }/* i2c_write */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*************************************************************************
 | ||||||
|  |  Read one byte from the I2C device, request more data from device  | ||||||
|  |   | ||||||
|  |  Return:  byte read from I2C device | ||||||
|  | *************************************************************************/ | ||||||
|  | unsigned char i2c_readAck(void) | ||||||
|  | { | ||||||
|  | 	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); | ||||||
|  | 	while(!(TWCR & (1<<TWINT)));     | ||||||
|  | 
 | ||||||
|  |     return TWDR; | ||||||
|  | 
 | ||||||
|  | }/* i2c_readAck */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*************************************************************************
 | ||||||
|  |  Read one byte from the I2C device, read is followed by a stop condition  | ||||||
|  |   | ||||||
|  |  Return:  byte read from I2C device | ||||||
|  | *************************************************************************/ | ||||||
|  | unsigned char i2c_readNak(void) | ||||||
|  | { | ||||||
|  | 	TWCR = (1<<TWINT) | (1<<TWEN); | ||||||
|  | 	while(!(TWCR & (1<<TWINT))); | ||||||
|  | 	 | ||||||
|  |     return TWDR; | ||||||
|  | 
 | ||||||
|  | }/* i2c_readNak */ | ||||||
					Loading…
					
					
				
		Reference in New Issue