arch/arm/src/samv7: Add ability for CAN BUS_OFF autorecovery according ISO11898-1:2015. With this change we added an ioctl for triggering the autorecovery sequence for BUS_OFF to the CAN-driver and the SAMV7 low-level driver. According the datasheet: If the device goes Bus_Off, it will set MCAN_CCCR.INIT of its own accord, stopping all bus activities. Once MCAN_CCCR.INIT has been cleared by the processor (application), the device will then wait for 129 occurrences of Bus Idle (129 * 11 consecutive recessive bits) before resuming normal operation. At the end of the Bus_Off recovery sequence, the Error Management Counters will be reset. During the waiting time after the resetting of MCAN_CCCR.INIT, each time a sequence of 11 recessive bits has been monitored, a Bit0 Error code is written to MCAN_PSR.LEC, enabling the processor to readily check up whether the CAN bus is stuck at dominant or continuously disturbed and to monitor the Bus_Off recovery sequence. MCAN_ECR.REC is used to count these sequences.

This commit is contained in:
Frank Benkert 2018-07-04 07:48:59 -06:00 committed by Gregory Nutt
parent 254924029b
commit 317c7c2aff
2 changed files with 82 additions and 1 deletions

View File

@ -2225,6 +2225,63 @@ static int mcan_del_stdfilter(FAR struct sam_mcan_s *priv, int ndx)
return OK;
}
/****************************************************************************
* Name: mcan_start_busoff_recovery_sequence
*
* Description:
* This function initiates the BUS-OFF recovery sequence.
* CAN Specification Rev. 2.0 or ISO11898-1:2015
* According the SAMV71 datasheet:
* If the device goes Bus_Off, it will set MCAN_CCCR.INIT of its own accord,
* stopping all bus activities. Once MCAN_CCCR.INIT has been cleared by the
* processor (application), the device will then wait for 129 occurrences of
* Bus Idle (129 * 11 consecutive recessive bits) before resuming normal
* operation. At the end of the Bus_Off recovery sequence, the Error
* Management Counters will be reset. During the waiting time after the
* resetting of MCAN_CCCR.INIT, each time a sequence of 11 recessive bits
* has been monitored, a Bit0 Error code is written to MCAN_PSR.LEC, enablin
* the processor to readily check up whether the CAN bus is stuck at dominant
* or continuously disturbed and to monitor the Bus_Off recovery sequence.
* MCAN_ECR.REC is used to count these sequences.
*
* Input Parameters:
* priv - An instance of the MCAN driver state structure.
*
* Returned Value:
* Zero (OK) is returned on success. Otherwise a negated errno value is
* returned to indicate the nature of the error.
*
****************************************************************************/
static int mcan_start_busoff_recovery_sequence(FAR struct sam_mcan_s *priv)
{
uint32_t regval;
DEBUGASSERT(priv);
/* Get exclusive access to the MCAN peripheral */
mcan_dev_lock(priv);
/* only start BUS-OFF recovery if we are in BUS-OFF state */
regval = mcan_getreg(priv, SAM_MCAN_PSR_OFFSET);
if (!(regval & MCAN_PSR_BO))
{
mcan_dev_unlock(priv);
return -EPERM;
}
/* Disable initialization mode to issue the recovery sequence */
regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
regval &= ~MCAN_CCCR_INIT;
mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
mcan_dev_unlock(priv);
return OK;
}
/****************************************************************************
* Name: mcan_reset
*
@ -2709,6 +2766,21 @@ static int mcan_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg)
}
break;
/* CANIOC_BUSOFF_RECOVERY:
* Description : Initiates the BUS - OFF recovery sequence
* Argument : None
* Returned Value : Zero(OK) is returned on success.Otherwise - 1 (ERROR)
* is returned with the errno variable set to indicate the
* nature of the error.
* Dependencies : None
*/
case CANIOC_BUSOFF_RECOVERY:
{
ret = mcan_start_busoff_recovery_sequence(priv);
}
break;
/* Unsupported/unrecognized command */
default:

View File

@ -185,6 +185,14 @@
* is returned with the errno variable set to indicate the
* nature of the error.
* Dependencies: None
*
* CANIOC_BUSOFF_RECOVERY:
* Description: Initiates the BUS-OFF recovery sequence
* Argument: None
* Returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR)
* is returned with the errno variable set to indicate the
* nature of the error.
* Dependencies: None
*/
#define CANIOC_RTR _CANIOC(1)
@ -196,9 +204,10 @@
#define CANIOC_DEL_EXTFILTER _CANIOC(7)
#define CANIOC_GET_CONNMODES _CANIOC(8)
#define CANIOC_SET_CONNMODES _CANIOC(9)
#define CANIOC_BUSOFF_RECOVERY _CANIOC(10)
#define CAN_FIRST 0x0001 /* First common command */
#define CAN_NCMDS 9 /* Nine common commands */
#define CAN_NCMDS 10 /* Ten common commands */
/* User defined ioctl commands are also supported. These will be forwarded
* by the upper-half CAN driver to the lower-half CAN driver via the co_ioctl()