Page 1 of 1

CAN High Level Driver States

Posted: Tue Feb 23, 2016 10:17 am
by neums
Hi,
in the documentation of the CAN driver's state machine are transitions from CAN_STARTING and READY to itselfs by calling canStart(). In code it is an illegal call/transition due to osalDbgAssert

Code: Select all

void canStart(CANDriver *canp, const CANConfig *config) {

  osalDbgCheck(canp != NULL);

  osalSysLock();
  osalDbgAssert(canp->state == CAN_STOP, "invalid state");

Is this a bug?
Thanks

Re: CAN High Level Driver States

Posted: Tue Feb 23, 2016 11:00 am
by Giovanni
Hi,

It looks like a bug, I will look into it, queued for next release.

Giovanni

Re: CAN High Level Driver States

Posted: Tue Feb 23, 2016 11:55 am
by neums
Hi,
thanks for your help.
How i can restart the CAN when it is gone into BUS OFF without using the automatic bus off management (ABOM)?
I know that i can stop and start it again. But in the context where i want to restart it the CANConfig structure is not available due to my software structure. May it is a good feature to have a function which just restarts the driver or writes the RESET bit in MCR? So the configuration is unaffected but the CAN gets reset.

Thanks

Re: CAN High Level Driver States

Posted: Tue Feb 23, 2016 12:06 pm
by Giovanni
Hi,

All drivers keep a pointer to the configuration structure internally, do not assume that the structure is no more required after starting the driver, some drivers could incidentally work but the structure is supposed to be persistent.

Giovanni

Re: CAN High Level Driver States

Posted: Tue Feb 23, 2016 12:49 pm
by neums
So a restart can be done with

Code: Select all

canStart(&CAND1,&CAND1->config)

where the reset bit is set in the mcr register of the config structure?

Re: CAN High Level Driver States

Posted: Tue Feb 23, 2016 2:17 pm
by Giovanni
canStart reinitializes the CAN controller, see INRQ bit in the STM32 RM, then MCR is initialized again.

Giovanni

Re: CAN High Level Driver States

Posted: Tue Feb 23, 2016 2:37 pm
by neums
OK that is the first way. But why not reset the CAN controller with an procedure like this:

Code: Select all

// clear all transmit mailboxes
canp->can->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2;
// reset CAN controller by setting the RESET BIT which is cleared again by hardware
canp->can->MCR |= CAN_MCR_RESET;

In this procedure the CANConfig structure is not needed because of the canStart call. So the user can reset the CAN controller in case of CAN High-Low short without the availability of the CANConfig structure which is required by canStart.

Re: CAN High Level Driver States

Posted: Tue Feb 23, 2016 4:04 pm
by Giovanni
To be placed where?

Giovanni

Re: CAN High Level Driver States

Posted: Tue Feb 23, 2016 4:16 pm
by neums
Something like this in the LLD:

Code: Select all

void can_lld_reset_controller(CANDriver *canp) {
// clear all transmit mailboxes
canp->can->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2;
// reset CAN controller by setting the RESET BIT which is cleared again by hardware
canp->can->MCR |= CAN_MCR_RESET;
}

and this in HLD:

Code: Select all

void canResetController(CANDriver *canp) {
  osalDbgCheck(canp != NULL);

  osalSysLock();
  osalDbgAssert((canp->state == CAN_STOP) || (canp->state == CAN_READY),
                "invalid state");

  can_lld_reset_can_controller(canp);

  osalSysUnlock();
}


And if it makes sence an I-class function to reset the controller from the error callback.

Re: CAN High Level Driver States

Posted: Sun Jan 06, 2019 5:09 pm
by Giovanni
Moving topic.

Giovanni