Как правильно отслеживать ситуацию?
В прерываниях реагирую на следующие события:
CAN->IER |= CAN_IER_FMPIE0 | CAN_IER_BOFIE | CAN_IER_ERRIE | CAN_IER_FOVIE0 | CAN_IER_LECIE;
Делаю CAN->MCR |= CAN_MCR_ABOM — ничего не получается, прерывания по ошибке вызываются настолько часто, что МК просто не успевает что-либо еще сделать, в итоге отрубается вотчдогом. Хотя, этот флаг должен был бы через 127 ошибок дернуть соответствующее прерывание — не дергает.
Если сделать CAN->MCR |= CAN_MCR_NART, то сообщения не повторяются, однако, обработчик прерываний опять зацикливается.
Вот такой обработчик:
void cec_can_isr(){
uint32_t CAN_ReceiveMessage = 0;
last_err_code = 0;
MSG("CAN->MSR: ");
printu(CAN->MSR); newline();
if(CAN->RF0R & CAN_RF0R_FOVR0){ // FIFO overrun
MSG("fifo overrun\n");
CAN->RF0R &= ~CAN_RF0R_FOVR0;
}
if(CAN->RF0R & CAN_RF0R_FMP0){ /* check if a message is filtered and received by FIFO 0 */
LED_on(LED1); // Toggle LED1
MSG("Receive, RDTR=");
printu(CAN->sFIFOMailBox[0].RDTR);
newline();
// need 2 check bit CAN_RI0R_RTR ini CAN_RIxR
// RDTR: (16-31) - timestamp, (8-15) - filter match index, (0-3) - data length
if(1 == (CAN->sFIFOMailBox[0].RDTR & 0xf))
CAN_ReceiveMessage = CAN->sFIFOMailBox[0].RDLR; /* read data */
CAN->RF0R |= CAN_RF0R_RFOM0; /* release FIFO */
if((CAN_ReceiveMessage & 0xFF) == CMD_TOGGLE){
CAN_flags |= CAN_FLAG_GOTDUMMY;
}
}
//if(CAN->ESR){ // Error
if(CAN->MSR & CAN_MSR_ERRI){
CAN->MSR &= ~CAN_MSR_ERRI;
// CAN_IER_BOFIE | CAN_IER_ERRIE | CAN_IER_LECIE | CAN_IER_FOVIE0 | CAN_IER_FMPIE0
// count errors: errctr = (CAN->ESR & CAN_ESR_REC) >> 24;
// Least significant byte of the 9-bit transmit error counter tec = (CAN->ESR & CAN_ESR_TEC) >> 16;
last_err_code = CAN->ESR; //(CAN->ESR & CAN_ESR_LEC) >> 4;
CAN->ESR = 0;
MSG("CAN->ESR was: ");
printu(last_err_code);
SEND(", become: ");
printu(CAN->ESR);
newline();
//CAN_ESR_BOFF; CAN_ESR_EPVF; CAN_ESR_EWGF;
}
}Если запретить прерывания по CAN_IER_LECIE, то ничего не происходит: сообщение бесконечно повторяется, прерывания по ошибке нет.