NAK in CAN when programming stm32f407vg uC

ccanlogic analyzerstm32f4

I am getting NAK error in CAN communication. Not really sure why, also frame itself is quite strange as in program I am sending different things. I have got two devices and therefore I monitor 4 logical pins:

  1. Device first (first and second logical view) CAN1 Tx(1) and Rx(2)

  2. Device second CAN2 Tx(3) and CAN2 Rx(4)

A screenshot from saleae of two frames is shown below:

two frames different errors

First frame in zoom looks like:
Error frame

It's the first frame in zoom. I get error as CAN2 keeps high state all the time.

Second frame (and all later) in zoom looks like:
enter image description here

The thing in last on CAN1 Tx is NAK and on CAN1 Rx and CAN2 Rx is ACK. In zoom:

enter image description here

what I want to do in fact is:

  • Run CAN at 100kB/s
  • CAN1 and 2 sends the same message (CAN2 in fact does not send anything as CAN1 and CAN2 sends the same thing)
  • I want to send/receive 8 bytes of data(for the time being it can be anything)

And the code responsible for setting the CAN is :

CAN_InitTypeDef canInit;
RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE); //enable clock

CAN_DeInit(CANx);

/* CAN cell init */
canInit.CAN_TTCM = DISABLE;
canInit.CAN_ABOM = DISABLE;
canInit.CAN_AWUM = DISABLE;
canInit.CAN_NART = DISABLE; //retransmission
canInit.CAN_RFLM = DISABLE;
canInit.CAN_TXFP = DISABLE;
canInit.CAN_Mode = CAN_Mode_Normal;
canInit.CAN_SJW = CAN_SJW_1tq;

/* CAN Baudrate = 100 kBps (CAN clocked at 42 MHz(168MHz / 4)) */
canInit.CAN_BS1 = CAN_BS1_11tq;
canInit.CAN_BS2 = CAN_BS2_8tq;
canInit.CAN_Prescaler = 21; // 42MHz/21 | 2MHz/(11+8+1)
CAN_Init(CANx, &canInit); //CANx == CAN2

/* CAN filter init */
CAN_FilterInitTypeDef  canFilterInit;
canFilterInit.CAN_FilterNumber = 0;
canFilterInit.CAN_FilterMode = CAN_FilterMode_IdMask;
canFilterInit.CAN_FilterScale = CAN_FilterScale_32bit;
canFilterInit.CAN_FilterIdHigh = 0x0000;
canFilterInit.CAN_FilterIdLow = 0x0000;
canFilterInit.CAN_FilterMaskIdHigh = 0x0000;
canFilterInit.CAN_FilterMaskIdLow = 0x0000;
canFilterInit.CAN_FilterFIFOAssignment = 0;
canFilterInit.CAN_FilterActivation = DISABLE; //do not use filter at all
CAN_FilterInit(&canFilterInit);

/* Enable FIFO 0 message pending Interrupt */
CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);

Frame is as follows:

sendMessage.StdId = 0x7FF;
sendMessage.ExtId = 0x1FFFFFFF;
sendMessage.RTR = CAN_RTR_Data;
sendMessage.IDE = CAN_Id_Extended;
sendMessage.DLC = 8;

for(int dataByte=0; dataByte<8; dataByte++){
  sendMessage.Data[dataByte] = 0xFF;
}

strongDelay();

while(1){   
    CAN_Transmit(CAN2, &sendMessage);
}

I do not know what kind of information should else be provided, but what I see:

  • Id is completely different from the one, that I want to send
  • Frame is interpreted as RTR, but should be as DATA frame
  • Some of the bits are wrong as you can see them crossed out in the program
  • Frequency is just like the one I wanted (so it's not random thing, that is being send)
  • It rather is not caused by noise in connections (pseudo analog view seems ok)
  • transciever and other stuff should be ok, because it was bought as ready to go CAN boards.

Any help would be apprecieated, as I am running out of ideas what should I change.

Best Answer

So, what I did wrong was the fact, that I have forgotten to initialize RCC for CAN1, as it is always needed, when initializing CAN2