STM32L4 CAN: Port support for both RX FIFOs from STM32 CAN

This commit is contained in:
Paul A. Patience
2016-06-29 12:33:34 -04:00
parent fd9c9a7f4f
commit 52a4a20efb
3 changed files with 219 additions and 192 deletions
+59 -91
View File
@@ -58,16 +58,17 @@
#include "up_internal.h"
#include "up_arch.h"
#include "chip.h"
#include "stm32.h"
#include "stm32_can.h"
#if defined(CONFIG_CAN) && (defined(CONFIG_STM32_CAN1) || defined(CONFIG_STM32_CAN2))
#if defined(CONFIG_CAN) && \
(defined(CONFIG_STM32_CAN1) || defined(CONFIG_STM32_CAN2))
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Delays *******************************************************************/
/* Time out for INAK bit */
@@ -106,19 +107,21 @@ struct stm32_can_s
/* CAN Register access */
static uint32_t stm32can_getreg(FAR struct stm32_can_s *priv, int offset);
static uint32_t stm32can_getfreg(FAR struct stm32_can_s *priv, int offset);
static uint32_t stm32can_getreg(FAR struct stm32_can_s *priv,
int offset);
static uint32_t stm32can_getfreg(FAR struct stm32_can_s *priv,
int offset);
static void stm32can_putreg(FAR struct stm32_can_s *priv, int offset,
uint32_t value);
uint32_t value);
static void stm32can_putfreg(FAR struct stm32_can_s *priv, int offset,
uint32_t value);
uint32_t value);
#ifdef CONFIG_STM32_CAN_REGDEBUG
static void stm32can_dumpctrlregs(FAR struct stm32_can_s *priv,
FAR const char *msg);
FAR const char *msg);
static void stm32can_dumpmbregs(FAR struct stm32_can_s *priv,
FAR const char *msg);
FAR const char *msg);
static void stm32can_dumpfiltregs(FAR struct stm32_can_s *priv,
FAR const char *msg);
FAR const char *msg);
#else
# define stm32can_dumpctrlregs(priv,msg)
# define stm32can_dumpmbregs(priv,msg)
@@ -129,14 +132,14 @@ static void stm32can_dumpfiltregs(FAR struct stm32_can_s *priv,
#ifdef CONFIG_CAN_EXTID
static int stm32can_addextfilter(FAR struct stm32_can_s *priv,
FAR struct canioc_extfilter_s *arg);
FAR struct canioc_extfilter_s *arg);
static int stm32can_delextfilter(FAR struct stm32_can_s *priv,
int arg);
int arg);
#endif
static int stm32can_addstdfilter(FAR struct stm32_can_s *priv,
FAR struct canioc_stdfilter_s *arg);
FAR struct canioc_stdfilter_s *arg);
static int stm32can_delstdfilter(FAR struct stm32_can_s *priv,
int arg);
int arg);
/* CAN driver methods */
@@ -146,10 +149,11 @@ static void stm32can_shutdown(FAR struct can_dev_s *dev);
static void stm32can_rxint(FAR struct can_dev_s *dev, bool enable);
static void stm32can_txint(FAR struct can_dev_s *dev, bool enable);
static int stm32can_ioctl(FAR struct can_dev_s *dev, int cmd,
unsigned long arg);
static int stm32can_remoterequest(FAR struct can_dev_s *dev, uint16_t id);
unsigned long arg);
static int stm32can_remoterequest(FAR struct can_dev_s *dev,
uint16_t id);
static int stm32can_send(FAR struct can_dev_s *dev,
FAR struct can_msg_s *msg);
FAR struct can_msg_s *msg);
static bool stm32can_txready(FAR struct can_dev_s *dev);
static bool stm32can_txempty(FAR struct can_dev_s *dev);
@@ -348,7 +352,6 @@ static uint32_t stm32can_getfreg(FAR struct stm32_can_s *priv, int offset)
#ifdef CONFIG_STM32_CAN_REGDEBUG
static void stm32can_vputreg(uint32_t addr, uint32_t value)
{
/* Show the register value being written */
caninfo("%08x<-%08x\n", addr, value);
@@ -400,7 +403,7 @@ static void stm32can_putfreg(FAR struct stm32_can_s *priv, int offset,
#ifdef CONFIG_STM32_CAN_REGDEBUG
static void stm32can_dumpctrlregs(FAR struct stm32_can_s *priv,
FAR const char *msg)
FAR const char *msg)
{
if (msg)
{
@@ -445,7 +448,7 @@ static void stm32can_dumpctrlregs(FAR struct stm32_can_s *priv,
#ifdef CONFIG_STM32_CAN_REGDEBUG
static void stm32can_dumpmbregs(FAR struct stm32_can_s *priv,
FAR const char *msg)
FAR const char *msg)
{
if (msg)
{
@@ -506,7 +509,7 @@ static void stm32can_dumpmbregs(FAR struct stm32_can_s *priv,
#ifdef CONFIG_STM32_CAN_REGDEBUG
static void stm32can_dumpfiltregs(FAR struct stm32_can_s *priv,
FAR const char *msg)
FAR const char *msg)
{
int i;
@@ -627,7 +630,8 @@ static int stm32can_setup(FAR struct can_dev_s *dev)
ret = stm32can_cellinit(priv);
if (ret < 0)
{
canerr("ERROR: CAN%d cell initialization failed: %d\n", priv->port, ret);
canerr("ERROR: CAN%d cell initialization failed: %d\n",
priv->port, ret);
return ret;
}
@@ -639,7 +643,8 @@ static int stm32can_setup(FAR struct can_dev_s *dev)
ret = stm32can_filterinit(priv);
if (ret < 0)
{
canerr("ERROR: CAN%d filter initialization failed: %d\n", priv->port, ret);
canerr("ERROR: CAN%d filter initialization failed: %d\n",
priv->port, ret);
return ret;
}
@@ -652,7 +657,7 @@ static int stm32can_setup(FAR struct can_dev_s *dev)
ret = irq_attach(priv->canrx[0], stm32can_rx0interrupt);
if (ret < 0)
{
canerr(ERROR: "Failed to attach CAN%d RX0 IRQ (%d)",
canerr("ERROR: Failed to attach CAN%d RX0 IRQ (%d)",
priv->port, priv->canrx[0]);
return ret;
}
@@ -754,6 +759,7 @@ static void stm32can_rxint(FAR struct can_dev_s *dev, bool enable)
{
regval &= ~(CAN_IER_FMPIE0 | CAN_IER_FMPIE1);
}
stm32can_putreg(priv, STM32_CAN_IER_OFFSET, regval);
}
@@ -925,7 +931,7 @@ static int stm32can_ioctl(FAR struct can_dev_s *dev, int cmd,
/* Bit timing can only be configured in init mode. */
ret = stm32can_enterinitmode(priv);
if (ret != 0)
if (ret < 0)
{
break;
}
@@ -933,8 +939,7 @@ static int stm32can_ioctl(FAR struct can_dev_s *dev, int cmd,
stm32can_putreg(priv, STM32_CAN_BTR_OFFSET, regval);
ret = stm32can_exitinitmode(priv);
if (ret == 0)
if (ret >= 0)
{
priv->baud = STM32_PCLK1_FREQUENCY /
(brp * (bt->bt_tseg1 + bt->bt_tseg2 + 1));
@@ -992,26 +997,26 @@ static int stm32can_ioctl(FAR struct can_dev_s *dev, int cmd,
if (bm->bm_loopback)
{
regval |= CAN_BTR_LBKM;
regval |= CAN_BTR_LBKM;
}
else
{
regval &= ~CAN_BTR_LBKM;
regval &= ~CAN_BTR_LBKM;
}
if (bm->bm_silent)
{
regval |= CAN_BTR_SILM;
regval |= CAN_BTR_SILM;
}
else
{
regval &= ~CAN_BTR_SILM;
regval &= ~CAN_BTR_SILM;
}
/* This register can only be configured in init mode. */
ret = stm32can_enterinitmode(priv);
if (ret != 0)
if (ret < 0)
{
break;
}
@@ -1035,7 +1040,8 @@ static int stm32can_ioctl(FAR struct can_dev_s *dev, int cmd,
case CANIOC_ADD_EXTFILTER:
{
DEBUGASSERT(arg != 0);
ret = stm32can_addextfilter(priv, (FAR struct canioc_extfilter_s *)arg);
ret = stm32can_addextfilter(priv,
(FAR struct canioc_extfilter_s *)arg);
}
break;
@@ -1051,7 +1057,9 @@ static int stm32can_ioctl(FAR struct can_dev_s *dev, int cmd,
case CANIOC_DEL_EXTFILTER:
{
#if 0 /* Unimplemented */
DEBUGASSERT(arg <= priv->config->nextfilters);
#endif
ret = stm32can_delextfilter(priv, (int)arg);
}
break;
@@ -1069,7 +1077,8 @@ static int stm32can_ioctl(FAR struct can_dev_s *dev, int cmd,
case CANIOC_ADD_STDFILTER:
{
DEBUGASSERT(arg != 0);
ret = stm32can_addstdfilter(priv, (FAR struct canioc_stdfilter_s *)arg);
ret = stm32can_addstdfilter(priv,
(FAR struct canioc_stdfilter_s *)arg);
}
break;
@@ -1085,7 +1094,9 @@ static int stm32can_ioctl(FAR struct can_dev_s *dev, int cmd,
case CANIOC_DEL_STDFILTER:
{
#if 0 /* Unimplemented */
DEBUGASSERT(arg <= priv->config->nstdfilters);
#endif
ret = stm32can_delstdfilter(priv, (int)arg);
}
break;
@@ -1143,7 +1154,8 @@ static int stm32can_remoterequest(FAR struct can_dev_s *dev, uint16_t id)
*
****************************************************************************/
static int stm32can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
static int stm32can_send(FAR struct can_dev_s *dev,
FAR struct can_msg_s *msg)
{
FAR struct stm32_can_s *priv = dev->cd_priv;
FAR uint8_t *ptr;
@@ -1239,6 +1251,7 @@ static int stm32can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
}
}
}
stm32can_putreg(priv, STM32_CAN_TDLR_OFFSET(txmb), regval);
regval = 0;
@@ -1265,6 +1278,7 @@ static int stm32can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
}
}
}
stm32can_putreg(priv, STM32_CAN_TDHR_OFFSET(txmb), regval);
/* Enable the transmit mailbox empty interrupt (may already be enabled) */
@@ -1669,6 +1683,7 @@ static int stm32can_txinterrupt(int irq, FAR void *context)
* Tbs1 = Tq * ts1
* Tbs2 = Tq * ts2
* Tq = brp * Tpclk1
* baud = Fpclk1 / (brp * (1 + ts1 + ts2))
*
* Where:
* Tpclk1 is the period of the APB1 clock (PCLK1).
@@ -1814,7 +1829,7 @@ static int stm32can_enterinitmode(FAR struct stm32_can_s *priv)
return -ETIMEDOUT;
}
return 0;
return OK;
}
/****************************************************************************
@@ -1859,11 +1874,12 @@ static int stm32can_exitinitmode(FAR struct stm32_can_s *priv)
if (timeout < 1)
{
canerr("ERROR: Timed out waiting to exit initialization mode: %08x\n", regval);
canerr("ERROR: Timed out waiting to exit initialization mode: %08x\n",
regval);
return -ETIMEDOUT;
}
return 0;
return OK;
}
/****************************************************************************
@@ -1882,7 +1898,6 @@ static int stm32can_exitinitmode(FAR struct stm32_can_s *priv)
static int stm32can_cellinit(FAR struct stm32_can_s *priv)
{
volatile uint32_t timeout;
uint32_t regval;
int ret;
@@ -1894,30 +1909,10 @@ static int stm32can_cellinit(FAR struct stm32_can_s *priv)
regval &= ~CAN_MCR_SLEEP;
stm32can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
/* Enter initialization mode */
regval |= CAN_MCR_INRQ;
stm32can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
/* Wait until initialization mode is acknowledged */
for (timeout = INAK_TIMEOUT; timeout > 0; timeout--)
ret = stm32can_enterinitmode(priv);
if(ret != 0)
{
regval = stm32can_getreg(priv, STM32_CAN_MSR_OFFSET);
if ((regval & CAN_MSR_INAK) != 0)
{
/* We are in initialization mode */
break;
}
}
/* Check for a timeout */
if (timeout < 1)
{
canerr("ERROR: Timed out waiting to enter initialization mode\n");
return -ETIMEDOUT;
return ret;
}
/* Disable the following modes:
@@ -1944,34 +1939,7 @@ static int stm32can_cellinit(FAR struct stm32_can_s *priv)
return ret;
}
/* Exit initialization mode */
regval = stm32can_getreg(priv, STM32_CAN_MCR_OFFSET);
regval &= ~CAN_MCR_INRQ;
stm32can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
/* Wait until the initialization mode exit is acknowledged */
for (timeout = INAK_TIMEOUT; timeout > 0; timeout--)
{
regval = stm32can_getreg(priv, STM32_CAN_MSR_OFFSET);
if ((regval & CAN_MSR_INAK) == 0)
{
/* We are out of initialization mode */
break;
}
}
/* Check for a timeout */
if (timeout < 1)
{
canerr("ERROR: Timed out waiting to exit initialization mode: %08x\n",
regval);
return -ETIMEDOUT;
}
return OK;
return stm32can_exitinitmode(priv);
}
/****************************************************************************
@@ -2124,7 +2092,7 @@ static int stm32can_addextfilter(FAR struct stm32_can_s *priv,
****************************************************************************/
#ifdef CONFIG_CAN_EXTID
static int stm32can_delextfilter(FAR struct stm32_can_s *priv, int arg)
static int stm32can_delextfilter(FAR struct stm32_can_s *priv, int arg)
{
return -ENOTTY;
}
@@ -2171,7 +2139,7 @@ static int stm32can_addstdfilter(FAR struct stm32_can_s *priv,
*
****************************************************************************/
static int stm32can_delstdfilter(FAR struct stm32_can_s *priv, int arg)
static int stm32can_delstdfilter(FAR struct stm32_can_s *priv, int arg)
{
return -ENOTTY;
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -117,7 +117,7 @@ extern "C"
************************************************************************************/
/****************************************************************************
* Name: stm32l4_caninitialize
* Name: stm32l4can_initialize
*
* Description:
* Initialize the selected CAN port