SAMA5D2 add new mcan ioctls
This commit is contained in:
parent
b565e28da3
commit
bfa14406d6
@ -878,17 +878,17 @@ struct sam_mcan_s
|
||||
|
||||
const struct sam_config_s *config;
|
||||
|
||||
enum can_state_s state; /* See enum can_state_s */
|
||||
enum can_state_s state; /* See enum can_state_s */
|
||||
#ifdef CONFIG_CAN_EXTID
|
||||
uint8_t nextalloc; /* Number of allocated extended filters */
|
||||
uint8_t nextalloc; /* Number of allocated extended filters */
|
||||
#endif
|
||||
uint8_t nstdalloc; /* Number of allocated standard filters */
|
||||
mutex_t lock; /* Enforces mutually exclusive access */
|
||||
sem_t txfsem; /* Used to wait for TX FIFO availability */
|
||||
uint32_t btp; /* Current bit timing */
|
||||
uint32_t fbtp; /* Current fast bit timing */
|
||||
uint32_t rxints; /* Configured RX interrupts */
|
||||
uint32_t txints; /* Configured TX interrupts */
|
||||
uint8_t nstdalloc; /* Number of allocated standard filters */
|
||||
mutex_t lock; /* Enforces mutually exclusive access */
|
||||
sem_t txfsem; /* Used to wait for TX FIFO availability */
|
||||
uint32_t btp; /* Current bit timing */
|
||||
uint32_t fbtp; /* Current fast bit timing */
|
||||
uint32_t rxints; /* Configured RX interrupts */
|
||||
uint32_t txints; /* Configured TX interrupts */
|
||||
|
||||
#ifdef CONFIG_CAN_EXTID
|
||||
uint32_t extfilters[2]; /* Extended filter bit allocator. 2*32=64 */
|
||||
@ -936,6 +936,10 @@ static int mcan_add_stdfilter(struct sam_mcan_s *priv,
|
||||
struct canioc_stdfilter_s *stdconfig);
|
||||
static int mcan_del_stdfilter(struct sam_mcan_s *priv, int ndx);
|
||||
|
||||
static int mcan_set_nart(struct sam_mcan_s *priv, bool enable);
|
||||
static int mcan_cancel_tx_buffers(struct sam_mcan_s *priv);
|
||||
static int mcan_cancel_rx_fifos(struct sam_mcan_s *priv);
|
||||
|
||||
/* CAN driver methods */
|
||||
|
||||
static void mcan_reset(struct can_dev_s *dev);
|
||||
@ -2838,6 +2842,69 @@ static int mcan_ioctl(struct can_dev_s *dev, int cmd, unsigned long arg)
|
||||
}
|
||||
break;
|
||||
|
||||
/* CANIOC_SET_NART:
|
||||
* Description: Enable/Disable NART (No Automatic Retry)
|
||||
* Argument: Set to 1 to enable NART, 0 to disable.
|
||||
* Default is disabled.
|
||||
* 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_SET_NART:
|
||||
{
|
||||
ret = mcan_set_nart(priv, (bool)arg);
|
||||
}
|
||||
break;
|
||||
|
||||
/* CANIOC_IFLUSH
|
||||
* Description: Flush data received but not read
|
||||
* 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_IFLUSH:
|
||||
{
|
||||
ret = mcan_cancel_rx_fifos(priv);
|
||||
}
|
||||
break;
|
||||
|
||||
/* CANIOC_OFLUSH
|
||||
* Description: Flush data queued but not transmitted
|
||||
* 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_OFLUSH:
|
||||
{
|
||||
ret = mcan_cancel_tx_buffers(priv);
|
||||
}
|
||||
break;
|
||||
|
||||
/* CANIOC_IOFLUSH
|
||||
* Description: Flush data received but not read, and data queued
|
||||
but not transmitted
|
||||
* 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_IOFLUSH:
|
||||
{
|
||||
ret = mcan_cancel_tx_buffers(priv);
|
||||
ret = mcan_cancel_rx_fifos(priv);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Unsupported/unrecognized command */
|
||||
|
||||
default:
|
||||
@ -2876,7 +2943,8 @@ static int mcan_remoterequest(struct can_dev_s *dev, uint16_t id)
|
||||
* Send one can message.
|
||||
*
|
||||
* One CAN-message consists of a maximum of 10 bytes. A message is
|
||||
* composed of at least the first 2 bytes (when there are no data bytes).
|
||||
* composed of at least the && priv->config != NULLfirst 2 bytes
|
||||
* (when there are no data bytes).
|
||||
*
|
||||
* Byte 0: Bits 0-7: Bits 3-10 of the 11-bit CAN identifier
|
||||
* Byte 1: Bits 5-7: Bits 0-2 of the 11-bit CAN identifier
|
||||
@ -3380,6 +3448,114 @@ static void mcan_error(struct can_dev_s *dev, uint32_t status)
|
||||
}
|
||||
#endif /* CONFIG_CAN_ERRORS */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mcan_set_nart
|
||||
*
|
||||
* Description:
|
||||
* Enable/Disable NART (No Automatic Retry),
|
||||
* AKA "DAR" - Disable Automatic Retry
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - An instance of the MCAN driver state structure.
|
||||
* enable - enable or disable.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mcan_set_nart(struct sam_mcan_s *priv, bool enable)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
|
||||
if (enable)
|
||||
{
|
||||
regval |= MCAN_CCCR_DAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= ~MCAN_CCCR_DAR;
|
||||
}
|
||||
|
||||
mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mcan_cancel_tx_buffers
|
||||
*
|
||||
* Description:
|
||||
* Cancel all pending, buffered, transmissions
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - An instance of the MCAN driver state structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* Success
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mcan_cancel_tx_buffers(struct sam_mcan_s *priv)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
mcan_putreg(priv, SAM_MCAN_TXBCR_OFFSET, 0xffff);
|
||||
|
||||
do
|
||||
{
|
||||
regval = mcan_getreg(priv, SAM_MCAN_TXBRP_OFFSET);
|
||||
}
|
||||
while (regval != 0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mcan_cancel_rx_fifos
|
||||
*
|
||||
* Description:
|
||||
* Cancel all queued/received messages
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - An instance of the MCAN driver state structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* Success
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mcan_cancel_rx_fifos(struct sam_mcan_s *priv)
|
||||
{
|
||||
uint32_t ir;
|
||||
uint32_t ie;
|
||||
uint32_t pending;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
mcan_putreg(priv, SAM_MCAN_RXF0A_OFFSET, 0);
|
||||
mcan_putreg(priv, SAM_MCAN_RXF1A_OFFSET, 0);
|
||||
|
||||
/* Clear RX interrupts */
|
||||
|
||||
ir = mcan_getreg(priv, SAM_MCAN_IR_OFFSET);
|
||||
ie = mcan_getreg(priv, SAM_MCAN_IE_OFFSET);
|
||||
|
||||
pending = (ir & ie);
|
||||
|
||||
if ((pending & priv->rxints) != 0)
|
||||
{
|
||||
mcan_putreg(priv, SAM_MCAN_IR_OFFSET, priv->rxints);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mcan_receive
|
||||
*
|
||||
@ -3713,7 +3889,7 @@ static int mcan_interrupt(int irq, void *context, void *arg)
|
||||
/* Check if there is anything in RX FIFO1 */
|
||||
|
||||
regval = mcan_getreg(priv, SAM_MCAN_RXF1S_OFFSET);
|
||||
nelem = (regval & MCAN_RXF0S_F0FL_MASK) >> MCAN_RXF0S_F0FL_SHIFT;
|
||||
nelem = (regval & MCAN_RXF1S_F1FL_MASK) >> MCAN_RXF1S_F1FL_SHIFT;
|
||||
if (nelem == 0)
|
||||
{
|
||||
/* Break out of the loop if RX FIFO1 is empty */
|
||||
@ -3729,7 +3905,7 @@ static int mcan_interrupt(int irq, void *context, void *arg)
|
||||
|
||||
ndx = (regval & MCAN_RXF1S_F1GI_MASK) >> MCAN_RXF1S_F1GI_SHIFT;
|
||||
|
||||
if ((regval & MCAN_RXF0S_RF0L) != 0)
|
||||
if ((regval & MCAN_RXF1S_RF1L) != 0)
|
||||
{
|
||||
canerr("ERROR: Message lost: %08" PRIx32 "\n", regval);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user