Simple single-color 8x8x8 LED Cube with AVRs
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.

twi.c 6.1KB

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