@ -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 ) , & regaddr , 1 , data , length , TIME_MS2I ( timeout ) ) ;
msg_t status = i2cMasterTransmitTimeout ( & I2C_DRIVER , ( devaddr > > 1 ) , & regaddr , 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 ) ;
}