summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/stm32
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-12-10 15:14:29 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-12-10 15:14:29 +0000
commitf8731df8137c569696cddec635ce82f178f22bbe (patch)
tree01c8d73aa66dbc0627851a1c0fed022fb93a816a /nuttx/arch/arm/src/stm32
parent4f53ac9b20b0f871b940f5738d9f4fa358c52298 (diff)
downloadpx4-nuttx-f8731df8137c569696cddec635ce82f178f22bbe.tar.gz
px4-nuttx-f8731df8137c569696cddec635ce82f178f22bbe.tar.bz2
px4-nuttx-f8731df8137c569696cddec635ce82f178f22bbe.zip
Add Ethernet interrupt configuration and handling
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4157 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm/src/stm32')
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_eth.h57
-rwxr-xr-xnuttx/arch/arm/src/stm32/stm32_eth.c134
2 files changed, 144 insertions, 47 deletions
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_eth.h b/nuttx/arch/arm/src/stm32/chip/stm32_eth.h
index b58c9c87f..991695a09 100644
--- a/nuttx/arch/arm/src/stm32/chip/stm32_eth.h
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_eth.h
@@ -549,23 +549,28 @@
/* Ethernet DMA receive descriptor list address register (32-bit address) */
/* Ethernet DMA transmit descriptor list address register (32-bit address) */
-/* Ethernet DMA status register */
-
-#define ETH_DMASR_TS (1 << 0) /* Bit 0: Transmit status */
-#define ETH_DMASR_TPSS (1 << 1) /* Bit 1: Transmit process stopped status */
-#define ETH_DMASR_TBUS (1 << 2) /* Bit 2: Transmit buffer unavailable status */
-#define ETH_DMASR_TJTS (1 << 3) /* Bit 3: Transmit jabber timeout status */
-#define ETH_DMASR_ROS (1 << 4) /* Bit 4: Receive overflow status */
-#define ETH_DMASR_TUS (1 << 5) /* Bit 5: Transmit underflow status */
-#define ETH_DMASR_RS (1 << 6) /* Bit 6: Receive status */
-#define ETH_DMASR_RBUS (1 << 7) /* Bit 7: Receive buffer unavailable status */
-#define ETH_DMASR_RPSS (1 << 8) /* Bit 8: Receive process stopped status */
-#define ETH_DMASR_RWTS (1 << 9) /* Bit 9: Receive watchdog timeout status */
-#define ETH_DMASR_ETS (1 << 10) /* Bit 10: Early transmit status */
-#define ETH_DMASR_FBES (1 << 13) /* Bit 13: Fatal bus error status */
-#define ETH_DMASR_ERS (1 << 14) /* Bit 14: Early receive status */
-#define ETH_DMASR_AIS (1 << 15) /* Bit 15: Abnormal interrupt summary */
-#define ETH_DMASR_NIS (1 << 16) /* Bit 16: Normal interrupt summary */
+/* Interrupt bit definitions common between the DMA status register (DMASR) and
+ * the DMA interrupt enable register (DMAIER).
+ */
+
+#define ETH_DMAINT_TI (1 << 0) /* Bit 0: Transmit interrupt */
+#define ETH_DMAINT_TPSI (1 << 1) /* Bit 1: Transmit process stopped interrupt */
+#define ETH_DMAINT_TBUI (1 << 2) /* Bit 2: Transmit buffer unavailable interrupt */
+#define ETH_DMAINT_TJTI (1 << 3) /* Bit 3: Transmit jabber timeout interrupt */
+#define ETH_DMAINT_ROI (1 << 4) /* Bit 4: Overflow interrupt */
+#define ETH_DMAINT_TUI (1 << 5) /* Bit 5: Underflow interrupt */
+#define ETH_DMAINT_RI (1 << 6) /* Bit 6: Receive interrupt */
+#define ETH_DMAINT_RBUI (1 << 7) /* Bit 7: Receive buffer unavailable interrupt */
+#define ETH_DMAINT_RPSI (1 << 8) /* Bit 8: Receive process stopped interrupt */
+#define ETH_DMAINT_RWTI (1 << 9) /* Bit 9: Receive watchdog timeout interrupt */
+#define ETH_DMAINT_ETI (1 << 10) /* Bit 10: Early transmit interrupt */
+#define ETH_DMAINT_FBEI (1 << 13) /* Bit 13: Fatal bus error interrupt */
+#define ETH_DMAINT_ERI (1 << 14) /* Bit 14: Early receive interrupt */
+#define ETH_DMAINT_AIS (1 << 15) /* Bit 15: Abnormal interrupt summary */
+#define ETH_DMAINT_NIS (1 << 16) /* Bit 16: Normal interrupt summary */
+
+/* Ethernet DMA status register (in addition to the interrupt bits above */
+
#define ETH_DMASR_RPS_SHIFT (17) /* Bits 17-19: Receive process state */
#define ETH_DMASR_RPS_MASK (7 << ETH_DMASR_RPS_SHIFT)
# define ETH_DMASR_RPS_STOPPED (0 << ETH_DMASR_RPS_SHIFT) /* 000: Stopped: Reset or Stop Receive Command issued */
@@ -620,24 +625,6 @@
#define ETH_DMAOMR_RSF (1 << 25) /* Bit 25: Receive store and forward */
#define ETH_DMAOMR_DTCEFD (1 << 26) /* Bit 26: Dropping of TCP/IP checksum error frames disable */
-/* Ethernet DMA interrupt enable register */
-
-#define ETH_DMAIER_TIE (1 << 0) /* Bit 0: Transmit interrupt enable */
-#define ETH_DMAIER_TPSIE (1 << 1) /* Bit 1: Transmit process stopped interrupt enable */
-#define ETH_DMAIER_TBUIE (1 << 2) /* Bit 2: Transmit buffer unavailable interrupt enable */
-#define ETH_DMAIER_TJTIE (1 << 3) /* Bit 3: Transmit jabber timeout interrupt enable */
-#define ETH_DMAIER_ROIE (1 << 4) /* Bit 4: Overflow interrupt enable */
-#define ETH_DMAIER_TUIE (1 << 5) /* Bit 5: Underflow interrupt enable */
-#define ETH_DMAIER_RIE (1 << 6) /* Bit 6: Receive interrupt enable */
-#define ETH_DMAIER_RBUIE (1 << 7) /* Bit 7: Receive buffer unavailable interrupt enable */
-#define ETH_DMAIER_RPSIE (1 << 8) /* Bit 8: Receive process stopped interrupt enable */
-#define ETH_DMAIER_RWTIE (1 << 9) /* Bit 9: Receive watchdog timeout interrupt enable */
-#define ETH_DMAIER_ETIE (1 << 10) /* Bit 10: Early transmit interrupt enable */
-#define ETH_DMAIER_FBEIE (1 << 13) /* Bit 13: Fatal bus error interrupt enable */
-#define ETH_DMAIER_ERIE (1 << 14) /* Bit 14: Early receive interrupt enable */
-#define ETH_DMAIER_AISE (1 << 15) /* Bit 15: Abnormal interrupt summary enable */
-#define ETH_DMAIER_NISE (1 << 16) /* Bit 16: Normal interrupt summary enable */
-
/* Ethernet DMA missed frame and buffer overflow counter register */
#define ETH_DMAMFBOC_MFC_SHIFT (0) /* Bits 0-15: Missed frames by the controller */
diff --git a/nuttx/arch/arm/src/stm32/stm32_eth.c b/nuttx/arch/arm/src/stm32/stm32_eth.c
index 05798b6b8..d4c833f40 100755
--- a/nuttx/arch/arm/src/stm32/stm32_eth.c
+++ b/nuttx/arch/arm/src/stm32/stm32_eth.c
@@ -428,6 +428,29 @@
ETH_DMABMR_RDP(32) | ETH_DMABMR_USP | ETH_DMABMR_AAB)
#endif
+/* Interrupt bit sets *******************************************************/
+/* All interrupts in the normal and abnormal interrupt summary */
+
+#define ETH_DMAINT_NORMAL \
+ (ETH_DMAINT_TI | ETH_DMAINT_TBUI |ETH_DMAINT_RI | ETH_DMAINT_ERI)
+
+#define ETH_DMAINT_ABNORMAL \
+ (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \
+ ETH_DMAINT_RBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI | ETH_DMAINT_ETI | \
+ ETH_DMAINT_FBEI)
+
+/* Normal receive, transmit, error interrupt enable bit sets */
+
+#define ETH_DMAINT_RECV_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_RI)
+#define ETH_DMAINT_XMIT_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_TI)
+#define ETH_DMAINT_XMIT_DISABLE (ETH_DMAINT_TI)
+
+#ifdef CONFIG_DEBUG_NET
+# define ETH_DMAINT_ERROR_ENABLE (ETH_DMAINT_AIS | ETH_DMAINT_ABNORMAL)
+#else
+# define ETH_DMAINT_ERROR_ENABLE (0)
+#endif
+
/* Helpers ******************************************************************/
/* This is a helper pointer for accessing the contents of the Ethernet
* header
@@ -531,6 +554,8 @@ static int stm32_ethconfig(FAR struct stm32_ethmac_s *priv);
static int stm32_transmit(FAR struct stm32_ethmac_s *priv)
{
+ uint32_t regval;
+
/* Verify that the hardware is ready to send another packet. If we get
* here, then we are committed to sending a packet; Higher level logic
* must have assured that there is no transmission in progress.
@@ -542,6 +567,10 @@ static int stm32_transmit(FAR struct stm32_ethmac_s *priv)
/* Enable Tx interrupts */
+ regval = getreg32(STM32_ETH_DMAIER);
+ regval |= ETH_DMAINT_XMIT_ENABLE;
+ putreg32(regval, STM32_ETH_DMAIER);
+
/* Setup the TX timeout watchdog (perhaps restarting the timer) */
(void)wd_start(priv->txtimeout, STM32_TXTIMEOUT, stm32_txtimeout, 1, (uint32_t)priv);
@@ -683,14 +712,20 @@ static void stm32_receive(FAR struct stm32_ethmac_s *priv)
static void stm32_txdone(FAR struct stm32_ethmac_s *priv)
{
+ uint32_t regval;
+
/* Check for errors and update statistics */
- /* If no further xmits are pending, then cancel the TX timeout and
- * disable further Tx interrupts.
- */
+ /* If no further xmits are pending, then cancel the TX timeout */
wd_cancel(priv->txtimeout);
+ /* And disable further Tx interrupts. */
+
+ regval = getreg32(STM32_ETH_DMAIER);
+ regval &= ~ETH_DMAINT_XMIT_DISABLE;
+ putreg32(regval, STM32_ETH_DMAIER);
+
/* Then poll uIP for new XMIT data */
(void)uip_poll(&priv->dev, stm32_uiptxpoll);
@@ -716,22 +751,79 @@ static void stm32_txdone(FAR struct stm32_ethmac_s *priv)
static int stm32_interrupt(int irq, FAR void *context)
{
register FAR struct stm32_ethmac_s *priv = &g_stm32ethmac[0];
+ uint32_t dmasr;
- /* Get and clear interrupt status bits */
+ /* Get the DMA interrupt status bits (no MAC interrupts are expected) */
- /* Handle interrupts according to status bit settings */
+ dmasr = getreg32(STM32_ETH_DMASR);
- /* Check if we received an incoming packet, if so, call stm32_receive() */
+ /* Mask only enabled interrupts. This depends on the fact that the interrupt
+ * related bits (0-16) correspond in these two registers.
+ */
- stm32_receive(priv);
+ dmasr &= ~getreg32(STM32_ETH_DMAIER);
- /* Check if a packet transmission just completed. If so, call stm32_txdone.
- * This may disable further Tx interrupts if there are no pending
- * tansmissions.
- */
+ /* Check if there are pending "normal" interrupts */
- stm32_txdone(priv);
+ if ((dmasr & ETH_DMAINT_NIS) != 0)
+ {
+ /* Yes.. Check if we received an incoming packet, if so, call
+ * stm32_receive()
+ */
+ if ((dmasr & ETH_DMAINT_RI) != 0)
+ {
+ /* Clear the pending receive interrupt */
+
+ putreg32(ETH_DMAINT_RI, STM32_ETH_DMASR);
+
+ /* Handle the received package */
+
+ stm32_receive(priv);
+ }
+
+ /* Check if a packet transmission just completed. If so, call
+ * stm32_txdone(). This may disable further Tx interrupts if there
+ * are no pending tansmissions.
+ */
+
+ if ((dmasr & ETH_DMAINT_TI) != 0)
+ {
+ /* Clear the pending receive interrupt */
+
+ putreg32(ETH_DMAINT_TI, STM32_ETH_DMASR);
+
+ /* Check if there are pending transmissions */
+
+ stm32_txdone(priv);
+ }
+
+ /* Clear the pending normal summary interrupt */
+
+ putreg32(ETH_DMAINT_NIS, STM32_ETH_DMASR);
+ }
+
+ /* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */
+
+#ifdef CONFIG_DEBUG_NET
+
+ /* Check if there are pending "anormal" interrupts */
+
+ if ((dmasr & ETH_DMAINT_AIS) != 0)
+ {
+ /* Just let the user know what happened */
+
+ nlldbg("Abormal event(s): %08x\n", dmasr);
+
+ /* Clear all pending abnormal events */
+
+ putreg32(ETH_DMAINT_ABNORMAL, STM32_ETH_DMASR);
+
+ /* Clear the pending normal summary interrupt */
+
+ putreg32(ETH_DMAINT_NIS, STM32_ETH_DMASR);
+ }
+#endif
return OK;
}
@@ -1498,6 +1590,24 @@ static int stm32_macconfig(FAR struct stm32_ethmac_s *priv)
regval |= DMABMR_SET_MASK;
putreg32(regval, STM32_ETH_DMABMR);
+ /* Enable Ethernet DMA interrupts.
+ *
+ * The STM32 hardware supports two interrupts: (1) one dedicated to normal
+ * Ethernet operations and the other, used only for the Ethernet wakeup
+ * event. The wake-up interrupt is not used by this driver.
+ *
+ * The first Ethernet vector is reserved for interrupts generated by the
+ * MAC and the DMA. The MAC provides PMT and time stamp trigger interrupts,
+ * neither of which are used by this driver.
+ *
+ * Ethernet DMA supports two classes of interrupts: Normal interrupt
+ * summary (NIS) and Abnormal interrupt summary (AIS) with a variety
+ * individual normal and abnormal interrupting events. Here only
+ * the normal receive event is enabled (unless DEBUG is enabled). Transmit
+ * events will only be enabled when a transmit interrupt is expected.
+ */
+
+ putreg32((ETH_DMAINT_RECV_ENABLE | ETH_DMAINT_ERROR_ENABLE), STM32_ETH_DMAIER);
return OK;
}