1
0

I2C.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * I2C.c
  3. * k4be 2022
  4. * License: BSD
  5. */
  6. #include <avr/io.h>
  7. #include <util/delay.h>
  8. #include "I2C.h"
  9. #include "main.h"
  10. void I2C_init(void){
  11. TWBR = 18;
  12. TWSR |= 0;
  13. }
  14. /* two byte command (or command + value) */
  15. unsigned int I2C_SendCommand(unsigned char address, unsigned char command, unsigned char data_byte)
  16. {
  17. unsigned int error = ERROR_I2C;
  18. for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
  19. {
  20. error = 0;
  21. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition
  22. error |= I2C_WaitForTWInt();
  23. error |= I2C_SendOneCommandByte(address << 1);
  24. error |= I2C_SendOneCommandByte(command);
  25. error |= I2C_SendOneCommandByte(data_byte);
  26. TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
  27. }
  28. return error;
  29. }
  30. /* three byte command (or command + 2 values) */
  31. unsigned int I2C_SendCommand3byte(unsigned char address,unsigned char command,unsigned char data0, unsigned char data1)
  32. {
  33. unsigned int error = ERROR_I2C;
  34. for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
  35. {
  36. error = 0;
  37. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition
  38. error |= I2C_WaitForTWInt();
  39. error |= I2C_SendOneCommandByte(address << 1);
  40. error |= I2C_SendOneCommandByte(command);
  41. error |= I2C_SendOneCommandByte(data0);
  42. error |= I2C_SendOneCommandByte(data1);
  43. TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
  44. }
  45. return error;
  46. }
  47. /* read single byte */
  48. unsigned int I2C_ReceiveCommand(unsigned char address, unsigned char command, unsigned char *data_byte)
  49. {
  50. unsigned int error = ERROR_I2C;
  51. unsigned char _unused;
  52. for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
  53. {
  54. error = 0;
  55. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition
  56. error |= I2C_WaitForTWInt();
  57. error |= I2C_SendOneCommandByte(address << 1);
  58. error |= I2C_SendOneCommandByte(command);
  59. error |= I2C_SendOneCommandByte((address << 1) | 1);
  60. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
  61. error |= I2C_WaitForTWInt();
  62. error |= I2C_ReceiveOneCommandByte(&_unused, 0);
  63. error |= I2C_ReceiveOneCommandByte(data_byte, 0);
  64. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  65. }
  66. return error;
  67. }
  68. /* send command + any byte count */
  69. unsigned int I2C_Send_n_bytes(unsigned char address,unsigned char command, const unsigned char *data, unsigned int length)
  70. {
  71. unsigned int error = ERROR_I2C;
  72. unsigned int i;
  73. for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
  74. {
  75. error = 0;
  76. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition
  77. error |= I2C_WaitForTWInt();
  78. error |= I2C_SendOneCommandByte(address << 1);
  79. error |= I2C_SendOneCommandByte(command);
  80. for(i=0;i<length;i++){
  81. error |= I2C_SendOneCommandByte(data[i]);
  82. }
  83. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  84. }
  85. return error;
  86. }
  87. /* read any byte count */
  88. unsigned int I2C_Receive_n_bytes(unsigned char address, unsigned char command, unsigned char *data, unsigned int length)
  89. {
  90. unsigned int i;
  91. unsigned int error = ERROR_I2C;
  92. for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
  93. {
  94. error = 0;
  95. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition
  96. error |= I2C_WaitForTWInt();
  97. error |= I2C_SendOneCommandByte(address << 1);
  98. error |= I2C_SendOneCommandByte(command);
  99. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  100. _delay_us(1);
  101. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
  102. error |= I2C_WaitForTWInt();
  103. error |= I2C_SendOneCommandByte((address << 1) | 1);
  104. for(i=0; i<length; i++){
  105. error |= I2C_ReceiveOneCommandByte(&data[i], i != length-1);
  106. }
  107. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  108. }
  109. return error;
  110. }
  111. /* read 2 bytes */
  112. unsigned int I2C_ReceiveCommand3byte(unsigned char address, unsigned char command, unsigned char *data0, unsigned char *data1)
  113. {
  114. unsigned int error = ERROR_I2C;
  115. unsigned char addressTrash;
  116. for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
  117. {
  118. error = 0;
  119. TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);//Send START condition
  120. error |= I2C_WaitForTWInt();
  121. error |= I2C_SendOneCommandByte(address << 1);
  122. error |= I2C_SendOneCommandByte(command);
  123. error |= I2C_SendOneCommandByte((address << 1) | 1);
  124. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
  125. error |= I2C_WaitForTWInt();
  126. error |= I2C_ReceiveOneCommandByte(&addressTrash, 0);
  127. error |= I2C_ReceiveOneCommandByte(data0, 0);
  128. error |= I2C_ReceiveOneCommandByte(data1, 0);
  129. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  130. }
  131. return error;
  132. }
  133. unsigned int I2C_SendOneCommandByte(unsigned char command)
  134. {
  135. TWDR = command;
  136. TWCR = (1<<TWINT) | (1<<TWEN);
  137. return I2C_WaitForTWInt();
  138. }
  139. unsigned int I2C_ReceiveOneCommandByte(unsigned char *command, unsigned char ack)
  140. {
  141. TWCR = (1<<TWINT) | (1<<TWEN) | (ack?_BV(TWEA):0);
  142. unsigned int error = I2C_WaitForTWInt();
  143. *command = TWDR;
  144. return error;
  145. }
  146. unsigned int I2C_WaitForTWInt(void){
  147. unsigned char count = 20;
  148. while (count && !(TWCR & (1<<TWINT))){
  149. count--;
  150. _delay_us(6);
  151. }
  152. if(count == 0) return ERROR_I2C_TIMEOUT;
  153. return ERROR_NO;
  154. }