3

I have a STM32F2 controller and a FRAM device FM24V10-G connected to it via I2C. Usually, in order to communicate with I2C devices I use a library, based on libopencm3. However, using FRAM requires a slightly different order of I2C actions(like sending start, 7 bit address, etc), meaning I can't use standard library functions like read and write, which helped me with other I2C devices. In this library I2C is implemented as a class, and it has stream operators overloaded in order to send those I2C commands in a desired order.

For example:

I2c& I2c::operator<< (operation_t operation)
{
    switch (operation) {
        case Start:
            i2c_send_start(_reg);
            while (!checkEvent(SR2(I2C_SR2_BUSY | I2C_SR2_MSL) | I2C_SR1_SB));
            break;
        case Stop:
            i2c_send_stop(_reg);
            break;
        case Wait_End:
            while (!checkEvent(I2C_SR1_TxE));
            break;
    return *this;
}

Sometimes, some of these commands fail to be executed, resulting in the CPU waiting for some flag(like in case of Wait_End), stopping the whole system from functioning.

So here's my question: Is there a way to return some kind of a timeout flag in the code above? For me, it's crucial to have the system functioning at all times, just skipping one command if the I2C operation fails and reaches timeout is OK.

Thanks to everyone who is reading this!

4

1 回答 1

2

你可以像这样做一个非常基本的超时:

I2c& I2c::operator<< (operation_t operation)
{
    int count = 0;
    const int TIMEOUT = 4242;
    switch (operation) {
        case Start:
            i2c_send_start(_reg);
            while (!checkEvent(SR2(I2C_SR2_BUSY | I2C_SR2_MSL) | I2C_SR1_SB) 
                    && count != TIMEOUT) {
                count++;
            }
            break;
        case Stop:
            i2c_send_stop(_reg);
            break;
        case Wait_End:
            while (!checkEvent(I2C_SR1_TxE) && count != TIMEOUT) {
                count++;
            }
            break;
    }
    if (count == TIMEOUT) {
        //error handling
        return -1;
    }
    return *this;
}

当然,如果您需要准确的超时并且不想浪费处理时间来增加count变量,您应该使用硬件计时器。

于 2013-11-23T01:22:59.937 回答