Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не приходят прерывания I2C START после "сна"
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
embddr
Здравствуйте!

Контроллер MSP430F5152 сидит на шине I2C в режиме slave и спит в LPM3. При старте транзакции I2C (мастер - центральный процессор) контроллер просыпается и начинает обмен.

Все работает нормально кроме одного случая - когда в контроллер передается посылка длинной один байт. В этом случае не приходит прерывание "Start condition". Т.е. оно совсем пропускается - первое приходит "Data received", потом "Stop condition" и всё.

При этом, во всех остальных случаях все работает корректно - при посылке больше одного байта, при отключении засыпания и даже если после однобайтной посылки послать Restart (придет первый старт, данные и второй старт).

Код инициализации I2C:
Код
    /* ---- Init I2C in slave mode ---- */
    UCB0CTL1 |= UCSWRST;
    UCB0CTL0 = UCMM | UCMODE_3 | UCSYNC;
    UCB0CTL1 = UCSSEL_3 | UCSWRST;
    UCB0BRW = 12;
    UCB0I2COA = I2C_OWN_ADDRESS;
    UCB0CTL1 &= ~UCSWRST;
    UCB0IE = UCTXIE | UCRXIE | UCSTTIE | UCSTPIE;


Код прерывания:
Код
#pragma vector = USCI_B0_VECTOR
__interrupt void i2c_interrupt(void)
{
        uint8_t rdata;

        switch (__even_in_range(UCB0IV, 12)) {
        case 0: break;      // no interrupt
        case 2: break;      // arbitration lost
        case 4: break;      // not acknowledgement

        /* ---- START Condition ---- */
        case 6:
            if (state == IIC_STATE_STOP)
                state = IIC_STATE_RCMD;
            break;

        /* ---- STOP Condition ---- */
        case 8:
            state = IIC_STATE_STOP;
            break;

        /* ---- Data Received ---- */
        case 10:
            rdata = UCB0RXBUF;

            if (state == IIC_STATE_RCMD) {
                state = IIC_STATE_DATA;
                /* COMMAND handler */
            } else {
                /* DATA handler */
            }
            break;

        /* ---- Transmit Buffer Ready ---- */
        case 12:
            UCB0TXBUF = EMPTY_BYTE;
            break;

        /* ---- UNKNOWN ---- */
        default:
            break;
        }
}


Дополнение:

Контроллер тактируется от внутреннего генератора REFO 32768Гц, ядро от FLL, которая выдает 1МГц.

Описанная проблема возникает в режимах сна LPM2 и ниже (в LPM0 и LPM1 всё работает), т.е. тогда, когда отключается генератор DCO.
Обратно DCO включается, судя по даташиту, за 150мкс (в режиме Low Side). Если учесть, что транзакция сейчас занимает 170мкс, запуск DCO приходится на конец приема байта данных.

Получается, что из-за того, что DCO долго просыпается, контроллер забывает про start condition?
Почему он тогда не забывает про start если передается два байта?

Надо попробовать на более высокой скорости.
SM
Цитата(embddr @ Mar 6 2015, 14:17) *
Почему он тогда не забывает про start если передается два байта?

Что-то мне подсказывает, что с этим надо на e2e идти, или в техподдержку. И наседать на них со страшной силой.
controller_m30
Попробуйте скорость SCL понизить, вместо 60 кГц - например 10 кГц. Или 1 кГц, или 0,1 кГц. И какой будет результат.
Или после посылки Slave-адреса сделать паузу на 150мкс (на стороне Мастера), или 1мс, или 1 сек. - аж пока не заработает прерывание.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.