HW_ARM.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. void DS3231::begin()
  2. {
  3. _use_hw = false;
  4. if ((_sda_pin == SDA) and (_scl_pin == SCL))
  5. {
  6. _use_hw = true;
  7. twi = TWI1;
  8. pmc_enable_periph_clk(WIRE_INTERFACE_ID);
  9. PIO_Configure(g_APinDescription[PIN_WIRE_SDA].pPort, g_APinDescription[PIN_WIRE_SDA].ulPinType, g_APinDescription[PIN_WIRE_SDA].ulPin, g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration);
  10. PIO_Configure(g_APinDescription[PIN_WIRE_SCL].pPort, g_APinDescription[PIN_WIRE_SCL].ulPinType, g_APinDescription[PIN_WIRE_SCL].ulPin, g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration);
  11. NVIC_DisableIRQ(TWI1_IRQn);
  12. NVIC_ClearPendingIRQ(TWI1_IRQn);
  13. NVIC_SetPriority(TWI1_IRQn, 0);
  14. NVIC_EnableIRQ(TWI1_IRQn);
  15. }
  16. else if ((_sda_pin == SDA1) and (_scl_pin == SCL1))
  17. {
  18. _use_hw = true;
  19. twi = TWI0;
  20. pmc_enable_periph_clk(WIRE1_INTERFACE_ID);
  21. PIO_Configure(g_APinDescription[PIN_WIRE1_SDA].pPort, g_APinDescription[PIN_WIRE1_SDA].ulPinType, g_APinDescription[PIN_WIRE1_SDA].ulPin, g_APinDescription[PIN_WIRE1_SDA].ulPinConfiguration);
  22. PIO_Configure(g_APinDescription[PIN_WIRE1_SCL].pPort, g_APinDescription[PIN_WIRE1_SCL].ulPinType, g_APinDescription[PIN_WIRE1_SCL].ulPin, g_APinDescription[PIN_WIRE1_SCL].ulPinConfiguration);
  23. NVIC_DisableIRQ(TWI0_IRQn);
  24. NVIC_ClearPendingIRQ(TWI0_IRQn);
  25. NVIC_SetPriority(TWI0_IRQn, 0);
  26. NVIC_EnableIRQ(TWI0_IRQn);
  27. }
  28. if (_use_hw)
  29. {
  30. // activate internal pullups for twi.
  31. digitalWrite(SDA, 1);
  32. digitalWrite(SCL, 1);
  33. // Reset the TWI
  34. twi->TWI_CR = TWI_CR_SWRST;
  35. // TWI Slave Mode Disabled, TWI Master Mode Disabled.
  36. twi->TWI_CR = TWI_CR_SVDIS;
  37. twi->TWI_CR = TWI_CR_MSDIS;
  38. // Set TWI Speed
  39. twi->TWI_CWGR = (TWI_DIV << 16) | (TWI_SPEED << 8) | TWI_SPEED;
  40. // Set master mode
  41. twi->TWI_CR = TWI_CR_MSEN;
  42. }
  43. else
  44. {
  45. pinMode(_scl_pin, OUTPUT);
  46. }
  47. }
  48. void DS3231::_burstRead()
  49. {
  50. if (_use_hw)
  51. {
  52. // Set slave address and number of internal address bytes.
  53. twi->TWI_MMR = (1 << 8) | TWI_MMR_MREAD | (DS3231_ADDR << 16);
  54. // Set internal address bytes
  55. twi->TWI_IADR = 0;
  56. // Send START condition
  57. twi->TWI_CR = TWI_CR_START;
  58. for (int i=0; i<6; i++)
  59. {
  60. while ((twi->TWI_SR & TWI_SR_RXRDY) != TWI_SR_RXRDY)
  61. {
  62. };
  63. _burstArray[i] = twi->TWI_RHR;
  64. }
  65. twi->TWI_CR = TWI_CR_STOP;
  66. while ((twi->TWI_SR & TWI_SR_RXRDY) != TWI_SR_RXRDY) {};
  67. _burstArray[6] = twi->TWI_RHR;
  68. while ((twi->TWI_SR & TWI_SR_TXCOMP) != TWI_SR_TXCOMP) {};
  69. }
  70. else
  71. {
  72. _sendStart(DS3231_ADDR_W);
  73. _waitForAck();
  74. _writeByte(0);
  75. _waitForAck();
  76. _sendStart(DS3231_ADDR_R);
  77. _waitForAck();
  78. for (int i=0; i<7; i++)
  79. {
  80. _burstArray[i] = _readByte();
  81. if (i<6)
  82. _sendAck();
  83. else
  84. _sendNack();
  85. }
  86. _sendStop();
  87. }
  88. }
  89. uint8_t DS3231::_readRegister(uint8_t reg)
  90. {
  91. uint8_t readValue=0;
  92. if (_use_hw)
  93. {
  94. // Set slave address and number of internal address bytes.
  95. twi->TWI_MMR = (1 << 8) | TWI_MMR_MREAD | (DS3231_ADDR << 16);
  96. // Set internal address bytes
  97. twi->TWI_IADR = reg;
  98. // Send START and STOP condition to read a single byte
  99. twi->TWI_CR = TWI_CR_START | TWI_CR_STOP;
  100. while ((twi->TWI_SR & TWI_SR_RXRDY) != TWI_SR_RXRDY) {};
  101. readValue = twi->TWI_RHR;
  102. while ((twi->TWI_SR & TWI_SR_TXCOMP) != TWI_SR_TXCOMP) {};
  103. }
  104. else
  105. {
  106. _sendStart(DS3231_ADDR_W);
  107. _waitForAck();
  108. _writeByte(reg);
  109. _waitForAck();
  110. _sendStart(DS3231_ADDR_R);
  111. _waitForAck();
  112. readValue = _readByte();
  113. _sendNack();
  114. _sendStop();
  115. }
  116. return readValue;
  117. }
  118. void DS3231::_writeRegister(uint8_t reg, uint8_t value)
  119. {
  120. if (_use_hw)
  121. {
  122. // Set slave address and number of internal address bytes.
  123. twi->TWI_MMR = (1 << 8) | (DS3231_ADDR << 16);
  124. // Set internal address bytes
  125. twi->TWI_IADR = reg;
  126. // Send a single byte to start transfer
  127. twi->TWI_THR = value;
  128. while ((twi->TWI_SR & TWI_SR_TXRDY) != TWI_SR_TXRDY) {};
  129. // Send STOP condition
  130. twi->TWI_CR = TWI_CR_STOP;
  131. while ((twi->TWI_SR & TWI_SR_TXCOMP) != TWI_SR_TXCOMP) {};
  132. }
  133. else
  134. {
  135. _sendStart(DS3231_ADDR_W);
  136. _waitForAck();
  137. _writeByte(reg);
  138. _waitForAck();
  139. _writeByte(value);
  140. _waitForAck();
  141. _sendStop();
  142. }
  143. }