i2c.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* Copyright 2023 Dual Tachyon
  2. * https://github.com/DualTachyon
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "bsp/dp32g030/gpio.h"
  17. #include "bsp/dp32g030/portcon.h"
  18. #include "driver/gpio.h"
  19. #include "driver/i2c.h"
  20. #include "driver/systick.h"
  21. void I2C_Start(void)
  22. {
  23. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
  24. SYSTICK_DelayUs(1);
  25. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  26. SYSTICK_DelayUs(1);
  27. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
  28. SYSTICK_DelayUs(1);
  29. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  30. SYSTICK_DelayUs(1);
  31. }
  32. void I2C_Stop(void)
  33. {
  34. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
  35. SYSTICK_DelayUs(1);
  36. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  37. SYSTICK_DelayUs(1);
  38. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  39. SYSTICK_DelayUs(1);
  40. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
  41. SYSTICK_DelayUs(1);
  42. }
  43. uint8_t I2C_Read(bool bFinal)
  44. {
  45. uint8_t i, Data;
  46. PORTCON_PORTA_IE |= PORTCON_PORTA_IE_A11_BITS_ENABLE;
  47. PORTCON_PORTA_OD &= ~PORTCON_PORTA_OD_A11_MASK;
  48. GPIOA->DIR &= ~GPIO_DIR_11_MASK;
  49. Data = 0;
  50. for (i = 0; i < 8; i++) {
  51. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  52. SYSTICK_DelayUs(1);
  53. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  54. SYSTICK_DelayUs(1);
  55. Data <<= 1;
  56. SYSTICK_DelayUs(1);
  57. if (GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA)) {
  58. Data |= 1U;
  59. }
  60. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  61. SYSTICK_DelayUs(1);
  62. }
  63. PORTCON_PORTA_IE &= ~PORTCON_PORTA_IE_A11_MASK;
  64. PORTCON_PORTA_OD |= PORTCON_PORTA_OD_A11_BITS_ENABLE;
  65. GPIOA->DIR |= GPIO_DIR_11_BITS_OUTPUT;
  66. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  67. SYSTICK_DelayUs(1);
  68. if (bFinal) {
  69. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
  70. } else {
  71. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
  72. }
  73. SYSTICK_DelayUs(1);
  74. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  75. SYSTICK_DelayUs(1);
  76. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  77. SYSTICK_DelayUs(1);
  78. return Data;
  79. }
  80. int I2C_Write(uint8_t Data)
  81. {
  82. uint8_t i;
  83. int ret = -1;
  84. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  85. SYSTICK_DelayUs(1);
  86. for (i = 0; i < 8; i++) {
  87. if ((Data & 0x80) == 0) {
  88. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
  89. } else {
  90. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
  91. }
  92. Data <<= 1;
  93. SYSTICK_DelayUs(1);
  94. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  95. SYSTICK_DelayUs(1);
  96. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  97. SYSTICK_DelayUs(1);
  98. }
  99. PORTCON_PORTA_IE |= PORTCON_PORTA_IE_A11_BITS_ENABLE;
  100. PORTCON_PORTA_OD &= ~PORTCON_PORTA_OD_A11_MASK;
  101. GPIOA->DIR &= ~GPIO_DIR_11_MASK;
  102. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
  103. SYSTICK_DelayUs(1);
  104. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  105. SYSTICK_DelayUs(1);
  106. for (i = 0; i < 255; i++) {
  107. if (GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA) == 0) {
  108. ret = 0;
  109. break;
  110. }
  111. }
  112. GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
  113. SYSTICK_DelayUs(1);
  114. PORTCON_PORTA_IE &= ~PORTCON_PORTA_IE_A11_MASK;
  115. PORTCON_PORTA_OD |= PORTCON_PORTA_OD_A11_BITS_ENABLE;
  116. GPIOA->DIR |= GPIO_DIR_11_BITS_OUTPUT;
  117. GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
  118. return ret;
  119. }
  120. int I2C_ReadBuffer(void *pBuffer, uint8_t Size)
  121. {
  122. uint8_t *pData = (uint8_t *)pBuffer;
  123. uint8_t i;
  124. for (i = 0; i < Size - 1; i++) {
  125. SYSTICK_DelayUs(1);
  126. pData[i] = I2C_Read(false);
  127. }
  128. SYSTICK_DelayUs(1);
  129. pData[i] = I2C_Read(true);
  130. return Size;
  131. }
  132. int I2C_WriteBuffer(const void *pBuffer, uint8_t Size)
  133. {
  134. const uint8_t *pData = (const uint8_t *)pBuffer;
  135. uint8_t i;
  136. for (i = 0; i < Size; i++) {
  137. if (I2C_Write(*pData++) < 0) {
  138. return -1;
  139. }
  140. }
  141. return 0;
  142. }