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:
parent
254924029b
commit
317c7c2aff
@ -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:
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user