1 | #include "I2C_DMA_INTERRUPT.h"
|
2 |
|
3 | /*
|
4 | * private variables
|
5 | */
|
6 |
|
7 | uint8_t MPU6050_RX_BUFF[MPU6050_BUFF_SIZE_RX];
|
8 | uint8_t MPU6050_TX_BUFF[MPU6050_BUFF_SIZE_TX]; // We need only to write the register value for ACC -> 0x3B
|
9 |
|
10 | uint8_t isNewData = 0; //For initialization
|
11 | uint8_t dmaStarted=0;
|
12 | uint8_t dataReadyMPU=0;
|
13 | uint8_t tx_finish;
|
14 | uint8_t interrupt_error=0;
|
15 | uint8_t i2c_hard_failure=0;
|
16 |
|
17 | /*
|
18 | * global functions
|
19 | */
|
20 |
|
21 | uint8_t startMPU6050() {
|
22 | Fill_Buffer(MPU6050_RX_BUFF,MPU6050_BUFF_SIZE_RX);
|
23 | MPU6050_TX_BUFF[0]=(uint8_t)ACCEL_ADDR;
|
24 | uint8_t fail_flag=0;
|
25 |
|
26 | I2C_I2C_init();
|
27 | I2C_GPIO_init();
|
28 | I2C_DMA_init();
|
29 |
|
30 | //Power ON
|
31 | fail_flag|=writeI2C(MPU6050_ADDRESS_1,MPU6050_PWR,0x00); //Power up MPU6050_1
|
32 |
|
33 | //Gyro Mode
|
34 | fail_flag|=writeI2C(MPU6050_ADDRESS_1,0x1B,MPU6050_GYRO_MODE); //Gyro Mode: 1000°/s
|
35 |
|
36 | //Set Sampling mode filtered
|
37 | fail_flag|=writeI2C(MPU6050_ADDRESS_1,0x1A,MPU6050_DLPF);
|
38 |
|
39 |
|
40 | return fail_flag;
|
41 | }
|
42 |
|
43 | uint8_t restartMPU6050() {
|
44 | uint8_t fail_flag=0;
|
45 | dmaStarted=0;
|
46 | isNewData =0;
|
47 | i2c_hard_failure=0;
|
48 |
|
49 | //First solve problems:
|
50 | unlockI2C();
|
51 |
|
52 | I2C_I2C_init();
|
53 | I2C_GPIO_init();
|
54 | I2C_DMA_init();
|
55 |
|
56 | //Power ON
|
57 | fail_flag|=writeI2C(MPU6050_ADDRESS_1,MPU6050_PWR,0x00); //Power up MPU6050_1
|
58 |
|
59 | //Gyro Mode
|
60 | fail_flag|=writeI2C(MPU6050_ADDRESS_1,0x1B,MPU6050_GYRO_MODE); //Gyro Mode: 1000°/s
|
61 |
|
62 | //Set Sampling mode filtered
|
63 | fail_flag|=writeI2C(MPU6050_ADDRESS_1,0x1A,MPU6050_DLPF);
|
64 |
|
65 |
|
66 | return fail_flag;
|
67 | }
|
68 |
|
69 | void unlockI2C() {
|
70 | GPIO_InitTypeDef gpioInit;
|
71 | gpioInit.GPIO_Pin = I2Cx_SCL_PIN;
|
72 | gpioInit.GPIO_Mode = GPIO_Mode_OUT;
|
73 | gpioInit.GPIO_Speed = GPIO_Speed_100MHz;
|
74 | gpioInit.GPIO_OType = GPIO_OType_OD;
|
75 | gpioInit.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
76 | GPIO_Init(I2Cx_SCL_GPIO_PORT, &gpioInit);
|
77 |
|
78 | gpioInit.GPIO_Pin = I2Cx_SDA_PIN;
|
79 | gpioInit.GPIO_Mode = GPIO_Mode_IN;
|
80 | GPIO_Init(I2Cx_SCL_GPIO_PORT, &gpioInit);
|
81 |
|
82 | uint8_t j=GPIO_ReadInputDataBit(GPIOB, I2Cx_SDA_PIN);
|
83 |
|
84 | while(j==0) {
|
85 | GPIO_ToggleBits(GPIOB, I2Cx_SCL_PIN);
|
86 | j=GPIO_ReadInputDataBit(GPIOB, I2Cx_SDA_PIN);
|
87 | }
|
88 | }
|
89 |
|
90 | void I2C_I2C_init(void) {
|
91 |
|
92 | I2C_Cmd(I2C2, DISABLE);
|
93 | I2C_InitTypeDef i2cInit;
|
94 |
|
95 | clearAllI2CFlags();
|
96 |
|
97 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
|
98 | RCC_APB1PeriphClockCmd(I2Cx_CLK, ENABLE);
|
99 | RCC_AHB1PeriphClockCmd(I2Cx_SDA_GPIO_CLK, ENABLE);
|
100 | RCC_AHB1PeriphClockCmd(I2Cx_SCL_GPIO_CLK, ENABLE);
|
101 | RCC_APB1PeriphResetCmd(I2Cx_CLK, ENABLE);
|
102 | RCC_APB1PeriphResetCmd(I2Cx_CLK, DISABLE);
|
103 | RCC_AHB1PeriphClockCmd(DMAx_CLK, ENABLE);
|
104 |
|
105 | // configure I2C2
|
106 | i2cInit.I2C_ClockSpeed = 400000;
|
107 | i2cInit.I2C_Mode = I2C_Mode_I2C;
|
108 | i2cInit.I2C_DutyCycle = I2C_DutyCycle_2; // 50% duty cycle
|
109 | i2cInit.I2C_OwnAddress1 = 0x00; // own address
|
110 | i2cInit.I2C_Ack = I2C_Ack_Enable;
|
111 | i2cInit.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses
|
112 | I2C_Init(I2C2, &i2cInit);
|
113 |
|
114 | // enable I2C2
|
115 | I2C_Cmd(I2C2, ENABLE);
|
116 |
|
117 | //I2C Interrupt Routine -> For events
|
118 | NVIC_InitTypeDef NVIC_InitStructure;
|
119 | NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;
|
120 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //GIVE HIGHEST PRIORITY FOR ALL INTERRUPTS
|
121 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
122 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
123 | NVIC_Init(&NVIC_InitStructure);
|
124 | }
|
125 |
|
126 | void I2C_GPIO_init() {
|
127 | GPIO_InitTypeDef gpioInit;
|
128 |
|
129 | gpioInit.GPIO_Pin = I2Cx_SCL_PIN;
|
130 | gpioInit.GPIO_Mode = GPIO_Mode_AF;
|
131 | gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
|
132 | gpioInit.GPIO_OType = GPIO_OType_OD;
|
133 | gpioInit.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
134 | GPIO_Init(I2Cx_SCL_GPIO_PORT, &gpioInit);
|
135 |
|
136 | gpioInit.GPIO_Pin = I2Cx_SDA_PIN;
|
137 | GPIO_Init(I2Cx_SDA_GPIO_PORT, &gpioInit);
|
138 | GPIO_PinAFConfig(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_SOURCE, I2Cx_SCL_AF);
|
139 | GPIO_PinAFConfig(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_SOURCE, I2Cx_SDA_AF);
|
140 | }
|
141 |
|
142 |
|
143 | void I2C_DMA_init() { // From the ST Standard Peripheral Library Example for I2C
|
144 | NVIC_InitTypeDef nvicInit;
|
145 | DMA_InitTypeDef dmaInit;
|
146 |
|
147 | //Clear all flags and deinit before initialization
|
148 | DMA_ClearFlag(MPU6050_DMA_STREAM_RX, I2Cx_RX_DMA_TCFLAG | I2Cx_RX_DMA_FEIFLAG | I2Cx_RX_DMA_DMEIFLAG | \
|
149 | I2Cx_RX_DMA_TEIFLAG | I2Cx_RX_DMA_HTIFLAG);
|
150 | DMA_ClearFlag(MPU6050_DMA_STREAM_TX, I2Cx_TX_DMA_TCFLAG | I2Cx_TX_DMA_FEIFLAG | I2Cx_TX_DMA_DMEIFLAG | \
|
151 | I2Cx_TX_DMA_TEIFLAG | I2Cx_TX_DMA_HTIFLAG);
|
152 |
|
153 | DMA_Cmd(MPU6050_DMA_STREAM_RX, DISABLE);
|
154 | DMA_Cmd(MPU6050_DMA_STREAM_TX, DISABLE);
|
155 | DMA_DeInit(MPU6050_DMA_STREAM_RX);
|
156 | DMA_DeInit(MPU6050_DMA_STREAM_TX);
|
157 |
|
158 | // Initialization DMA
|
159 | dmaInit.DMA_Channel = MPU6050_DMA_CHANNEL;
|
160 | dmaInit.DMA_PeripheralBaseAddr = (uint32_t)MPU6050_DR_ADDRESS;
|
161 | dmaInit.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
162 | dmaInit.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
163 | dmaInit.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
164 | dmaInit.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
165 | dmaInit.DMA_Mode = DMA_Mode_Normal;
|
166 | dmaInit.DMA_Priority = DMA_Priority_VeryHigh;
|
167 | dmaInit.DMA_FIFOMode = DMA_FIFOMode_Enable;
|
168 | dmaInit.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
|
169 | dmaInit.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
170 | dmaInit.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
171 |
|
172 | //Init DMA Receiver
|
173 | dmaInit.DMA_DIR = DMA_DIR_PeripheralToMemory;
|
174 | dmaInit.DMA_Memory0BaseAddr = (uint32_t)MPU6050_RX_BUFF;
|
175 | dmaInit.DMA_BufferSize = MPU6050_BUFF_SIZE_RX;
|
176 | DMA_DeInit(MPU6050_DMA_STREAM_RX);
|
177 | DMA_Init(MPU6050_DMA_STREAM_RX, &dmaInit);
|
178 | DMA_ITConfig(MPU6050_DMA_STREAM_RX, DMA_IT_TC, ENABLE);
|
179 |
|
180 | //Init DMA transmitter
|
181 | dmaInit.DMA_DIR = DMA_DIR_MemoryToPeripheral;
|
182 | dmaInit.DMA_Memory0BaseAddr = (uint32_t)MPU6050_TX_BUFF;
|
183 | dmaInit.DMA_BufferSize = MPU6050_BUFF_SIZE_TX;
|
184 | DMA_DeInit(MPU6050_DMA_STREAM_TX);
|
185 | DMA_Init(MPU6050_DMA_STREAM_TX, &dmaInit);
|
186 | DMA_ITConfig(MPU6050_DMA_STREAM_TX, DMA_IT_TC, ENABLE);
|
187 |
|
188 | // DMA Interrupt initialization
|
189 | nvicInit.NVIC_IRQChannel = DMA1_Stream2_IRQn; //RX Interrupt
|
190 | nvicInit.NVIC_IRQChannelPreemptionPriority = 1;
|
191 | nvicInit.NVIC_IRQChannelSubPriority = 1;
|
192 | nvicInit.NVIC_IRQChannelCmd = ENABLE;
|
193 | NVIC_Init(&nvicInit);
|
194 |
|
195 | nvicInit.NVIC_IRQChannel = DMA1_Stream7_IRQn; //TX Interrupt
|
196 | NVIC_Init(&nvicInit);
|
197 |
|
198 | DMA_ClearFlag(DMA1_Stream2, DMA_FLAG_FEIF2|DMA_FLAG_DMEIF2|DMA_FLAG_TEIF2|DMA_FLAG_HTIF2|DMA_FLAG_TCIF2);
|
199 | DMA_Cmd(DMA1_Stream2, ENABLE);
|
200 |
|
201 | DMA_ClearFlag(DMA1_Stream7, DMA_FLAG_FEIF2|DMA_FLAG_DMEIF2|DMA_FLAG_TEIF2|DMA_FLAG_HTIF2|DMA_FLAG_TCIF2);
|
202 | DMA_Cmd(DMA1_Stream7, ENABLE);
|
203 |
|
204 | }
|
205 |
|
206 | void Fill_Buffer(uint8_t *pBuffer, uint16_t BufferLength) {
|
207 | uint16_t index = 0;
|
208 | for (index = 0; index < BufferLength; index++ )
|
209 | {
|
210 | pBuffer[index] = 0x00;
|
211 | }
|
212 | }
|
213 |
|
214 | void DMA1_Stream2_IRQHandler(void) {
|
215 | if (DMA_GetFlagStatus(MPU6050_DMA_CHANNEL,DMA_FLAG_TCIF2)) {
|
216 | DMA_ClearITPendingBit(MPU6050_DMA_CHANNEL, DMA_FLAG_TCIF2);
|
217 |
|
218 | I2C_ITConfig(I2C2, I2C_IT_EVT, DISABLE);
|
219 | I2C_GenerateSTOP(I2Cx, ENABLE);
|
220 | DMA_Cmd(MPU6050_DMA_STREAM_RX, DISABLE);
|
221 | I2C_DMACmd(I2Cx,DISABLE);
|
222 | DMA_ClearFlag(MPU6050_DMA_STREAM_RX, I2Cx_RX_DMA_TCFLAG | I2Cx_RX_DMA_FEIFLAG | I2Cx_RX_DMA_DMEIFLAG | \
|
223 | I2Cx_RX_DMA_TEIFLAG | I2Cx_RX_DMA_HTIFLAG);
|
224 |
|
225 | isNewData=1;
|
226 | dmaStarted=0;
|
227 | }
|
228 | }
|
229 |
|
230 | void DMA1_Stream7_IRQHandler(void) {
|
231 | if (DMA_GetFlagStatus(MPU6050_DMA_CHANNEL,DMA_FLAG_TCIF7)) {
|
232 | DMA_ClearITPendingBit(MPU6050_DMA_CHANNEL, DMA_FLAG_TCIF7);
|
233 |
|
234 | I2C_DMACmd(I2Cx, DISABLE);
|
235 | I2C_GenerateSTOP(I2Cx, ENABLE);
|
236 | DMA_Cmd(MPU6050_DMA_STREAM_TX, DISABLE);
|
237 | DMA_ClearFlag(MPU6050_DMA_STREAM_TX, I2Cx_TX_DMA_TCFLAG | I2Cx_TX_DMA_FEIFLAG | I2Cx_TX_DMA_DMEIFLAG | \
|
238 | I2Cx_TX_DMA_TEIFLAG | I2Cx_TX_DMA_HTIFLAG);
|
239 |
|
240 | DMARead(); //Activate Read after successfully transfered register read command
|
241 | }
|
242 | }
|
243 |
|
244 | void clearAllI2CFlags() {
|
245 | I2C_ClearITPendingBit(I2C2,I2C_IT_SMBALERT);
|
246 | I2C_ClearITPendingBit(I2C2,I2C_IT_TIMEOUT);
|
247 | I2C_ClearITPendingBit(I2C2,I2C_IT_PECERR);
|
248 | I2C_ClearITPendingBit(I2C2,I2C_IT_OVR);
|
249 | I2C_ClearITPendingBit(I2C2,I2C_IT_AF);
|
250 | I2C_ClearITPendingBit(I2C2,I2C_IT_ARLO);
|
251 | I2C_ClearITPendingBit(I2C2,I2C_IT_BERR);
|
252 | I2C_ClearITPendingBit(I2C2,I2C_IT_TXE);
|
253 | I2C_ClearITPendingBit(I2C2,I2C_IT_RXNE);
|
254 | I2C_ClearITPendingBit(I2C2,I2C_IT_STOPF);
|
255 | I2C_ClearITPendingBit(I2C2,I2C_IT_ADD10);
|
256 | I2C_ClearITPendingBit(I2C2,I2C_IT_BTF);
|
257 | I2C_ClearITPendingBit(I2C2,I2C_IT_ADDR);
|
258 | I2C_ClearITPendingBit(I2C2,I2C_IT_SB);
|
259 |
|
260 | I2C_ClearFlag(I2C2,I2C_FLAG_SMBALERT);
|
261 | I2C_ClearFlag(I2C2,I2C_FLAG_TIMEOUT);
|
262 | I2C_ClearFlag(I2C2,I2C_FLAG_PECERR);
|
263 | I2C_ClearFlag(I2C2,I2C_FLAG_OVR);
|
264 | I2C_ClearFlag(I2C2,I2C_FLAG_AF);
|
265 | I2C_ClearFlag(I2C2,I2C_FLAG_ARLO);
|
266 | I2C_ClearFlag(I2C2,I2C_FLAG_BERR);
|
267 | I2C_ClearFlag(I2C2,I2C_FLAG_TXE);
|
268 | I2C_ClearFlag(I2C2,I2C_FLAG_RXNE);
|
269 | I2C_ClearFlag(I2C2,I2C_FLAG_STOPF);
|
270 | I2C_ClearFlag(I2C2,I2C_FLAG_ADD10);
|
271 | I2C_ClearFlag(I2C2,I2C_FLAG_BTF);
|
272 | I2C_ClearFlag(I2C2,I2C_FLAG_ADDR);
|
273 | I2C_ClearFlag(I2C2,I2C_FLAG_SB);
|
274 |
|
275 | I2C_ClearFlag(I2C2,I2C_FLAG_DUALF);
|
276 | I2C_ClearFlag(I2C2,I2C_FLAG_SMBHOST);
|
277 | I2C_ClearFlag(I2C2,I2C_FLAG_SMBDEFAULT);
|
278 | I2C_ClearFlag(I2C2,I2C_FLAG_GENCALL);
|
279 | I2C_ClearFlag(I2C2,I2C_FLAG_TRA);
|
280 | I2C_ClearFlag(I2C2,I2C_FLAG_BUSY);
|
281 | I2C_ClearFlag(I2C2,I2C_FLAG_MSL);
|
282 | }
|
283 |
|
284 | void I2C2_EV_IRQHandler(void)
|
285 | {
|
286 | switch(I2C_GetLastEvent(I2C2))
|
287 | {
|
288 | case I2C_EVENT_MASTER_MODE_SELECT :
|
289 | if(!tx_finish) {
|
290 | I2C_Send7bitAddress(I2Cx, MPU6050_ADDRESS_1, I2C_Direction_Transmitter);
|
291 | I2C_DMACmd(I2Cx, ENABLE);
|
292 | } else {
|
293 | I2C_Send7bitAddress(I2Cx, MPU6050_ADDRESS_1, I2C_Direction_Receiver);
|
294 | I2C_DMACmd(I2Cx, ENABLE);
|
295 | }
|
296 | interrupt_error=0;
|
297 | break;
|
298 | case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
|
299 | DMA_Cmd(MPU6050_DMA_STREAM_TX, ENABLE);
|
300 | break;
|
301 | case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:
|
302 | DMA_Cmd(MPU6050_DMA_STREAM_RX, ENABLE);
|
303 | I2C_ITConfig(I2C2, I2C_IT_EVT, DISABLE);
|
304 | break;
|
305 | case I2C_EVENT_SLAVE_STOP_DETECTED :
|
306 | break;
|
307 | case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
|
308 | break;
|
309 | case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
|
310 | break;
|
311 | case I2C_EVENT_SLAVE_ACK_FAILURE:
|
312 | break;
|
313 | case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
|
314 | break;
|
315 | case I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED:
|
316 | break;
|
317 | case I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED:
|
318 | break;
|
319 | case I2C_EVENT_SLAVE_BYTE_RECEIVED:
|
320 | break;
|
321 | case I2C_EVENT_MASTER_BYTE_RECEIVED:
|
322 | break;
|
323 | case I2C_EVENT_MASTER_BYTE_TRANSMITTING:
|
324 | break;
|
325 | case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
|
326 | break;
|
327 | case I2C_EVENT_MASTER_MODE_ADDRESS10:
|
328 | break;
|
329 | case I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED:
|
330 | break;
|
331 | default:
|
332 | interrupt_error++;
|
333 | if(interrupt_error>10) {
|
334 | i2c_hard_failure=1;
|
335 | I2C_ITConfig(I2C2, I2C_IT_EVT, DISABLE);
|
336 | I2C_Cmd(I2C2, DISABLE);
|
337 | interrupt_error=0;
|
338 | }
|
339 | break;
|
340 | }
|
341 | }
|
342 |
|
343 |
|
344 | uint8_t copyNewAccData(MPU6050Data *dataStruct, MPU6050DataOffset *offset, uint8_t sensor_numb) {
|
345 | if(isNewData) {
|
346 | int accX=(MPU6050_RX_BUFF[0]<<8) | MPU6050_RX_BUFF[1];
|
347 | int accY=(MPU6050_RX_BUFF[2]<<8) | MPU6050_RX_BUFF[3];
|
348 | int accZ=(MPU6050_RX_BUFF[4]<<8) | MPU6050_RX_BUFF[5];
|
349 | int temp=(MPU6050_RX_BUFF[6]<<8) | MPU6050_RX_BUFF[7];
|
350 | int gyroX=(MPU6050_RX_BUFF[8]<<8) | MPU6050_RX_BUFF[9];
|
351 | int gyroY=(MPU6050_RX_BUFF[10]<<8) | MPU6050_RX_BUFF[11];
|
352 | //int gyroZ=(MPU6050_RX_BUFF[12]<<8) | MPU6050_RX_BUFF[13];
|
353 |
|
354 | if(accX>32768)
|
355 | accX=accX-65546;
|
356 | if(accY>32768)
|
357 | accY=accY-65546;
|
358 | if(accZ>32768)
|
359 | accZ=accZ-65546;
|
360 |
|
361 | if(gyroX>=32768)
|
362 | gyroX=gyroX-65546;
|
363 | if(gyroY>=32768)
|
364 | gyroY=gyroY-65546;
|
365 | /*if(gyroZ>32768)
|
366 | gyroZ=gyroZ-65546;*/
|
367 |
|
368 | dataStruct->dataAccX = accX - offset->dataAccXOffset; //- offset->dataAccXOffset;
|
369 | dataStruct->dataAccY = accY - offset->dataAccYOffset; //- offset->dataAccYOffset;
|
370 | dataStruct->dataAccZ = accZ - offset->dataAccZOffset;
|
371 |
|
372 | dataStruct->dataGyroX= gyroX - offset->dataGyroXOffset; // - offset->dataGyroXOffset;
|
373 | dataStruct->dataGyroY= gyroY - offset->dataGyroYOffset; //- offset->dataGyroYOffset;
|
374 | //dataStruct->dataGyroZ=gyroZ;
|
375 |
|
376 | isNewData=0;
|
377 | return 0;
|
378 | } else {
|
379 | return 2;
|
380 | }
|
381 | }
|
382 |
|
383 | uint8_t DMAInitRead() {
|
384 | if(i2c_hard_failure)
|
385 | return 1;
|
386 |
|
387 | if(!isNewData && !dmaStarted) {
|
388 | dmaStarted=1;
|
389 | tx_finish=0;
|
390 |
|
391 | I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE);
|
392 | I2C_GenerateSTART(I2Cx, ENABLE);
|
393 |
|
394 | return 0;
|
395 | }
|
396 | return 0;
|
397 |
|
398 | }
|
399 |
|
400 | uint8_t DMARead() {
|
401 |
|
402 | //Start DMA Read process:
|
403 | I2C_DMALastTransferCmd(I2Cx, ENABLE); //Enable automatic NACK
|
404 | I2C_GenerateSTART(I2Cx, ENABLE);
|
405 |
|
406 | tx_finish=1;
|
407 |
|
408 | return 0;
|
409 |
|
410 | }
|
411 |
|
412 | //FUNCTIONS WITHOUT DMA: USE ONLY FOR INITIALIZATION
|
413 |
|
414 | uint8_t writeI2C(uint8_t addr, uint8_t reg, uint8_t data) {
|
415 | uint8_t fail_flag=0;
|
416 |
|
417 | fail_flag|=I2C_start(addr, 0, 0); //dir==0 is transmitter, no ack since only one write
|
418 | fail_flag|=I2C_write(reg);
|
419 | fail_flag|=I2C_write(data);
|
420 | I2C_stop();
|
421 |
|
422 | return fail_flag;
|
423 | }
|
424 |
|
425 |
|
426 |
|
427 | uint8_t I2C_start(uint8_t address, uint8_t direction, uint8_t ack) { //direction transmitter==0
|
428 | uint16_t timeout = TIMEOUT; //Wait maximum 20000 cycles
|
429 |
|
430 | while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)) {
|
431 | if (--timeout == 0) {
|
432 | return 1;
|
433 | }
|
434 | }
|
435 |
|
436 | I2C_GenerateSTART(I2C2, ENABLE);
|
437 |
|
438 | while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) {
|
439 | if (--timeout == 0) {
|
440 | return 1;
|
441 | }
|
442 | }
|
443 |
|
444 | //Ack enable
|
445 | if(ack)
|
446 | I2C2->CR1 |= I2C_CR1_ACK;
|
447 |
|
448 | //Send Adress
|
449 | I2C_Send7bitAddress(I2C2, address, direction);
|
450 | while (!(I2C2->SR1 & I2C_SR1_ADDR)) { //Wait until Address is received by slave
|
451 | if (--timeout == 0) {
|
452 | return 1;
|
453 | }
|
454 | }
|
455 |
|
456 | if(direction == I2C_Direction_Transmitter){
|
457 | while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
|
458 | if (--timeout == 0) {
|
459 | return 1;
|
460 | }
|
461 | }
|
462 | }
|
463 | else if(direction == I2C_Direction_Receiver){
|
464 | while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) {
|
465 | if (--timeout == 0) {
|
466 | return 1;
|
467 | }
|
468 | }
|
469 | }
|
470 |
|
471 | /* Read status register to clear ADDR flag */
|
472 | I2C2->SR2;
|
473 |
|
474 | return 0;
|
475 | }
|
476 |
|
477 |
|
478 | uint8_t I2C_write(uint8_t data) {
|
479 | uint16_t timeout = TIMEOUT; //Wait maximum 20000 cycles
|
480 |
|
481 | I2C_SendData(I2C2, data);
|
482 |
|
483 | while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
|
484 | if (--timeout == 0) {
|
485 | return 1;
|
486 | }
|
487 | }
|
488 |
|
489 | return 0;
|
490 | }
|
491 |
|
492 | void I2C_stop() {
|
493 | I2C_GenerateSTOP(I2C2, ENABLE);
|
494 | }
|
495 |
|
496 | void initOffset(MPU6050DataOffset *offset) {
|
497 | offset->dataAccXOffset=0;
|
498 | offset->dataAccYOffset=0;
|
499 | offset->dataAccZOffset=0;
|
500 | offset->dataGyroXOffset=0;
|
501 | offset->dataGyroYOffset=0;
|
502 | offset->dataGyroZOffset=0;
|
503 | }
|
504 |
|
505 | void setOffset(MPU6050Data *MPU1, MPU6050DataOffset *MPU1_Offset) {
|
506 | MPU1_Offset->dataAccXOffset=MPU1->dataAccX;
|
507 | MPU1_Offset->dataAccYOffset=MPU1->dataAccY;
|
508 | MPU1_Offset->dataAccZOffset=MPU1->dataAccZ;
|
509 | MPU1_Offset->dataGyroXOffset=MPU1->dataGyroX;
|
510 | MPU1_Offset->dataGyroYOffset=MPU1->dataGyroY;
|
511 | }
|