aboutsummaryrefslogtreecommitdiff
path: root/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'platforms')
-rw-r--r--platforms/avr/drivers/i2c_master.c56
-rw-r--r--platforms/avr/drivers/i2c_master.h2
-rw-r--r--platforms/chibios/drivers/i2c_master.c25
-rw-r--r--platforms/chibios/drivers/i2c_master.h2
4 files changed, 84 insertions, 1 deletions
diff --git a/platforms/avr/drivers/i2c_master.c b/platforms/avr/drivers/i2c_master.c
index 2773e0077..111b55d6b 100644
--- a/platforms/avr/drivers/i2c_master.c
+++ b/platforms/avr/drivers/i2c_master.c
@@ -202,6 +202,25 @@ i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data,
202 return status; 202 return status;
203} 203}
204 204
205i2c_status_t i2c_writeReg16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) {
206 i2c_status_t status = i2c_start(devaddr | 0x00, timeout);
207 if (status >= 0) {
208 status = i2c_write(regaddr >> 8, timeout);
209
210 if (status >= 0) {
211 status = i2c_write(regaddr & 0xFF, timeout);
212
213 for (uint16_t i = 0; i < length && status >= 0; i++) {
214 status = i2c_write(data[i], timeout);
215 }
216 }
217 }
218
219 i2c_stop();
220
221 return status;
222}
223
205i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { 224i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
206 i2c_status_t status = i2c_start(devaddr, timeout); 225 i2c_status_t status = i2c_start(devaddr, timeout);
207 if (status < 0) { 226 if (status < 0) {
@@ -235,6 +254,43 @@ error:
235 return (status < 0) ? status : I2C_STATUS_SUCCESS; 254 return (status < 0) ? status : I2C_STATUS_SUCCESS;
236} 255}
237 256
257i2c_status_t i2c_readReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
258 i2c_status_t status = i2c_start(devaddr, timeout);
259 if (status < 0) {
260 goto error;
261 }
262
263 status = i2c_write(regaddr >> 8, timeout);
264 if (status < 0) {
265 goto error;
266 }
267 status = i2c_write(regaddr & 0xFF, timeout);
268 if (status < 0) {
269 goto error;
270 }
271
272 status = i2c_start(devaddr | 0x01, timeout);
273
274 for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) {
275 status = i2c_read_ack(timeout);
276 if (status >= 0) {
277 data[i] = status;
278 }
279 }
280
281 if (status >= 0) {
282 status = i2c_read_nack(timeout);
283 if (status >= 0) {
284 data[(length - 1)] = status;
285 }
286 }
287
288error:
289 i2c_stop();
290
291 return (status < 0) ? status : I2C_STATUS_SUCCESS;
292}
293
238void i2c_stop(void) { 294void i2c_stop(void) {
239 // transmit STOP condition 295 // transmit STOP condition
240 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); 296 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
diff --git a/platforms/avr/drivers/i2c_master.h b/platforms/avr/drivers/i2c_master.h
index e5af73364..2d95846db 100644
--- a/platforms/avr/drivers/i2c_master.h
+++ b/platforms/avr/drivers/i2c_master.h
@@ -39,5 +39,7 @@ int16_t i2c_read_nack(uint16_t timeout);
39i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout); 39i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
40i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); 40i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
41i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout); 41i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
42i2c_status_t i2c_writeReg16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
42i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); 43i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
44i2c_status_t i2c_readReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
43void i2c_stop(void); 45void i2c_stop(void);
diff --git a/platforms/chibios/drivers/i2c_master.c b/platforms/chibios/drivers/i2c_master.c
index 981f6fa06..312b4c7d0 100644
--- a/platforms/chibios/drivers/i2c_master.c
+++ b/platforms/chibios/drivers/i2c_master.c
@@ -102,7 +102,7 @@ i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data,
102 i2cStart(&I2C_DRIVER, &i2cconfig); 102 i2cStart(&I2C_DRIVER, &i2cconfig);
103 103
104 uint8_t complete_packet[length + 1]; 104 uint8_t complete_packet[length + 1];
105 for (uint8_t i = 0; i < length; i++) { 105 for (uint16_t i = 0; i < length; i++) {
106 complete_packet[i + 1] = data[i]; 106 complete_packet[i + 1] = data[i];
107 } 107 }
108 complete_packet[0] = regaddr; 108 complete_packet[0] = regaddr;
@@ -111,6 +111,21 @@ i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data,
111 return chibios_to_qmk(&status); 111 return chibios_to_qmk(&status);
112} 112}
113 113
114i2c_status_t i2c_writeReg16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) {
115 i2c_address = devaddr;
116 i2cStart(&I2C_DRIVER, &i2cconfig);
117
118 uint8_t complete_packet[length + 2];
119 for (uint16_t i = 0; i < length; i++) {
120 complete_packet[i + 2] = data[i];
121 }
122 complete_packet[0] = regaddr >> 8;
123 complete_packet[1] = regaddr & 0xFF;
124
125 msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 2, 0, 0, TIME_MS2I(timeout));
126 return chibios_to_qmk(&status);
127}
128
114i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { 129i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
115 i2c_address = devaddr; 130 i2c_address = devaddr;
116 i2cStart(&I2C_DRIVER, &i2cconfig); 131 i2cStart(&I2C_DRIVER, &i2cconfig);
@@ -118,4 +133,12 @@ i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16
118 return chibios_to_qmk(&status); 133 return chibios_to_qmk(&status);
119} 134}
120 135
136i2c_status_t i2c_readReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
137 i2c_address = devaddr;
138 i2cStart(&I2C_DRIVER, &i2cconfig);
139 uint8_t register_packet[2] = {regaddr >> 8, regaddr & 0xFF};
140 msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), &register_packet, 2, data, length, TIME_MS2I(timeout));
141 return chibios_to_qmk(&status);
142}
143
121void i2c_stop(void) { i2cStop(&I2C_DRIVER); } 144void i2c_stop(void) { i2cStop(&I2C_DRIVER); }
diff --git a/platforms/chibios/drivers/i2c_master.h b/platforms/chibios/drivers/i2c_master.h
index ce32fd245..5f082e9d1 100644
--- a/platforms/chibios/drivers/i2c_master.h
+++ b/platforms/chibios/drivers/i2c_master.h
@@ -96,5 +96,7 @@ i2c_status_t i2c_start(uint8_t address);
96i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout); 96i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
97i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); 97i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
98i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout); 98i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
99i2c_status_t i2c_writeReg16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
99i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); 100i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
101i2c_status_t i2c_readReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
100void i2c_stop(void); 102void i2c_stop(void);