static uint8_t i2c_address;
-// This configures the I2C clock to 400khz assuming a 72Mhz clock
-// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
static const I2CConfig i2cconfig = {
- STM32_TIMINGR_PRESC(15U) |
- STM32_TIMINGR_SCLDEL(4U) | STM32_TIMINGR_SDADEL(2U) |
- STM32_TIMINGR_SCLH(15U) | STM32_TIMINGR_SCLL(21U),
+ STM32_TIMINGR_PRESC(I2C1_TIMINGR_PRESC) |
+ STM32_TIMINGR_SCLDEL(I2C1_TIMINGR_SCLDEL) | STM32_TIMINGR_SDADEL(I2C1_TIMINGR_SDADEL) |
+ STM32_TIMINGR_SCLH(I2C1_TIMINGR_SCLH) | STM32_TIMINGR_SCLL(I2C1_TIMINGR_SCLL),
0,
0
};
+static i2c_status_t chibios_to_qmk(const msg_t* status) {
+ switch (*status) {
+ case I2C_NO_ERROR:
+ return I2C_STATUS_SUCCESS;
+ case I2C_TIMEOUT:
+ return I2C_STATUS_TIMEOUT;
+ // I2C_BUS_ERROR, I2C_ARBITRATION_LOST, I2C_ACK_FAILURE, I2C_OVERRUN, I2C_PEC_ERROR, I2C_SMB_ALERT
+ default:
+ return I2C_STATUS_ERROR;
+ }
+}
+
__attribute__ ((weak))
void i2c_init(void)
{
// Try releasing special pins for a short time
- palSetPadMode(I2C1_BANK, I2C1_SCL, PAL_MODE_INPUT);
- palSetPadMode(I2C1_BANK, I2C1_SDA, PAL_MODE_INPUT);
+ palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_INPUT);
+ palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_INPUT);
chThdSleepMilliseconds(10);
- palSetPadMode(I2C1_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN);
- palSetPadMode(I2C1_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN);
+ palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(I2C1_SCL_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
+ palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(I2C1_SDA_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
//i2cInit(); //This is invoked by halInit() so no need to redo it.
}
-// This is usually not needed
-uint8_t i2c_start(uint8_t address)
+i2c_status_t i2c_start(uint8_t address)
{
i2c_address = address;
i2cStart(&I2C_DRIVER, &i2cconfig);
- return 0;
+ return I2C_STATUS_SUCCESS;
}
-uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)
+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);
- return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, MS2ST(timeout));
+ msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, MS2ST(timeout));
+ return chibios_to_qmk(&status);
}
-uint8_t i2c_receive(uint8_t address, 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_address = address;
i2cStart(&I2C_DRIVER, &i2cconfig);
- return i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, MS2ST(timeout));
+ msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, MS2ST(timeout));
+ return chibios_to_qmk(&status);
}
-uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
+i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout)
{
i2c_address = devaddr;
i2cStart(&I2C_DRIVER, &i2cconfig);
}
complete_packet[0] = regaddr;
- return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout));
+ msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout));
+ return chibios_to_qmk(&status);
}
-uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
+i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
{
i2c_address = devaddr;
i2cStart(&I2C_DRIVER, &i2cconfig);
- return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), regaddr, 1, data, length, MS2ST(timeout));
+ msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), regaddr, 1, data, length, MS2ST(timeout));
+ return chibios_to_qmk(&status);
}
-// This is usually not needed. It releases the driver to allow pins to become GPIO again.
-uint8_t i2c_stop(uint16_t timeout)
+void i2c_stop(void)
{
i2cStop(&I2C_DRIVER);
- return 0;
}