1 | #include "i2c.h"
|
2 |
|
3 | void InitI2C()
|
4 | {
|
5 | I2C_InitTypeDef I2C_InitStructure;
|
6 | GPIO_InitTypeDef GPIO_InitStructure;
|
7 |
|
8 | SystemInit();
|
9 |
|
10 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
|
11 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
|
12 |
|
13 | /* Reset I2Cx IP */
|
14 | RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
|
15 |
|
16 | /* Release reset signal of I2Cx IP */
|
17 | RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
|
18 |
|
19 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
|
20 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
21 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // Open Drain, I2C bus pulled high externally
|
22 | GPIO_Init(GPIOB, &GPIO_InitStructure);
|
23 |
|
24 |
|
25 | I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
|
26 | //I2C_InitStructure.I2C_OwnAddress1 = 0x00; //Eigene Adresse für Slave oder Multimaster betrieb, ansonsten irrelevant
|
27 | I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
|
28 | I2C_InitStructure.I2C_Ack = I2C_Ack_Disable;
|
29 | I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //Adress-Modus, normalerweise 7-Bit
|
30 | I2C_InitStructure.I2C_ClockSpeed = 50000; //Taktgeschwindigkeit von SCL, hier 50kHz
|
31 |
|
32 | I2C_Init(I2C1, &I2C_InitStructure);
|
33 |
|
34 | I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE); //Keine Interrupts
|
35 |
|
36 | I2C_Cmd(I2C1, ENABLE);
|
37 | }
|
38 |
|
39 | void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction){
|
40 | // wait until I2C1 is not busy any more
|
41 | while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
|
42 |
|
43 | // Send I2C1 START condition
|
44 | I2C_GenerateSTART(I2Cx, ENABLE);
|
45 |
|
46 | // wait for I2C1 EV5 --> Slave has acknowledged start condition
|
47 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
|
48 |
|
49 | // Send slave Address for write
|
50 | I2C_Send7bitAddress(I2Cx, address, direction);
|
51 |
|
52 | /* wait for I2Cx EV6, check if
|
53 | * either Slave has acknowledged Master transmitter or
|
54 | * Master receiver mode, depending on the transmission
|
55 | * direction
|
56 | */
|
57 | if(direction == I2C_Direction_Transmitter){
|
58 | GPIOC->BSRR = 1<<8; //Switch on blue
|
59 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // Here it hangs...
|
60 | GPIOC->BSRR = 1<<9 ; //Switch green on
|
61 | }
|
62 | else if(direction == I2C_Direction_Receiver){
|
63 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
|
64 | }
|
65 | }
|
66 |
|
67 | void I2C_restart(I2C_TypeDef * I2Cx, uint8_t address, uint8_t direction)
|
68 | {
|
69 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
|
70 | I2Cx->CR1 |= I2C_CR1_START;
|
71 |
|
72 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
73 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
|
74 |
|
75 | // Send slave Address for write
|
76 | I2C_Send7bitAddress(I2Cx, address, direction);
|
77 |
|
78 | /* wait for I2Cx EV6, check if
|
79 | * either Slave has acknowledged Master transmitter or
|
80 | * Master receiver mode, depending on the transmission
|
81 | * direction
|
82 | */
|
83 | if(direction == I2C_Direction_Transmitter){
|
84 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
|
85 | }
|
86 | else if(direction == I2C_Direction_Receiver){
|
87 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
|
88 | }
|
89 | }
|
90 |
|
91 | void I2C_write(I2C_TypeDef* I2Cx, uint8_t data)
|
92 | {
|
93 | // wait for I2C1 EV8 --> last byte is still being transmitted (last byte in SR, buffer empty), next byte can already be written
|
94 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
|
95 | I2C_SendData(I2Cx, data);
|
96 | }
|
97 |
|
98 |
|
99 | uint8_t I2C_read_ack(I2C_TypeDef* I2Cx){
|
100 | // enable acknowledge of received data
|
101 | I2C_AcknowledgeConfig(I2Cx, ENABLE);
|
102 | // wait until one byte has been received
|
103 | while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
|
104 | // read data from I2C data register and return data byte
|
105 | uint8_t data = I2C_ReceiveData(I2Cx);
|
106 | return data;
|
107 | }
|
108 |
|
109 |
|
110 | uint8_t I2C_read_nack(I2C_TypeDef* I2Cx){
|
111 | // disable acknowledge of received data
|
112 | // nack also generates stop condition after last byte received
|
113 | // see reference manual for more info
|
114 | I2C_AcknowledgeConfig(I2Cx, DISABLE);
|
115 | I2C_GenerateSTOP(I2Cx, ENABLE);
|
116 | // wait until one byte has been received
|
117 | while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
|
118 | // read data from I2C data register and return data byte
|
119 | uint8_t data = I2C_ReceiveData(I2Cx);
|
120 | return data;
|
121 | }
|
122 |
|
123 |
|
124 | void I2C_stop(I2C_TypeDef* I2Cx){
|
125 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
126 | // Send I2C1 STOP Condition after last byte has been transmitted
|
127 | I2C_GenerateSTOP(I2Cx, ENABLE);
|
128 | // wait for I2C1 EV8_2 --> byte has been transmitted
|
129 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
130 | }
|