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.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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. volatile uint8_t i2c_force_stop = 0;
  20. #define CHECK_FORCE_STOP() if(i2c_force_stop){i2c_force_stop=0;break;}
  21. /*************************************************************************
  22. Initialization of the I2C bus interface. Need to be called only once
  23. *************************************************************************/
  24. void i2c_init(void)
  25. {
  26. /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
  27. TWSR = 0; /* no prescaler */
  28. TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */
  29. }/* i2c_init */
  30. /*************************************************************************
  31. Issues a start condition and sends address and transfer direction.
  32. return 0 = device accessible, 1= failed to access device
  33. *************************************************************************/
  34. unsigned char i2c_start(unsigned char address)
  35. {
  36. uint8_t twst;
  37. // send START condition
  38. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
  39. // wait until transmission completed
  40. while(!(TWCR & (1<<TWINT))) { CHECK_FORCE_STOP(); };
  41. // check value of TWI Status Register. Mask prescaler bits.
  42. twst = TW_STATUS & 0xF8;
  43. if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
  44. // send device address
  45. TWDR = address;
  46. TWCR = (1<<TWINT) | (1<<TWEN);
  47. // wail until transmission completed and ACK/NACK has been received
  48. while(!(TWCR & (1<<TWINT))) { CHECK_FORCE_STOP(); };
  49. // check value of TWI Status Register. Mask prescaler bits.
  50. twst = TW_STATUS & 0xF8;
  51. if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
  52. return 0;
  53. }/* i2c_start */
  54. /*************************************************************************
  55. Issues a start condition and sends address and transfer direction.
  56. If device is busy, use ack polling to wait until device is ready
  57. Input: address and transfer direction of I2C device
  58. *************************************************************************/
  59. void i2c_start_wait(unsigned char address)
  60. {
  61. uint8_t twst;
  62. while ( 1 )
  63. {
  64. // send START condition
  65. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
  66. // wait until transmission completed
  67. while(!(TWCR & (1<<TWINT)));
  68. // check value of TWI Status Register. Mask prescaler bits.
  69. twst = TW_STATUS & 0xF8;
  70. if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
  71. // send device address
  72. TWDR = address;
  73. TWCR = (1<<TWINT) | (1<<TWEN);
  74. // wail until transmission completed
  75. while(!(TWCR & (1<<TWINT)));
  76. // check value of TWI Status Register. Mask prescaler bits.
  77. twst = TW_STATUS & 0xF8;
  78. if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
  79. {
  80. /* device busy, send stop condition to terminate write operation */
  81. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  82. // wait until stop condition is executed and bus released
  83. while(TWCR & (1<<TWSTO)) { CHECK_FORCE_STOP(); };
  84. continue;
  85. }
  86. //if( twst != TW_MT_SLA_ACK) return 1;
  87. break;
  88. }
  89. }/* i2c_start_wait */
  90. /*************************************************************************
  91. Issues a repeated start condition and sends address and transfer direction
  92. Input: address and transfer direction of I2C device
  93. Return: 0 device accessible
  94. 1 failed to access device
  95. *************************************************************************/
  96. unsigned char i2c_rep_start(unsigned char address)
  97. {
  98. return i2c_start( address );
  99. }/* i2c_rep_start */
  100. /*************************************************************************
  101. Terminates the data transfer and releases the I2C bus
  102. *************************************************************************/
  103. void i2c_stop(void)
  104. {
  105. /* send stop condition */
  106. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  107. // wait until stop condition is executed and bus released
  108. while(TWCR & (1<<TWSTO)) { CHECK_FORCE_STOP(); };
  109. }/* i2c_stop */
  110. /*************************************************************************
  111. Send one byte to I2C device
  112. Input: byte to be transfered
  113. Return: 0 write successful
  114. 1 write failed
  115. *************************************************************************/
  116. unsigned char i2c_write( unsigned char data )
  117. {
  118. uint8_t twst;
  119. // send data to the previously addressed device
  120. TWDR = data;
  121. TWCR = (1<<TWINT) | (1<<TWEN);
  122. // wait until transmission completed
  123. while(!(TWCR & (1<<TWINT))) { CHECK_FORCE_STOP() };
  124. // check value of TWI Status Register. Mask prescaler bits
  125. twst = TW_STATUS & 0xF8;
  126. if( twst != TW_MT_DATA_ACK) return 1;
  127. return 0;
  128. }/* i2c_write */
  129. /*************************************************************************
  130. Read one byte from the I2C device, request more data from device
  131. Return: byte read from I2C device
  132. *************************************************************************/
  133. unsigned char i2c_readAck(void)
  134. {
  135. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
  136. while(!(TWCR & (1<<TWINT))) { CHECK_FORCE_STOP(); };
  137. return TWDR;
  138. }/* i2c_readAck */
  139. /*************************************************************************
  140. Read one byte from the I2C device, read is followed by a stop condition
  141. Return: byte read from I2C device
  142. *************************************************************************/
  143. unsigned char i2c_readNak(void)
  144. {
  145. TWCR = (1<<TWINT) | (1<<TWEN);
  146. while(!(TWCR & (1<<TWINT))) { CHECK_FORCE_STOP(); };
  147. return TWDR;
  148. }/* i2c_readNak */