Использование операторов для операций I2c

У меня есть контроллер STM32F2 и устройство FRAM FM24V10-G, подключенное к нему через I2C. Обычно для связи с устройствами I2C я использую библиотеку, основанную на libopencm3. Однако использование FRAM требует немного другого порядка действий I2C (например, отправка начала, 7-битный адрес и т. Д.), То есть я не могу использовать стандартные библиотечные функции, такие как чтение и запись, которые помогли мне с другими устройствами I2C. В этой библиотеке I2C реализован как класс, и в нем есть перегруженные операторы потоков для отправки этих команд I2C в нужном порядке.

Например:

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;
}

Иногда некоторые из этих команд не выполняются, в результате чего процессор ожидает некоторый флаг (как в случае Wait_End), останавливая работу всей системы.

Итак, вот мой вопрос: есть ли способ вернуть какой-нибудь флаг тайм-аута в коде выше? Для меня очень важно, чтобы система работала постоянно, просто пропустив одну команду, если операция I2C не удалась и истекло время ожидания, все в порядке.

Спасибо всем, кто читает это!

1 ответ

Решение

Вы можете сделать очень простой тайм-аут, как это:

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 Переменная вы должны использовать аппаратные таймеры.

Другие вопросы по тегам