From a522b1f15627c69f94cbc814968be5a63519b8e3 Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 16 Jan 2024 13:26:40 +1100 Subject: i2c: rename read/write register functions (#22905) --- docs/i2c_driver.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'docs/i2c_driver.md') diff --git a/docs/i2c_driver.md b/docs/i2c_driver.md index faff0a1d7b..2457e8e7b9 100644 --- a/docs/i2c_driver.md +++ b/docs/i2c_driver.md @@ -197,11 +197,11 @@ Receive multiple bytes from the selected I2C device. --- -### `i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` :id=api-i2c-writereg +### `i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` :id=api-i2c-write-register Writes to a register with an 8-bit address on the I2C device. -#### Arguments :id=api-i2c-writereg-arguments +#### Arguments :id=api-i2c-write-register-arguments - `uint8_t devaddr` The 7-bit I2C address of the device. @@ -214,17 +214,17 @@ Writes to a register with an 8-bit address on the I2C device. - `uint16_t timeout` The time in milliseconds to wait for a response from the target device. -#### Return Value :id=api-i2c-writereg-return +#### Return Value :id=api-i2c-write-register-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_writeReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` :id=api-i2c-writereg16 +### `i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` :id=api-i2c-write-register16 Writes to a register with a 16-bit address (big endian) on the I2C device. -#### Arguments :id=api-i2c-writereg16-arguments +#### Arguments :id=api-i2c-write-register16-arguments - `uint8_t devaddr` The 7-bit I2C address of the device. @@ -237,17 +237,17 @@ Writes to a register with a 16-bit address (big endian) on the I2C device. - `uint16_t timeout` The time in milliseconds to wait for a response from the target device. -#### Return Value :id=api-i2c-writereg16-return +#### Return Value :id=api-i2c-write-register16-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_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` :id=api-i2c-readreg +### `i2c_status_t i2c_read_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` :id=api-i2c-read-register Reads from a register with an 8-bit address on the I2C device. -#### Arguments :id=api-i2c-readreg-arguments +#### Arguments :id=api-i2c-read-register-arguments - `uint8_t devaddr` The 7-bit I2C address of the device. @@ -258,17 +258,17 @@ Reads from a register with an 8-bit address on the I2C device. - `uint16_t timeout` The time in milliseconds to wait for a response from the target device. -#### Return Value :id=api-i2c-readreg-return +#### Return Value :id=api-i2c-read-register-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_readReg16(uint8_t devaddr, uint16_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)` :id=api-i2c-read-register16 Reads from a register with a 16-bit address (big endian) on the I2C device. -#### Arguments :id=api-i2c-readreg16-arguments +#### Arguments :id=api-i2c-read-register16-arguments - `uint8_t devaddr` The 7-bit I2C address of the device. @@ -279,7 +279,7 @@ Reads from a register with a 16-bit address (big endian) on the I2C device. - `uint16_t timeout` The time in milliseconds to wait for a response from the target device. -#### Return Value :id=api-i2c-readreg16-return +#### Return Value :id=api-i2c-read-register16-return `I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`. -- cgit v1.2.3 From e9bd7d7ad308f9c72c86863bf9f19382c7e2d892 Mon Sep 17 00:00:00 2001 From: David Hoelscher Date: Wed, 17 Jan 2024 07:05:38 -0600 Subject: I2C driver cleanup (#21273) * remove i2c_start and i2c_stop from i2c drivers * remove static i2c_address variable from chibios i2c driver --- docs/i2c_driver.md | 36 +++++----- docs/ja/i2c_driver.md | 3 +- drivers/gpio/pca9505.c | 2 - drivers/gpio/pca9555.c | 2 - drivers/oled/oled_driver.c | 7 +- drivers/painter/comms/qp_comms_i2c.c | 8 +-- drivers/sensors/cirque_pinnacle_i2c.c | 2 - .../keymaps/default_pimoroni/pimoroni_trackball.c | 4 +- .../keymaps/default_pimoroni/pimoroni_trackball.h | 4 +- keyboards/bajjak/bajjak.c | 47 ++++-------- keyboards/bajjak/bajjak.h | 4 +- keyboards/bajjak/matrix.c | 16 ++--- keyboards/dc01/left/matrix.c | 36 ++-------- keyboards/ergodox_ez/ergodox_ez.c | 51 ++++--------- keyboards/ergodox_ez/ergodox_ez.h | 4 +- keyboards/ergodox_ez/led_i2c.c | 27 ++++--- keyboards/ergodox_ez/matrix.c | 17 ++--- keyboards/ferris/0_2/matrix.c | 24 +++---- keyboards/gboards/ergotaco/ergotaco.c | 28 +++----- keyboards/gboards/ergotaco/ergotaco.h | 5 +- keyboards/gboards/ergotaco/matrix.c | 18 ++--- keyboards/gboards/georgi/georgi.c | 26 +++---- keyboards/gboards/georgi/georgi.h | 5 +- keyboards/gboards/georgi/matrix.c | 17 ++--- keyboards/gboards/gergo/gergo.c | 24 +++---- keyboards/gboards/gergo/gergo.h | 5 +- keyboards/gboards/gergo/matrix.c | 20 ++---- keyboards/gboards/gergoplex/gergoplex.c | 34 +++------ keyboards/gboards/gergoplex/gergoplex.h | 4 +- keyboards/gboards/gergoplex/matrix.c | 28 +++----- keyboards/handwired/d48/ds1307.c | 1 - keyboards/handwired/frenchdev/frenchdev.c | 27 +++---- keyboards/handwired/frenchdev/frenchdev.h | 4 +- keyboards/handwired/frenchdev/matrix.c | 28 +++----- .../handwired/onekey/keymaps/i2c_scanner/keymap.c | 15 +--- keyboards/handwired/pterodactyl/matrix.c | 83 ++++++---------------- keyboards/hotdox/left.c | 34 +++------ keyboards/hotdox/left.h | 7 +- keyboards/ingrained/matrix.c | 14 ++-- keyboards/kagizaraya/chidori/board.c | 3 +- keyboards/nek_type_a/nek_type_a.h | 4 +- keyboards/system76/launch_1/usb_mux.c | 77 ++++---------------- keyboards/ymdk/sp64/matrix.c | 4 +- keyboards/ymdk/sp64/sp64.c | 6 +- keyboards/ymdk/sp64/sp64.h | 4 +- platforms/avr/drivers/i2c_master.c | 31 ++++++-- platforms/avr/drivers/i2c_master.h | 7 +- platforms/chibios/drivers/i2c_master.c | 39 ++++------ platforms/chibios/drivers/i2c_master.h | 3 +- 49 files changed, 288 insertions(+), 611 deletions(-) (limited to 'docs/i2c_driver.md') 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<. #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 . #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 . # 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<> 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 // 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<. #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< 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 #include -#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<= 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); -- cgit v1.2.3 From b8646bc40bd616167da150f6da4eda372f7de23d Mon Sep 17 00:00:00 2001 From: Ryan Date: Sat, 17 Feb 2024 00:18:26 +1100 Subject: Update naming convention for GPIO control macros (#23085) --- docs/custom_quantum_functions.md | 10 +++++----- docs/feature_led_indicators.md | 12 ++++++------ docs/gpio_control.md | 38 +++++++++++++++++++------------------- docs/i2c_driver.md | 4 ++-- platforms/arm_atsam/gpio.h | 24 ++++++++++++------------ platforms/avr/gpio.h | 22 +++++++++++----------- platforms/chibios/gpio.h | 34 +++++++++++++++++----------------- platforms/gpio.h | 19 ++++++++++++++++++- quantum/encoder/tests/mock.c | 4 ++-- quantum/encoder/tests/mock.h | 8 ++++---- quantum/encoder/tests/mock_split.c | 4 ++-- quantum/encoder/tests/mock_split.h | 8 ++++---- 12 files changed, 102 insertions(+), 85 deletions(-) (limited to 'docs/i2c_driver.md') diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md index 957633837c..bc3b28bbba 100644 --- a/docs/custom_quantum_functions.md +++ b/docs/custom_quantum_functions.md @@ -119,11 +119,11 @@ void keyboard_pre_init_user(void) { // Call the keyboard pre init code. // Set our LED pins as output - setPinOutput(B0); - setPinOutput(B1); - setPinOutput(B2); - setPinOutput(B3); - setPinOutput(B4); + gpio_set_pin_output(B0); + gpio_set_pin_output(B1); + gpio_set_pin_output(B2); + gpio_set_pin_output(B3); + gpio_set_pin_output(B4); } ``` diff --git a/docs/feature_led_indicators.md b/docs/feature_led_indicators.md index 1f71cdb1c8..b35a174490 100644 --- a/docs/feature_led_indicators.md +++ b/docs/feature_led_indicators.md @@ -56,16 +56,16 @@ This is a template indicator function that can be implemented on keyboard level bool led_update_kb(led_t led_state) { bool res = led_update_user(led_state); if(res) { - // writePin sets the pin high for 1 and low for 0. + // gpio_write_pin sets the pin high for 1 and low for 0. // In this example the pins are inverted, setting // it low/0 turns it on, and high/1 turns the LED off. // This behavior depends on whether the LED is between the pin // and VCC or the pin and GND. - writePin(B0, !led_state.num_lock); - writePin(B1, !led_state.caps_lock); - writePin(B2, !led_state.scroll_lock); - writePin(B3, !led_state.compose); - writePin(B4, !led_state.kana); + gpio_write_pin(B0, !led_state.num_lock); + gpio_write_pin(B1, !led_state.caps_lock); + gpio_write_pin(B2, !led_state.scroll_lock); + gpio_write_pin(B3, !led_state.compose); + gpio_write_pin(B4, !led_state.kana); } return res; } diff --git a/docs/gpio_control.md b/docs/gpio_control.md index 12413dfc8e..90798fc87b 100644 --- a/docs/gpio_control.md +++ b/docs/gpio_control.md @@ -2,29 +2,29 @@ QMK has a GPIO control abstraction layer which is microcontroller agnostic. This is done to allow easy access to pin control across different platforms. -## Functions :id=functions - -The following functions provide basic control of GPIOs and are found in `platforms//gpio.h`. - -| Function | Description | Old AVR Examples | Old ChibiOS/ARM Examples | -|------------------------------|-----------------------------------------------------|-------------------------------------------------|--------------------------------------------------| -| `setPinInput(pin)` | Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` | -| `setPinInputHigh(pin)` | Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` | -| `setPinInputLow(pin)` | Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` | -| `setPinOutput(pin)` | Set pin as output (alias of `setPinOutputPushPull`) | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | -| `setPinOutputPushPull(pin)` | Set pin as output, push/pull mode | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | -| `setPinOutputOpenDrain(pin)` | Set pin as output, open-drain mode | N/A (Not implemented on AVR) | `palSetLineMode(pin, PAL_MODE_OUTPUT_OPENDRAIN)` | -| `writePinHigh(pin)` | Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` | -| `writePinLow(pin)` | Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` | -| `writePin(pin, level)` | Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` | -| `readPin(pin)` | Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` | -| `togglePin(pin)` | Invert pin level, assuming it is an output | `PORTB ^= (1<<2)` | `palToggleLine(pin)` | +## Macros :id=macros + +The following macros provide basic control of GPIOs and are found in `platforms//gpio.h`. + +|Macro |Description | +|-------------------------------------|---------------------------------------------------------------------| +|`gpio_set_pin_input(pin)` |Set pin as input with high impedance (High-Z) | +|`gpio_set_pin_input_high(pin)` |Set pin as input with builtin pull-up resistor | +|`gpio_set_pin_input_low(pin)` |Set pin as input with builtin pull-down resistor (unavailable on AVR)| +|`gpio_set_pin_output(pin)` |Set pin as output (alias of `gpio_set_pin_output_push_pull`) | +|`gpio_set_pin_output_push_pull(pin)` |Set pin as output, push/pull mode | +|`gpio_set_pin_output_open_drain(pin)`|Set pin as output, open-drain mode (unavailable on AVR and ATSAM) | +|`gpio_write_pin_high(pin)` |Set pin level as high, assuming it is an output | +|`gpio_write_pin_low(pin)` |Set pin level as low, assuming it is an output | +|`gpio_write_pin(pin, level)` |Set pin level, assuming it is an output | +|`gpio_read_pin(pin)` |Returns the level of the pin | +|`gpio_toggle_pin(pin)` |Invert pin level, assuming it is an output | ## Advanced Settings :id=advanced-settings -Each microcontroller can have multiple advanced settings regarding its GPIO. This abstraction layer does not limit the use of architecture-specific functions. Advanced users should consult the datasheet of their desired device and include any needed libraries. For AVR, the standard avr/io.h library is used; for STM32, the ChibiOS [PAL library](https://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used. +Each microcontroller can have multiple advanced settings regarding its GPIO. This abstraction layer does not limit the use of architecture-specific functions. Advanced users should consult the datasheet of their desired device. For AVR, the standard `avr/io.h` library is used; for STM32, the ChibiOS [PAL library](https://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used. -## Atomic Operation +## Atomic Operation :id=atomic-operation The above functions are not always guaranteed to work atomically. Therefore, if you want to prevent interruptions in the middle of operations when using multiple combinations of the above functions, use the following `ATOMIC_BLOCK_FORCEON` macro. diff --git a/docs/i2c_driver.md b/docs/i2c_driver.md index 868715a62c..9a3c08b90b 100644 --- a/docs/i2c_driver.md +++ b/docs/i2c_driver.md @@ -127,8 +127,8 @@ This function is weakly defined, meaning it can be overridden if necessary for y ```c void i2c_init(void) { - setPinInput(B6); // Try releasing special pins for a short time - setPinInput(B7); + gpio_set_pin_input(B6); // Try releasing special pins for a short time + gpio_set_pin_input(B7); wait_ms(10); // Wait for the release to happen palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B6 to I2C function diff --git a/platforms/arm_atsam/gpio.h b/platforms/arm_atsam/gpio.h index a42aaff54d..fd8caeab0b 100644 --- a/platforms/arm_atsam/gpio.h +++ b/platforms/arm_atsam/gpio.h @@ -15,7 +15,7 @@ */ #pragma once -#include "stdint.h" +#include #include "samd51j18a.h" #include "pin_defs.h" @@ -26,13 +26,13 @@ typedef uint8_t pin_t; #define SAMD_PIN(pin) ((pin)&0x1f) #define SAMD_PIN_MASK(pin) (1 << ((pin)&0x1f)) -#define setPinInput(pin) \ +#define gpio_set_pin_input(pin) \ do { \ PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.INEN = 1; \ PORT->Group[SAMD_PORT(pin)].DIRCLR.reg = SAMD_PIN_MASK(pin); \ } while (0) -#define setPinInputHigh(pin) \ +#define gpio_set_pin_input_high(pin) \ do { \ PORT->Group[SAMD_PORT(pin)].DIRCLR.reg = SAMD_PIN_MASK(pin); \ PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \ @@ -40,7 +40,7 @@ typedef uint8_t pin_t; PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.PULLEN = 1; \ } while (0) -#define setPinInputLow(pin) \ +#define gpio_set_pin_input_low(pin) \ do { \ PORT->Group[SAMD_PORT(pin)].DIRCLR.reg = SAMD_PIN_MASK(pin); \ PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \ @@ -48,27 +48,27 @@ typedef uint8_t pin_t; PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.PULLEN = 1; \ } while (0) -#define setPinOutputPushPull(pin) \ +#define gpio_set_pin_output_push_pull(pin) \ do { \ PORT->Group[SAMD_PORT(pin)].DIRSET.reg = SAMD_PIN_MASK(pin); \ PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \ } while (0) -#define setPinOutputOpenDrain(pin) _Static_assert(0, "arm_atsam platform does not implement an open-drain output") +#define gpio_set_pin_output_open_drain(pin) _Static_assert(0, "Open-drain outputs are not available on ATSAM") -#define setPinOutput(pin) setPinOutputPushPull(pin) +#define gpio_set_pin_output(pin) gpio_set_pin_output_push_pull(pin) -#define writePinHigh(pin) \ +#define gpio_write_pin_high(pin) \ do { \ PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \ } while (0) -#define writePinLow(pin) \ +#define gpio_write_pin_low(pin) \ do { \ PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \ } while (0) -#define writePin(pin, level) \ +#define gpio_write_pin(pin, level) \ do { \ if (level) \ PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \ @@ -76,6 +76,6 @@ typedef uint8_t pin_t; PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \ } while (0) -#define readPin(pin) ((PORT->Group[SAMD_PORT(pin)].IN.reg & SAMD_PIN_MASK(pin)) != 0) +#define gpio_read_pin(pin) ((PORT->Group[SAMD_PORT(pin)].IN.reg & SAMD_PIN_MASK(pin)) != 0) -#define togglePin(pin) (PORT->Group[SAMD_PORT(pin)].OUTTGL.reg = SAMD_PIN_MASK(pin)) +#define gpio_toggle_pin(pin) (PORT->Group[SAMD_PORT(pin)].OUTTGL.reg = SAMD_PIN_MASK(pin)) diff --git a/platforms/avr/gpio.h b/platforms/avr/gpio.h index 95f15c28dc..6f089bc663 100644 --- a/platforms/avr/gpio.h +++ b/platforms/avr/gpio.h @@ -22,17 +22,17 @@ typedef uint8_t pin_t; /* Operation of GPIO by pin. */ -#define setPinInput(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) -#define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) -#define setPinInputLow(pin) _Static_assert(0, "AVR processors cannot implement an input as pull low") -#define setPinOutputPushPull(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF)) -#define setPinOutputOpenDrain(pin) _Static_assert(0, "AVR platform does not implement an open-drain output") -#define setPinOutput(pin) setPinOutputPushPull(pin) +#define gpio_set_pin_input(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) +#define gpio_set_pin_input_high(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) +#define gpio_set_pin_input_low(pin) _Static_assert(0, "GPIO pulldowns in input mode are not available on AVR") +#define gpio_set_pin_output_push_pull(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF)) +#define gpio_set_pin_output_open_drain(pin) _Static_assert(0, "Open-drain outputs are not available on AVR") +#define gpio_set_pin_output(pin) gpio_set_pin_output_push_pull(pin) -#define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) -#define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) -#define writePin(pin, level) ((level) ? writePinHigh(pin) : writePinLow(pin)) +#define gpio_write_pin_high(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) +#define gpio_write_pin_low(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) +#define gpio_write_pin(pin, level) ((level) ? gpio_write_pin_high(pin) : gpio_write_pin_low(pin)) -#define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF))) +#define gpio_read_pin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF))) -#define togglePin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF)) +#define gpio_toggle_pin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF)) diff --git a/platforms/chibios/gpio.h b/platforms/chibios/gpio.h index 80551abac5..a8d6554f29 100644 --- a/platforms/chibios/gpio.h +++ b/platforms/chibios/gpio.h @@ -22,24 +22,24 @@ typedef ioline_t pin_t; /* Operation of GPIO by pin. */ -#define setPinInput(pin) palSetLineMode((pin), PAL_MODE_INPUT) -#define setPinInputHigh(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLUP) -#define setPinInputLow(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLDOWN) -#define setPinOutputPushPull(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_PUSHPULL) -#define setPinOutputOpenDrain(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_OPENDRAIN) -#define setPinOutput(pin) setPinOutputPushPull(pin) +#define gpio_set_pin_input(pin) palSetLineMode((pin), PAL_MODE_INPUT) +#define gpio_set_pin_input_high(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLUP) +#define gpio_set_pin_input_low(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLDOWN) +#define gpio_set_pin_output_push_pull(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_PUSHPULL) +#define gpio_set_pin_output_open_drain(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_OPENDRAIN) +#define gpio_set_pin_output(pin) gpio_set_pin_output_push_pull(pin) -#define writePinHigh(pin) palSetLine(pin) -#define writePinLow(pin) palClearLine(pin) -#define writePin(pin, level) \ - do { \ - if (level) { \ - writePinHigh(pin); \ - } else { \ - writePinLow(pin); \ - } \ +#define gpio_write_pin_high(pin) palSetLine(pin) +#define gpio_write_pin_low(pin) palClearLine(pin) +#define gpio_write_pin(pin, level) \ + do { \ + if (level) { \ + gpio_write_pin_high(pin); \ + } else { \ + gpio_write_pin_low(pin); \ + } \ } while (0) -#define readPin(pin) palReadLine(pin) +#define gpio_read_pin(pin) palReadLine(pin) -#define togglePin(pin) palToggleLine(pin) +#define gpio_toggle_pin(pin) palToggleLine(pin) diff --git a/platforms/gpio.h b/platforms/gpio.h index b47f6f8e43..6a87e75b01 100644 --- a/platforms/gpio.h +++ b/platforms/gpio.h @@ -19,4 +19,21 @@ #if __has_include_next("gpio.h") # include_next "gpio.h" /* Include the platforms gpio.h */ -#endif \ No newline at end of file +#endif + +// ======== DEPRECATED DEFINES - DO NOT USE ======== + +#define setPinInput(pin) gpio_set_pin_input(pin) +#define setPinInputHigh(pin) gpio_set_pin_input_high(pin) +#define setPinInputLow(pin) gpio_set_pin_input_low(pin) +#define setPinOutputPushPull(pin) gpio_set_pin_output_push_pull(pin) +#define setPinOutputOpenDrain(pin) gpio_set_pin_output_open_drain(pin) +#define setPinOutput(pin) gpio_set_pin_output_push_pull(pin) + +#define writePinHigh(pin) gpio_write_pin_high(pin) +#define writePinLow(pin) gpio_write_pin_low(pin) +#define writePin(pin, level) gpio_write_pin(pin, level) + +#define readPin(pin) gpio_read_pin(pin) + +#define togglePin(pin) gpio_toggle_pin(pin) diff --git a/quantum/encoder/tests/mock.c b/quantum/encoder/tests/mock.c index 61f2f8294d..1524e61ca4 100644 --- a/quantum/encoder/tests/mock.c +++ b/quantum/encoder/tests/mock.c @@ -19,14 +19,14 @@ bool pins[32] = {0}; bool pinIsInputHigh[32] = {0}; -uint8_t mockSetPinInputHigh(pin_t pin) { +uint8_t mock_set_pin_input_high(pin_t pin) { // dprintf("Setting pin %d input high.", pin); pins[pin] = true; pinIsInputHigh[pin] = true; return 0; } -bool mockReadPin(pin_t pin) { +bool mock_read_pin(pin_t pin) { return pins[pin]; } diff --git a/quantum/encoder/tests/mock.h b/quantum/encoder/tests/mock.h index 80c336b5ef..28774b82ab 100644 --- a/quantum/encoder/tests/mock.h +++ b/quantum/encoder/tests/mock.h @@ -24,11 +24,11 @@ typedef uint8_t pin_t; extern bool pins[]; extern bool pinIsInputHigh[]; -#define setPinInputHigh(pin) (mockSetPinInputHigh(pin)) -#define readPin(pin) (mockReadPin(pin)) +#define gpio_set_pin_input_high(pin) (mock_set_pin_input_high(pin)) +#define gpio_read_pin(pin) (mock_read_pin(pin)) -uint8_t mockSetPinInputHigh(pin_t pin); +uint8_t mock_set_pin_input_high(pin_t pin); -bool mockReadPin(pin_t pin); +bool mock_read_pin(pin_t pin); bool setPin(pin_t pin, bool val); diff --git a/quantum/encoder/tests/mock_split.c b/quantum/encoder/tests/mock_split.c index 5cc6cd19e1..f024c2058d 100644 --- a/quantum/encoder/tests/mock_split.c +++ b/quantum/encoder/tests/mock_split.c @@ -19,14 +19,14 @@ bool pins[32] = {0}; bool pinIsInputHigh[32] = {0}; -uint8_t mockSetPinInputHigh(pin_t pin) { +uint8_t mock_set_pin_input_high(pin_t pin) { // dprintf("Setting pin %d input high.", pin); pins[pin] = true; pinIsInputHigh[pin] = true; return 0; } -bool mockReadPin(pin_t pin) { +bool mock_read_pin(pin_t pin) { return pins[pin]; } diff --git a/quantum/encoder/tests/mock_split.h b/quantum/encoder/tests/mock_split.h index 2fc12f1830..8b4a141078 100644 --- a/quantum/encoder/tests/mock_split.h +++ b/quantum/encoder/tests/mock_split.h @@ -28,11 +28,11 @@ void encoder_update_raw(uint8_t* slave_state); extern bool pins[]; extern bool pinIsInputHigh[]; -#define setPinInputHigh(pin) (mockSetPinInputHigh(pin)) -#define readPin(pin) (mockReadPin(pin)) +#define gpio_set_pin_input_high(pin) (mock_set_pin_input_high(pin)) +#define gpio_read_pin(pin) (mock_read_pin(pin)) -uint8_t mockSetPinInputHigh(pin_t pin); +uint8_t mock_set_pin_input_high(pin_t pin); -bool mockReadPin(pin_t pin); +bool mock_read_pin(pin_t pin); bool setPin(pin_t pin, bool val); -- cgit v1.2.3