Как правильно отслеживать ситуацию?
В прерываниях реагирую на следующие события:
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, то ничего не происходит: сообщение бесконечно повторяется, прерывания по ошибке нет.