summaryrefslogtreecommitdiff
path: root/platforms/avr/drivers
diff options
context:
space:
mode:
authorDavid Hoelscher <infinityis@users.noreply.github.com>2024-01-17 07:05:38 -0600
committerGitHub <noreply@github.com>2024-01-17 14:05:38 +0100
commite9bd7d7ad308f9c72c86863bf9f19382c7e2d892 (patch)
treec46ce87aaa57b8f49dc0a2b56527f0bc606038ab /platforms/avr/drivers
parent2b0965944d9065daa65cd25540cf2dd007f23eda (diff)
I2C driver cleanup (#21273)
* remove i2c_start and i2c_stop from i2c drivers * remove static i2c_address variable from chibios i2c driver
Diffstat (limited to 'platforms/avr/drivers')
-rw-r--r--platforms/avr/drivers/i2c_master.c31
-rw-r--r--platforms/avr/drivers/i2c_master.h7
2 files changed, 27 insertions, 11 deletions
diff --git a/platforms/avr/drivers/i2c_master.c b/platforms/avr/drivers/i2c_master.c
index 0183103707..64083d862a 100644
--- a/platforms/avr/drivers/i2c_master.c
+++ b/platforms/avr/drivers/i2c_master.c
@@ -24,6 +24,7 @@
#include "timer.h"
#include "wait.h"
#include "util.h"
+#include "progmem.h"
#ifndef F_SCL
# define F_SCL 400000UL // SCL frequency
@@ -38,7 +39,7 @@
#define TWBR_val (((F_CPU / F_SCL) - 16) / 2)
-void i2c_init(void) {
+__attribute__((weak)) void i2c_init(void) {
TWSR = 0; /* no prescaler */
TWBR = (uint8_t)TWBR_val;
@@ -94,7 +95,7 @@ static i2c_status_t i2c_start_impl(uint8_t address, uint16_t timeout) {
return I2C_STATUS_SUCCESS;
}
-i2c_status_t i2c_start(uint8_t address, uint16_t timeout) {
+__attribute__((always_inline)) static inline i2c_status_t i2c_start(uint8_t address, uint16_t timeout) {
// Retry i2c_start_impl a bunch times in case the remote side has interrupts disabled.
uint16_t timeout_timer = timer_read();
uint16_t time_slice = MAX(1, (timeout == (I2C_TIMEOUT_INFINITE)) ? 5 : (timeout / (I2C_START_RETRY_COUNT))); // if it's infinite, wait 1ms between attempts, otherwise split up the entire timeout into the number of retries
@@ -105,6 +106,11 @@ i2c_status_t i2c_start(uint8_t address, uint16_t timeout) {
return status;
}
+__attribute__((always_inline)) static inline void i2c_stop(void) {
+ // transmit STOP condition
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
+}
+
i2c_status_t i2c_write(uint8_t data, uint16_t timeout) {
// load data into data register
TWDR = data;
@@ -167,6 +173,18 @@ i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length,
return status;
}
+i2c_status_t i2c_transmit_P(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) {
+ i2c_status_t status = i2c_start(address | I2C_ACTION_WRITE, timeout);
+
+ for (uint16_t i = 0; i < length && status >= 0; i++) {
+ status = i2c_write(pgm_read_byte((const char*)data++), timeout);
+ }
+
+ i2c_stop();
+
+ return status;
+}
+
i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) {
i2c_status_t status = i2c_start(address | I2C_ACTION_READ, timeout);
@@ -293,7 +311,8 @@ error:
return (status < 0) ? status : I2C_STATUS_SUCCESS;
}
-void i2c_stop(void) {
- // transmit STOP condition
- TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
-}
+__attribute__((weak)) i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout) {
+ i2c_status_t status = i2c_start(address, timeout);
+ i2c_stop();
+ return status;
+} \ No newline at end of file
diff --git a/platforms/avr/drivers/i2c_master.h b/platforms/avr/drivers/i2c_master.h
index 18587c4a57..b797997619 100644
--- a/platforms/avr/drivers/i2c_master.h
+++ b/platforms/avr/drivers/i2c_master.h
@@ -41,14 +41,11 @@ typedef int16_t i2c_status_t;
#define I2C_TIMEOUT_INFINITE (0xFFFF)
void i2c_init(void);
-i2c_status_t i2c_start(uint8_t address, uint16_t timeout);
-i2c_status_t i2c_write(uint8_t data, uint16_t timeout);
-int16_t i2c_read_ack(uint16_t timeout);
-int16_t i2c_read_nack(uint16_t timeout);
i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
+i2c_status_t i2c_transmit_P(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_read_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_read_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
-void i2c_stop(void);
+i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout);