i2c.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * (c) danielinux 2019
  3. * GPLv.2
  4. *
  5. * See LICENSE for details
  6. */
  7. #include <stdint.h>
  8. #include <stdlib.h>
  9. #include "system.h"
  10. #include "i2c.h"
  11. #include "display.h"
  12. #define DISPLAY_I2C_ADDR 0x3C
  13. #define I2C1 (0x40005400)
  14. #define APB1_SPEED_IN_MHZ (42)
  15. #define I2C1_CR1 (*(volatile uint32_t *)(I2C1))
  16. #define I2C1_CR2 (*(volatile uint32_t *)(I2C1 + 0x04))
  17. #define I2C1_OAR1 (*(volatile uint32_t *)(I2C1 + 0x08))
  18. #define I2C1_OAR2 (*(volatile uint32_t *)(I2C1 + 0x0c))
  19. #define I2C1_DR (*(volatile uint32_t *)(I2C1 + 0x10))
  20. #define I2C1_SR1 (*(volatile uint32_t *)(I2C1 + 0x14))
  21. #define I2C1_SR2 (*(volatile uint32_t *)(I2C1 + 0x18))
  22. #define I2C1_CCR (*(volatile uint32_t *)(I2C1 + 0x1c))
  23. #define I2C1_TRISE (*(volatile uint32_t *)(I2C1 + 0x20))
  24. #define I2C_CR1_ENABLE (1 << 0)
  25. #define I2C_CR1_START (1 << 8)
  26. #define I2C_CR1_STOP (1 << 9)
  27. #define I2C_CR1_ACK (1 << 10)
  28. #define I2C_CR2_FREQ_MASK (0x3ff)
  29. #define I2C_CCR_MASK (0xfff)
  30. #define I2C_TRISE_MASK (0x3f)
  31. #define I2C_SR1_START (1 << 0)
  32. #define I2C_SR1_TX_BTF (1 << 2)
  33. #define I2C_SR1_ADDR_SENT (1 << 1)
  34. #define I2C_SR1_RX_NOTEMPTY (1 << 6)
  35. #define I2C_SR1_TX_EMPTY (1 << 7)
  36. #define I2C_SR2_MASTER (1 << 0)
  37. #define I2C_SR2_BUSY (1 << 1)
  38. #define I2C_SR2_XMIT (1 << 2)
  39. #define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40023840))
  40. #define APB1_CLOCK_RST (*(volatile uint32_t *)(0x40023820))
  41. #define I2C1_APB1_CLOCK_ER_VAL (1 << 21)
  42. static void i2c1_pins_setup(void)
  43. {
  44. uint32_t reg;
  45. AHB1_CLOCK_ER |= GPIOB_AHB1_CLOCK_ER;
  46. /* Set mode = AF */
  47. reg = GPIOB_MODE & ~ (0x03 << (I2C1_SCL * 2));
  48. GPIOB_MODE = reg | (2 << (I2C1_SCL * 2));
  49. reg = GPIOB_MODE & ~ (0x03 << (I2C1_SDA * 2));
  50. GPIOB_MODE = reg | (2 << (I2C1_SDA * 2));
  51. /* Alternate function: */
  52. reg = GPIOB_AFH & ~(0xf << ((I2C1_SCL - 8) * 4));
  53. GPIOB_AFH = reg | (I2C1_PIN_AF << ((I2C1_SCL - 8) * 4));
  54. reg = GPIOB_AFH & ~(0xf << ((I2C1_SDA - 8) * 4));
  55. GPIOB_AFH = reg | (I2C1_PIN_AF << ((I2C1_SDA - 8) * 4));
  56. }
  57. static void i2c1_reset(void)
  58. {
  59. APB1_CLOCK_RST |= I2C1_APB1_CLOCK_ER_VAL;
  60. APB1_CLOCK_RST &= ~I2C1_APB1_CLOCK_ER_VAL;
  61. }
  62. static void i2c1_send_start(void)
  63. {
  64. volatile uint32_t sr1;
  65. I2C1_CR1 |= I2C_CR1_START;
  66. do {
  67. sr1 = I2C1_SR1;
  68. } while ((sr1 & I2C_SR1_START) == 0);;
  69. }
  70. static void i2c1_send_stop(void)
  71. {
  72. I2C1_CR1 |= I2C_CR1_STOP;
  73. }
  74. void display_send_data(void *priv, const uint8_t *buf, int len)
  75. {
  76. volatile uint32_t sr1, sr2;
  77. int i;
  78. volatile uint8_t drval;
  79. uint32_t start_data = 0x00000040;
  80. uint8_t address = DISPLAY_I2C_ADDR;
  81. I2C1_CR1 &= ~I2C_CR1_ENABLE;
  82. I2C1_CR1 &= ~I2C_CR1_STOP;
  83. I2C1_CR1 &= ~I2C_CR1_ACK;
  84. I2C1_CR1 |= I2C_CR1_ENABLE;
  85. /* Wait if the bus is busy */
  86. do {
  87. sr2 = I2C1_SR2;
  88. } while ((sr2 & I2C_SR2_BUSY) != 0);;
  89. /* Send a start condition */
  90. i2c1_send_start();
  91. /* Send address + R/W = 0 */
  92. I2C1_DR = (address << 1);
  93. do {
  94. sr1 = I2C1_SR1;
  95. } while ((sr1 & I2C_SR1_ADDR_SENT) != I2C_SR1_ADDR_SENT);
  96. do {
  97. sr2 = I2C1_SR2;
  98. } while ((sr2 & (I2C_SR2_BUSY | I2C_SR2_MASTER)) != (I2C_SR2_BUSY | I2C_SR2_MASTER));;
  99. I2C1_DR = start_data;
  100. do {
  101. sr1 = I2C1_SR1;
  102. } while ((sr1 & (I2C_SR1_TX_EMPTY)) == 0);
  103. for (i = 0; i < len; i++) {
  104. I2C1_DR = buf[i];
  105. do {
  106. sr1 = I2C1_SR1;
  107. if ((sr1 & I2C_SR1_RX_NOTEMPTY) == I2C_SR1_RX_NOTEMPTY) {
  108. drval = I2C1_DR;
  109. }
  110. } while ((sr1 & (I2C_SR1_TX_EMPTY)) == 0);
  111. }
  112. while ((sr1 & (I2C_SR1_TX_BTF)) == 0) {
  113. sr1 = I2C1_SR1;
  114. }
  115. i2c1_send_stop();
  116. }
  117. int i2c1_send(uint8_t address, const uint8_t *buf, int len)
  118. {
  119. volatile uint32_t sr1, sr2;
  120. int i;
  121. volatile uint8_t drval;
  122. I2C1_CR1 &= ~I2C_CR1_ENABLE;
  123. I2C1_CR1 &= ~I2C_CR1_STOP;
  124. I2C1_CR1 &= ~I2C_CR1_ACK;
  125. I2C1_CR1 |= I2C_CR1_ENABLE;
  126. /* Wait if the bus is busy */
  127. do {
  128. sr2 = I2C1_SR2;
  129. } while ((sr2 & I2C_SR2_BUSY) != 0);;
  130. /* Send a start condition */
  131. i2c1_send_start();
  132. /* Send address + R/W = 0 */
  133. I2C1_DR = (address << 1);
  134. do {
  135. sr1 = I2C1_SR1;
  136. } while ((sr1 & I2C_SR1_ADDR_SENT) != I2C_SR1_ADDR_SENT);
  137. do {
  138. sr2 = I2C1_SR2;
  139. } while ((sr2 & (I2C_SR2_BUSY | I2C_SR2_MASTER)) != (I2C_SR2_BUSY | I2C_SR2_MASTER));;
  140. for (i = 0; i < len; i++) {
  141. I2C1_DR = buf[i];
  142. do {
  143. sr1 = I2C1_SR1;
  144. if ((sr1 & I2C_SR1_RX_NOTEMPTY) == I2C_SR1_RX_NOTEMPTY) {
  145. drval = I2C1_DR;
  146. }
  147. } while ((sr1 & (I2C_SR1_TX_EMPTY)) == 0);
  148. }
  149. while ((sr1 & (I2C_SR1_TX_BTF)) == 0) {
  150. sr1 = I2C1_SR1;
  151. }
  152. i2c1_send_stop();
  153. return i;
  154. }
  155. void i2c1_setup(void)
  156. {
  157. uint32_t reg;
  158. i2c1_pins_setup();
  159. APB1_CLOCK_ER |= I2C1_APB1_CLOCK_ER_VAL;
  160. I2C1_CR1 &= ~I2C_CR1_ENABLE;
  161. i2c1_reset();
  162. reg = I2C1_CR2 & ~(I2C_CR2_FREQ_MASK);
  163. I2C1_CR2 = reg | APB1_SPEED_IN_MHZ;
  164. reg = I2C1_CCR & ~(I2C_CCR_MASK);
  165. // I2C1_CCR = reg | (APB1_SPEED_IN_MHZ * 5);
  166. I2C1_CCR = reg | 35;
  167. reg = I2C1_TRISE & ~(I2C_TRISE_MASK);
  168. I2C1_TRISE = reg | (APB1_SPEED_IN_MHZ + 1);
  169. I2C1_CR1 |= I2C_CR1_ENABLE;
  170. }
  171. void i2c_display_init(void)
  172. {
  173. i2c1_setup();
  174. display_init(NULL);
  175. }
  176. void display_send_cmd(void *priv, uint8_t cmd)
  177. {
  178. uint8_t buf[2] = {0x00, cmd};
  179. volatile int j;
  180. i2c1_send(DISPLAY_I2C_ADDR, buf, 2);
  181. }
  182. void display_send_cmd1(void *priv, uint8_t cmd, uint8_t arg1)
  183. {
  184. uint8_t buf[3] = {0x00, cmd, arg1};
  185. volatile int j;
  186. i2c1_send(DISPLAY_I2C_ADDR, buf, 3);
  187. }
  188. void display_send_cmd2(void *priv, uint8_t cmd, uint8_t arg1, uint8_t arg2)
  189. {
  190. uint8_t buf[4] = {0x00, cmd, arg1, arg2};
  191. volatile int j;
  192. i2c1_send(DISPLAY_I2C_ADDR, buf, 3);
  193. }