2018-02-17 1:09 AM
I have a problem with STM32F042 CAN Filter mechanism. Basically the CAN is working. I can send and receive messages. But my filter are passing more messages to the FIFO as defined. This is leading to an overrun.Proved by the status bits. I carefully read the register in the reference manual and can not find what I am doing wrong. Here is my code
void initCAN(void){
RCC->APB1ENR|=RCC_APB1ENR_CANEN; // enable CAN clk
CAN->MCR |= CAN_MCR_INRQ; // Enter CAN init mode to write the configuration
while ((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { // Wait the init mode entering
/* add time out here for a robust application */
}
CAN->MCR &=~ CAN_MCR_SLEEP; // Exit sleep mode
CAN->BTR &= ~CAN_BTR_TS1_0; // reset Bit0 and Bit1
CAN->BTR &= ~CAN_BTR_TS1_1;
CAN->BTR &= ~CAN_BTR_TS2_1; // reset Bit 1 in TS2
CAN->BTR |= 0x1 << 20 | 0x4 << 16 | 0x02F << 0; // set timing to 125kb/s@75%: BS1 = 5, BS2 = 2, prescaler = 48
CAN->MCR &=~ CAN_MCR_INRQ; // Leave init mode
while ((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) // Wait the init mode leaving
{
/* add time out here for a robust application */
}
CAN->FMR |= CAN_FMR_FINIT;// enter Filter init mode
CAN->FA1R &= ~(uint32_t)(CAN_FA1R_FACT0|CAN_FA1R_FACT1); // deactivate filter 0 and 1
CAN->FS1R|=CAN_FS1R_FSC0; // Teo single 32 bit register on filterbank 0
CAN->sFilterRegister[0].FR1 = (uint32_t)(13)<<21 ; // only IDs with stdID 13 should pass
CAN->sFilterRegister[0].FR2 = (uint32_t)(14)<<21;// only IDs with stdID 14 should pass
CAN->FM1R |= CAN_FM1R_FBM0; // Filterbank 0 in ID List mode
CAN->FFA1R|=0x03;// route Filteroutput 0 and 1 to FIFO 1
CAN->FA1R |= CAN_FA1R_FACT0|CAN_FA1R_FACT1; // activate Filter 0 and 1
CAN->FMR &=~ CAN_FMR_FINIT; // leave filterinit mode
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
#stm32f042can #can-filter #can-init
2018-02-18 6:25 AM
Not sure I'm up for grinding through the bit level settings.
To filter 13 (0x0D) and 14 (0x0E)
{
CAN_FilterInitTypeDef CAN_FilterInitStructure; /* CAN filter configuration */ CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // FIFO = 0 CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // Filter mode = identifier mask based filtering CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;/* Filter 0x00D */
CAN_FilterInitStructure.CAN_FilterNumber = 0; // CAN 1 [0..13] CAN 2 [14..27] CAN_FilterInitStructure.CAN_FilterIdHigh = 0x00D << 5; //11-bit ID in top bits CAN_FilterInitStructure.CAN_FilterIdLow = 0; CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x7FF << 5; CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0; CAN_FilterInit(&CAN_FilterInitStructure);/* Filter 0x00E */
CAN_FilterInitStructure.CAN_FilterNumber = 1; // CAN 1 [0..13] CAN 2 [14..27] CAN_FilterInitStructure.CAN_FilterIdHigh = 0x00E << 5; //11-bit ID in top bits CAN_FilterInitStructure.CAN_FilterIdLow = 0; CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x7FF << 5; CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0; CAN_FilterInit(&CAN_FilterInitStructure);}2018-02-18 3:35 PM
if you enable the interrupts, you can stack the receieved frames into a LOOKUPTABLE....
void CEC_CAN_IRQHandler(void) {
/* USER CODE BEGIN CEC_CAN_IRQn 0 */ CAN_IRQFlag = true; checkCanRxFifos(); /* USER CODE END CEC_CAN_IRQn 0 */ HAL_CAN_IRQHandler(&hcan); /* USER CODE BEGIN CEC_CAN_IRQn 1 *//* USER CODE END CEC_CAN_IRQn 1 */
}void checkCanRxFifos(void) {
int readCanBytecount; char canFifo1FullFlag = CAN->RF1R & CAN_RF1R_FMP1; if (canFifo1FullFlag) { { readCanBytecount = (CAN->sFIFOMailBox[1].RDTR & 0x0f);canRxMsgBottomWord[canRxMsgIN] = CAN->sFIFOMailBox[1].RDLR;
canRxMsgTopWord[canRxMsgIN] = CAN->sFIFOMailBox[1].RDHR;canRxMsgID[canRxMsgIN] = CAN->sFIFOMailBox[1].RIR >> 21;
CAN->RF1R |= CAN_RF1R_RFOM1; // release FIFOcanRxMsgLength[canRxMsgIN] = readCanBytecount;
canRxMsgIN++;
canRxMsgIN &= 0x3F; // 64 entries only canRxMsgTableEMPTY = false; if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true; } CAN->IER |= CAN_IER_FMPIE1; // (11) Set FIFO1 message pending IT enable }char canFifo0FullFlag = CAN->RF0R & CAN_RF0R_FMP0;
if (canFifo0FullFlag) { { readCanBytecount = (CAN->sFIFOMailBox[0].RDTR & 0x0f);canRxMsgBottomWord[canRxMsgIN] = CAN->sFIFOMailBox[0].RDLR;
canRxMsgTopWord[canRxMsgIN] = CAN->sFIFOMailBox[0].RDHR;uint32_t canRxmsgID = CAN->sFIFOMailBox[0].RIR >> 21;
CAN->RF0R |= CAN_RF0R_RFOM0; // release FIFOif(canRxMsgTableFULL) {
canRxMsgTableOverflow = true; // now dump new frame... }else { canRxMsgID[canRxMsgIN] = canRxmsgID; canRxMsgLength[canRxMsgIN] = readCanBytecount; // to signify FIFO0 canRxMsgIN++; canRxMsgIN &= 0x3F; // 64 entries only canRxMsgTableEMPTY = false; if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true; } //length = sprintf(string + length,'%08X, %08X :W',canFifoBuf.d32[0],canFifoBuf.d32[1]); // for( int i = 0; i < readCanBytecount; i++){ // canRxBuffer[canRxpointerIN++] = canFifoBuf.d8[i]; // canRxpointerIN &= 0xFF; // if (canRxpointerIN == canRxpointerOUT ) CanRxbufferOverrun = true; // //length += sprintf(string + length,'%02X, ',canFifoBuf.d8[i]); // } //sprintf(string + length -2,'\n\r'); // remove 2 bytes, the last comma and space } CAN->IER |= CAN_IER_FMPIE0; // (11) Set FIFO1 message pending IT enable } // if (length >0) puts(string);}
2018-02-19 1:22 AM
You seem to be confusing the filter banks with the filters themselves. In your configuration (32 bit ID list mode) filter bank 0 (CAN->sFilterRegister[0]) stores two ID filters. Therefore you need to enable filter bank 0 only, and not enable filter bank 1, which is why you get undesired frames now.