CAN High Level Driver States

Use this forum for requesting small changes in ChibiOS. Large changes should be discussed in the development forum. This forum is NOT for support.
neums
Posts: 137
Joined: Fri May 08, 2015 1:09 pm
Location: Dresden, Germany
Has thanked: 10 times
Been thanked: 5 times

CAN High Level Driver States

Postby neums » Tue Feb 23, 2016 10:17 am

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

User avatar
Giovanni
Site Admin
Posts: 12166
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 566 times
Been thanked: 487 times
Contact:

Re: CAN High Level Driver States

Postby Giovanni » Tue Feb 23, 2016 11:00 am

Hi,

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

Giovanni

neums
Posts: 137
Joined: Fri May 08, 2015 1:09 pm
Location: Dresden, Germany
Has thanked: 10 times
Been thanked: 5 times

Re: CAN High Level Driver States

Postby neums » Tue Feb 23, 2016 11:55 am

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

User avatar
Giovanni
Site Admin
Posts: 12166
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 566 times
Been thanked: 487 times
Contact:

Re: CAN High Level Driver States

Postby Giovanni » Tue Feb 23, 2016 12:06 pm

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

neums
Posts: 137
Joined: Fri May 08, 2015 1:09 pm
Location: Dresden, Germany
Has thanked: 10 times
Been thanked: 5 times

Re: CAN High Level Driver States

Postby neums » Tue Feb 23, 2016 12:49 pm

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?

User avatar
Giovanni
Site Admin
Posts: 12166
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 566 times
Been thanked: 487 times
Contact:

Re: CAN High Level Driver States

Postby Giovanni » Tue Feb 23, 2016 2:17 pm

canStart reinitializes the CAN controller, see INRQ bit in the STM32 RM, then MCR is initialized again.

Giovanni

neums
Posts: 137
Joined: Fri May 08, 2015 1:09 pm
Location: Dresden, Germany
Has thanked: 10 times
Been thanked: 5 times

Re: CAN High Level Driver States

Postby neums » Tue Feb 23, 2016 2:37 pm

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.

User avatar
Giovanni
Site Admin
Posts: 12166
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 566 times
Been thanked: 487 times
Contact:

Re: CAN High Level Driver States

Postby Giovanni » Tue Feb 23, 2016 4:04 pm

To be placed where?

Giovanni

neums
Posts: 137
Joined: Fri May 08, 2015 1:09 pm
Location: Dresden, Germany
Has thanked: 10 times
Been thanked: 5 times

Re: CAN High Level Driver States

Postby neums » Tue Feb 23, 2016 4:16 pm

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.

User avatar
Giovanni
Site Admin
Posts: 12166
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 566 times
Been thanked: 487 times
Contact:

Re: CAN High Level Driver States

Postby Giovanni » Sun Jan 06, 2019 5:09 pm

Moving topic.

Giovanni


Last bumped by Giovanni on Sun Jan 06, 2019 5:09 pm.


Return to “Small Change Requests”

Who is online

Users browsing this forum: No registered users and 1 guest