aboutsummaryrefslogtreecommitdiff
path: root/drivers/avr/i2c_master.c
diff options
context:
space:
mode:
authorJack Humbert <jack.humb@gmail.com>2018-06-22 21:26:30 -0400
committerJack Humbert <jack.humb@gmail.com>2018-06-22 21:26:30 -0400
commit6380f8319057d33bb6d07c66789867e49c634504 (patch)
treee469a238792c60c3016e4f8fd4226497451da9e6 /drivers/avr/i2c_master.c
parent76e0d23887b8ddc70e9afb30bb7b91e9fec96c35 (diff)
downloadqmk_firmware-6380f8319057d33bb6d07c66789867e49c634504.tar.gz
qmk_firmware-6380f8319057d33bb6d07c66789867e49c634504.zip
refactor, non-working
Diffstat (limited to 'drivers/avr/i2c_master.c')
-rwxr-xr-xdrivers/avr/i2c_master.c133
1 files changed, 82 insertions, 51 deletions
diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c
index caca2179e..30ea760c9 100755
--- a/drivers/avr/i2c_master.c
+++ b/drivers/avr/i2c_master.c
@@ -19,7 +19,7 @@ void i2c_init(void)
19 //TWBR = 10; 19 //TWBR = 10;
20} 20}
21 21
22i2c_status_t i2c_start(uint8_t address, uint8_t timeout) 22i2c_status_t i2c_start(uint8_t address, uint16_t timeout)
23{ 23{
24 // reset TWI control register 24 // reset TWI control register
25 TWCR = 0; 25 TWCR = 0;
@@ -28,13 +28,13 @@ i2c_status_t i2c_start(uint8_t address, uint8_t timeout)
28 28
29 uint16_t timeout_timer = timer_read(); 29 uint16_t timeout_timer = timer_read();
30 while( !(TWCR & (1<<TWINT)) ) { 30 while( !(TWCR & (1<<TWINT)) ) {
31 if (timeout && (timer_read() - timeout_timer) > timeout) { 31 if (timeout && ((timer_read() - timeout_timer) > timeout)) {
32 return I2C_STATUS_TIMEOUT; 32 return I2C_STATUS_TIMEOUT;
33 } 33 }
34 } 34 }
35 35
36 // check if the start condition was successfully transmitted 36 // check if the start condition was successfully transmitted
37 if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return 1; } 37 if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return I2C_STATUS_ERROR; }
38 38
39 // load slave address into data register 39 // load slave address into data register
40 TWDR = address; 40 TWDR = address;
@@ -43,19 +43,19 @@ i2c_status_t i2c_start(uint8_t address, uint8_t timeout)
43 43
44 timeout_timer = timer_read(); 44 timeout_timer = timer_read();
45 while( !(TWCR & (1<<TWINT)) ) { 45 while( !(TWCR & (1<<TWINT)) ) {
46 if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) { 46 if (timeout && ((timer_read() - timeout_timer) > timeout)) {
47 return I2C_STATUS_TIMEOUT; 47 return I2C_STATUS_TIMEOUT;
48 } 48 }
49 } 49 }
50 50
51 // check if the device has acknowledged the READ / WRITE mode 51 // check if the device has acknowledged the READ / WRITE mode
52 uint8_t twst = TW_STATUS & 0xF8; 52 uint8_t twst = TW_STATUS & 0xF8;
53 if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1; 53 if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return I2C_STATUS_ERROR;
54 54
55 return 0; 55 return I2C_STATUS_SUCCESS;
56} 56}
57 57
58i2c_status_t i2c_write(uint8_t data, uint8_t timeout) 58i2c_status_t i2c_write(uint8_t data, uint16_t timeout)
59{ 59{
60 // load data into data register 60 // load data into data register
61 TWDR = data; 61 TWDR = data;
@@ -64,17 +64,17 @@ i2c_status_t i2c_write(uint8_t data, uint8_t timeout)
64 64
65 uint16_t timeout_timer = timer_read(); 65 uint16_t timeout_timer = timer_read();
66 while( !(TWCR & (1<<TWINT)) ) { 66 while( !(TWCR & (1<<TWINT)) ) {
67 if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) { 67 if (timeout && ((timer_read() - timeout_timer) > timeout)) {
68 return I2C_STATUS_TIMEOUT; 68 return I2C_STATUS_TIMEOUT;
69 } 69 }
70 } 70 }
71 71
72 if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return 1; } 72 if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return I2C_STATUS_ERROR; }
73 73
74 return 0; 74 return I2C_STATUS_SUCCESS;
75} 75}
76 76
77i2c_status_t i2c_read_ack(uint8_t timeout) 77int16_t i2c_read_ack(uint16_t timeout)
78{ 78{
79 79
80 // start TWI module and acknowledge data after reception 80 // start TWI module and acknowledge data after reception
@@ -82,7 +82,7 @@ i2c_status_t i2c_read_ack(uint8_t timeout)
82 82
83 uint16_t timeout_timer = timer_read(); 83 uint16_t timeout_timer = timer_read();
84 while( !(TWCR & (1<<TWINT)) ) { 84 while( !(TWCR & (1<<TWINT)) ) {
85 if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) { 85 if (timeout && ((timer_read() - timeout_timer) > timeout)) {
86 return I2C_STATUS_TIMEOUT; 86 return I2C_STATUS_TIMEOUT;
87 } 87 }
88 } 88 }
@@ -91,7 +91,7 @@ i2c_status_t i2c_read_ack(uint8_t timeout)
91 return TWDR; 91 return TWDR;
92} 92}
93 93
94i2c_status_t i2c_read_nack(uint8_t timeout) 94int16_t i2c_read_nack(uint16_t timeout)
95{ 95{
96 96
97 // start receiving without acknowledging reception 97 // start receiving without acknowledging reception
@@ -99,7 +99,7 @@ i2c_status_t i2c_read_nack(uint8_t timeout)
99 99
100 uint16_t timeout_timer = timer_read(); 100 uint16_t timeout_timer = timer_read();
101 while( !(TWCR & (1<<TWINT)) ) { 101 while( !(TWCR & (1<<TWINT)) ) {
102 if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) { 102 if (timeout && ((timer_read() - timeout_timer) > timeout)) {
103 return I2C_STATUS_TIMEOUT; 103 return I2C_STATUS_TIMEOUT;
104 } 104 }
105 } 105 }
@@ -108,81 +108,112 @@ i2c_status_t i2c_read_nack(uint8_t timeout)
108 return TWDR; 108 return TWDR;
109} 109}
110 110
111i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length) 111i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)
112{ 112{
113 if (i2c_start(address | I2C_WRITE)) return 1; 113 i2c_status_t status = i2c_start(address | I2C_WRITE, timeout);
114 if (status) return status;
114 115
115 for (uint16_t i = 0; i < length; i++) 116 for (uint16_t i = 0; i < length; i++) {
116 { 117 status = i2c_write(data[i], timeout);
117 if (i2c_write(data[i])) return 1; 118 if (status) return status;
118 } 119 }
119 120
120 i2c_stop(); 121 status = i2c_stop(timeout);
122 if (status) return status;
121 123
122 return 0; 124 return I2C_STATUS_SUCCESS;
123} 125}
124 126
125uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length) 127i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)
126{ 128{
127 if (i2c_start(address | I2C_READ)) return 1; 129 i2c_status_t status = i2c_start(address | I2C_READ, timeout);
128 130 if (status) return status;
129 for (uint16_t i = 0; i < (length-1); i++) 131
130 { 132 for (uint16_t i = 0; i < (length-1); i++) {
131 data[i] = i2c_read_ack(); 133 status = i2c_read_ack(timeout);
134 if (status >= 0) {
135 data[i] = status;
136 } else {
137 return status;
138 }
132 } 139 }
133 data[(length-1)] = i2c_read_nack();
134 140
135 i2c_stop(); 141 status = i2c_read_nack(timeout);
142 if (status >= 0 ) {
143 data[(length-1)] = status;
144 } else {
145 return status;
146 }
147
148 status = i2c_stop(timeout);
149 if (status) return status;
136 150
137 return 0; 151 return I2C_STATUS_SUCCESS;
138} 152}
139 153
140uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length) 154i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
141{ 155{
142 if (i2c_start(devaddr | 0x00)) return 1; 156 i2c_status_t status = i2c_start(devaddr | 0x00, timeout);
157 if (status) return status;
143 158
144 i2c_write(regaddr); 159 status = i2c_write(regaddr, timeout);
160 if (status) return status;
145 161
146 for (uint16_t i = 0; i < length; i++) 162 for (uint16_t i = 0; i < length; i++) {
147 { 163 status = i2c_write(data[i], timeout);
148 if (i2c_write(data[i])) return 1; 164 if (status) return status;
149 } 165 }
150 166
151 i2c_stop(); 167 status = i2c_stop(timeout);
168 if (status) return status;
152 169
153 return 0; 170 return I2C_STATUS_SUCCESS;
154} 171}
155 172
156uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length) 173i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
157{ 174{
158 if (i2c_start(devaddr)) return 1; 175 i2c_status_t status = i2c_start(devaddr, timeout);
176 if (status) return status;
159 177
160 i2c_write(regaddr); 178 status = i2c_write(regaddr, timeout);
179 if (status) return status;
161 180
162 if (i2c_start(devaddr | 0x01)) return 1; 181 status = i2c_start(devaddr | 0x01, timeout);
182 if (status) return status;
163 183
164 for (uint16_t i = 0; i < (length-1); i++) 184 for (uint16_t i = 0; i < (length-1); i++) {
165 { 185 status = i2c_read_ack(timeout);
166 data[i] = i2c_read_ack(); 186 if (status >= 0) {
187 data[i] = status;
188 } else {
189 return status;
190 }
167 } 191 }
168 data[(length-1)] = i2c_read_nack();
169 192
170 i2c_stop(); 193 status = i2c_read_nack(timeout);
194 if (status >= 0 ) {
195 data[(length-1)] = status;
196 } else {
197 return status;
198 }
199
200 status = i2c_stop(timeout);
201 if (status) return status;
171 202
172 return 0; 203 return I2C_STATUS_SUCCESS;
173} 204}
174 205
175i2c_status_t i2c_stop(uint8_t timeout) 206i2c_status_t i2c_stop(uint16_t timeout)
176{ 207{
177 // transmit STOP condition 208 // transmit STOP condition
178 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); 209 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
179 210
180 uint16_t timeout_timer = timer_read(); 211 uint16_t timeout_timer = timer_read();
181 while(TWCR & (1<<TWSTO)) { 212 while(TWCR & (1<<TWSTO)) {
182 if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) { 213 if (timeout && ((timer_read() - timeout_timer) > timeout)) {
183 return I2C_STATUS_TIMEOUT; 214 return I2C_STATUS_TIMEOUT;
184 } 215 }
185 } 216 }
186 217
187 return 0; 218 return I2C_STATUS_SUCCESS;
188} 219}