HW_AVR.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. void DS3231::begin()
  2. {
  3. if ((_sda_pin == SDA) and (_scl_pin == SCL))
  4. {
  5. _use_hw = true;
  6. // activate internal pullups for twi.
  7. digitalWrite(SDA, HIGH);
  8. digitalWrite(SCL, HIGH);
  9. //delay(1); // Workaround for a linker bug
  10. // initialize twi prescaler and bit rate
  11. cbi(TWSR, TWPS0);
  12. cbi(TWSR, TWPS1);
  13. TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
  14. // enable twi module, acks, and twi interrupt
  15. TWCR = _BV(TWEN) | _BV(TWIE)/* | _BV(TWEA)*/;
  16. }
  17. else
  18. {
  19. _use_hw = false;
  20. pinMode(_scl_pin, OUTPUT);
  21. }
  22. }
  23. void DS3231::_burstRead()
  24. {
  25. if (_use_hw)
  26. {
  27. // Send start address
  28. TWCR = _BV(TWEN) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); // Send START
  29. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  30. TWDR = DS3231_ADDR_W;
  31. TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Clear TWINT to proceed
  32. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  33. TWDR = 0;
  34. TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Clear TWINT to proceed
  35. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  36. // Read data starting from start address
  37. TWCR = _BV(TWEN) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); // Send rep. START
  38. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  39. TWDR = DS3231_ADDR_R;
  40. TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Clear TWINT to proceed
  41. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  42. for (int i=0; i<7; i++)
  43. {
  44. TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Send ACK and clear TWINT to proceed
  45. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  46. _burstArray[i] = TWDR;
  47. }
  48. TWCR = _BV(TWEN) | _BV(TWINT); // Send NACK and clear TWINT to proceed
  49. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  50. TWCR = _BV(TWEN)| _BV(TWINT) | _BV(TWSTO); // Send STOP
  51. }
  52. else
  53. {
  54. _sendStart(DS3231_ADDR_W);
  55. _waitForAck();
  56. _writeByte(0);
  57. _waitForAck();
  58. _sendStart(DS3231_ADDR_R);
  59. _waitForAck();
  60. for (int i=0; i<7; i++)
  61. {
  62. _burstArray[i] = _readByte();
  63. if (i<6)
  64. _sendAck();
  65. else
  66. _sendNack();
  67. }
  68. _sendStop();
  69. }
  70. }
  71. uint8_t DS3231::_readRegister(uint8_t reg)
  72. {
  73. uint8_t readValue=0;
  74. if (_use_hw)
  75. {
  76. // Send start address
  77. TWCR = _BV(TWEN) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); // Send START
  78. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  79. TWDR = DS3231_ADDR_W;
  80. TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Clear TWINT to proceed
  81. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  82. TWDR = reg;
  83. TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Clear TWINT to proceed
  84. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  85. // Read data starting from start address
  86. TWCR = _BV(TWEN) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); // Send rep. START
  87. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  88. TWDR = DS3231_ADDR_R;
  89. TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Clear TWINT to proceed
  90. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  91. TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Send ACK and clear TWINT to proceed
  92. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  93. readValue = TWDR;
  94. TWCR = _BV(TWEN) | _BV(TWINT); // Send NACK and clear TWINT to proceed
  95. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  96. TWCR = _BV(TWEN)| _BV(TWINT) | _BV(TWSTO); // Send STOP
  97. }
  98. else
  99. {
  100. _sendStart(DS3231_ADDR_W);
  101. _waitForAck();
  102. _writeByte(reg);
  103. _waitForAck();
  104. _sendStart(DS3231_ADDR_R);
  105. _waitForAck();
  106. readValue = _readByte();
  107. _sendNack();
  108. _sendStop();
  109. }
  110. return readValue;
  111. }
  112. void DS3231::_writeRegister(uint8_t reg, uint8_t value)
  113. {
  114. if (_use_hw)
  115. {
  116. // Send start address
  117. TWCR = _BV(TWEN) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); // Send START
  118. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  119. TWDR = DS3231_ADDR_W;
  120. TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Clear TWINT to proceed
  121. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  122. TWDR = reg;
  123. TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Clear TWINT to proceed
  124. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  125. TWDR = value;
  126. TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Clear TWINT to proceed
  127. while ((TWCR & _BV(TWINT)) == 0) {}; // Wait for TWI to be ready
  128. TWCR = _BV(TWEN)| _BV(TWINT) | _BV(TWSTO); // Send STOP
  129. }
  130. else
  131. {
  132. _sendStart(DS3231_ADDR_W);
  133. _waitForAck();
  134. _writeByte(reg);
  135. _waitForAck();
  136. _writeByte(value);
  137. _waitForAck();
  138. _sendStop();
  139. }
  140. }