По непонятной причине портится последний байт при чтении данных из устройства (I2C FRAM).
Процедура чтения, запускающая обмен по прерываниям:
Код
//buf - буфер чтения, len - сколько байт читать
if (len>1) {
*AT91C_TWI_CR = AT91C_TWI_START;
*AT91C_TWI_IER = AT91C_TWI_RXRDY | AT91C_TWI_NACK | AT91C_TWI_OVRE;
}
else {
*AT91C_TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
*AT91C_TWI_IER = AT91C_TWI_TXCOMP;
}
WAIT(semaphore, timeout); //ждать окончания приёма
Обработчик прерывания TWI; показано только чтение, обработка ошибок убрана:
Код
void TWI_ISRHandler() {
unsigned int status;
status = *AT91C_TWI_SR; //маска событий
status &= *AT91C_TWI_IMR;
*AT91C_AIC_IVR = 0; /* Debug variant of vector read (protect mode is used) */
*AT91C_AIC_ICCR = 1<<AT91C_ID_TWI; /* Clear TWI interrupt */
if (status&AT91C_TWI_TXCOMP) { //STOP передан, дождаться последнего байта
*AT91C_TWI_IDR = 0xFFFFFFFF;
*AT91C_TWI_IER = AT91C_TWI_RXRDY;
}
if (status&AT91C_TWI_RXRDY) { //принят байт
char n = *AT91C_TWI_RHR; //очистить приемник, снять RXRDY
*buf++ = n; //записать принятый байт в буфер
if (len>1) {
if (--len==1) { //принят предпоследний байт - послать STOP и принять последний байт
*AT91C_TWI_IDR = 0xFFFFFFFF;
*AT91C_TWI_CR = AT91C_TWI_STOP;
*AT91C_TWI_IER = AT91C_TWI_TXCOMP;
}
}
else { //принят последний байт
*AT91C_TWI_IDR = 0xFFFFFFFF;
SIGNAL(semaphore); //завершить чтение, вернуть управление вызывающей процедуре
}
}
*AT91C_AIC_EOICR = 0; /* Signal end of interrupt */
}
Если читаю из уст-ва один байт, ошибок нет. Если несколько - последний байт считывается неверно. Посоветуйте, как с этим бороться?