i2c.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /****************************************************
  2. Low Level I2C Data Transreceiveing APIs
  3. PLEASE SEE WWW.EXTREMEELECTRONICS.CO.IN FOR DETAILED
  4. SCHEMATICS,USER GUIDE AND VIDOES.
  5. COPYRIGHT (C) 2008-2009 EXTREME ELECTRONICS INDIA
  6. ****************************************************/
  7. #include <avr/io.h>
  8. #include "i2c.h"
  9. /* Private defines */
  10. // twi_br must be 3
  11. #define TWI_SPEED 400000UL
  12. #define TWI_PRESCALER 4
  13. #define TWI_BR ((F_CPU / TWI_SPEED) - 16) / (2 * TWI_PRESCALER)
  14. #define TWPS_1 ((0<<TWPS1) | (0<<TWPS0))
  15. #define TWPS_4 ((0<<TWPS1) | (1<<TWPS0))
  16. #define TWPS_16 ((1<<TWPS1) | (0<<TWPS0))
  17. #define TWPS_64 ((1<<TWPS1) | (1<<TWPS0))
  18. #define TWI_PS TWPS_4
  19. #define TWI_WDT_TIMEOUT 10
  20. /* Private variables */
  21. uint8_t TWI_WDT;
  22. /**
  23. * @brief Initialize TWI
  24. * @param None
  25. * @return None
  26. */
  27. void I2C_Init(void) {
  28. //Set up TWI Module
  29. TWSR = TWI_PS;
  30. TWBR = TWI_BR;
  31. //Enable the TWI Module
  32. TWCR |= 1<<TWEN;
  33. }
  34. /**
  35. * @brief Disable TWI
  36. * @param None
  37. * @return None
  38. */
  39. void I2C_Close(void)
  40. {
  41. //Disable the module
  42. TWCR &= ~(1<<TWEN);
  43. }
  44. /**
  45. * @brief TWI Start condition
  46. * @param None
  47. * @return Operation status
  48. */
  49. twi_stats_t I2C_Start(void) {
  50. //Put Start Condition on Bus
  51. TWCR= (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
  52. //Poll Till Done
  53. TWI_WDT = TWI_WDT_TIMEOUT;
  54. while (!(TWCR & (1<<TWINT))) {
  55. if (TWI_WDT == 0) {
  56. return TWI_TIMEOUT;
  57. }
  58. }
  59. if ((TWSR & 0xF8) == 0x08 || (TWSR & 0xF8) == 0x10) {
  60. //start condition sent from master
  61. //or
  62. //repeat start condition sent from master
  63. return TWI_SUCCESS;
  64. } else {
  65. return TWI_ERROR;
  66. }
  67. }
  68. /**
  69. * @brief TWI Stop condition
  70. * @param None
  71. * @return Operation status
  72. */
  73. twi_stats_t I2C_Stop(void) {
  74. //Put Stop Condition on bus
  75. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  76. //Wait for STOP to finish
  77. // зачем это ждать тут? проверять перед стартом и всё!
  78. TWI_WDT = TWI_WDT_TIMEOUT;
  79. while (TWCR & (1<<TWSTO)) {
  80. if (TWI_WDT == 0) {
  81. return TWI_TIMEOUT;
  82. }
  83. }
  84. return TWI_SUCCESS;
  85. }
  86. /**
  87. * @brief TWI Send Byte
  88. * @param None
  89. * @return Operation status
  90. */
  91. twi_stats_t I2C_WriteByte(uint8_t data) {
  92. TWDR = data;
  93. //Initiate Transfer
  94. TWCR = (1<<TWEN) | (1<<TWINT);
  95. //Poll Till Done
  96. TWI_WDT = TWI_WDT_TIMEOUT;
  97. while (!(TWCR & (1<<TWINT))) {
  98. if (TWI_WDT == 0) {
  99. return TWI_TIMEOUT;
  100. }
  101. }
  102. //Check Status
  103. if ((TWSR & 0xF8) == 0x18 || (TWSR & 0xF8) == 0x28 || (TWSR & 0xF8) == 0x40) {
  104. //SLA+W Transmitted and ACK received
  105. //or
  106. //SLA+R Transmitted and ACK received
  107. //or
  108. //DATA Transmitted and ACK recived
  109. return TWI_SUCCESS;
  110. } else {
  111. return TWI_ERROR; //Error
  112. }
  113. }
  114. /**
  115. * @brief TWI Receive Byte
  116. * @param None
  117. * @return Operation status
  118. */
  119. twi_stats_t I2C_ReadByte(uint8_t *data, twi_ask_t ack) {
  120. //Set up ACK
  121. if (ack == TWI_ACK) {
  122. //return ACK after reception
  123. TWCR |= (1<<TWEA);
  124. } else {
  125. //return NACK after reception
  126. //Signals slave to stop giving more data
  127. //usually used for last byte read.
  128. TWCR &= ~(1<<TWEA);
  129. }
  130. //Now enable Reception of data by clearing TWINT
  131. TWCR |= (1<<TWINT);
  132. //Wait till done
  133. TWI_WDT = TWI_WDT_TIMEOUT;
  134. while(!(TWCR & (1<<TWINT))) {
  135. if (TWI_WDT == 0) {
  136. return TWI_TIMEOUT;
  137. }
  138. }
  139. //Check status
  140. if ((TWSR & 0xF8) == 0x58 || (TWSR & 0xF8) == 0x50) {
  141. //Data received and ACK returned
  142. // or
  143. //Data received and NACK returned
  144. //Read the data
  145. *data = TWDR;
  146. return TWI_SUCCESS;
  147. } else {
  148. return TWI_ERROR; //Error
  149. }
  150. }