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;
|
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
|
* Name: mcan_reset
|
||||||
*
|
*
|
||||||
@ -2709,6 +2766,21 @@ static int mcan_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg)
|
|||||||
}
|
}
|
||||||
break;
|
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 */
|
/* Unsupported/unrecognized command */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -185,6 +185,14 @@
|
|||||||
* is returned with the errno variable set to indicate the
|
* is returned with the errno variable set to indicate the
|
||||||
* nature of the error.
|
* nature of the error.
|
||||||
* Dependencies: None
|
* 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)
|
#define CANIOC_RTR _CANIOC(1)
|
||||||
@ -196,9 +204,10 @@
|
|||||||
#define CANIOC_DEL_EXTFILTER _CANIOC(7)
|
#define CANIOC_DEL_EXTFILTER _CANIOC(7)
|
||||||
#define CANIOC_GET_CONNMODES _CANIOC(8)
|
#define CANIOC_GET_CONNMODES _CANIOC(8)
|
||||||
#define CANIOC_SET_CONNMODES _CANIOC(9)
|
#define CANIOC_SET_CONNMODES _CANIOC(9)
|
||||||
|
#define CANIOC_BUSOFF_RECOVERY _CANIOC(10)
|
||||||
|
|
||||||
#define CAN_FIRST 0x0001 /* First common command */
|
#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
|
/* 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()
|
* by the upper-half CAN driver to the lower-half CAN driver via the co_ioctl()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user