|
@@ -15,13 +15,32 @@
|
|
|
static i2c_status_t st_Read = I2C_Ret_OK;
|
|
|
|
|
|
|
|
|
-i2c_status_t i2c_check_err(void);
|
|
|
+static i2c_status_t i2c_check_err(void);
|
|
|
+
|
|
|
+static inline void i2c_start(void) {
|
|
|
+
|
|
|
+ I2C1->CR2 |= (I2C_CR2_START);
|
|
|
+ while ((I2C1->CR2 & I2C_CR2_START)) {}
|
|
|
+}
|
|
|
+
|
|
|
+static inline void i2c_stop(void) {
|
|
|
+
|
|
|
+ I2C1->CR2 |= (I2C_CR2_STOP);
|
|
|
+ while ((I2C1->CR2 & I2C_CR2_STOP)) {}
|
|
|
+
|
|
|
+ I2C1->ICR |= (I2C_ICR_STOPCF);
|
|
|
+ while ((I2C1->ICR & I2C_ICR_STOPCF)) {}
|
|
|
+}
|
|
|
+
|
|
|
+static void i2c_write_byte(uint8_t dat);
|
|
|
+static uint8_t i2c_read_byte(void);
|
|
|
+static uint8_t i2c_read_register(uint8_t reg_addr);
|
|
|
|
|
|
|
|
|
* @brief Check I2C bus for errors.
|
|
|
* @retval I2C return code
|
|
|
*/
|
|
|
-i2c_status_t i2c_check_err(void) {
|
|
|
+static i2c_status_t i2c_check_err(void) {
|
|
|
i2c_status_t r = I2C_Ret_OK;
|
|
|
|
|
|
if ((I2C1->ISR & I2C_ISR_NACKF) != 0) {
|
|
@@ -49,7 +68,7 @@ i2c_status_t i2c_check_err(void) {
|
|
|
* @brief Read len bytes from I2C bus to data by reg_addr.
|
|
|
* @retval I2C return code
|
|
|
*/
|
|
|
-i2c_status_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *data, const uint16_t len) {
|
|
|
+i2c_status_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *data, uint16_t len) {
|
|
|
|
|
|
while ( I2C1->ISR & I2C_ISR_BUSY ) { __NOP(); };
|
|
|
|
|
@@ -61,16 +80,11 @@ i2c_status_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *da
|
|
|
|
|
|
|
|
|
I2C1->CR2 &= ~(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
- I2C1->CR2 |= (id | 1 << I2C_CR2_NBYTES_Pos);
|
|
|
-
|
|
|
- I2C1->CR2 |= I2C_CR2_START;
|
|
|
+ I2C1->CR2 |= (id | (1 << I2C_CR2_NBYTES_Pos));
|
|
|
+ i2c_start();
|
|
|
|
|
|
|
|
|
-
|
|
|
while ((I2C1->ISR & (I2C_ISR_TIMEOUT | I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF | I2C_ISR_TXE)) == 0) {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
__NOP();
|
|
|
}
|
|
|
|
|
@@ -79,10 +93,9 @@ i2c_status_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *da
|
|
|
I2C1->TXDR = reg_addr;
|
|
|
} else {
|
|
|
st_Read = i2c_check_err();
|
|
|
- if (st_Read != I2C_Ret_OK) {
|
|
|
- Flag.I2C_TX_Err = 1;
|
|
|
- return st_Read;
|
|
|
- }
|
|
|
+ Flag.I2C_TX_Err = 1;
|
|
|
+ Flag.I2C_RX_End = 1;
|
|
|
+ return st_Read;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -90,37 +103,32 @@ i2c_status_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *da
|
|
|
st_Read = i2c_check_err();
|
|
|
if (st_Read != I2C_Ret_OK) {
|
|
|
Flag.I2C_TX_Err = 1;
|
|
|
+ Flag.I2C_RX_End = 1;
|
|
|
return st_Read;
|
|
|
}
|
|
|
|
|
|
- int cnt = 0;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- while ((((I2C1->ISR & I2C_ISR_TC)==0) && ((I2C1->ISR & I2C_ISR_NACKF)==0)) && (I2C1->ISR & I2C_ISR_BUSY)) {
|
|
|
+
|
|
|
+ I2C1->CR2 &= ~(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
+ I2C1->CR2 |= (id | (len << I2C_CR2_NBYTES_Pos) | I2C_CR2_RD_WRN);
|
|
|
+
|
|
|
+ i2c_start();
|
|
|
+
|
|
|
+
|
|
|
+ while (len) {
|
|
|
+ while ((I2C1->ISR & (I2C_ISR_NACKF | I2C_ISR_RXNE))==0) { __NOP(); }
|
|
|
if (I2C1->ISR & I2C_ISR_RXNE) {
|
|
|
*data = I2C1->RXDR;
|
|
|
data ++;
|
|
|
- cnt ++;
|
|
|
- if (cnt > len) {
|
|
|
- st_Read = I2C_Ret_Err;
|
|
|
- break;
|
|
|
- }
|
|
|
+ len --;
|
|
|
+ } else {
|
|
|
+ st_Read = i2c_check_err();
|
|
|
+ Flag.I2C_RX_Err = 1;
|
|
|
+ Flag.I2C_RX_End = 1;
|
|
|
+ return st_Read;
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ Flag.I2C_RX_End = 1;
|
|
|
return st_Read;
|
|
|
}
|
|
|
|
|
@@ -136,19 +144,11 @@ i2c_status_t user_i2c_write(const uint8_t id, const uint8_t reg_addr, uint8_t *d
|
|
|
Flag.I2C_TX_End = 0;
|
|
|
Flag.I2C_TX_Err = 0;
|
|
|
|
|
|
- DMA1_Channel2->CMAR = (uint32_t)data;
|
|
|
- DMA1_Channel2->CPAR = (uint32_t)&(I2C1->TXDR);
|
|
|
- DMA1_Channel2->CNDTR = len;
|
|
|
-
|
|
|
- I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
- I2C1->CR2 |= ( id | (len + 1) << I2C_CR2_NBYTES_Pos );
|
|
|
- I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
+ I2C1->CR2 &= ~(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
+ I2C1->CR2 |= (id | ((len + 1) << I2C_CR2_NBYTES_Pos ));
|
|
|
+ i2c_start();
|
|
|
|
|
|
-
|
|
|
while ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF | I2C_ISR_TXE)) == 0) {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
__NOP();
|
|
|
}
|
|
|
|
|
@@ -156,28 +156,69 @@ i2c_status_t user_i2c_write(const uint8_t id, const uint8_t reg_addr, uint8_t *d
|
|
|
I2C1->TXDR = reg_addr;
|
|
|
} else {
|
|
|
r = i2c_check_err();
|
|
|
- if (r != I2C_Ret_OK) {
|
|
|
- Flag.I2C_TX_Err = 1;
|
|
|
- return r;
|
|
|
- }
|
|
|
+ Flag.I2C_TX_Err = 1;
|
|
|
+ Flag.I2C_TX_End = 1;
|
|
|
+ return r;
|
|
|
}
|
|
|
|
|
|
while (len) {
|
|
|
- while ((I2C1->ISR & (I2C_ISR_TC | I2C_ISR_BUSY | I2C_ISR_NACKF | I2C_ISR_TXE)) == 0) { __NOP(); }
|
|
|
- if (I2C1->ISR & I2C_ISR_TXE) {
|
|
|
+ while ((I2C1->ISR & (I2C_ISR_NACKF | I2C_ISR_TXE)) == 0) { __NOP(); }
|
|
|
+ if ((I2C1->ISR & I2C_ISR_TXE) != 0) {
|
|
|
I2C1->TXDR = *data;
|
|
|
data ++;
|
|
|
len --;
|
|
|
} else {
|
|
|
r = i2c_check_err();
|
|
|
- if (r != I2C_Ret_OK) {
|
|
|
- Flag.I2C_TX_Err = 1;
|
|
|
- return r;
|
|
|
- }
|
|
|
+ Flag.I2C_TX_Err = 1;
|
|
|
+ Flag.I2C_TX_End = 1;
|
|
|
+ return r;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
|
|
|
+ Flag.I2C_TX_End = 1;
|
|
|
return r;
|
|
|
}
|
|
|
+
|
|
|
+static void i2c_write_byte(uint8_t dat) {
|
|
|
+ I2C1->TXDR = (I2C1->TXDR & 0xFFFFFF00) | dat;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ while (!(I2C1->ISR & (I2C_ISR_TXIS | I2C_ISR_TC))) {}
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+static uint8_t i2c_read_byte(void) {
|
|
|
+
|
|
|
+ while (!(I2C1->ISR & I2C_ISR_RXNE)) {}
|
|
|
+ return (I2C1->RXDR & 0xFF);
|
|
|
+}
|
|
|
+
|
|
|
+static uint8_t i2c_read_register(uint8_t reg_addr) {
|
|
|
+
|
|
|
+ I2C1->CR2 &= ~(I2C_CR2_NBYTES);
|
|
|
+ I2C1->CR2 |= (0x01 << I2C_CR2_NBYTES_Pos);
|
|
|
+
|
|
|
+ i2c_start();
|
|
|
+
|
|
|
+ i2c_write_byte(reg_addr);
|
|
|
+
|
|
|
+ i2c_stop();
|
|
|
+
|
|
|
+ I2C1->CR2 &= ~(I2C_CR2_NBYTES);
|
|
|
+ I2C1->CR2 |= (0x01 << I2C_CR2_NBYTES_Pos);
|
|
|
+
|
|
|
+ I2C1->CR2 |= (I2C_CR2_RD_WRN);
|
|
|
+
|
|
|
+ i2c_start();
|
|
|
+
|
|
|
+ uint8_t read_result = i2c_read_byte();
|
|
|
+
|
|
|
+ i2c_stop();
|
|
|
+
|
|
|
+ I2C1->CR2 &= ~(I2C_CR2_RD_WRN);
|
|
|
+
|
|
|
+
|
|
|
+ return read_result;
|
|
|
+}
|