2019-04-01 02:44 PM
I have a STM32F030C6 on a custom board and I want to use it as an I2C slave device.
With the example given with the cube hal (FW 1.9) I got it working. Kind of.
I can write data from the master to the slave. But I have problems reading data from the device.
I also used this example I found online, because it is mostly what I want
https://github.com/cnoviello/mastering-stm32/blob/master/nucleo-f030R8/src/ch14/main-ex2.c
What I got now is this:
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection,
uint16_t AddrMatchCode) {
if (hi2c->Instance == I2C1 && AddrMatchCode == hi2c->Init.OwnAddress1) {
transferRequested = 1;
transferDirection = TransferDirection;
}
}
void processI2C() {
HAL_I2C_EnableListen_IT(&hi2c1);
if (transferRequested) {
transferRequested = 0;
HAL_I2C_Slave_Sequential_Receive_IT(&hi2c1, i2c_buf, 1,
I2C_FIRST_FRAME);
if (transferDirection == TRANSFER_DIR_READ) {
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
;
// Register is in buffer for all to read
reg = i2c_buf[0];
switch (i2c_buf[0]) {
case GLOBAL_GO: // we read a byte
HAL_I2C_Slave_Sequential_Receive_IT(&hi2c1, i2c_buf, 1,
I2C_LAST_FRAME);
game_running = i2c_buf[1];
break;
case GAME_POINTS:
// do something?
break;
}
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
;
}
if (transferDirection == TRANSFER_DIR_WRITE) {
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_LISTEN)
;
switch (i2c_buf[0]) {
case GAME_POINTS:
// prepare buffer for Point transmission
i2c_buf[0] = game.points.u8[0];
i2c_buf[1] = game.points.u8[1];
i2c_buf[2] = game.points.u8[2];
i2c_buf[3] = game.points.u8[3];
break;
default:
i2c_buf[0] = 0;
i2c_buf[1] = 0;
i2c_buf[2] = 0;
i2c_buf[3] = 0;
}
HAL_I2C_Slave_Sequential_Transmit_IT(&hi2c1, i2c_buf, 4,
I2C_LAST_FRAME);
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
;
}
}
}
Using a master device to write to register GLOBAL_GO works perfectly. But reading Register GAME_POINTS causes the thing to be stuck in Line 11 of the code above with State HAL_I2C_STATE_LISTEN
This causes clock stretching to keep SCL low and everything comes to a halt. Is there a resource where it is shown how read and write is done? Or do I simply miss a little information?
I attached a trace of a working write
and a not working read
2019-04-02 11:21 PM
I used byte wise transfers and they work. To bad HAL does not clearly statzes how to do sequential transfers correctly.