i2c_master.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /* Library made by: g4lvanix
  2. * Github repository: https://github.com/g4lvanix/I2C-master-lib
  3. */
  4. #include <avr/io.h>
  5. #include <util/twi.h>
  6. #include "i2c_master.h"
  7. #define F_SCL 400000UL // SCL frequency
  8. #define Prescaler 1
  9. #define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2)
  10. void i2c_init(void)
  11. {
  12. TWBR = (uint8_t)TWBR_val;
  13. }
  14. uint8_t i2c_start(uint8_t address)
  15. {
  16. // reset TWI control register
  17. TWCR = 0;
  18. // transmit START condition
  19. TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
  20. // wait for end of transmission
  21. while( !(TWCR & (1<<TWINT)) );
  22. // check if the start condition was successfully transmitted
  23. if((TWSR & 0xF8) != TW_START){ return 1; }
  24. // load slave address into data register
  25. TWDR = address;
  26. // start transmission of address
  27. TWCR = (1<<TWINT) | (1<<TWEN);
  28. // wait for end of transmission
  29. while( !(TWCR & (1<<TWINT)) );
  30. // check if the device has acknowledged the READ / WRITE mode
  31. uint8_t twst = TW_STATUS & 0xF8;
  32. if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
  33. return 0;
  34. }
  35. uint8_t i2c_write(uint8_t data)
  36. {
  37. // load data into data register
  38. TWDR = data;
  39. // start transmission of data
  40. TWCR = (1<<TWINT) | (1<<TWEN);
  41. // wait for end of transmission
  42. while( !(TWCR & (1<<TWINT)) );
  43. if( (TWSR & 0xF8) != TW_MT_DATA_ACK ){ return 1; }
  44. return 0;
  45. }
  46. uint8_t i2c_read_ack(void)
  47. {
  48. // start TWI module and acknowledge data after reception
  49. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
  50. // wait for end of transmission
  51. while( !(TWCR & (1<<TWINT)) );
  52. // return received data from TWDR
  53. return TWDR;
  54. }
  55. uint8_t i2c_read_nack(void)
  56. {
  57. // start receiving without acknowledging reception
  58. TWCR = (1<<TWINT) | (1<<TWEN);
  59. // wait for end of transmission
  60. while( !(TWCR & (1<<TWINT)) );
  61. // return received data from TWDR
  62. return TWDR;
  63. }
  64. uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
  65. {
  66. if (i2c_start(address | I2C_WRITE)) return 1;
  67. for (uint16_t i = 0; i < length; i++)
  68. {
  69. if (i2c_write(data[i])) return 1;
  70. }
  71. i2c_stop();
  72. return 0;
  73. }
  74. uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length)
  75. {
  76. if (i2c_start(address | I2C_READ)) return 1;
  77. for (uint16_t i = 0; i < (length-1); i++)
  78. {
  79. data[i] = i2c_read_ack();
  80. }
  81. data[(length-1)] = i2c_read_nack();
  82. i2c_stop();
  83. return 0;
  84. }
  85. uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
  86. {
  87. if (i2c_start(devaddr | 0x00)) return 1;
  88. i2c_write(regaddr);
  89. for (uint16_t i = 0; i < length; i++)
  90. {
  91. if (i2c_write(data[i])) return 1;
  92. }
  93. i2c_stop();
  94. return 0;
  95. }
  96. uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
  97. {
  98. if (i2c_start(devaddr)) return 1;
  99. i2c_write(regaddr);
  100. if (i2c_start(devaddr | 0x01)) return 1;
  101. for (uint16_t i = 0; i < (length-1); i++)
  102. {
  103. data[i] = i2c_read_ack();
  104. }
  105. data[(length-1)] = i2c_read_nack();
  106. i2c_stop();
  107. return 0;
  108. }
  109. void i2c_stop(void)
  110. {
  111. // transmit STOP condition
  112. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  113. }