summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-09-13 11:20:10 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-09-13 11:20:10 -0600
commitc84875b8610b207c1f3b733c943288c7ec324941 (patch)
tree022ec0a89c44b6f6462f7b9fc63174f76874c99b
parent638873507a18f44592e24cd1100e786ce63d115b (diff)
downloadpx4-nuttx-c84875b8610b207c1f3b733c943288c7ec324941.tar.gz
px4-nuttx-c84875b8610b207c1f3b733c943288c7ec324941.tar.bz2
px4-nuttx-c84875b8610b207c1f3b733c943288c7ec324941.zip
Make filter register accessible for CAN1 and CAN2. Provided by Lorenz Meier
-rw-r--r--nuttx/ChangeLog4
-rw-r--r--nuttx/arch/arm/src/stm32/Kconfig34
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_can.c114
3 files changed, 99 insertions, 53 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index f40770775..fd906065d 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -5542,4 +5542,8 @@
* arch/arm/src/sama5/chip/sam_emac.h and sam_gmac.h: Register
definition files for the SAMA5 EMAC and GMAC peripherals
(incomplete on the initial commit) (2013-9-12).
+ * arch/arm/src/stm32/stm32_can.c: Patch provided by Lorenz
+ Meier (2013-9-13).
+
+
diff --git a/nuttx/arch/arm/src/stm32/Kconfig b/nuttx/arch/arm/src/stm32/Kconfig
index f0fec3b44..b42fce8a3 100644
--- a/nuttx/arch/arm/src/stm32/Kconfig
+++ b/nuttx/arch/arm/src/stm32/Kconfig
@@ -2586,21 +2586,6 @@ config SDIO_WIDTH_D1_ONLY
endmenu
-menu "CAN Configuration"
- depends on STM32_CAN
-
-config CAN1_BAUD
- int "Baud rate for CAN1"
- default 250000
- depends on STM32_CAN1
-
-config CAN2_BAUD
- int "Baud rate for CAN2"
- default 250000
- depends on STM32_CAN2
-
-endmenu
-
if STM32_ETHMAC
menu "Ethernet MAC configuration"
@@ -2882,3 +2867,22 @@ config STM32_USB_ITRMP
either retain the legacy F1 behavior or to map the USB interupts to
there own dedicated vectors. The option is available only for the
F3 family and selects the use of the dedicated USB interrupts.
+
+menu "CAN driver configuration"
+ depends on STM32_CAN1 || STM32_CAN2
+
+config CAN1_BAUD
+ int "CAN1 BAUD"
+ default 250000
+ depends on STM32_CAN1
+ ---help---
+ CAN1 BAUD rate. Required if STM32_CAN1 is defined.
+
+config CAN2_BAUD
+ int "CAN2 BAUD"
+ default 250000
+ depends on STM32_CAN2
+ ---help---
+ CAN2 BAUD rate. Required if STM32_CAN2 is defined.
+
+endmenu
diff --git a/nuttx/arch/arm/src/stm32/stm32_can.c b/nuttx/arch/arm/src/stm32/stm32_can.c
index 9333baec3..809b50ddf 100644
--- a/nuttx/arch/arm/src/stm32/stm32_can.c
+++ b/nuttx/arch/arm/src/stm32/stm32_can.c
@@ -107,7 +107,8 @@ struct stm32_can_s
uint8_t canrx0; /* CAN RX FIFO 0 IRQ number */
uint8_t cantx; /* CAN TX IRQ number */
uint8_t filter; /* Filter number */
- uint32_t base; /* Base address of the CAN registers */
+ uint32_t base; /* Base address of the CAN control registers */
+ uint32_t fbase; /* Base address of the CAN filter registers */
uint32_t baud; /* Configured baud */
};
@@ -118,7 +119,9 @@ struct stm32_can_s
/* CAN Register access */
static uint32_t can_getreg(struct stm32_can_s *priv, int offset);
+static uint32_t can_getfreg(struct stm32_can_s *priv, int offset);
static void can_putreg(struct stm32_can_s *priv, int offset, uint32_t value);
+static void can_putfreg(struct stm32_can_s *priv, int offset, uint32_t value);
#ifdef CONFIG_CAN_REGDEBUG
static void can_dumpctrlregs(struct stm32_can_s *priv, FAR const char *msg);
static void can_dumpmbregs(struct stm32_can_s *priv, FAR const char *msg);
@@ -179,6 +182,7 @@ static struct stm32_can_s g_can1priv =
.cantx = STM32_IRQ_CAN1TX,
.filter = 0,
.base = STM32_CAN1_BASE,
+ .fbase = STM32_CAN1_BASE,
.baud = CONFIG_CAN1_BAUD,
};
@@ -197,6 +201,7 @@ static struct stm32_can_s g_can2priv =
.cantx = STM32_IRQ_CAN2TX,
.filter = CAN_NFILTERS / 2,
.base = STM32_CAN2_BASE,
+ .fbase = STM32_CAN1_BASE,
.baud = CONFIG_CAN2_BAUD,
};
@@ -213,9 +218,10 @@ static struct can_dev_s g_can2dev =
/****************************************************************************
* Name: can_getreg
+ * Name: can_getfreg
*
* Description:
- * Read the value of an CAN register.
+ * Read the value of a CAN register or filter block register.
*
* Input Parameters:
* priv - A reference to the CAN block status
@@ -226,12 +232,11 @@ static struct can_dev_s g_can2dev =
****************************************************************************/
#ifdef CONFIG_CAN_REGDEBUG
-static uint32_t can_getreg(struct stm32_can_s *priv, int offset)
+static uint32_t can_vgetreg(uint32_t addr)
{
static uint32_t prevaddr = 0;
static uint32_t preval = 0;
static uint32_t count = 0;
- uint32_t addr = priv->base + offset;
/* Read the value from the register */
@@ -278,18 +283,36 @@ static uint32_t can_getreg(struct stm32_can_s *priv, int offset)
lldbg("%08x->%08x\n", addr, val);
return val;
}
+
+static uint32_t can_getreg(struct stm32_can_s *priv, int offset)
+{
+ return can_vgetreg(priv->base + offset);
+}
+
+static uint32_t can_getfreg(struct stm32_can_s *priv, int offset)
+{
+ return can_vgetreg(priv->fbase + offset);
+}
+
#else
static uint32_t can_getreg(struct stm32_can_s *priv, int offset)
{
return getreg32(priv->base + offset);
}
+
+static uint32_t can_getfreg(struct stm32_can_s *priv, int offset)
+{
+ return getreg32(priv->fbase + offset);
+}
+
#endif
/****************************************************************************
* Name: can_putreg
+ * Name: can_putfreg
*
* Description:
- * Set the value of an CAN register.
+ * Set the value of a CAN register or filter block register.
*
* Input Parameters:
* priv - A reference to the CAN block status
@@ -302,9 +325,8 @@ static uint32_t can_getreg(struct stm32_can_s *priv, int offset)
****************************************************************************/
#ifdef CONFIG_CAN_REGDEBUG
-static void can_putreg(struct stm32_can_s *priv, int offset, uint32_t value)
+static void can_vputreg(uint32_t addr, uint32_t value)
{
- uint32_t addr = priv->base + offset;
/* Show the register value being written */
@@ -314,11 +336,27 @@ static void can_putreg(struct stm32_can_s *priv, int offset, uint32_t value)
putreg32(value, addr);
}
+
+static void can_putreg(struct stm32_can_s *priv, int offset, uint32_t value)
+{
+ can_vputreg(priv->base + offset, value);
+}
+
+static void can_putfreg(struct stm32_can_s *priv, int offset, uint32_t value)
+{
+ can_vputreg(priv->fbase + offset, value);
+}
+
#else
static void can_putreg(struct stm32_can_s *priv, int offset, uint32_t value)
{
putreg32(value, priv->base + offset);
}
+
+static void can_putfreg(struct stm32_can_s *priv, int offset, uint32_t value)
+{
+ putreg32(value, priv->fbase + offset);
+}
#endif
/****************************************************************************
@@ -346,7 +384,7 @@ static void can_dumpctrlregs(struct stm32_can_s *priv, FAR const char *msg)
{
canlldbg("Control Registers:\n");
}
-
+
/* CAN control and status registers */
lldbg(" MCR: %08x MSR: %08x TSR: %08x\n",
@@ -495,14 +533,14 @@ static void can_reset(FAR struct can_dev_s *dev)
/* Get the bits in the AHB1RSTR register needed to reset this CAN device */
-#ifdef CONFIG_STM32_CAN1
+#ifdef CONFIG_STM32_CAN1
if (priv->port == 1)
{
regbit = RCC_APB1RSTR_CAN1RST;
}
else
#endif
-#ifdef CONFIG_STM32_CAN2
+#ifdef CONFIG_STM32_CAN2
if (priv->port == 2)
{
regbit = RCC_APB1RSTR_CAN2RST;
@@ -1153,7 +1191,7 @@ static int can_txinterrupt(int irq, void *context)
if ((regval & CAN_TSR_TXOK0) != 0)
{
/* Tell the upper half that the tansfer is finished. */
-
+
(void)can_txdone(dev);
}
}
@@ -1173,7 +1211,7 @@ static int can_txinterrupt(int irq, void *context)
if ((regval & CAN_TSR_TXOK1) != 0)
{
/* Tell the upper half that the tansfer is finished. */
-
+
(void)can_txdone(dev);
}
}
@@ -1193,7 +1231,7 @@ static int can_txinterrupt(int irq, void *context)
if ((regval & CAN_TSR_TXOK2) != 0)
{
/* Tell the upper half that the tansfer is finished. */
-
+
(void)can_txdone(dev);
}
}
@@ -1313,7 +1351,7 @@ static int can_bittiming(struct stm32_can_s *priv)
if (ts1 == ts2 && ts1 > 1 && ts2 < CAN_BTR_TSEG2_MAX)
{
ts1--;
- ts2++;
+ ts2++;
}
}
@@ -1427,7 +1465,7 @@ static int can_cellinit(struct stm32_can_s *priv)
can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
/* Configure bit timing. */
-
+
ret = can_bittiming(priv);
if (ret < 0)
{
@@ -1477,7 +1515,7 @@ static int can_cellinit(struct stm32_can_s *priv)
* Filters can also be configured as:
*
* 3. 16- or 32-bit. The advantage of 16-bit filters is that you get
- * more filters; The advantage of 32-bit filters is that you get
+ * more filters; The advantage of 32-bit filters is that you get
* finer control of the filtering.
*
* One filter is set up for each CAN. The filter resources are shared
@@ -1510,52 +1548,52 @@ static int can_filterinit(struct stm32_can_s *priv)
/* Enter filter initialization mode */
- regval = can_getreg(priv, STM32_CAN_FMR_OFFSET);
+ regval = can_getfreg(priv, STM32_CAN_FMR_OFFSET);
regval |= CAN_FMR_FINIT;
- can_putreg(priv, STM32_CAN_FMR_OFFSET, regval);
+ can_putfreg(priv, STM32_CAN_FMR_OFFSET, regval);
/* Disable the filter */
- regval = can_getreg(priv, STM32_CAN_FA1R_OFFSET);
+ regval = can_getfreg(priv, STM32_CAN_FA1R_OFFSET);
regval &= ~bitmask;
- can_putreg(priv, STM32_CAN_FA1R_OFFSET, regval);
+ can_putfreg(priv, STM32_CAN_FA1R_OFFSET, regval);
/* Select the 32-bit scale for the filter */
- regval = can_getreg(priv, STM32_CAN_FS1R_OFFSET);
+ regval = can_getfreg(priv, STM32_CAN_FS1R_OFFSET);
regval |= bitmask;
- can_putreg(priv, STM32_CAN_FS1R_OFFSET, regval);
-
+ can_putfreg(priv, STM32_CAN_FS1R_OFFSET, regval);
+
/* There are 14 or 28 filter banks (depending) on the device. Each filter bank is
* composed of two 32-bit registers, CAN_FiR:
*/
- can_putreg(priv, STM32_CAN_FR_OFFSET(priv->filter, 1), 0);
- can_putreg(priv, STM32_CAN_FR_OFFSET(priv->filter, 2), 0);
+ can_putfreg(priv, STM32_CAN_FR_OFFSET(priv->filter, 1), 0);
+ can_putfreg(priv, STM32_CAN_FR_OFFSET(priv->filter, 2), 0);
/* Set Id/Mask mode for the filter */
- regval = can_getreg(priv, STM32_CAN_FM1R_OFFSET);
+ regval = can_getfreg(priv, STM32_CAN_FM1R_OFFSET);
regval &= ~bitmask;
- can_putreg(priv, STM32_CAN_FM1R_OFFSET, regval);
+ can_putfreg(priv, STM32_CAN_FM1R_OFFSET, regval);
/* Assign FIFO 0 for the filter */
- regval = can_getreg(priv, STM32_CAN_FFA1R_OFFSET);
+ regval = can_getfreg(priv, STM32_CAN_FFA1R_OFFSET);
regval &= ~bitmask;
- can_putreg(priv, STM32_CAN_FFA1R_OFFSET, regval);
-
+ can_putfreg(priv, STM32_CAN_FFA1R_OFFSET, regval);
+
/* Enable the filter */
- regval = can_getreg(priv, STM32_CAN_FA1R_OFFSET);
+ regval = can_getfreg(priv, STM32_CAN_FA1R_OFFSET);
regval |= bitmask;
- can_putreg(priv, STM32_CAN_FA1R_OFFSET, regval);
+ can_putfreg(priv, STM32_CAN_FA1R_OFFSET, regval);
/* Exit filter initialization mode */
- regval = can_getreg(priv, STM32_CAN_FMR_OFFSET);
+ regval = can_getfreg(priv, STM32_CAN_FMR_OFFSET);
regval &= ~CAN_FMR_FINIT;
- can_putreg(priv, STM32_CAN_FMR_OFFSET, regval);
+ can_putfreg(priv, STM32_CAN_FMR_OFFSET, regval);
return OK;
}
@@ -1587,7 +1625,7 @@ FAR struct can_dev_s *stm32_caninitialize(int port)
* by stm32_clockconfig() early in the reset sequence.
*/
-#ifdef CONFIG_STM32_CAN1
+#ifdef CONFIG_STM32_CAN1
if( port == 1 )
{
/* Select the CAN1 device structure */
@@ -1602,8 +1640,8 @@ FAR struct can_dev_s *stm32_caninitialize(int port)
stm32_configgpio(GPIO_CAN1_TX);
}
else
-#endif
-#ifdef CONFIG_STM32_CAN2
+#endif
+#ifdef CONFIG_STM32_CAN2
if ( port ==2 )
{
/* Select the CAN2 device structure */
@@ -1618,7 +1656,7 @@ FAR struct can_dev_s *stm32_caninitialize(int port)
stm32_configgpio(GPIO_CAN2_TX);
}
else
-#endif
+#endif
{
candbg("ERROR: Unsupported port %d\n", port);
return NULL;