i2c.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "main.h"
  2. /**
  3. * @brief Check I2C for errors.
  4. * @retval I2C return code
  5. */
  6. int8_t i2c_check_err(void) {
  7. int8_t r = I2C_RET_OK;
  8. if ((I2C1->ISR & I2C_ISR_NACKF) != 0) {
  9. /* device not present */
  10. r = I2C_RET_NACK;
  11. } else if ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR)) != 0) {
  12. /* other error */
  13. r = I2C_RET_ERR;
  14. }
  15. if (r != I2C_RET_OK) {
  16. /* restart I2C and clear flags */
  17. I2C1->CR1 &= ~I2C_CR1_PE;
  18. while ((I2C1->CR1 & I2C_CR1_PE) != 0);
  19. I2C1->CR1 |= I2C_CR1_PE;
  20. }
  21. return r;
  22. }
  23. /**
  24. * @brief Read len bytes from I2C bus to data by reg_addr.
  25. * @retval I2C return code
  26. */
  27. int8_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *data, const uint16_t len) {
  28. int8_t r = I2C_RET_OK;
  29. Flag.I2C_RX_End = 0;
  30. Flag.I2C_RX_Err = 0;
  31. Flag.I2C_TX_Err = 0;
  32. /* wait for i2c */
  33. while ( I2C1->ISR & I2C_ISR_BUSY ) { __NOP(); };
  34. /* prepare i2c for sending reg addr */
  35. I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
  36. I2C1->CR2 |= ( id | 1 << I2C_CR2_NBYTES_Pos );
  37. /* gen START */
  38. I2C1->CR2 |= ( I2C_CR2_START );
  39. /* wait for byte request or any error */
  40. while ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF | I2C_ISR_TXE)) == 0) { __NOP(); };
  41. if ((I2C1->ISR & I2C_ISR_TXE) != 0) {
  42. /* device ok, send reg addr */
  43. I2C1->TXDR = reg_addr;
  44. } else {
  45. r = i2c_check_err();
  46. if (r != I2C_RET_OK) {
  47. Flag.I2C_TX_Err = 1;
  48. return r;
  49. }
  50. }
  51. /* wait for i2c or any error */
  52. while (((I2C1->ISR & I2C_ISR_BUSY) != 0) && ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF)) == 0)) { __NOP(); };
  53. r = i2c_check_err();
  54. if (r != I2C_RET_OK) {
  55. Flag.I2C_TX_Err = 1;
  56. return r;
  57. }
  58. /* prepare dma channel for receiving data */
  59. DMA1_Channel2->CMAR = (uint32_t)data;
  60. DMA1_Channel2->CPAR = (uint32_t)&(I2C1->RXDR);
  61. DMA1_Channel2->CNDTR = len;
  62. DMA1_Channel2->CCR |= DMA_CCR_EN;
  63. /* prepare i2c for receiving data */
  64. I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
  65. I2C1->CR2 |= ( id | len << I2C_CR2_NBYTES_Pos | I2C_CR2_RD_WRN);
  66. /* launch receiving */
  67. I2C1->CR1 |= ( I2C_CR1_RXDMAEN );
  68. I2C1->CR2 |= ( I2C_CR2_START );
  69. /* wait for receiving data */
  70. while ((Flag.I2C_RX_End == 0) && (Flag.I2C_RX_Err == 0)) { __NOP(); };
  71. return r;
  72. }
  73. /**
  74. * @brief Write len bytes to I2C bus from data by reg_addr.
  75. * @retval I2C return code
  76. */
  77. int8_t user_i2c_write(const uint8_t id, const uint8_t reg_addr, uint8_t *data, const uint16_t len) {
  78. int8_t r = I2C_RET_OK;
  79. Flag.I2C_TX_End = 0;
  80. Flag.I2C_TX_Err = 0;
  81. DMA1_Channel3->CMAR = (uint32_t)data;
  82. DMA1_Channel3->CPAR = (uint32_t)&(I2C1->TXDR);
  83. DMA1_Channel3->CNDTR = len;
  84. while ( I2C1->ISR & I2C_ISR_BUSY );
  85. I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
  86. I2C1->CR2 |= ( id | (len + 1) << I2C_CR2_NBYTES_Pos );
  87. I2C1->CR2 |= ( I2C_CR2_START );
  88. while ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF | I2C_ISR_TXE)) == 0) { __NOP(); };
  89. if ((I2C1->ISR & I2C_ISR_TXE) != 0) {
  90. I2C1->TXDR = reg_addr;
  91. } else {
  92. r = i2c_check_err();
  93. if (r != I2C_RET_OK) {
  94. Flag.I2C_TX_Err = 1;
  95. return r;
  96. }
  97. }
  98. DMA1_Channel3->CCR |= DMA_CCR_EN;
  99. I2C1->CR1 |= ( I2C_CR1_TXDMAEN );
  100. return r;
  101. }