diff options
Diffstat (limited to 'platforms/chibios/drivers/i2c_master.c')
-rw-r--r-- | platforms/chibios/drivers/i2c_master.c | 47 |
1 files changed, 19 insertions, 28 deletions
diff --git a/platforms/chibios/drivers/i2c_master.c b/platforms/chibios/drivers/i2c_master.c index 7c49f9d005..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_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_address = devaddr; +i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) { i2cStart(&I2C_DRIVER, &i2cconfig); uint8_t complete_packet[length + 1]; @@ -180,12 +170,11 @@ i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, } 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_writeReg16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_address = devaddr; +i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) { i2cStart(&I2C_DRIVER, &i2cconfig); uint8_t complete_packet[length + 2]; @@ -195,25 +184,27 @@ i2c_status_t i2c_writeReg16(uint8_t devaddr, uint16_t regaddr, const uint8_t* da 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_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_address = devaddr; +i2c_status_t i2c_read_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { 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_readReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_address = devaddr; +i2c_status_t i2c_read_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { 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 |