diff options
author | David Hoelscher <[email protected]> | 2024-01-17 07:05:38 -0600 |
---|---|---|
committer | GitHub <[email protected]> | 2024-01-17 14:05:38 +0100 |
commit | e9bd7d7ad308f9c72c86863bf9f19382c7e2d892 (patch) | |
tree | c46ce87aaa57b8f49dc0a2b56527f0bc606038ab | |
parent | 2b0965944d9065daa65cd25540cf2dd007f23eda (diff) | |
download | qmk_firmware-e9bd7d7ad308f9c72c86863bf9f19382c7e2d892.tar.gz qmk_firmware-e9bd7d7ad308f9c72c86863bf9f19382c7e2d892.zip |
I2C driver cleanup (#21273)
* remove i2c_start and i2c_stop from i2c drivers
* remove static i2c_address variable from chibios i2c driver
49 files changed, 288 insertions, 611 deletions
diff --git a/docs/i2c_driver.md b/docs/i2c_driver.md index 2457e8e7b9..868715a62c 100644 --- a/docs/i2c_driver.md +++ b/docs/i2c_driver.md @@ -138,23 +138,6 @@ void i2c_init(void) { --- -### `i2c_status_t i2c_start(uint8_t address, uint16_t timeout)` :id=api-i2c-start - -Start an I2C transaction. - -#### Arguments :id=api-i2c-start-arguments - - - `uint8_t address` - The 7-bit I2C address of the device (ie. without the read/write bit - this will be set automatically). - - `uint16_t timeout` - The time in milliseconds to wait for a response from the target device. - -#### Return Value :id=api-i2c-start-return - -`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`. - ---- - ### `i2c_status_t i2c_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout)` :id=api-i2c-transmit Send multiple bytes to the selected I2C device. @@ -285,6 +268,21 @@ Reads from a register with a 16-bit address (big endian) on the I2C device. --- -### `i2c_status_t i2c_stop(void)` :id=api-i2c-stop +### `i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout)` :id=api-i2c-ping-address -Stop the current I2C transaction. +Pings the I2C bus for a specific address. + +On ChibiOS a "best effort" attempt is made by reading a single byte from register 0 at the requested address. This should generally work except for I2C devices that do not not respond to a register 0 read request, which will result in a false negative result (unsucessful response to ping attempt). + +This function is weakly defined, meaning it can be overridden if necessary for your particular use case: + +#### Arguments + + - `uint8_t address` + The 7-bit I2C address of the device (ie. without the read/write bit - this will be set automatically). + - `uint16_t timeout` + The time in milliseconds to wait for a response from the target device. + +#### Return Value + +`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`. diff --git a/docs/ja/i2c_driver.md b/docs/ja/i2c_driver.md index 1d8f70e163..92c4185370 100644 --- a/docs/ja/i2c_driver.md +++ b/docs/ja/i2c_driver.md @@ -23,12 +23,11 @@ I2C アドレスと他の技術詳細について、さらなる情報を得る� | 関数 | 説明 | |-------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `void i2c_init(void);` | I2C ドライバを初期化します。他のあらゆるトランザクションを開始する前に、この関数を一度だけ呼ぶ必要があります。 | -| `i2c_status_t i2c_start(uint8_t address, uint16_t timeout);` | I2C トランザクションを開始します。アドレスは方向ビットのない7ビットスレーブアドレスです。 | | `i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);` | I2C 経由でデータを送信します。アドレスは方向ビットのない7ビットスレーブアドレスです。トランザクションのステータスを返します。 | | `i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);` | I2C 経由でデータを受信します。アドレスは方向ビットのない7ビットスレーブアドレスです。 `length` で指定した長さのバイト列を `data` に保存し、トランザクションのステータスを返します。 | | `i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` | `i2c_transmit` と同様ですが、 `regaddr` でスレーブのデータ書き込み先のレジスタを指定します。 | | `i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` | `i2c_receive` と同様ですが、 `regaddr` でスレーブのデータ読み込み先のレジスタを指定します。 | -| `i2c_status_t i2c_stop(void);` | I2C トランザクションを終了します。 | +| `i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout);` | I2C アドレスをテストします。アドレスは方向ビットのない7ビットスレーブアドレスです。 | ### 関数の戻り値 :id=function-return diff --git a/drivers/gpio/pca9505.c b/drivers/gpio/pca9505.c index 4a11724ecf..5617a14a8b 100644 --- a/drivers/gpio/pca9505.c +++ b/drivers/gpio/pca9505.c @@ -41,8 +41,6 @@ void pca9505_init(uint8_t slave_addr) { } // TODO: could check device connected - // i2c_start(SLAVE_TO_ADDR(slave) | I2C_WRITE); - // i2c_stop(); } bool pca9505_set_config(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) { diff --git a/drivers/gpio/pca9555.c b/drivers/gpio/pca9555.c index 23727d21b3..0fc30099ac 100644 --- a/drivers/gpio/pca9555.c +++ b/drivers/gpio/pca9555.c @@ -29,8 +29,6 @@ void pca9555_init(uint8_t slave_addr) { } // TODO: could check device connected - // i2c_start(SLAVE_TO_ADDR(slave) | I2C_WRITE); - // i2c_stop(); } bool pca9555_set_config(uint8_t slave_addr, pca9555_port_t port, uint8_t conf) { diff --git a/drivers/oled/oled_driver.c b/drivers/oled/oled_driver.c index c674675d11..8cca41394f 100644 --- a/drivers/oled/oled_driver.c +++ b/drivers/oled/oled_driver.c @@ -223,13 +223,8 @@ __attribute__((weak)) bool oled_send_cmd_P(const uint8_t *data, uint16_t size) { spi_stop(); return (status >= 0); # elif defined(OLED_TRANSPORT_I2C) - i2c_status_t status = i2c_start((OLED_DISPLAY_ADDRESS << 1) | I2C_WRITE, OLED_I2C_TIMEOUT); - for (uint16_t i = 0; i < size && status >= 0; i++) { - status = i2c_write(pgm_read_byte((const char *)data++), OLED_I2C_TIMEOUT); - } - - i2c_stop(); + i2c_status_t status = i2c_transmit_P((OLED_DISPLAY_ADDRESS << 1), data, size, OLED_I2C_TIMEOUT); return (status == I2C_STATUS_SUCCESS); # endif diff --git a/drivers/painter/comms/qp_comms_i2c.c b/drivers/painter/comms/qp_comms_i2c.c index ec45ddfb3b..93f503f3dd 100644 --- a/drivers/painter/comms/qp_comms_i2c.c +++ b/drivers/painter/comms/qp_comms_i2c.c @@ -28,18 +28,14 @@ bool qp_comms_i2c_init(painter_device_t device) { } bool qp_comms_i2c_start(painter_device_t device) { - painter_driver_t * driver = (painter_driver_t *)device; - qp_comms_i2c_config_t *comms_config = (qp_comms_i2c_config_t *)driver->comms_config; - return i2c_start(comms_config->chip_address << 1) == I2C_STATUS_SUCCESS; + return true; } uint32_t qp_comms_i2c_send_data(painter_device_t device, const void *data, uint32_t byte_count) { return qp_comms_i2c_send_raw(device, data, byte_count); } -void qp_comms_i2c_stop(painter_device_t device) { - i2c_stop(); -} +void qp_comms_i2c_stop(painter_device_t device) {} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Command+Data I2C support diff --git a/drivers/sensors/cirque_pinnacle_i2c.c b/drivers/sensors/cirque_pinnacle_i2c.c index c9b9bece5f..a3622e9d60 100644 --- a/drivers/sensors/cirque_pinnacle_i2c.c +++ b/drivers/sensors/cirque_pinnacle_i2c.c @@ -19,7 +19,6 @@ void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count) { pd_dprintf("error cirque_pinnacle i2c_read_register\n"); touchpad_init = false; } - i2c_stop(); } } @@ -32,6 +31,5 @@ void RAP_Write(uint8_t address, uint8_t data) { pd_dprintf("error cirque_pinnacle i2c_write_register\n"); touchpad_init = false; } - i2c_stop(); } } diff --git a/keyboards/3w6/rev2/keymaps/default_pimoroni/pimoroni_trackball.c b/keyboards/3w6/rev2/keymaps/default_pimoroni/pimoroni_trackball.c index 35a85b5476..0db58bfabd 100644 --- a/keyboards/3w6/rev2/keymaps/default_pimoroni/pimoroni_trackball.c +++ b/keyboards/3w6/rev2/keymaps/default_pimoroni/pimoroni_trackball.c @@ -38,7 +38,7 @@ static uint16_t i2c_timeout_timer; void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) { uint8_t data[] = {0x00, red, green, blue, white}; - i2c_transmit(TRACKBALL_WRITE, data, sizeof(data), I2C_TIMEOUT); + i2c_transmit(TRACKBALL_ADDRESS, data, sizeof(data), I2C_TIMEOUT); } int16_t mouse_offset(uint8_t positive, uint8_t negative, int16_t scale) { @@ -120,7 +120,7 @@ bool pointing_device_task(void) { static uint16_t debounce_timer; uint8_t state[5] = {}; if (timer_elapsed(i2c_timeout_timer) > I2C_WAITCHECK) { - if (i2c_read_register(TRACKBALL_WRITE, 0x04, state, 5, I2C_TIMEOUT) == I2C_STATUS_SUCCESS) { + if (i2c_read_register(TRACKBALL_ADDRESS, 0x04, state, 5, I2C_TIMEOUT) == I2C_STATUS_SUCCESS) { if (!state[4] && !debounce) { if (scrolling) { #ifdef PIMORONI_TRACKBALL_INVERT_X diff --git a/keyboards/3w6/rev2/keymaps/default_pimoroni/pimoroni_trackball.h b/keyboards/3w6/rev2/keymaps/default_pimoroni/pimoroni_trackball.h index cfcd5a47a1..ca2559bec7 100644 --- a/keyboards/3w6/rev2/keymaps/default_pimoroni/pimoroni_trackball.h +++ b/keyboards/3w6/rev2/keymaps/default_pimoroni/pimoroni_trackball.h @@ -20,10 +20,8 @@ #include "pointing_device.h" #ifndef TRACKBALL_ADDRESS -# define TRACKBALL_ADDRESS 0x0A +# define TRACKBALL_ADDRESS (0x0A << 1) #endif -#define TRACKBALL_WRITE ((TRACKBALL_ADDRESS << 1) | I2C_WRITE) -#define TRACKBALL_READ ((TRACKBALL_ADDRESS << 1) | I2C_READ) void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white); void trackball_check_click(bool pressed, report_mouse_t *mouse); diff --git a/keyboards/bajjak/bajjak.c b/keyboards/bajjak/bajjak.c index 74e2b2aa8c..e6102e817b 100644 --- a/keyboards/bajjak/bajjak.c +++ b/keyboards/bajjak/bajjak.c @@ -137,23 +137,16 @@ uint8_t init_mcp23018(void) { // - unused : input : 1 // - input : input : 1 // - driving : output : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(IODIRA, BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00000000, BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00111111, BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - i2c_stop(); - - // set pull-up - // - unused : on : 1 - // - input : on : 1 - // - driving : off : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPPUA, BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00000000, BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b01111111, BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - -out: - i2c_stop(); + uint8_t data[] = {0b00000000, 0b00111111}; + mcp23018_status = i2c_writeReg(I2C_ADDR, IODIRA, data, 2, BAJJAK_EZ_I2C_TIMEOUT); + + if (!mcp23018_status) { + // set pull-up + // - unused : on : 1 + // - input : on : 1 + // - driving : off : 0 + mcp23018_status = i2c_writeReg(I2C_ADDR, IODIRA, data, 2, BAJJAK_EZ_I2C_TIMEOUT); + } #ifdef LEFT_LEDS if (!mcp23018_status) mcp23018_status = bajjak_left_leds_update(); @@ -176,21 +169,11 @@ uint8_t bajjak_left_leds_update(void) { // - unused : hi-Z : 1 // - input : hi-Z : 1 // - driving : hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, BAJJAK_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(OLATA, BAJJAK_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111 - & ~(bajjak_left_led_1<<LEFT_LED_1_SHIFT), - BAJJAK_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111 - & ~(bajjak_left_led_2<<LEFT_LED_2_SHIFT), - BAJJAK_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - - out: - i2c_stop(); + uint8_t data[2]; + data[0] = 0b11111111 & ~(bajjak_left_led_1<<LEFT_LED_1_SHIFT); + data[1] = 0b11111111 & ~(bajjak_left_led_2<<LEFT_LED_2_SHIFT); + mcp23018_status = i2c_writeReg(I2C_ADDR, OLATA, data, 2, BAJJAK_EZ_I2C_TIMEOUT); + return mcp23018_status; } #endif diff --git a/keyboards/bajjak/bajjak.h b/keyboards/bajjak/bajjak.h index 52f14ad3ea..c2d2d77ef6 100644 --- a/keyboards/bajjak/bajjak.h +++ b/keyboards/bajjak/bajjak.h @@ -27,9 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "i2c_master.h" // I2C aliases and register addresses (see "mcp23018.md") -#define I2C_ADDR 0b0100000 -#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE ) -#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ ) +#define I2C_ADDR (0b0100000<<1) #define IODIRA 0x00 // i/o direction register #define IODIRB 0x01 #define GPPUA 0x0C // GPIO pull-up resistor register diff --git a/keyboards/bajjak/matrix.c b/keyboards/bajjak/matrix.c index 20fc3c8f23..424bc29e4e 100644 --- a/keyboards/bajjak/matrix.c +++ b/keyboards/bajjak/matrix.c @@ -145,12 +145,7 @@ static matrix_row_t read_cols(uint8_t row) { uint8_t data = 0; // reading GPIOB (column port) since in mcp23018's sequential mode // it is addressed directly after writing to GPIOA in select_row() - mcp23018_status = i2c_start(I2C_ADDR_READ, BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_read_nack(BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status < 0) goto out; - data = ~((uint8_t)mcp23018_status); - mcp23018_status = I2C_STATUS_SUCCESS; - out: - i2c_stop(); + mcp23018_status = i2c_receive(I2C_ADDR, &data, 1, BAJJAK_EZ_I2C_TIMEOUT); return data; } } else { @@ -195,11 +190,10 @@ static void select_row(uint8_t row) { if (!mcp23018_status) { // set active row low : 0 // set other rows hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOA, BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0xFF & ~(1 << row), BAJJAK_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - out: - i2c_stop(); + uint8_t data; + data = 0xFF & ~(1 << row); + mcp23018_status = i2c_writeReg(I2C_ADDR, GPIOA, &data, 1, BAJJAK_EZ_I2C_TIMEOUT); + } } else { // select on teensy diff --git a/keyboards/dc01/left/matrix.c b/keyboards/dc01/left/matrix.c index d384c6a4bc..fd21d4333b 100644 --- a/keyboards/dc01/left/matrix.c +++ b/keyboards/dc01/left/matrix.c @@ -387,37 +387,13 @@ static void unselect_cols(void) // Complete rows from other modules over i2c i2c_status_t i2c_transaction(uint8_t address, uint32_t mask, uint8_t col_offset) { - i2c_status_t status = i2c_start(address, 5); - if (status < 0) { - goto error; - } - - status = i2c_write(0x01, 50); - if (status < 0) { - goto error; - } - - status = i2c_start(address | I2C_READ, 50); + uint8_t data[MATRIX_ROWS + 1]; + i2c_status_t status = i2c_readReg(address, 0x01, data, (MATRIX_ROWS + 1), 5); - status = i2c_read_ack(50); - if (status != 0x55) { //synchronization byte - goto error; + for (uint8_t i = 0; i < (MATRIX_ROWS) && status >= 0; i++) { //assemble slave matrix in main matrix + matrix[i] &= mask; //mask bits to keep + matrix[i] |= ((uint32_t)data[i+1] << (MATRIX_COLS_SCANNED + col_offset)); //add new bits at the end } - for (uint8_t i = 0; i < MATRIX_ROWS-1 && status >= 0; i++) { //assemble slave matrix in main matrix - matrix[i] &= mask; //mask bits to keep - status = i2c_read_ack(50); - matrix[i] |= ((uint32_t)status << (MATRIX_COLS_SCANNED + col_offset)); //add new bits at the end - } - //last read request must be followed by a NACK - if (status >= 0) { - matrix[MATRIX_ROWS - 1] &= mask; //mask bits to keep - status = i2c_read_nack(50); - matrix[MATRIX_ROWS - 1] |= ((uint32_t)status << (MATRIX_COLS_SCANNED + col_offset)); //add new bits at the end - } - -error: - i2c_stop(); - - return (status < 0) ? status : I2C_STATUS_SUCCESS; + return status; } diff --git a/keyboards/ergodox_ez/ergodox_ez.c b/keyboards/ergodox_ez/ergodox_ez.c index f088036c4a..3d6272ae66 100644 --- a/keyboards/ergodox_ez/ergodox_ez.c +++ b/keyboards/ergodox_ez/ergodox_ez.c @@ -155,31 +155,16 @@ uint8_t init_mcp23018(void) { // - unused : input : 1 // - input : input : 1 // - driving : output : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00000000, ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00111111, ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - i2c_stop(); - - // set pull-up - // - unused : on : 1 - // - input : on : 1 - // - driving : off : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPPUA, ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00000000, ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00111111, ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - -out: - i2c_stop(); + uint8_t data[] = {0b00000000, 0b00111111}; + mcp23018_status = i2c_writeReg(I2C_ADDR, IODIRA, data, 2, ERGODOX_EZ_I2C_TIMEOUT); + + if (!mcp23018_status) { + // set pull-up + // - unused : on : 1 + // - input : on : 1 + // - driving : off : 0 + mcp23018_status = i2c_writeReg(I2C_ADDR, GPPUA, data, 2, ERGODOX_EZ_I2C_TIMEOUT); + } #ifdef LEFT_LEDS if (!mcp23018_status) mcp23018_status = ergodox_left_leds_update(); @@ -203,17 +188,11 @@ uint8_t ergodox_left_leds_update(void) { // - unused : hi-Z : 1 // - input : hi-Z : 1 // - driving : hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(OLATA, ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111 & ~(ergodox_left_led_3 << LEFT_LED_3_SHIFT), ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111 & ~(ergodox_left_led_2 << LEFT_LED_2_SHIFT) & ~(ergodox_left_led_1 << LEFT_LED_1_SHIFT), ERGODOX_EZ_I2C_TIMEOUT); - if (mcp23018_status) goto out; - -out: - i2c_stop(); + uint8_t data[2]; + data[0] = 0b11111111 & ~(ergodox_left_led_3 << LEFT_LED_3_SHIFT); + data[1] = 0b11111111 & ~(ergodox_left_led_2 << LEFT_LED_2_SHIFT) & ~(ergodox_left_led_1 << LEFT_LED_1_SHIFT); + mcp23018_status = i2c_writeReg(I2C_ADDR, OLATA, data, 2, ERGODOX_EZ_I2C_TIMEOUT); + return mcp23018_status; } #endif diff --git a/keyboards/ergodox_ez/ergodox_ez.h b/keyboards/ergodox_ez/ergodox_ez.h index befc114617..df2dbed715 100644 --- a/keyboards/ergodox_ez/ergodox_ez.h +++ b/keyboards/ergodox_ez/ergodox_ez.h @@ -26,9 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "i2c_master.h" // I2C aliases and register addresses (see "mcp23018.md") -#define I2C_ADDR 0b0100000 -#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE ) -#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ ) +#define I2C_ADDR (0b0100000<<1) #define IODIRA 0x00 // i/o direction register #define IODIRB 0x01 #define GPPUA 0x0C // GPIO pull-up resistor register diff --git a/keyboards/ergodox_ez/led_i2c.c b/keyboards/ergodox_ez/led_i2c.c index a8802858ec..80dabf4815 100644 --- a/keyboards/ergodox_ez/led_i2c.c +++ b/keyboards/ergodox_ez/led_i2c.c @@ -24,30 +24,41 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. # include "ws2812.h" void setleds_custom(rgb_led_t *led, uint16_t led_num) { - i2c_init(); - i2c_start(0x84, ERGODOX_EZ_I2C_TIMEOUT); + uint16_t length = 0; int i = 0; + int j = 0; +# ifdef RGBW + int bytes_per_led = 4; +# else + int bytes_per_led = 3; +# endif # if defined(ERGODOX_LED_30) // prevent right-half code from trying to bitbang all 30 // so with 30 LEDs, we count from 29 to 15 here, and the // other half does 0 to 14. uint8_t half_led_num = RGBLIGHT_LED_COUNT / 2; + length = half_led_num * bytes_per_led; + uint8_t data[length]; for (i = half_led_num + half_led_num - 1; i >= half_led_num; --i) # elif defined(ERGODOX_LED_15_MIRROR) + length = led_num * bytes_per_led; + uint8_t data[length]; for (i = 0; i < led_num; ++i) # else // ERGDOX_LED_15 non-mirrored + length = led_num * bytes_per_led; + uint8_t data[length]; for (i = led_num - 1; i >= 0; --i) # endif { - uint8_t *data = (uint8_t *)(led + i); - i2c_write(*data++, ERGODOX_EZ_I2C_TIMEOUT); - i2c_write(*data++, ERGODOX_EZ_I2C_TIMEOUT); - i2c_write(*data++, ERGODOX_EZ_I2C_TIMEOUT); + uint8_t *data_byte = (uint8_t *)(led + i); + data[j++] = data_byte[0]; + data[j++] = data_byte[1]; + data[j++] = data_byte[2]; #ifdef RGBW - i2c_write(*data++, ERGODOX_EZ_I2C_TIMEOUT); + data[j++] = data_byte[3]; #endif } - i2c_stop(); + i2c_transmit(0x84, data, sizeof(data), ERGODOX_EZ_I2C_TIMEOUT); ws2812_setleds(led, led_num); } diff --git a/keyboards/ergodox_ez/matrix.c b/keyboards/ergodox_ez/matrix.c index e84a5e2bd3..28bee05779 100644 --- a/keyboards/ergodox_ez/matrix.c +++ b/keyboards/ergodox_ez/matrix.c @@ -146,13 +146,8 @@ static matrix_row_t read_cols(uint8_t row) { uint8_t data = 0; // reading GPIOB (column port) since in mcp23018's sequential mode // it is addressed directly after writing to GPIOA in select_row() - mcp23018_status = i2c_start(I2C_ADDR_READ, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_read_nack(ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status < 0) goto out; - data = ~((uint8_t)mcp23018_status); - mcp23018_status = I2C_STATUS_SUCCESS; - out: - i2c_stop(); - return data; + mcp23018_status = i2c_receive(I2C_ADDR, &data, 1, ERGODOX_EZ_I2C_TIMEOUT); + return ~data; } } else { /* read from teensy @@ -196,11 +191,9 @@ static void select_row(uint8_t row) { if (!mcp23018_status) { // set active row low : 0 // set other rows hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0xFF & ~(1 << row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - out: - i2c_stop(); + uint8_t data; + data = 0xFF & ~(1 << row); + mcp23018_status = i2c_writeReg(I2C_ADDR, GPIOA, &data, 1, ERGODOX_EZ_I2C_TIMEOUT); } } else { // select on teensy diff --git a/keyboards/ferris/0_2/matrix.c b/keyboards/ferris/0_2/matrix.c index af4b045eb8..cf26385f4c 100644 --- a/keyboards/ferris/0_2/matrix.c +++ b/keyboards/ferris/0_2/matrix.c @@ -42,9 +42,7 @@ extern i2c_status_t mcp23017_status; // All address pins of the mcp23017 are connected to the ground on the ferris // | 0 | 1 | 0 | 0 | A2 | A1 | A0 | // | 0 | 1 | 0 | 0 | 0 | 0 | 0 | -#define I2C_ADDR 0b0100000 -#define I2C_ADDR_WRITE ((I2C_ADDR << 1) | I2C_WRITE) -#define I2C_ADDR_READ ((I2C_ADDR << 1) | I2C_READ) +#define I2C_ADDR (0b0100000 << 1) // Register addresses // See https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/Adafruit_MCP23017.h @@ -77,9 +75,9 @@ uint8_t init_mcp23017(void) { // - driving : output : 0 // This means: we will read all the bits on GPIOA // This means: we will write to the pins 0-4 on GPIOB (in select_rows) - uint8_t buf[] = {IODIRA, 0b11111111, 0b11110000}; + uint8_t buf[] = {0b11111111, 0b11110000}; print("before transmit\n"); - mcp23017_status = i2c_transmit(I2C_ADDR_WRITE, buf, sizeof(buf), MCP23017_I2C_TIMEOUT); + mcp23017_status = i2c_writeReg(I2C_ADDR, IODIRA, buf, sizeof(buf), MCP23017_I2C_TIMEOUT) uprintf("after transmit %i\n", mcp23017_status); if (!mcp23017_status) { // set pull-up @@ -88,8 +86,7 @@ uint8_t init_mcp23017(void) { // - driving : off : 0 // This means: we will read all the bits on GPIOA // This means: we will write to the pins 0-4 on GPIOB (in select_rows) - uint8_t pullup_buf[] = {GPPUA, 0b11111111, 0b11110000}; - mcp23017_status = i2c_transmit(I2C_ADDR_WRITE, pullup_buf, sizeof(pullup_buf), MCP23017_I2C_TIMEOUT); + mcp23017_status = i2c_writeReg(I2C_ADDR, GPPUA, buf, sizeof(buf), MCP23017_I2C_TIMEOUT) uprintf("after transmit2 %i\n", mcp23017_status); } return mcp23017_status; @@ -189,18 +186,13 @@ static matrix_row_t read_cols(uint8_t row) { if (mcp23017_status) { // if there was an error return 0; } else { - uint8_t buf[] = {MCP23017_GPIOA}; - mcp23017_status = i2c_transmit(I2C_ADDR_WRITE, buf, sizeof(buf), MCP23017_I2C_TIMEOUT); // We read all the pins on GPIOA. // The initial state was all ones and any depressed key at a given column for the currently selected row will have its bit flipped to zero. // The return value is a row as represented in the generic matrix code were the rightmost bits represent the lower columns and zeroes represent non-depressed keys while ones represent depressed keys. // Since the pins connected to eact columns are sequential, and counting from zero up (col 5 -> GPIOA0, col 6 -> GPIOA1 and so on), the only transformation needed is a bitwise not to swap all zeroes and ones. uint8_t data[] = {0}; - if (!mcp23017_status) { - mcp23017_status = i2c_receive(I2C_ADDR_READ, data, sizeof(data), MCP23017_I2C_TIMEOUT); - data[0] = ~(data[0]); - } - return data[0]; + mcp23017_status = i2c_readReg(I2C_ADDR, MCP23017_GPIOA, data, sizeof(data), MCP23017_I2C_TIMEOUT); + return ~data[0]; } } } @@ -244,8 +236,8 @@ static void select_row(uint8_t row) { } else { // Select the desired row by writing a byte for the entire GPIOB bus where only the bit representing the row we want to select is a zero (write instruction) and every other bit is a one. // Note that the row - MATRIX_ROWS_PER_SIDE reflects the fact that being on the right hand, the columns are numbered from MATRIX_ROWS_PER_SIDE to MATRIX_ROWS, but the pins we want to write to are indexed from zero up on the GPIOB bus. - uint8_t buf[] = {MCP23017_GPIOB, 0xFF & ~(1 << (row - MATRIX_ROWS_PER_SIDE))}; - mcp23017_status = i2c_transmit(I2C_ADDR_WRITE, buf, sizeof(buf), I2C_TIMEOUT); + uint8_t buf[] = {0xFF & ~(1 << (row - MATRIX_ROWS_PER_SIDE))}; + mcp23017_status = i2c_writeReg(I2C_ADDR, MCP23017_GPIOB, buf, sizeof(buf), MCP23017_I2C_TIMEOUT); } } } diff --git a/keyboards/gboards/ergotaco/ergotaco.c b/keyboards/gboards/ergotaco/ergotaco.c index daeba1e0a6..694e07f031 100644 --- a/keyboards/gboards/ergotaco/ergotaco.c +++ b/keyboards/gboards/ergotaco/ergotaco.c @@ -49,23 +49,17 @@ uint8_t init_mcp23018(void) { // - unused : input : 1 // - input : input : 1 // - driving : output : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - i2c_stop(); - - // set pull-up - // - unused : on : 1 - // - input : on : 1 - // - driving : off : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPPUA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - -out: - i2c_stop(); + uint8_t data[] = {0b00000000, 0b00111111}; + mcp23018_status = i2c_writeReg(I2C_ADDR, IODIRA, data, sizeof(data), ERGODOX_EZ_I2C_TIMEOUT); + + if (!mcp23018_status) { + // set pull-up + // - unused : on : 1 + // - input : on : 1 + // - driving : off : 0 + mcp23018_status = i2c_writeReg(I2C_ADDR, GPPUA, data, sizeof(data), ERGODOX_EZ_I2C_TIMEOUT); + } + // SREG=sreg_prev; //uprintf("Init %x\n", mcp23018_status); return mcp23018_status; diff --git a/keyboards/gboards/ergotaco/ergotaco.h b/keyboards/gboards/ergotaco/ergotaco.h index e23fc264f4..6ab47ced74 100644 --- a/keyboards/gboards/ergotaco/ergotaco.h +++ b/keyboards/gboards/ergotaco/ergotaco.h @@ -11,10 +11,7 @@ extern i2c_status_t mcp23018_status; #define ERGODOX_EZ_I2C_TIMEOUT 1000 // I2C aliases and register addresses (see "mcp23018.md") -//#define I2C_ADDR 0b0100000 -#define I2C_ADDR 0x20 -#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE ) -#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ ) +#define I2C_ADDR (0x20<<1) #define IODIRA 0x00 // i/o direction register #define IODIRB 0x01 #define GPPUA 0x0C // GPIO pull-up resistor register diff --git a/keyboards/gboards/ergotaco/matrix.c b/keyboards/gboards/ergotaco/matrix.c index 63d4c4f5f3..3c49f2802e 100644 --- a/keyboards/gboards/ergotaco/matrix.c +++ b/keyboards/gboards/ergotaco/matrix.c @@ -234,15 +234,8 @@ static matrix_row_t read_cols(uint8_t row) return 0; } else { uint8_t data = 0; - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOB, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_start(I2C_ADDR_READ, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_read_nack(ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status < 0) goto out; - data = (~((uint8_t)mcp23018_status) >> 2) & 0x01 ; - mcp23018_status = I2C_STATUS_SUCCESS; - out: - i2c_stop(); - + mcp23018_status = i2c_readReg(I2C_ADDR, GPIOB, &data, 1, ERGODOX_EZ_I2C_TIMEOUT); + data = (~((uint8_t)data) >> 2) & 0x01 ; #ifdef DEBUG_MATRIX if (data != 0x00) xprintf("I2C: %d\n", data); #endif @@ -274,11 +267,8 @@ static void select_row(uint8_t row) if (mcp23018_status) { // do nothing on error // Read using bitmask } else { // set active row low : 0 // set other rows hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(~(1<<row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - out: - i2c_stop(); + uint8_t data = ~(1<<row); + mcp23018_status = i2c_writeReg(I2C_ADDR, GPIOA, &data, 1, ERGODOX_EZ_I2C_TIMEOUT); } } else { // Output low(DDR:1, PORT:0) to select diff --git a/keyboards/gboards/georgi/georgi.c b/keyboards/gboards/georgi/georgi.c index dd95b593f1..745e8ab35d 100644 --- a/keyboards/gboards/georgi/georgi.c +++ b/keyboards/gboards/georgi/georgi.c @@ -45,23 +45,17 @@ uint8_t init_mcp23018(void) { // - unused : input : 1 // - input : input : 1 // - driving : output : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b10000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - i2c_stop(); - - // set pull-up - // - unused : on : 1 - // - input : on : 1 - // - driving : off : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPPUA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b10000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; + uint8_t data[] = {0b10000000, 0b11111111}; + mcp23018_status = i2c_writeReg(I2C_ADDR, IODIRA, data, 2, ERGODOX_EZ_I2C_TIMEOUT); + + if (!mcp23018_status) { + // set pull-up + // - unused : on : 1 + // - input : on : 1 + // - driving : off : 0 + mcp23018_status = i2c_writeReg(I2C_ADDR, GPPUA, data, 2, ERGODOX_EZ_I2C_TIMEOUT); + } -out: - i2c_stop(); // SREG=sreg_prev; //uprintf("Init %x\n", mcp23018_status); return mcp23018_status; diff --git a/keyboards/gboards/georgi/georgi.h b/keyboards/gboards/georgi/georgi.h index e23fc264f4..6ab47ced74 100644 --- a/keyboards/gboards/georgi/georgi.h +++ b/keyboards/gboards/georgi/georgi.h @@ -11,10 +11,7 @@ extern i2c_status_t mcp23018_status; #define ERGODOX_EZ_I2C_TIMEOUT 1000 // I2C aliases and register addresses (see "mcp23018.md") -//#define I2C_ADDR 0b0100000 -#define I2C_ADDR 0x20 -#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE ) -#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ ) +#define I2C_ADDR (0x20<<1) #define IODIRA 0x00 // i/o direction register #define IODIRB 0x01 #define GPPUA 0x0C // GPIO pull-up resistor register diff --git a/keyboards/gboards/georgi/matrix.c b/keyboards/gboards/georgi/matrix.c index b66b1a194c..d1151ae80e 100644 --- a/keyboards/gboards/georgi/matrix.c +++ b/keyboards/gboards/georgi/matrix.c @@ -254,14 +254,7 @@ static matrix_row_t read_cols(uint8_t row) return 0; } else { uint8_t data = 0; - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOB, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_start(I2C_ADDR_READ, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_read_nack(ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status < 0) goto out; - data = ~((uint8_t)mcp23018_status); - mcp23018_status = I2C_STATUS_SUCCESS; - out: - i2c_stop(); + mcp23018_status = i2c_readReg(I2C_ADDR, GPIOB, &data, 1, ERGODOX_EZ_I2C_TIMEOUT); #ifdef DEBUG_MATRIX if (data != 0x00) xprintf("I2C: %d\n", data); @@ -304,11 +297,9 @@ static void select_row(uint8_t row) // select on mcp23018 if (mcp23018_status) { // do nothing on error } else { // set active row low : 0 // set other rows hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0xFF & ~(1<<row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - out: - i2c_stop(); + uint8_t data = 0xFF & ~(1<<row); + mcp23018_status = i2c_writeReg(I2C_ADDR, GPIOA, &data, 1, ERGODOX_EZ_I2C_TIMEOUT); + } } else { // Output low(DDR:1, PORT:0) to select diff --git a/keyboards/gboards/gergo/gergo.c b/keyboards/gboards/gergo/gergo.c index da2a3007a8..41d383d408 100644 --- a/keyboards/gboards/gergo/gergo.c +++ b/keyboards/gboards/gergo/gergo.c @@ -43,23 +43,17 @@ uint8_t init_mcp23018(void) { // - unused : input : 1 // - input : input : 1 // - driving : output : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(IODIRA, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b10000000, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111, I2C_TIMEOUT); if (mcp23018_status) goto out; - i2c_stop(); + uint8_t data[] = {0b10000000, 0b11111111}; + mcp23018_status = i2c_writeReg(I2C_ADDR, IODIRA, data, sizeof(data), I2C_TIMEOUT); - // set pull-up - // - unused : on : 1 - // - input : on : 1 - // - driving : off : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPPUA, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b10000000, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111, I2C_TIMEOUT); if (mcp23018_status) goto out; + if (!mcp23018_status) { + // set pull-up + // - unused : on : 1 + // - input : on : 1 + // - driving : off : 0 + mcp23018_status = i2c_writeReg(I2C_ADDR, GPPUA, data, sizeof(data), I2C_TIMEOUT); + } -out: - i2c_stop(); // SREG=sreg_prev; //uprintf("Init %x\n", mcp23018_status); return mcp23018_status; diff --git a/keyboards/gboards/gergo/gergo.h b/keyboards/gboards/gergo/gergo.h index ea6368e2f1..f6dc1498f0 100644 --- a/keyboards/gboards/gergo/gergo.h +++ b/keyboards/gboards/gergo/gergo.h @@ -11,10 +11,7 @@ extern i2c_status_t mcp23018_status; #define I2C_TIMEOUT 1000 // I2C aliases and register addresses (see "mcp23018.md") -//#define I2C_ADDR 0b0100000 -#define I2C_ADDR 0x20 -#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE ) -#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ ) +#define I2C_ADDR (0x20<<1) #define IODIRA 0x00 // i/o direction register #define IODIRB 0x01 #define GPPUA 0x0C // GPIO pull-up resistor register diff --git a/keyboards/gboards/gergo/matrix.c b/keyboards/gboards/gergo/matrix.c index 8a6b38bf73..b4885361fb 100644 --- a/keyboards/gboards/gergo/matrix.c +++ b/keyboards/gboards/gergo/matrix.c @@ -297,19 +297,12 @@ static matrix_row_t read_cols(uint8_t row) { return 0; } else { uint8_t data = 0; - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOB, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_start(I2C_ADDR_READ, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_read_nack(I2C_TIMEOUT); if (mcp23018_status < 0) goto out; - data = ~((uint8_t)mcp23018_status); - mcp23018_status = I2C_STATUS_SUCCESS; - out: - i2c_stop(); + mcp23018_status = i2c_readReg(I2C_ADDR, GPIOB, &data, 1, I2C_TIMEOUT); #ifdef DEBUG_MATRIX - if (data != 0x00) xprintf("I2C: %d\n", data); + if (~data != 0x00) xprintf("I2C: %d\n", ~data); #endif - return data; + return ~data; } } else { /* read from teensy @@ -350,11 +343,8 @@ static void select_row(uint8_t row) // select on mcp23018 if (mcp23018_status) { // do nothing on error } else { // set active row low : 0 // set other rows hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOA, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0xFF & ~(1<<row), I2C_TIMEOUT); if (mcp23018_status) goto out; - out: - i2c_stop(); + uint8_t data = 0xFF & ~(1<<row); + mcp23018_status = i2c_writeReg(I2C_ADDR, GPIOA, &data, 1, I2C_TIMEOUT); } } else { // Output low(DDR:1, PORT:0) to select diff --git a/keyboards/gboards/gergoplex/gergoplex.c b/keyboards/gboards/gergoplex/gergoplex.c index 1e44583895..b621201c16 100644 --- a/keyboards/gboards/gergoplex/gergoplex.c +++ b/keyboards/gboards/gergoplex/gergoplex.c @@ -39,30 +39,16 @@ uint8_t init_mcp23018(void) { // - unused : input : 1 // - input : input : 1 // - driving : output : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(IODIRA, I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11000001, I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111, I2C_TIMEOUT); - if (mcp23018_status) goto out; - i2c_stop(); - - // set pull-up - // - unused : on : 1 - // - input : on : 1 - // - driving : off : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPPUA, I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11000001, I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b11111111, I2C_TIMEOUT); - if (mcp23018_status) goto out; + uint8_t data[] = {0b11000001, 0b11111111}; + mcp23018_status = i2c_writeReg(I2C_ADDR, IODIRA, data, sizeof(data), I2C_TIMEOUT); + + if (!mcp23018_status) { + // set pull-up + // - unused : on : 1 + // - input : on : 1 + // - driving : off : 0 + mcp23018_status = i2c_writeReg(I2C_ADDR, GPPUA, data, sizeof(data), I2C_TIMEOUT); + } -out: - i2c_stop(); return mcp23018_status; } diff --git a/keyboards/gboards/gergoplex/gergoplex.h b/keyboards/gboards/gergoplex/gergoplex.h index 549228104a..217cb8dff1 100644 --- a/keyboards/gboards/gergoplex/gergoplex.h +++ b/keyboards/gboards/gergoplex/gergoplex.h @@ -25,9 +25,7 @@ extern i2c_status_t mcp23018_status; #define XXX KC_NO // I2C aliases and register addresses (see "mcp23018.md") -#define I2C_ADDR 0x20 // 0b0100000 -#define I2C_ADDR_WRITE ((I2C_ADDR << 1) | I2C_WRITE) -#define I2C_ADDR_READ ((I2C_ADDR << 1) | I2C_READ) +#define I2C_ADDR (0x20 << 1) // 0b0100000 #define IODIRA 0x00 // i/o direction register #define IODIRB 0x01 #define GPPUA 0x0C // GPIO pull-up resistor register diff --git a/keyboards/gboards/gergoplex/matrix.c b/keyboards/gboards/gergoplex/matrix.c index c9f5528b74..9437b24377 100644 --- a/keyboards/gboards/gergoplex/matrix.c +++ b/keyboards/gboards/gergoplex/matrix.c @@ -177,20 +177,12 @@ static matrix_row_t read_cols(uint8_t row) { if (mcp23018_status) { // if there was an error return 0; } else { - uint8_t data = 0; - mcp23018_status = i2c_start(I2C_ADDR_READ, I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_read_nack(I2C_TIMEOUT); - if (mcp23018_status < 0) goto out; - data = ~((uint8_t)mcp23018_status); - mcp23018_status = I2C_STATUS_SUCCESS; - out: - i2c_stop(); - + uint8_t data = 0; + mcp23018_status = i2c_receive(I2C_ADDR, &data, 1, I2C_TIMEOUT); #ifdef DEBUG_MATRIX - if (data != 0x00) xprintf("I2C: %d\n", data); + if (~data != 0x00) xprintf("I2C: %d\n", ~data); #endif - return data; + return ~data; } } else { return ~((((PINF & COL4) >> 1) | ((PINF & (COL1 | COL2 | COL3)) >> 3)) & 0xF); @@ -213,14 +205,10 @@ static void select_row(uint8_t row) { // select on mcp23018 if (mcp23018_status) { // do nothing on error } else { // set active row low : 0 // set other rows hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOA, I2C_TIMEOUT); - if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0xFF & ~(1 << (row + 1)), I2C_TIMEOUT); - if (mcp23018_status) goto out; - out: - i2c_stop(); + uint8_t data; + data = 0xFF & ~(1 << (row + 1)); + mcp23018_status = i2c_writeReg(I2C_ADDR, GPIOA, &data, 1, I2C_TIMEOUT); + } } else { setPinOutput(row_pins[row - MATRIX_ROWS_PER_SIDE]); diff --git a/keyboards/handwired/d48/ds1307.c b/keyboards/handwired/d48/ds1307.c index 2b3a88f315..5f4931bbf8 100644 --- a/keyboards/handwired/d48/ds1307.c +++ b/keyboards/handwired/d48/ds1307.c @@ -14,7 +14,6 @@ void ds1307_set_time(uint8_t h, uint8_t m, uint8_t s) { void ds1307_get_time(uint8_t *h, uint8_t *m, uint8_t *s) { uint8_t data[3]; i2c_read_register(DS1307_ADDR, 0, data, 3, 100); - i2c_stop(); *s = (data[0] & 0b1111) + ((data[0] & 0b1110000) >> 4) * 10; *m = (data[1] & 0b1111) + ((data[1] & 0b1110000) >> 4) * 10; *h = (data[2] & 0b1111) + ((data[2] & 0b0110000) >> 4) * 10; diff --git a/keyboards/handwired/frenchdev/frenchdev.c b/keyboards/handwired/frenchdev/frenchdev.c index 6eed4de5ff..65f1ccce4b 100644 --- a/keyboards/handwired/frenchdev/frenchdev.c +++ b/keyboards/handwired/frenchdev/frenchdev.c @@ -83,23 +83,16 @@ uint8_t init_mcp23018(void) { // - unused : input : 1 // - input : input : 1 // - driving : output : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(IODIRA, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00000000, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00111111, I2C_TIMEOUT); if (mcp23018_status) goto out; - i2c_stop(); - - // set pull-up - // - unused : on : 1 - // - input : on : 1 - // - driving : off : 0 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPPUA, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00000000, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0b00111111, I2C_TIMEOUT); if (mcp23018_status) goto out; - -out: - i2c_stop(); + uint8_t data[] = {0b00000000, 0b00111111}; + mcp23018_status = i2c_writeReg(I2C_ADDR, IODIRA, data, sizeof(data), I2C_TIMEOUT); + + if (!mcp23018_status) { + // set pull-up + // - unused : on : 1 + // - input : on : 1 + // - driving : off : 0 + mcp23018_status = i2c_writeReg(I2C_ADDR, GPPUA, data, sizeof(data), I2C_TIMEOUT); + } // SREG=sreg_prev; diff --git a/keyboards/handwired/frenchdev/frenchdev.h b/keyboards/handwired/frenchdev/frenchdev.h index 6bea49d87b..0f1ac7dcaa 100644 --- a/keyboards/handwired/frenchdev/frenchdev.h +++ b/keyboards/handwired/frenchdev/frenchdev.h @@ -7,9 +7,7 @@ #include <util/delay.h> // I2C aliases and register addresses (see "mcp23018.md" on tmk repository) -#define I2C_ADDR 0b0100000 -#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE ) -#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ ) +#define I2C_ADDR (0b0100000<<1) #define IODIRA 0x00 // i/o direction register #define IODIRB 0x01 #define GPPUA 0x0C // GPIO pull-up resistor register diff --git a/keyboards/handwired/frenchdev/matrix.c b/keyboards/handwired/frenchdev/matrix.c index 3e859d47ef..3afc6dcee6 100644 --- a/keyboards/handwired/frenchdev/matrix.c +++ b/keyboards/handwired/frenchdev/matrix.c @@ -224,15 +224,9 @@ static matrix_row_t read_cols(uint8_t row) return 0; } else { uint8_t data = 0; - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOB, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_start(I2C_ADDR_READ, I2C_TIMEOUT); if (mcp23018_status) goto out; - data = i2c_read_nack(I2C_TIMEOUT); if (mcp23018_status < 0) goto out; - data = ~((uint8_t)mcp23018_status); - mcp23018_status = I2C_STATUS_SUCCESS; - out: - i2c_stop(); - return data; + mcp23018_status = i2c_readReg(I2C_ADDR, GPIOB, &data, 1, I2C_TIMEOUT); + + return ~data; } } else { // read from teensy @@ -263,11 +257,10 @@ static void unselect_rows(void) // do nothing } else { // set all rows hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOA, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write( 0xFF & ~(0<<8), I2C_TIMEOUT); if (mcp23018_status) goto out; - out: - i2c_stop(); + uint8_t data; + data = 0xFF & ~(0<<8); + mcp23018_status = i2c_writeReg(I2C_ADDR, GPIOA, &data, 1, I2C_TIMEOUT); + } // unselect on teensy @@ -289,11 +282,8 @@ static void select_row(uint8_t row) } else { // set active row low : 0 // set other rows hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOA, I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write( 0xFF & ~(1<<row) & ~(0<<8), I2C_TIMEOUT); if (mcp23018_status) goto out; - out: - i2c_stop(); + uint8_t data = 0xFF & ~(1<<row) & ~(0<<8); + mcp23018_status = i2c_writeReg(I2C_ADDR, GPIOA, &data, 1, I2C_TIMEOUT); } } else { // select on teensy diff --git a/keyboards/handwired/onekey/keymaps/i2c_scanner/keymap.c b/keyboards/handwired/onekey/keymaps/i2c_scanner/keymap.c index 43e61c29d3..1d1a7c2b00 100644 --- a/keyboards/handwired/onekey/keymaps/i2c_scanner/keymap.c +++ b/keyboards/handwired/onekey/keymaps/i2c_scanner/keymap.c @@ -8,16 +8,6 @@ // TODO: remove patch #ifdef PROTOCOL_CHIBIOS # pragma message("ChibiOS is currently 'best effort' and might not report accurate results") - -i2c_status_t i2c_start_bodge(uint8_t address, uint16_t timeout) { - i2c_start(address); - - // except on ChibiOS where the only way is do do "something" - uint8_t data = 0; - return i2c_read_register(address, 0, &data, sizeof(data), TIMEOUT); -} - -# define i2c_start i2c_start_bodge #endif const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { @@ -31,10 +21,9 @@ void do_scan(void) { for (uint8_t address = 1; address < 127; address++) { // The i2c_scanner uses the return value of - // i2c_start to see if a device did acknowledge to the address. - i2c_status_t error = i2c_start(address << 1, TIMEOUT); + // i2c_ping_address to see if a device did acknowledge to the address. + i2c_status_t error = i2c_ping_address(address << 1, TIMEOUT); if (error == I2C_STATUS_SUCCESS) { - i2c_stop(); dprintf(" I2C device found at address 0x%02X\n", address); nDevices++; } else { diff --git a/keyboards/handwired/pterodactyl/matrix.c b/keyboards/handwired/pterodactyl/matrix.c index bc98bdd634..0dff65eda6 100644 --- a/keyboards/handwired/pterodactyl/matrix.c +++ b/keyboards/handwired/pterodactyl/matrix.c @@ -29,9 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define I2C_TIMEOUT 100 -#define I2C_ADDR 0b0100000 -#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE ) -#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ ) +#define I2C_ADDR (0b0100000<<1) #define IODIRA 0x00 // i/o direction register #define IODIRB 0x01 #define GPPUA 0x0C // GPIO pull-up resistor register @@ -159,9 +157,6 @@ void init_expander(void) { #endif } - expander_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(IODIRA, I2C_TIMEOUT); if (expander_status) goto out; - /* Pin direction and pull-up depends on both the diode direction and on whether the column register is GPIOA or GPIOB @@ -176,50 +171,27 @@ void init_expander(void) { #if (EXPANDER_COL_REGISTER == GPIOA) # if (DIODE_DIRECTION == COL2ROW) - expander_status = i2c_write(expander_input_pin_mask, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(0, I2C_TIMEOUT); if (expander_status) goto out; + uint8_t data[] = { expander_input_pin_mask, 0}; # elif (DIODE_DIRECTION == ROW2COL) - expander_status = i2c_write(0, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(expander_input_pin_mask, I2C_TIMEOUT); if (expander_status) goto out; + uint8_t data[] = { 0, expander_input_pin_mask}; # endif #elif (EXPANDER_COL_REGISTER == GPIOB) # if (DIODE_DIRECTION == COL2ROW) - expander_status = i2c_write(0, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(expander_input_pin_mask, I2C_TIMEOUT); if (expander_status) goto out; + uint8_t data[] = { 0, expander_input_pin_mask}; # elif (DIODE_DIRECTION == ROW2COL) - expander_status = i2c_write(expander_input_pin_mask, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(0, I2C_TIMEOUT); if (expander_status) goto out; -# endif -#endif - - i2c_stop(); - - // set pull-up - // - unused : off : 0 - // - input : on : 1 - // - driving : off : 0 - expander_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(GPPUA, I2C_TIMEOUT); if (expander_status) goto out; -#if (EXPANDER_COL_REGISTER == GPIOA) -# if (DIODE_DIRECTION == COL2ROW) - expander_status = i2c_write(expander_input_pin_mask, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(0, I2C_TIMEOUT); if (expander_status) goto out; -# elif (DIODE_DIRECTION == ROW2COL) - expander_status = i2c_write(0, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(expander_input_pin_mask, I2C_TIMEOUT); if (expander_status) goto out; -# endif -#elif (EXPANDER_COL_REGISTER == GPIOB) -# if (DIODE_DIRECTION == COL2ROW) - expander_status = i2c_write(0, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(expander_input_pin_mask, I2C_TIMEOUT); if (expander_status) goto out; -# elif (DIODE_DIRECTION == ROW2COL) - expander_status = i2c_write(expander_input_pin_mask, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(0, I2C_TIMEOUT); if (expander_status) goto out; + uint8_t data[] = { expander_input_pin_mask, 0}; # endif #endif + expander_status = i2c_writeReg(I2C_ADDR, IODIRA, data, sizeof(data), I2C_TIMEOUT); + + if (!expander_status) { + // set pull-up + // - unused : off : 0 + // - input : on : 1 + // - driving : off : 0 + expander_status = i2c_writeReg(I2C_ADDR, GPPUA, data, sizeof(data), I2C_TIMEOUT); + } -out: - i2c_stop(); } uint8_t matrix_scan(void) @@ -332,14 +304,9 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) // Read columns from expander, unless it's in an error state if (! expander_status) { - expander_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(EXPANDER_COL_REGISTER, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_start(I2C_ADDR_READ, I2C_TIMEOUT); if (expander_status) goto out; - - current_matrix[current_row] |= (~i2c_read_nack(I2C_TIMEOUT)) & expander_input_pin_mask; - - out: - i2c_stop(); + uint8_t data; + i2c_readReg(I2C_ADDR, EXPANDER_COL_REGISTER, &data, 1, I2C_TIMEOUT); + current_matrix[current_row] |= (~data) & expander_input_pin_mask; } // Read columns from onboard pins @@ -361,11 +328,8 @@ static void select_row(uint8_t row) { if (! expander_status) { // set active row low : 0 // set other rows hi-Z : 1 - expander_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(EXPANDER_ROW_REGISTER, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(0xFF & ~(1<<row), I2C_TIMEOUT); if (expander_status) goto out; - out: - i2c_stop(); + uint8_t data = 0xFF & ~(1<<row); + i2c_writeReg(I2C_ADDR, EXPANDER_ROW_REGISTER, &data, 1, I2C_TIMEOUT); } // select on teensy @@ -421,14 +385,7 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) return false; } - expander_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_write(EXPANDER_ROW_REGISTER, I2C_TIMEOUT); if (expander_status) goto out; - expander_status = i2c_start(I2C_ADDR_READ, I2C_TIMEOUT); if (expander_status) goto out; - column_state = i2c_read_nack(I2C_TIMEOUT); - - out: - i2c_stop(); - + i2c_writeReg(I2C_ADDR, EXPANDER_ROW_REGISTER, &column_state, 1, I2C_TIMEOUT); column_state = ~column_state; } else { for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { diff --git a/keyboards/hotdox/left.c b/keyboards/hotdox/left.c index 970d36f1b5..f963ecdae7 100644 --- a/keyboards/hotdox/left.c +++ b/keyboards/hotdox/left.c @@ -5,8 +5,8 @@ bool i2c_initialized = false; void left_config(void); -uint8_t left_write(uint8_t reg, uint8_t data); -uint8_t left_read(uint8_t reg, uint8_t *data); +i2c_status_t left_write(uint8_t reg, uint8_t data); +i2c_status_t left_read(uint8_t reg, uint8_t *data); uint8_t init_mcp23017(void) { @@ -35,12 +35,11 @@ void left_init(void) void left_scan(void) { - uint8_t ret = i2c_start(I2C_ADDR_WRITE, HOTDOX_I2C_TIMEOUT); + + i2c_status_t ret = i2c_ping_address(I2C_ADDR, HOTDOX_I2C_TIMEOUT); - if (ret == 0) + if (ret == I2C_STATUS_SUCCESS) { - i2c_stop(); - if (!i2c_initialized) { i2c_initialized = true; @@ -91,40 +90,29 @@ void left_config(void) left_write(MCP23017_B0_GPIOB, 0xC0); } -uint8_t left_write(uint8_t reg, uint8_t data) +i2c_status_t left_write(uint8_t reg, uint8_t data) { if (!i2c_initialized) { return 0; } - uint8_t ret; + i2c_status_t ret; - ret = i2c_start(I2C_ADDR_WRITE, HOTDOX_I2C_TIMEOUT); if (ret) goto out; - ret = i2c_write(reg, HOTDOX_I2C_TIMEOUT); if (ret) goto out; - ret = i2c_write(data, HOTDOX_I2C_TIMEOUT); + ret = i2c_writeReg(I2C_ADDR, reg, &data, sizeof(data), HOTDOX_I2C_TIMEOUT); -out: - i2c_stop(); return ret; } -uint8_t left_read(uint8_t reg, uint8_t *data) +i2c_status_t left_read(uint8_t reg, uint8_t *data) { if (!i2c_initialized) { return 0; } - uint8_t ret = 0; - - ret = i2c_start(I2C_ADDR_WRITE, HOTDOX_I2C_TIMEOUT); if (ret) goto out; - ret = i2c_write(reg, HOTDOX_I2C_TIMEOUT); if (ret) goto out; - ret = i2c_start(I2C_ADDR_READ, HOTDOX_I2C_TIMEOUT); if (ret) goto out; - - *data = i2c_read_nack(HOTDOX_I2C_TIMEOUT); + i2c_status_t ret = 0; + ret = i2c_readReg(I2C_ADDR, reg, data, 1, HOTDOX_I2C_TIMEOUT); -out: - i2c_stop(); return ret; } diff --git a/keyboards/hotdox/left.h b/keyboards/hotdox/left.h index 3d8b5a6ead..32faadba21 100644 --- a/keyboards/hotdox/left.h +++ b/keyboards/hotdox/left.h @@ -10,10 +10,7 @@ #define MCP23017_A1 0 #define MCP23017_A2 0 -#define I2C_ADDR (0x20) -#define I2C_ADDR_WRITE ((I2C_ADDR << 1) | I2C_WRITE) -#define I2C_ADDR_READ ((I2C_ADDR << 1) | I2C_READ) - +#define I2C_ADDR ((0x20) << 1) #define MCP23017_B0_IODIRA 0x00 #define MCP23017_B0_IODIRB 0x01 @@ -40,8 +37,6 @@ #define HOTDOX_I2C_TIMEOUT 100 -typedef int16_t i2c_status_t; - void left_init(void); void left_scan(void); diff --git a/keyboards/ingrained/matrix.c b/keyboards/ingrained/matrix.c index 154a275d7a..3ba9d8dcf3 100644 --- a/keyboards/ingrained/matrix.c +++ b/keyboards/ingrained/matrix.c @@ -41,9 +41,7 @@ extern i2c_status_t mcp23017_status; // All address pins of the mcp23017 are connected to the ground on the ferris // | 0 | 1 | 0 | 0 | A2 | A1 | A0 | // | 0 | 1 | 0 | 0 | 0 | 0 | 0 | -#define I2C_ADDR 0b0100000 -#define I2C_ADDR_WRITE ((I2C_ADDR << 1) | I2C_WRITE) -#define I2C_ADDR_READ ((I2C_ADDR << 1) | I2C_READ) +#define I2C_ADDR (0b0100000<<1) // Register addresses // See https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/Adafruit_MCP23017.h @@ -77,7 +75,7 @@ uint8_t init_mcp23017(void) { // This means: we will read all the bits on GPIOA // This means: we will write to the pins 0-4 on GPIOB (in select_rows) uint8_t buf[] = {IODIRA, 0b11111111, 0b11110000}; - mcp23017_status = i2c_transmit(I2C_ADDR_WRITE, buf, sizeof(buf), I2C_TIMEOUT); + mcp23017_status = i2c_transmit(I2C_ADDR, buf, sizeof(buf), I2C_TIMEOUT); if (!mcp23017_status) { // set pull-up // - unused : on : 1 @@ -86,7 +84,7 @@ uint8_t init_mcp23017(void) { // This means: we will read all the bits on GPIOA // This means: we will write to the pins 0-4 on GPIOB (in select_rows) uint8_t pullup_buf[] = {GPPUA, 0b11111111, 0b11110000}; - mcp23017_status = i2c_transmit(I2C_ADDR_WRITE, pullup_buf, sizeof(pullup_buf), I2C_TIMEOUT); + mcp23017_status = i2c_transmit(I2C_ADDR, pullup_buf, sizeof(pullup_buf), I2C_TIMEOUT); } return mcp23017_status; } @@ -205,14 +203,14 @@ static matrix_row_t read_cols(uint8_t row) { return 0; } else { uint8_t buf[] = {GPIOA}; - mcp23017_status = i2c_transmit(I2C_ADDR_WRITE, buf, sizeof(buf), I2C_TIMEOUT); + mcp23017_status = i2c_transmit(I2C_ADDR, buf, sizeof(buf), I2C_TIMEOUT); // We read all the pins on GPIOA. // The initial state was all ones and any depressed key at a given column for the currently selected row will have its bit flipped to zero. // The return value is a row as represented in the generic matrix code were the rightmost bits represent the lower columns and zeroes represent non-depressed keys while ones represent depressed keys. // Since the pins connected to eact columns are sequential, and counting from zero up (col 5 -> GPIOA0, col 6 -> GPIOA1 and so on), the only transformation needed is a bitwise not to swap all zeroes and ones. uint8_t data[] = {0}; if (!mcp23017_status) { - mcp23017_status = i2c_receive(I2C_ADDR_READ, data, sizeof(data), I2C_TIMEOUT); + mcp23017_status = i2c_receive(I2C_ADDR, data, sizeof(data), I2C_TIMEOUT); data[0] = ~(data[0]); } return data[0]; @@ -249,7 +247,7 @@ static void select_row(uint8_t row) { // Select the desired row by writing a byte for the entire GPIOB bus where only the bit representing the row we want to select is a zero (write instruction) and every other bit is a one. // Note that the row - MATRIX_ROWS_PER_SIDE reflects the fact that being on the right hand, the columns are numbered from MATRIX_ROWS_PER_SIDE to MATRIX_ROWS, but the pins we want to write to are indexed from zero up on the GPIOB bus. uint8_t buf[] = {GPIOB, 0xFF & ~(1 << (row - MATRIX_ROWS_PER_SIDE))}; - mcp23017_status = i2c_transmit(I2C_ADDR_WRITE, buf, sizeof(buf), I2C_TIMEOUT); + mcp23017_status = i2c_transmit(I2C_ADDR, buf, sizeof(buf), I2C_TIMEOUT); } } } diff --git a/keyboards/kagizaraya/chidori/board.c b/keyboards/kagizaraya/chidori/board.c index 117a4c0127..34e57a8874 100644 --- a/keyboards/kagizaraya/chidori/board.c +++ b/keyboards/kagizaraya/chidori/board.c @@ -124,10 +124,9 @@ static void board_slave_init(void) { if (board_is_master(board)) { continue; } - if (i2c_start(EXPANDER_ADDR(board->i2c_address), BOARD_I2C_TIMEOUT) != I2C_STATUS_SUCCESS) { + if (i2c_ping_address(EXPANDER_ADDR(board->i2c_address), BOARD_I2C_TIMEOUT) != I2C_STATUS_SUCCESS) { continue; } - i2c_stop(); if (board_slave_config(board)) { board->initialized = true; } diff --git a/keyboards/nek_type_a/nek_type_a.h b/keyboards/nek_type_a/nek_type_a.h index dda9e2bdde..fe6fb27a45 100644 --- a/keyboards/nek_type_a/nek_type_a.h +++ b/keyboards/nek_type_a/nek_type_a.h @@ -21,9 +21,7 @@ #include <stdbool.h> #include <util/delay.h> -#define I2C_ADDR 0b0100000 -#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE ) -#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ ) +#define I2C_ADDR (0b0100000<<1) #define IODIRA 0x00 // i/o direction register #define IODIRB 0x01 #define GPPUA 0x0C // GPIO pull-up resistor register diff --git a/keyboards/system76/launch_1/usb_mux.c b/keyboards/system76/launch_1/usb_mux.c index 1c6dd2376e..dd51b7c4b2 100644 --- a/keyboards/system76/launch_1/usb_mux.c +++ b/keyboards/system76/launch_1/usb_mux.c @@ -77,51 +77,14 @@ i2c_status_t usb7206_read_reg(struct USB7206* self, uint32_t addr, uint8_t* data return status; } - uint8_t read[2] = { - 0x00, // Buffer address MSB: always 0 - 0x06, // Buffer address LSB: 6 to skip header - }; - - status = i2c_start((self->addr << 1) | I2C_WRITE, I2C_TIMEOUT); - if (status >= 0) { - for (uint16_t i = 0; i < sizeof(read); i++) { - status = i2c_write(read[i], I2C_TIMEOUT); - if (status < 0) { - goto error; - } - } - } else { - goto error; - } - - status = i2c_start((self->addr << 1) | I2C_READ, I2C_TIMEOUT); - if (status < 0) { - goto error; - } - - // Read and ignore buffer length - status = i2c_read_ack(I2C_TIMEOUT); - if (status < 0) { - goto error; - } + uint16_t read = 0x0006; // Buffer address 6 to skip header + uint8_t data_with_buffer_length[length]; + status = i2c_readReg16((self->addr << 1), read, data_with_buffer_length, length, I2C_TIMEOUT); for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) { - status = i2c_read_ack(I2C_TIMEOUT); - if (status >= 0) { - data[i] = (uint8_t)status; - } + data[i] = data_with_buffer_length[i+1]; } - if (status >= 0) { - status = i2c_read_nack(I2C_TIMEOUT); - if (status >= 0) { - data[(length - 1)] = (uint8_t)status; - } - } - -error: - i2c_stop(); - return (status < 0) ? status : length; } @@ -160,35 +123,21 @@ i2c_status_t usb7206_write_reg(struct USB7206* self, uint32_t addr, uint8_t* dat (uint8_t)(addr >> 8), // Register address byte 1 (uint8_t)(addr >> 0), // Register address byte 0 }; + uint8_t send_buffer_length = sizeof(register_write) + length; + uint8_t send_buffer[send_buffer_length]; + uint8_t j = 0; - status = i2c_start((self->addr << 1) | I2C_WRITE, I2C_TIMEOUT); - if (status >= 0) { - for (uint16_t i = 0; i < sizeof(register_write); i++) { - status = i2c_write(register_write[i], I2C_TIMEOUT); - if (status < 0) { - goto error; - } - } + for (uint16_t i = 0; i < sizeof(register_write); i++) { + send_buffer[j++] = register_write[i]; + } - for (uint16_t i = 0; i < length; i++) { - status = i2c_write(data[i], I2C_TIMEOUT); - if (status < 0) { - goto error; - } - } - } else { - goto error; + for (uint16_t i = 0; i < length; i++) { + send_buffer[j++] = data[i]; } - i2c_stop(); + status = i2c_transmit((self->addr << 1), send_buffer, send_buffer_length, I2C_TIMEOUT); status = usb7206_register_access(self); - if (status < 0) { - goto error; - } - -error: - i2c_stop(); return (status < 0) ? status : length; } diff --git a/keyboards/ymdk/sp64/matrix.c b/keyboards/ymdk/sp64/matrix.c index b5f0e10462..6f8c7962eb 100644 --- a/keyboards/ymdk/sp64/matrix.c +++ b/keyboards/ymdk/sp64/matrix.c @@ -114,7 +114,7 @@ uint8_t matrix_scan(void) #ifdef RIGHT_HALF uint8_t data = 0x7F; // Receive the columns from right half - i2c_receive(I2C_ADDR_WRITE, &data, 1, MCP23018_I2C_TIMEOUT); + i2c_receive(I2C_ADDR, &data, 1, MCP23018_I2C_TIMEOUT); cols |= ((~(data) & 0x7F) << 7); #endif @@ -162,7 +162,7 @@ static void matrix_select_row(uint8_t row) //Set the remote row on port A txdata[0] = GPIOA; txdata[1] = 0xFF & ~(1<<row); - mcp23018_status = i2c_transmit(I2C_ADDR_WRITE, (uint8_t *)txdata, 2, MCP23018_I2C_TIMEOUT); + mcp23018_status = i2c_transmit(I2C_ADDR, (uint8_t *)txdata, 2, MCP23018_I2C_TIMEOUT); #endif // select other half diff --git a/keyboards/ymdk/sp64/sp64.c b/keyboards/ymdk/sp64/sp64.c index 12f2577713..e9f30d91f9 100644 --- a/keyboards/ymdk/sp64/sp64.c +++ b/keyboards/ymdk/sp64/sp64.c @@ -39,7 +39,7 @@ uint8_t init_mcp23018(void) data[0] = IODIRA; data[1] = 0b00000000; data[2] = 0b11111111; - mcp23018_status = i2c_transmit(I2C_ADDR_WRITE, (uint8_t *)data, 3, MCP23018_I2C_TIMEOUT); + mcp23018_status = i2c_transmit(I2C_ADDR, (uint8_t *)data, 3, MCP23018_I2C_TIMEOUT); if (mcp23018_status != I2C_STATUS_SUCCESS) goto out; @@ -50,7 +50,7 @@ uint8_t init_mcp23018(void) data[0] = GPPUA; data[1] = 0b00000000; data[2] = 0b11111111; - mcp23018_status = i2c_transmit(I2C_ADDR_WRITE, (uint8_t *)data, 3, MCP23018_I2C_TIMEOUT); + mcp23018_status = i2c_transmit(I2C_ADDR, (uint8_t *)data, 3, MCP23018_I2C_TIMEOUT); if (mcp23018_status != I2C_STATUS_SUCCESS) goto out; @@ -61,7 +61,7 @@ uint8_t init_mcp23018(void) data[0] = OLATA; data[1] = 0b11111111; data[2] = 0b11111111; - mcp23018_status = i2c_transmit(I2C_ADDR_WRITE, (uint8_t *)data, 3, MCP23018_I2C_TIMEOUT); + mcp23018_status = i2c_transmit(I2C_ADDR, (uint8_t *)data, 3, MCP23018_I2C_TIMEOUT); out: return (mcp23018_status); diff --git a/keyboards/ymdk/sp64/sp64.h b/keyboards/ymdk/sp64/sp64.h index afad36ee9a..0e3e3c38b8 100644 --- a/keyboards/ymdk/sp64/sp64.h +++ b/keyboards/ymdk/sp64/sp64.h @@ -23,9 +23,7 @@ # include "i2c_master.h" // I2C aliases and register addresses (see "mcp23018.md") -# define I2C_ADDR 0b0100000 -# define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE ) -# define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ ) +# define I2C_ADDR (0b0100000<<1) # define IODIRA 0x00 // i/o direction register # define IODIRB 0x01 # define GPPUA 0x0C // GPIO pull-up resistor register 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); diff --git a/platforms/chibios/drivers/i2c_master.c b/platforms/chibios/drivers/i2c_master.c index 5ee2738e6d..ad11d850dd 100644 --- a/platforms/chibios/drivers/i2c_master.c +++ b/platforms/chibios/drivers/i2c_master.c @@ -1,5 +1,6 @@ /* Copyright 2018 Jack Humbert * Copyright 2018 Yiancar + * Copyright 2023 customMK * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -90,8 +91,6 @@ # endif #endif -static uint8_t i2c_address; - static const I2CConfig i2cconfig = { #if defined(USE_I2CV1_CONTRIB) I2C1_CLOCK_SPEED, @@ -125,7 +124,7 @@ static i2c_status_t i2c_epilogue(const msg_t status) { // From ChibiOS HAL: "After a timeout the driver must be stopped and // restarted because the bus is in an uncertain state." We also issue that // hard stop in case of any error. - i2c_stop(); + i2cStop(&I2C_DRIVER); return status == MSG_TIMEOUT ? I2C_STATUS_TIMEOUT : I2C_STATUS_ERROR; } @@ -150,28 +149,19 @@ __attribute__((weak)) void i2c_init(void) { } } -i2c_status_t i2c_start(uint8_t address) { - i2c_address = address; - i2cStart(&I2C_DRIVER, &i2cconfig); - return I2C_STATUS_SUCCESS; -} - i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_address = address; i2cStart(&I2C_DRIVER, &i2cconfig); - msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, TIME_MS2I(timeout)); + msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (address >> 1), data, length, 0, 0, TIME_MS2I(timeout)); return i2c_epilogue(status); } i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_address = address; i2cStart(&I2C_DRIVER, &i2cconfig); - msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, TIME_MS2I(timeout)); + msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (address >> 1), data, length, TIME_MS2I(timeout)); return i2c_epilogue(status); } i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_address = devaddr; i2cStart(&I2C_DRIVER, &i2cconfig); uint8_t complete_packet[length + 1]; @@ -180,12 +170,11 @@ i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, const uint8_t* } complete_packet[0] = regaddr; - msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, TIME_MS2I(timeout)); + msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (devaddr >> 1), complete_packet, length + 1, 0, 0, TIME_MS2I(timeout)); return i2c_epilogue(status); } i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_address = devaddr; i2cStart(&I2C_DRIVER, &i2cconfig); uint8_t complete_packet[length + 2]; @@ -195,25 +184,27 @@ i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, const uint8 complete_packet[0] = regaddr >> 8; complete_packet[1] = regaddr & 0xFF; - msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 2, 0, 0, TIME_MS2I(timeout)); + msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (devaddr >> 1), complete_packet, length + 2, 0, 0, TIME_MS2I(timeout)); return i2c_epilogue(status); } i2c_status_t i2c_read_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_address = devaddr; i2cStart(&I2C_DRIVER, &i2cconfig); - msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), ®addr, 1, data, length, TIME_MS2I(timeout)); + msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (devaddr >> 1), ®addr, 1, data, length, TIME_MS2I(timeout)); return i2c_epilogue(status); } i2c_status_t i2c_read_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_address = devaddr; i2cStart(&I2C_DRIVER, &i2cconfig); uint8_t register_packet[2] = {regaddr >> 8, regaddr & 0xFF}; - msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), register_packet, 2, data, length, TIME_MS2I(timeout)); + msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (devaddr >> 1), register_packet, 2, data, length, TIME_MS2I(timeout)); return i2c_epilogue(status); } -void i2c_stop(void) { - i2cStop(&I2C_DRIVER); -} +__attribute__((weak)) i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout) { + // ChibiOS does not provide low level enough control to check for an ack. + // Best effort instead tries reading register 0 which will either succeed or timeout. + // This approach may produce false negative results for I2C devices that do not respond to a register 0 read request. + uint8_t data = 0; + return i2c_readReg(address, 0, &data, sizeof(data), timeout); +}
\ No newline at end of file diff --git a/platforms/chibios/drivers/i2c_master.h b/platforms/chibios/drivers/i2c_master.h index 5f16367831..132ffd14c0 100644 --- a/platforms/chibios/drivers/i2c_master.h +++ b/platforms/chibios/drivers/i2c_master.h @@ -40,11 +40,10 @@ typedef int16_t i2c_status_t; #define I2C_STATUS_TIMEOUT (-2) void i2c_init(void); -i2c_status_t i2c_start(uint8_t address); i2c_status_t i2c_transmit(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); |