You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

twimaster.c 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*************************************************************************
  2. * Title: I2C master library using hardware TWI interface
  3. * Author: Peter Fleury <[email protected]> http://jump.to/fleury
  4. * File: $Id: twimaster.c,v 1.3 2005/07/02 11:14:21 Peter Exp $
  5. * Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
  6. * Target: any AVR device with hardware TWI
  7. * Usage: API compatible with I2C Software Library i2cmaster.h
  8. **************************************************************************/
  9. #include <inttypes.h>
  10. #include <compat/twi.h>
  11. #include <i2cmaster.h>
  12. #include "debug.h"
  13. /* define CPU frequency in Mhz here if not defined in Makefile */
  14. #ifndef F_CPU
  15. #define F_CPU 4000000UL
  16. #endif
  17. /* I2C clock in Hz */
  18. #define SCL_CLOCK 400000L
  19. /*************************************************************************
  20. Initialization of the I2C bus interface. Need to be called only once
  21. *************************************************************************/
  22. void i2c_init(void)
  23. {
  24. /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
  25. TWSR = 0; /* no prescaler */
  26. TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */
  27. }/* i2c_init */
  28. /*************************************************************************
  29. Issues a start condition and sends address and transfer direction.
  30. return 0 = device accessible, 1= failed to access device
  31. *************************************************************************/
  32. unsigned char i2c_start(unsigned char address)
  33. {
  34. uint8_t twst;
  35. // send START condition
  36. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
  37. // wait until transmission completed
  38. while(!(TWCR & (1<<TWINT)));
  39. // check value of TWI Status Register. Mask prescaler bits.
  40. twst = TW_STATUS & 0xF8;
  41. if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
  42. // send device address
  43. TWDR = address;
  44. TWCR = (1<<TWINT) | (1<<TWEN);
  45. // wail until transmission completed and ACK/NACK has been received
  46. while(!(TWCR & (1<<TWINT)));
  47. // check value of TWI Status Register. Mask prescaler bits.
  48. twst = TW_STATUS & 0xF8;
  49. if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
  50. return 0;
  51. }/* i2c_start */
  52. /*************************************************************************
  53. Issues a start condition and sends address and transfer direction.
  54. If device is busy, use ack polling to wait until device is ready
  55. Input: address and transfer direction of I2C device
  56. *************************************************************************/
  57. void i2c_start_wait(unsigned char address)
  58. {
  59. uint8_t twst;
  60. while ( 1 )
  61. {
  62. // send START condition
  63. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
  64. // wait until transmission completed
  65. while(!(TWCR & (1<<TWINT)));
  66. // check value of TWI Status Register. Mask prescaler bits.
  67. twst = TW_STATUS & 0xF8;
  68. if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
  69. // send device address
  70. TWDR = address;
  71. TWCR = (1<<TWINT) | (1<<TWEN);
  72. // wail until transmission completed
  73. while(!(TWCR & (1<<TWINT)));
  74. // check value of TWI Status Register. Mask prescaler bits.
  75. twst = TW_STATUS & 0xF8;
  76. if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
  77. {
  78. /* device busy, send stop condition to terminate write operation */
  79. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  80. // wait until stop condition is executed and bus released
  81. while(TWCR & (1<<TWSTO));
  82. continue;
  83. }
  84. //if( twst != TW_MT_SLA_ACK) return 1;
  85. break;
  86. }
  87. }/* i2c_start_wait */
  88. /*************************************************************************
  89. Issues a repeated start condition and sends address and transfer direction
  90. Input: address and transfer direction of I2C device
  91. Return: 0 device accessible
  92. 1 failed to access device
  93. *************************************************************************/
  94. unsigned char i2c_rep_start(unsigned char address)
  95. {
  96. return i2c_start( address );
  97. }/* i2c_rep_start */
  98. /*************************************************************************
  99. Terminates the data transfer and releases the I2C bus
  100. *************************************************************************/
  101. void i2c_stop(void)
  102. {
  103. /* send stop condition */
  104. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  105. // wait until stop condition is executed and bus released
  106. while(TWCR & (1<<TWSTO));
  107. }/* i2c_stop */
  108. /*************************************************************************
  109. Send one byte to I2C device
  110. Input: byte to be transfered
  111. Return: 0 write successful
  112. 1 write failed
  113. *************************************************************************/
  114. unsigned char i2c_write( unsigned char data )
  115. {
  116. uint8_t twst;
  117. // send data to the previously addressed device
  118. TWDR = data;
  119. TWCR = (1<<TWINT) | (1<<TWEN);
  120. // wait until transmission completed
  121. while(!(TWCR & (1<<TWINT)));
  122. // check value of TWI Status Register. Mask prescaler bits
  123. twst = TW_STATUS & 0xF8;
  124. if( twst != TW_MT_DATA_ACK) return 1;
  125. return 0;
  126. }/* i2c_write */
  127. /*************************************************************************
  128. Read one byte from the I2C device, request more data from device
  129. Return: byte read from I2C device
  130. *************************************************************************/
  131. unsigned char i2c_readAck(void)
  132. {
  133. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
  134. while(!(TWCR & (1<<TWINT)));
  135. return TWDR;
  136. }/* i2c_readAck */
  137. /*************************************************************************
  138. Read one byte from the I2C device, read is followed by a stop condition
  139. Return: byte read from I2C device
  140. *************************************************************************/
  141. unsigned char i2c_readNak(void)
  142. {
  143. TWCR = (1<<TWINT) | (1<<TWEN);
  144. while(!(TWCR & (1<<TWINT)));
  145. return TWDR;
  146. }/* i2c_readNak */