From 82c6b5abe05bcf86f7f622a7474da4ff4c463b4c Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 24 Sep 2012 15:51:48 +0000 Subject: [PATCH] Fixes STM32F107 DMA issue git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5182 42af7a65-404d-4744-a932-0658087f49c3 --- arch/arm/src/stm32/chip/stm32_eth.h | 7 +++++-- arch/arm/src/stm32/stm32_eth.c | 16 +++++++++++----- arch/arm/src/stm32/stm32_idle.c | 23 ++++++++++++++++++++++- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/arch/arm/src/stm32/chip/stm32_eth.h b/arch/arm/src/stm32/chip/stm32_eth.h index 0b5ef18ca7a..a4a109d0168 100644 --- a/arch/arm/src/stm32/chip/stm32_eth.h +++ b/arch/arm/src/stm32/chip/stm32_eth.h @@ -711,7 +711,9 @@ /* RDES0: Receive descriptor Word0 */ #define ETH_RDES0_PCE (1 << 0) /* Bit 0: Payload checksum error */ -#define ETH_RDES0_ESA (1 << 0) /* Bit 0: Extended status available */ +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define ETH_RDES0_ESA (1 << 0) /* Bit 0: Extended status available */ +#endif #define ETH_RDES0_CE (1 << 1) /* Bit 1: CRC error */ #define ETH_RDES0_DBE (1 << 2) /* Bit 2: Dribble bit error */ #define ETH_RDES0_RE (1 << 3) /* Bit 3: Receive error */ @@ -735,8 +737,9 @@ /* RDES1: Receive descriptor Word1 */ -#define ETH_RDES1_RBS1_SHIFT (0) /* Bits 0-12: Receive buffer 1 size */ +#define ETH_RDES1_RBS1_SHIFT (0) /* Bits 0-12: Receive buffer 1 size */ #define ETH_RDES1_RBS1_MASK (0x1fff << ETH_RDES1_RBS1_SHIFT) + /* Bit 13: Reserved */ #define ETH_RDES1_RCH (1 << 14) /* Bit 14: Second address chained */ #define ETH_RDES1_RER (1 << 15) /* Bit 15: Receive end of ring */ #define ETH_RDES1_RBS2_SHIFT (16) /* Bits 16-28: Receive buffer 2 size */ diff --git a/arch/arm/src/stm32/stm32_eth.c b/arch/arm/src/stm32/stm32_eth.c index ab9cac209a4..2e892c9e54e 100644 --- a/arch/arm/src/stm32/stm32_eth.c +++ b/arch/arm/src/stm32/stm32_eth.c @@ -186,10 +186,12 @@ #endif /* Add 4 to the configured buffer size to account for the 2 byte checksum - * memory needed at the end of the maximum size packet. + * memory needed at the end of the maximum size packet. Buffer sizes must + * be an even multiple of 4, 8, or 16 bytes (depending on buswidth). We + * will use the 16-byte alignment in all cases. */ -#define OPTIMAL_ETH_BUFSIZE (CONFIG_NET_BUFSIZE+4) +#define OPTIMAL_ETH_BUFSIZE ((CONFIG_NET_BUFSIZE + 4 + 15) & ~15) #ifndef CONFIG_STM32_ETH_BUFSIZE # define CONFIG_STM32_ETH_BUFSIZE OPTIMAL_ETH_BUFSIZE @@ -199,6 +201,10 @@ # error "CONFIG_STM32_ETH_BUFSIZE is too large" #endif +#if (CONFIG_STM32_ETH_BUFSIZE & 15) != 0 +# error "CONFIG_STM32_ETH_BUFSIZE must be aligned" +#endif + #if CONFIG_STM32_ETH_BUFSIZE != OPTIMAL_ETH_BUFSIZE # warning "You using an incomplete/untested configuration" #endif @@ -1470,9 +1476,6 @@ static int stm32_recvframe(FAR struct stm32_ethmac_s *priv) { priv->segments++; - nllvdbg("rxhead: %p rxcurr: %p segments: %d\n", - priv->rxhead, priv->rxcurr, priv->segments); - /* Check if the there is only one segment in the frame */ if (priv->segments == 1) @@ -1484,6 +1487,9 @@ static int stm32_recvframe(FAR struct stm32_ethmac_s *priv) rxcurr = priv->rxcurr; } + nllvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + /* Check if any errors are reported in the frame */ if ((rxdesc->rdes0 & ETH_RDES0_ES) == 0) diff --git a/arch/arm/src/stm32/stm32_idle.c b/arch/arm/src/stm32/stm32_idle.c index 791a79429cc..0b69ff64855 100644 --- a/arch/arm/src/stm32/stm32_idle.c +++ b/arch/arm/src/stm32/stm32_idle.c @@ -45,6 +45,7 @@ #include +#include "chip.h" #include "stm32_pm.h" #include "up_internal.h" @@ -178,11 +179,31 @@ void up_idle(void) up_idlepm(); - /* Sleep until an interrupt occurs to save power */ + /* Sleep until an interrupt occurs to save power. + * + * NOTE: There is an STM32F107 errata that is fixed by the following + * workaround: + * + * "2.17.11 Ethernet DMA not working after WFI/WFE instruction + * Description + * If a WFI/WFE instruction is executed to put the system in sleep mode + * while the Ethernet MAC master clock on the AHB bus matrix is ON and all + * remaining masters clocks are OFF, the Ethernet DMA will be not able to + * perform any AHB master accesses during sleep mode." + * + * Workaround + * Enable DMA1 or DMA2 clocks in the RCC_AHBENR register before + * executing the WFI/WFE instruction." + * + * Here the workaround is just don't go into SLEEP mode for the connectivity + * line parts if Ethernet is enabled. + */ +#if !defined(CONFIG_STM32_CONNECTIVITYLINE) || !defined(CONFIG_STM32_ETHMAC) BEGIN_IDLE(); asm("WFI"); END_IDLE(); #endif +#endif }