0% found this document useful (0 votes)
14 views

Non Blocking I2C Read Function (Arduino)

Uploaded by

Bruno Voltz
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views

Non Blocking I2C Read Function (Arduino)

Uploaded by

Bruno Voltz
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

Non blocking I2C read function – Programming for Engineers http://programming4engineers.org/?

p=122

1. #ifndef FASTWIRE_H
2. #define FASTWIRE_H
3. #include <inttypes.h> // uint8_t is defined here
4.
5. void FastWireSend(uint8_t reg, uint8_t dat);
6. void FastWireRead(uint8_t reg, uint8_t * buf, uint8_t n);
7. uint8_t FastWireIsBusy(void);
8.
9. #endif

1. #include "FastWire.h"
2. #include <avr/io.h> // The I2C registers are defined here
3. #include <avr/interrupt.h>
4.
5. // Status messeges from I2C

1 sur 4 12/07/2018 à 17:30


Non blocking I2C read function – Programming for Engineers http://programming4engineers.org/?p=122

6. #define MT_START 0x08


7. #define MT_SLA_ACK 0x18
8. #define MT_DATA_ACK 0x28
9. #define MR_START 0x10 // repeated start
10. #define MR_SLA_ACK 0x40
11. #define MR_SLA_NACK 0x48
12. #define MR_DATA_ACK 0x50
13. #define MR_DATA_NACK 0x58
14.
15. // These are specific to MPU6050 and should be changed if used with other components
16. #define SLA_W 0xD0 // 11010000 // (208)
17. #define SLA_R 0xD1 // 11010001 // (209)
18.
19. static uint8_t I2Cwritebuffer[2];
20. static volatile uint8_t I2Cwrite_n = 0;
21. static volatile uint8_t I2Cwrite_i = 0;
22. static volatile uint8_t I2Cwrite_sendstop = 0;
23. static uint8_t * I2Creadbuffer;
24. static volatile uint8_t I2Cread_i = 0;
25. static volatile uint8_t I2Cbusy = 0;
26.
27. void FastWireSend(uint8_t reg, uint8_t dat){
28. // Wait for free line
29. while(I2Cbusy != 0);
30. while(TWCR & (1 << TWSTO));
31. I2Cwritebuffer[0] = reg;
32. I2Cwritebuffer[1] = dat;
33. I2Cwrite_n = 2;
34. I2Cwrite_i = 0;
35. I2Cwrite_sendstop = 1;
36.
37. I2Cbusy = 1;
38.
39. // Initiate the I2C comunication
40. TWCR =(1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE);
41. }
42.
43. void FastWireRead(uint8_t reg, uint8_t * buf, uint8_t n){
44. // Wait for free line
45. while(I2Cbusy != 0);
46. while(TWCR & (1 << TWSTO));
47. I2Cwritebuffer[0] = reg;
48. I2Cwrite_n = 1;
49. I2Cwrite_i = 0;
50. I2Cwrite_sendstop = 0;
51. I2Creadbuffer = buf;
52. I2Cread_i = n-1;
53.
54. I2Cbusy = 1;
55.
56. // Initiate the I2C comunication
57. TWCR =(1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE);
58. }
59.
60. uint8_t FastWireIsBusy(void){
61. return I2Cbusy;
62. }
63. /******************************************************************
64. The interrupt that does all the work
65. */
66. ISR(TWI_vect)
67. {
68. switch(TWSR & 0xF8){
69. case MT_START:
70. // Send the slave address and write bit
71. TWDR = SLA_W;
72. I2Cbusy = 2;

2 sur 4 12/07/2018 à 17:30


Non blocking I2C read function – Programming for Engineers http://programming4engineers.org/?p=122

73. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);


74. break;
75. case MT_SLA_ACK:
76. I2Cbusy = 3;
77. // Send the data in the transmit buffer
78. TWDR = I2Cwritebuffer[I2Cwrite_i];
79. I2Cwrite_i ++;
80. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
81. break;
82. case MT_DATA_ACK:
83. I2Cbusy = 4;
84. // Send more data or send stop signal
85. if (I2Cwrite_i < I2Cwrite_n){
86. TWDR = I2Cwritebuffer[I2Cwrite_i];
87. I2Cwrite_i ++;
88. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
89. }else{
90. if (I2Cwrite_sendstop){
91. // Stop the transmission
92. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO) | (1<<TWIE);
93. I2Cbusy = 0;
94. }else{
95. // Start recieving data by sending a start signal
96. TWCR =(1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE);
97. I2Cbusy = 1;
98. }
99. }
100. break;
101. case MR_START:
102. TWDR = SLA_R;
103. I2Cbusy = 5;
104. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
105. break;
106. case MR_SLA_ACK:
107. I2Cbusy = 6;
108. // Ask for the first uint8_t of data
109. if (I2Cread_i == 0){
110. // send NACK
111. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
112. }else{
113. TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
114. }
115. break;
116. // case MR_SLA_NACK:
117. // I2Cbusy = 8;
118. // break;
119. case MR_DATA_ACK:
120. I2Cbusy = 7;
121. // Save data in buffer
122. I2Creadbuffer[I2Cread_i] = TWDR;
123. // In case there is more data to read, ask for more
124. if (I2Cread_i == 1){
125. // send NACK
126. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
127. }else{
128. TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
129. }
130. I2Cread_i--;
131. break;
132. case MR_DATA_NACK:
133. // Save the lase uint8_t
134. I2Creadbuffer[I2Cread_i] = TWDR;
135. // End the transmission
136. TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN) | (1<<TWIE);
137. I2Cbusy = 0;
138. break;
139. default:

3 sur 4 12/07/2018 à 17:30


Non blocking I2C read function – Programming for Engineers http://programming4engineers.org/?p=122

140. I2Cbusy = TWSR;


141. }
142. }

4 sur 4 12/07/2018 à 17:30

You might also like