forked from romanjoe/stm32camera
/
i2c_ops.c
137 lines (115 loc) · 3.94 KB
/
i2c_ops.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "i2c_ops.h"
#include "stm32f4xx_i2c.h"
#define SLAVE_ADDRESS 0x42
/* This function issues a start condition and
* transmits the slave address + R/W bit
*
* Parameters:
* I2Cx --> the I2C peripheral e.g. i2c_dev
* address --> the 7 bit slave address
* direction --> the transmission direction can be:
* I2C_Direction_Tranmitter for Master transmitter mode
* I2C_Direction_Receiver for Master receiver
*/
void Delay(uint32_t volatile DelayTime_uS)
{
uint32_t DelayTime = 0;
DelayTime = (SystemCoreClock/1000000)*DelayTime_uS;
for (; DelayTime!=0; DelayTime--);
}
void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction)
{
// wait until i2c_dev is not busy anymore
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
// Send i2c_dev START condition
I2C_GenerateSTART(I2Cx, ENABLE);
// wait for i2c_dev EV5 --> Slave has acknowledged start condition
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
// Send slave Address for write
I2C_Send7bitAddress(I2Cx, address, direction);
/* wait for i2c_dev EV6, check if
* either Slave has acknowledged Master transmitter or
* Master receiver mode, depending on the transmission
* direction
*/
if(direction == I2C_Direction_Transmitter)
{
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
}
else if(direction == I2C_Direction_Receiver)
{
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
}
}
/* This function transmits one byte to the slave device
* Parameters:
* I2Cx --> the I2C peripheral e.g. i2c_dev
* data --> the data byte to be transmitted
*/
void I2C_write(I2C_TypeDef* I2Cx, uint8_t data)
{
I2C_SendData(I2Cx, data);
// wait for i2c_dev EV8_2 --> byte has been transmitted
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
/* This function reads one byte from the slave device
* and acknowledges the byte (requests another byte)
*/
uint8_t I2C_read_ack(I2C_TypeDef* I2Cx){
uint8_t data;
// enable acknowledge of received data
I2C_AcknowledgeConfig(I2Cx, ENABLE);
// wait until one byte has been received
while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
// read data from I2C data register and return data byte
data = I2C_ReceiveData(I2Cx);
return data;
}
/* This function reads one byte from the slave device
* and doesn't acknowledge the received data
*/
uint8_t I2C_read_nack(I2C_TypeDef* I2Cx){
uint8_t data;
// disable acknowledge of received data
I2C_AcknowledgeConfig(I2Cx, DISABLE);
// wait until one byte has been received
while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
// read data from I2C data register and return data byte
data = I2C_ReceiveData(I2Cx);
return data;
}
/* This function issues a stop condition and therefore
* releases the bus
*/
void I2C_stop(I2C_TypeDef* I2Cx){
// Send i2c_dev STOP Condition
I2C_GenerateSTOP(I2Cx, ENABLE);
}
uint8_t I2C_writereg(uint32_t reg, uint32_t data)
{
uint8_t tmp;
I2C_start(i2c_dev, SLAVE_ADDRESS, I2C_Direction_Transmitter); // start a transmission in Master transmitter mode
I2C_write(i2c_dev, (uint8_t) reg); // write one byte to the slave
Delay(100);
I2C_write(i2c_dev, (uint8_t) data); // write one byte to the slave
I2C_stop(i2c_dev); // stop the transmission
Delay(100);
I2C_start(i2c_dev, SLAVE_ADDRESS, I2C_Direction_Receiver); // start a transmission in Master receiver mode
tmp = I2C_read_nack(i2c_dev);
I2C_stop(i2c_dev); // stop the transmission
Delay(100);
return tmp;
}
uint8_t I2C_readreg(uint32_t reg)
{
uint8_t tmp;
I2C_start(i2c_dev, SLAVE_ADDRESS, I2C_Direction_Transmitter); // start a transmission in Master transmitter mode
I2C_write(i2c_dev, (uint8_t) reg); // write one byte to the slave
I2C_stop(i2c_dev); // stop the transmission
Delay(100);
I2C_start(i2c_dev, SLAVE_ADDRESS, I2C_Direction_Receiver); // start a transmission in Master receiver mode
tmp = I2C_read_nack(i2c_dev);
I2C_stop(i2c_dev); // stop the transmission
Delay(100);
return tmp;
}