cancel
Showing results for 
Search instead for 
Did you mean: 

CAN baud rate change, device is restarting continuously!

ramji
Associate

Facing issue with CAN baud rate change!
1. The Master and slave devices are communicating at baud rate of 1Mbps.
2. If I change the baud rate of Master device to any other baud rate(like, 250kbps, 500kbps,125kbps,50kbps) then master device contiguously restarting the device! Got to know that, it is restarting due to watch dog timer!
3. To resolve the restart issue, added the timeout logic in the while loop where it is entering into intialize mode and normal mode.
4. I gave CAN_TIMEOUT as 1000ms, If I add timeout logic, device is not communicating with slave and data is not exchanging due while timeout logic
5. Tried with different logic by calling HAL_NVIC_SystemReset(); in the timeout logic.

static UINT32 CanFunctin(void)
{
         UINT32 tickstart = 0,tickstart1=0;
        // static UINT32 BaudRateChange=0;
         UINT32 error=0;
// Exit Sleep mode and enter Initialize mode.
CAN1->MCR &= ~CAN_MCR_SLEEP;
CAN1->MCR |= CAN_MCR_INRQ;

        tickstart = FPGA_GET_FRT_UINT32;
// Wait for Initialize mode acknowledge.
while ((CAN1->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
{
          if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
          {
              uint32_t esr = CAN1->ESR;
              printf("Err-CanPortInit: Timeout waiting to enter initi mode\n");
              if (esr & CAN_ESR_BOFF) printf("CanPortInit - Bus-Off condition detected\n");
              if (esr & CAN_ESR_EPVF) printf("CanPortInit - Error Passive mode\n");
              if (esr & CAN_ESR_EWGF) printf("CanPortInit - Error Warning level reached\n");
              return error;
          }
}
CAN1->MCR |= CAN_MCR_ABOM;  // Auto Bus-Off Management
// Initialize Master Control Register.
CAN1->MCR |= MCR_INZ;

// Initialize CAN bit timing.
CAN1->BTR = BTR_INZ | CanBaud[CanBaudRate] | SJW_INZ(CanSjw);
if (CAN1->ESR & CAN_ESR_BOFF)
{
     CAN1->ESR = 0;  // Clear error flags
}
    // Enter Normal mode.
    CAN1->MCR &= ~CAN_MCR_INRQ;
    tickstart1 = FPGA_GET_FRT_UINT32;

// Wait for Normal mode acknowledge.
while ((CAN1->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
 {
          if ((HAL_GetTick() - tickstart1) > CAN_TIMEOUT_VALUE)
          {
              uint32_t esr = CAN1->ESR;
              printf("Err-CanPortInit: Timeout waiting to enter NORMAL mode\n");
              if (esr & CAN_ESR_BOFF) printf("CanPortInit - Bus-Off condition detected\n");
              if (esr & CAN_ESR_EPVF) printf("CanPortInit - Error Passive mode\n");
              if (esr & CAN_ESR_EWGF) printf("CanPortInit - Error Warning level reached\n");
              error=1;
              CAN1->ESR = 0;
              RCC->APB1RSTR |= RCC_APB1RSTR_CAN1RST;
              RCC->APB1RSTR &= ~RCC_APB1RSTR_CAN1RST;
              __NOP(); __NOP(); __NOP();
              HAL_NVIC_SystemReset();
               CAN1->ESR = 0;
              return error;
          }
}
// Enable CAN interrupt sources.
CAN1->IER = IER_INZ;
      return error;
}

Thank you in advance for any suggestions!



3 REPLIES 3
ramji
Associate

Merger thread. Please don't duplicate the same subject on separated threads.

Hello,

I’m using STM32F746 with CAN1 peripheral in Normal mode, and facing an issue during runtime:

  • when the master and slave device communicate at baud rate of 1Mbps and if I change the baud rate of master device to any other baud rate then then gets stuck in a while loop waiting for Normal Mode acknowledgment:

 

// Enter Normal Mode
CAN1->MCR &= ~CAN_MCR_INRQ;
while ((CAN1->MSR & CAN_MSR_INAK) == CAN_MSR_INAK); // stuck here

What I've Done:

  • I perform a software reset before reinitializing CAN:

     
    RCC->APB1RSTR |= RCC_APB1RSTR_CAN1RST;
    RCC->APB1RSTR &= ~RCC_APB1RSTR_CAN1RST;
  • I cleared the BUS-OFF condition manually:

     
    if (CAN1->ESR & CAN_ESR_BOFF)
    { CAN1->ESR = 0; }
  • I enabled auto bus-off recovery:

     
    CAN1->MCR |= CAN_MCR_ABOM;
  • CAN is configured in Normal mode, with filters set and interrupts enabled.

Problem:

After the master changes its baud rate, the STM32 re-initializes, but hangs at the wait for Normal mode acknowledge.

Question:

  • Is there something else needed to recover cleanly from this situation?

  • Do I need to delay or detect bus idle before exiting INIT mode?

  • Any additional register I should clear or sequence to follow?

Any suggestions or official guidance would be appreciated.

mƎALLEm
ST Employee

Hello,

I invite you to use the HAL and do your preliminary tests before using the direct access to the registers.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Ozone
Principal

> Facing issue with CAN baud rate change!

What do you actually mean here ?
CAN does not support a dynamic baudrate change in the network (leaving out CAN-FD and CAN-XL here).

> // Wait for Normal mode acknowledge.

What an acknowledge you are waiting for here ?
Those only come when another node responds to a sent message.

Do you have any node on your network beside the F7 board at all ?
Without another node, it will never work.

if (esr & CAN_ESR_BOFF) printf("CanPortInit - Bus-Off condition detected\n");
if (esr & CAN_ESR_EPVF) printf("CanPortInit - Error Passive mode\n");
if (esr & CAN_ESR_EWGF) printf("CanPortInit - Error Warning level reached\n");
...
HAL_NVIC_SystemReset();

Those CAN errors do NOT require a MCU reset.
Especially if your node is master device (in a CAN-Open context), a MCU reset is not alwaysthe right way to go.
A NMT-Reset is sufficient.