1 | uint8_t i2c_read(uint8_t slave_addr, uint8_t register_addr)
|
2 | {
|
3 | volatile uint32_t temp;
|
4 | uint8_t buffer;
|
5 | I2C_TypeDef *I2Cx = I2C1;
|
6 |
|
7 | // Generate START condition and wait for EV5
|
8 | while (I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
|
9 | I2C_GenerateSTART(I2Cx, ENABLE);
|
10 | while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
|
11 |
|
12 | // Send slave address and wait for EV6
|
13 | slave_addr <<= (uint8_t) 1;
|
14 | I2C_Send7bitAddress(I2Cx, slave_addr, I2C_Direction_Transmitter);
|
15 | while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
|
16 |
|
17 | while (I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR));
|
18 |
|
19 | // Wait for EV8_1
|
20 | while (!I2C_GetFlagStatus(I2Cx, I2C_FLAG_TXE));
|
21 |
|
22 | // Send register address and wait for EV8_2
|
23 | I2C_SendData(I2Cx, register_addr);
|
24 | while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
25 |
|
26 | // Generate (re)start condition and wait for EV5
|
27 | I2C_GenerateSTART(I2Cx, ENABLE);
|
28 |
|
29 | // Send slave address and wait until ADDR = 1
|
30 | slave_addr |= (uint8_t) 0x01;
|
31 | I2C_Send7bitAddress(I2C1, slave_addr, I2C_Direction_Receiver);
|
32 | while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR));
|
33 |
|
34 | // clear ACK bit
|
35 | I2Cx->CR1 &= (uint16_t) ~I2C_CR1_ACK;
|
36 |
|
37 | temp = I2Cx->SR1;
|
38 | temp = I2Cx->SR2;
|
39 | while (I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR));
|
40 | I2Cx->CR1 |= I2C_CR1_STOP;
|
41 |
|
42 | // Wait until data has been received in DR register (RXNE = 1) -> EV7
|
43 | while (!I2C_GetFlagStatus(I2Cx, I2C_FLAG_RXNE));
|
44 |
|
45 | // Read the data
|
46 | buffer = I2C_ReceiveData(I2Cx);
|
47 |
|
48 | // Make sure that the STOP bit is cleared by Hardware before CR1 write access
|
49 | while (I2Cx->CR1 & I2C_CR1_STOP);
|
50 |
|
51 | // Enable Acknowledgement to be ready for another reception
|
52 | I2Cx->CR1 |= I2C_CR1_ACK;
|
53 | return buffer;
|
54 | }
|