KE is built with the 'older, simpler' MsCAN peripheral, which I am familiar with only as from the Star08 parts. You should be able to 'clear' (by set) that flag once you have read the top entry. My RxISR there was this, to copy from the hardware FIFO to a software FIFO (and unscramble the ID bits on an 8bit CPU without the single-cycle barrel-shifter):
| typedef union{ | //Byte/DWord duality, big-endian |
struct{
| uint8_t hi; |
| uint8_t mhi; |
| uint8_t mlo; |
| uint8_t lo; |
} u8;
struct {
}u16;
uint32_t u32;
}u32u8_t;
typedef struct
{
u32u8_t id;
uint8_t buf[8];
uint8_t buf_len;
} can_t;
void can_rx_isr ( void ) {
u32u8_t tmp;
can_t volatile *ptr;
/* If the buffer is full, don't read message */
if( can_buf_rx_cnt < CAN_BUF_RX_SIZE ) {
/* Mark we have one more in the buffer */
can_buf_rx_cnt++;
/* Get pointer to the next open index */
ptr = &can_buf_rx[ can_buf_rx_head ];
/* Move on to next index in buffer */
if( ++can_buf_rx_head >= CAN_BUF_RX_SIZE )
can_buf_rx_head = 0;
/* Is it extended frame? */
/* Is it extended frame? */
if( CANRIDR1_IDE ) {
/* Re-Pack extended frame id.
The 31st bit signifies it's extended */
//First build it shifted << 1
tmp.u8.hi = (CANRIDR0 >> 2);
tmp.u8.mhi = ((CANRIDR0 & 0x03)<<6) //Squeeze out the IDE and SRR bits
| ((CANRIDR1 & CANRIDR1_ID_18_MASK) >> 2) // by shifting IDR0 and IDR1 bits 2
| (CANRIDR1 & CANRIDR1_ID_15_MASK);
tmp.u8.mlo = CANRIDR2;
tmp.u8.lo = CANRIDR3;
tmp.u32 >>= 1; //Finally, lop-off RTR from the LSB
tmp.u8.hi |= 0x80;
ptr->id.u8.lo = tmp.u8.lo;
ptr->id.u8.mlo = tmp.u8.mlo;
ptr->id.u8.mhi = tmp.u8.mhi;
ptr->id.u8.hi = tmp.u8.hi;
} else {
/* Get standard frame id */
ptr->id.u32 = ((u32_t)CANRIDR0 << (8-CANRIDR1_ID_18_BITNUM))
| (CANRIDR1 >> CANRIDR1_ID_18_BITNUM);
}
/* Load data */
ptr->buf[0] = CANRDSR0;
ptr->buf[1] = CANRDSR1;
ptr->buf[2] = CANRDSR2;
ptr->buf[3] = CANRDSR3;
ptr->buf[4] = CANRDSR4;
ptr->buf[5] = CANRDSR5;
ptr->buf[6] = CANRDSR6;
ptr->buf[7] = CANRDSR7;
/* Get data length code (DLC) */
ptr->buf_len = CANRDLR & CANRDLR_DLC_MASK;
}
/* Clear rx interrupt */
CANRFLG = CANRFLG_RXF_MASK;
return;
}
One other thing!!! DO NOT |= this MSCAN_CANRFLG register!!!! You will 'clear' ANY other 'active' indication therein all at the same time (in this case, I suppose, just the 'overrun' flag):
Write: Anytime when not in initialization mode, except
RSTAT[1:0] and TSTAT[1:0] flags which are read-only; write
of 1 clears flag; write of 0 is ignored.