2 Commits ebd371cc18 ... f12956c112

Author SHA1 Message Date
  helen f12956c112 更新MCU驱动(iram和sram-nos) 1 week ago
  helen 4f2d1cc918 更新CPU工程以太网驱动: 1 week ago

+ 3 - 0
amt630hv160-freertos-beta/ArkmicroFiles/libboard-amt630hv160/include/board.h

@@ -380,6 +380,9 @@
 
 /************ eth configuration ************/
 // #define ETH_SUPPORT
+#define ETH_VLAN_EN                     0
+#define ETH_VLAN_ID                     20UL
+#define ETH_VLAN_PRIORITY               2UL
 #define ETH_TXC_PAD_DIR_OUTPUT          1   // 0:TXC作为输入 1:TXC作为输出
 #define PHY_JL3101_SEL                  0
 #define PHY_JL3101_RST_IO               21

+ 14 - 10
amt630hv160-freertos-beta/ArkmicroFiles/libcpu-amt630hv160/source/eth.c

@@ -16,7 +16,7 @@
 #define HAL_Delay(ms)					mdelay(ms)
 
 #define TXC_NORMAL                    0
-#define TXC_INVERSION                 1     
+#define TXC_INVERSION                 1
 
 #define TXC_SRC_TXC_PAD               0
 #define TXC_SRC_RXC_PAD               1
@@ -211,7 +211,7 @@ HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
   }
 
-  /* Enable SYSCFG Clock */
+  /* Clock Config*/
 #if ETH_TXC_PAD_DIR_OUTPUT
   ETH_TXC_SourceSelect(heth, TXC_SRC_RXC_PAD);
 #else
@@ -701,7 +701,7 @@ HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameL
     return HAL_ERROR;
   }
 
-   heth->TxDesc->Status |= ETH_DMATXDESC_IC;
+  heth->TxDesc->Status |= ETH_DMATXDESC_IC;
 
   /* Get the number of needed Tx buffers for the current frame */
   if (FrameLength > ETH_TX_BUF_SIZE)
@@ -1032,7 +1032,6 @@ void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
   }
 }
 
-
 /**
   * @brief  Reads a PHY register
   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
@@ -1579,12 +1578,13 @@ HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
 /** @addtogroup ETH_Private_Functions
   * @{
   */
+
 /**
   * @brief  Configures Ethernet MAC TXC Output Source
   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
   *         the configuration information for ETHERNET module
   * @param  source: TXC_NORMAL or TXC_INVERSION
-  * @retval 
+  * @retval
   */
 static void ETH_TXC_OutputSourceSelect(ETH_HandleTypeDef *heth, int source)
 {
@@ -1605,7 +1605,7 @@ static void ETH_TXC_OutputSourceSelect(ETH_HandleTypeDef *heth, int source)
   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
   *         the configuration information for ETHERNET module
   * @param  source: TXC_SRC_TXC_PAD,TXC_SRC_RXC_PAD or TXC_SRC_RMII_CLK_DIV2
-  * @retval 
+  * @retval
   */
 static void ETH_TXC_SourceSelect(ETH_HandleTypeDef *heth, int source)
 {
@@ -1631,7 +1631,7 @@ static void ETH_TXC_SourceSelect(ETH_HandleTypeDef *heth, int source)
   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
   *         the configuration information for ETHERNET module
   * @param  source: TXC_NORMAL or TXC_INVERSION
-  * @retval 
+  * @retval
   */
 static void ETH_TX_ControllerClockSourceSelect(ETH_HandleTypeDef *heth, int source)
 {
@@ -1655,7 +1655,7 @@ static void ETH_TX_ControllerClockSourceSelect(ETH_HandleTypeDef *heth, int sour
   *                 RX_CTL_CLK_SRC_RXC_PAD_INV,
   *                 RX_CTL_CLK_SRC_RMII_DIV2,
   *                 RX_CTL_CLK_SRC_RMII_DIV2_INV
-  * @retval 
+  * @retval
   */
 static void ETH_RX_ControllerClockSourceSelect(ETH_HandleTypeDef *heth, int source)
 {
@@ -1745,8 +1745,12 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
   macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
   macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
   macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
-  macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
-  macinit.VLANTagIdentifier = 0x0;
+  macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_12BIT;
+#if ETH_VLAN_EN
+  macinit.VLANTagIdentifier = ETH_VLAN_ID;
+#else
+  macinit.VLANTagIdentifier = 0;
+#endif
 
   /*------------------------ ETHERNET MACCR Configuration --------------------*/
   /* Get the ETHERNET MACCR value */

+ 66 - 21
amt630hv160-freertos-beta/FreeRTOS-Plus/FreeRTOS-Plus-TCP/portable/NetworkInterface/Common/phyHandling.c

@@ -354,6 +354,7 @@ BaseType_t xPhyConfigure( EthernetPhy_t * pxPhyObject,
 {
     uint32_t ulConfig, ulAdvertise;
     BaseType_t xPhyIndex;
+    uint32_t regv;
 
     if( pxPhyObject->xPortCount < 1 ) {
         FreeRTOS_printf( ( "xPhyConfigure: No PHY's detected.\n" ) );
@@ -370,7 +371,7 @@ BaseType_t xPhyConfigure( EthernetPhy_t * pxPhyObject,
     else
     {
 
-    ulAdvertise = phyADVERTISE_CSMA;
+        ulAdvertise = phyADVERTISE_CSMA;
         if( pxPhyProperties->ucSpeed == ( uint8_t ) PHY_SPEED_AUTO )
         {
             if( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_FULL )
@@ -452,32 +453,25 @@ BaseType_t xPhyConfigure( EthernetPhy_t * pxPhyObject,
 #else
         pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
 #endif
- 
+
         ulConfig &= ~( phyBMCR_SPEED_100 | phyBMCR_FULL_DUPLEX );
         ulConfig |= phyBMCR_AN_ENABLE;
 
-        if( ( pxPhyProperties->ucSpeed == ( uint8_t ) PHY_SPEED_100 ) || ( pxPhyProperties->ucSpeed == ( uint8_t ) PHY_SPEED_AUTO ) )
-        {
+        if ((pxPhyProperties->ucSpeed == (uint8_t) PHY_SPEED_100) || (pxPhyProperties->ucSpeed == (uint8_t) PHY_SPEED_AUTO)) {
             ulConfig |= phyBMCR_SPEED_100;
-        }
-        else if( pxPhyProperties->ucSpeed == ( uint8_t ) PHY_SPEED_10 )
-        {
+        } else if (pxPhyProperties->ucSpeed == (uint8_t)PHY_SPEED_10) {
             ulConfig &= ~phyBMCR_SPEED_100;
         }
 
-        if( ( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_FULL ) || ( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_AUTO ) )
-        {
+        if ((pxPhyProperties->ucDuplex == (uint8_t) PHY_DUPLEX_FULL) || (pxPhyProperties->ucDuplex == (uint8_t)PHY_DUPLEX_AUTO)) {
             ulConfig |= phyBMCR_FULL_DUPLEX;
-        }
-        else if( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_HALF )
-        {
+        } else if(pxPhyProperties->ucDuplex == (uint8_t)PHY_DUPLEX_HALF) {
             ulConfig &= ~phyBMCR_FULL_DUPLEX;
         }
 
-        switch (pxPhyProperties->ucMacIf) {
-        case PHY_MACIF_MII:
+        /* ÅäÖÃMAC½Ó¿ÚÀàÐÍ */
+        if (pxPhyProperties->ucMacIf == PHY_MACIF_MII) {
             if (ulPhyID == PHY_ID_JL3101) {
-                uint32_t regv;
                 xPhyC45Read(pxPhyObject, xPhyAddress, 3, 0x8000, &regv);
                 if ((regv & 0xf) != 2) {
                     regv &= ~0xf;
@@ -488,14 +482,29 @@ BaseType_t xPhyConfigure( EthernetPhy_t * pxPhyObject,
                     mdelay(4);
                 }
             }
-            break;
-        case PHY_MACIF_RMII:
-            break;
-        default:
-            break;
+        } else if (pxPhyProperties->ucMacIf == PHY_MACIF_RMII) {
+
+        }
+
+        /* ÅäÖÃÖ÷´Ó */
+        if (pxPhyProperties->ucRole == PHY_ROLE_MASTER) {
+            if (ulPhyID == PHY_ID_JL3101) {
+                xPhyC45Read(pxPhyObject, xPhyAddress, 1, 0x834, &regv);
+                regv |= (1UL << 14);
+                xPhyC45Write(pxPhyObject, xPhyAddress, 1, 0x834, regv);
+            }
+        } else if (pxPhyProperties->ucRole == PHY_ROLE_SLAVE) {
+            if (ulPhyID == PHY_ID_JL3101) {
+                xPhyC45Read(pxPhyObject, xPhyAddress, 1, 0x834, &regv);
+                regv &= ~(1UL << 14);
+                xPhyC45Write(pxPhyObject, xPhyAddress, 1, 0x834, regv);
+            }
+        } else {
+
         }
 
-        if( xHas_19_PHYCR( ulPhyID ) ) {
+        /* ½»²æÏßÅäÖà */
+        if (xHas_19_PHYCR(ulPhyID)) {
             uint32_t ulPhyControl;
             /* Read PHY Control register. */
             pxPhyObject->fnPhyRead( xPhyAddress, phyREG_19_PHYCR, &ulPhyControl );
@@ -514,6 +523,42 @@ BaseType_t xPhyConfigure( EthernetPhy_t * pxPhyObject,
             }
             /* update PHY Control Register. */
             pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_19_PHYCR, ulPhyControl );
+        } else {
+            if (pxPhyProperties->ucMDI_X == PHY_MDIX_DIRECT) {
+                if (ulPhyID == PHY_ID_JL3101) {
+                    xPhyC45Read(pxPhyObject, xPhyAddress, 3, 0x8100, &regv);
+                    regv &= ~(1UL << 1);
+                    regv &= ~(1UL << 0);
+                    xPhyC45Write(pxPhyObject, xPhyAddress, 3, 0x8100, regv);
+
+                    xPhyC45Read(pxPhyObject, xPhyAddress, 3, 0x8200, &regv);
+                    regv &= ~(1UL << 1);
+                    regv &= ~(1UL << 0);
+                    xPhyC45Write(pxPhyObject, xPhyAddress, 3, 0x8200, regv);
+
+                    xPhyC45Read(pxPhyObject, xPhyAddress, 1, 0x0, &regv);
+                    regv |= (1UL << 15);
+                    xPhyC45Write(pxPhyObject, xPhyAddress, 1, 0x0, regv);
+                }
+            } else if (pxPhyProperties->ucMDI_X == PHY_MDIX_CROSSED) {
+                if (ulPhyID == PHY_ID_JL3101) {
+                    xPhyC45Read(pxPhyObject, xPhyAddress, 3, 0x8100, &regv);
+                    regv &= ~(1UL << 1);
+                    regv |= (1UL << 0);
+                    xPhyC45Write(pxPhyObject, xPhyAddress, 3, 0x8100, regv);
+
+                    xPhyC45Read(pxPhyObject, xPhyAddress, 3, 0x8200, &regv);
+                    regv &= ~(1UL << 1);
+                    regv &= ~(1UL << 0);
+                    xPhyC45Write(pxPhyObject, xPhyAddress, 3, 0x8200, regv);
+
+                    xPhyC45Read(pxPhyObject, xPhyAddress, 1, 0x0, &regv);
+                    regv |= (1UL << 15);
+                    xPhyC45Write(pxPhyObject, xPhyAddress, 1, 0x0, regv);
+                }
+            } else {
+
+            }
         }
         FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", ulAdvertise, ulConfig ) );
     }

+ 7 - 2
amt630hv160-freertos-beta/FreeRTOS-Plus/FreeRTOS-Plus-TCP/portable/NetworkInterface/include/phyHandling.h

@@ -38,6 +38,11 @@
     #define PHY_MACIF_MII          1
     #define PHY_MACIF_RMII         2
 
+/* Values for PhyProperties_t::ucRole : */
+    #define PHY_ROLE_MASTER        1
+    #define PHY_ROLE_SLAVE         2
+    #define PHY_ROLE_AUTO          3
+
 /* ID's of supported PHY's : */
     #define PHY_ID_LAN8742A        0x0007c130
     #define PHY_ID_LAN8720         0x0007c0f0
@@ -52,7 +57,7 @@
     #define PHY_ID_DP83848I        0x20005C90
 
     #define PHY_ID_RTL8211FD       0x001cc910
-    
+
     #define PHY_ID_JL3101          0x937c4010
 
 
@@ -82,7 +87,7 @@
         uint8_t ucMDI_X; /* MDI-X : Medium Dependent Interface - Crossover */
         uint8_t ucDuplex;
         uint8_t ucMacIf;
-        uint8_t ucSpare;
+        uint8_t ucRole;
     } PhyProperties_t;
 
 

+ 118 - 59
amt630hv160-freertos-beta/lib/lwip/src/netif/ethernetif_hv160.c

@@ -20,6 +20,7 @@
 
 #define niEMAC_HANDLER_TASK_PRIORITY    configMAX_PRIORITIES - 3
 #define configEMAC_TASK_STACK_SIZE      (32 * configMINIMAL_STACK_SIZE)
+#define DCACHE_LINE_SIZE                64ul
 
 #define ETH_DMA_ALL_INTS                                                  \
     ( ETH_DMA_IT_TST | ETH_DMA_IT_PMT | ETH_DMA_IT_MMC | ETH_DMA_IT_NIS | \
@@ -42,21 +43,29 @@ struct ethernetif {
 static ETH_HandleTypeDef xETH;
 
 /* Ethernet Rx MA Descriptor */
-#pragma data_alignment=4
-static ETH_DMADescTypeDef DMARxDscrTab[ ETH_RXBUFNB ];
+#if defined(__ICCARM__) || defined(__ICCRX__)         /* for IAR compiler */
+#pragma data_alignment=DCACHE_LINE_SIZE
+static uint8_t DMARxDscrTab[((ETH_RXBUFNB * sizeof(ETH_DMADescTypeDef) - 1) & ~(DCACHE_LINE_SIZE -1)) + DCACHE_LINE_SIZE];
+#else
+static uint8_t DMARxDscrTab[((ETH_RXBUFNB * sizeof(ETH_DMADescTypeDef) - 1) & ~(DCACHE_LINE_SIZE -1)) + DCACHE_LINE_SIZE] __attribute__((aligned(DCACHE_LINE_SIZE)));
+#endif
 
 /* DMATxDescToClear points to the next TX DMA descriptor
- * that must be cleared by vClearTXBuffers(). */
+ * that must be cleared by vClearTXBuffersFromISR(). */
 static __IO ETH_DMADescTypeDef * DMATxDescToClear;
 
 /* Ethernet Tx DMA Descriptor */
-#pragma data_alignment=4
-static ETH_DMADescTypeDef DMATxDscrTab[ ETH_TXBUFNB ];
+#if defined(__ICCARM__) || defined(__ICCRX__)         /* for IAR compiler */
+#pragma data_alignment=DCACHE_LINE_SIZE
+static uint8_t DMATxDscrTab[((ETH_TXBUFNB * sizeof(ETH_DMADescTypeDef) - 1) & ~(DCACHE_LINE_SIZE -1)) + DCACHE_LINE_SIZE];
+#else
+static uint8_t DMATxDscrTab[((ETH_TXBUFNB * sizeof(ETH_DMADescTypeDef) - 1) & ~(DCACHE_LINE_SIZE -1)) + DCACHE_LINE_SIZE] __attribute__((aligned(DCACHE_LINE_SIZE)));
+#endif
 
 /* xTXDescriptorSemaphore is a counting semaphore with
  * a maximum count of ETH_TXBUFNB, which is the number of
  * DMA TX descriptors. */
-static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
+static QueueHandle_t xTXDescriptorSemaphore = NULL;
 
 /* Holds the handle of the task used as a deferred interrupt processor.  The
  * handle is used so direct notifications can be sent to the task for all EMAC/DMA
@@ -79,8 +88,19 @@ static const PhyProperties_t xPHYProperties =
 #else
     .ucDuplex     = PHY_DUPLEX_AUTO,
 #endif
+
+#if PHY_JL3101_SEL
+    .ucMDI_X      = PHY_MDIX_DIRECT,
+#else
     .ucMDI_X      = PHY_MDIX_AUTO,
+#endif
+
     .ucMacIf      = PHY_MACIF_MII,
+#if PHY_JL3101_SEL
+    .ucRole       = PHY_ROLE_MASTER,
+#else
+    .ucRole       = PHY_ROLE_AUTO,
+#endif
 };
 
 static uint32_t ethernetif_input(void *h);
@@ -91,6 +111,7 @@ static BaseType_t ETH_WriteReg( BaseType_t xAddress,
                             BaseType_t xRegister,
                             uint32_t ulValue );
 static void ETH_PhyCfg(ETH_HandleTypeDef *heth);
+static void vClearTXBuffersFromISR(BaseType_t * const pxHigherPriorityTaskWoken);
 
 static void ETH_MspInitCallback(ETH_HandleTypeDef *heth)
 {
@@ -127,10 +148,9 @@ static void ETH_TxCpltCallback(ETH_HandleTypeDef * heth)
 
     ( void ) heth;
 
-    /* Pass a TX-event and wakeup the prvEMACHandlerTask. */
     if( xEMACTaskHandle != NULL )
     {
-        xTaskNotifyFromISR( xEMACTaskHandle, EMAC_IF_TX_EVENT, eSetBits, &( xHigherPriorityTaskWoken ) );
+        vClearTXBuffersFromISR( &xHigherPriorityTaskWoken );
         portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
     }
 }
@@ -401,18 +421,16 @@ static void prvDMARxDescListInit()
     xETH.Instance->DMARDLAR = ( uint32_t ) DMARxDscrTab;
 }
 
-
-static void vClearTXBuffers()
+static void vClearTXBuffersFromISR(BaseType_t * const pxHigherPriorityTaskWoken)
 {
     __IO ETH_DMADescTypeDef * txLastDescriptor = xETH.TxDesc;
     __IO ETH_DMADescTypeDef * Descriptor;
-    size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
+    size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxQueueMessagesWaitingFromISR(xTXDescriptorSemaphore);
 
     /* This function is called after a TX-completion interrupt.
      * It will release each Network Buffer used in xNetworkInterfaceOutput().
      * 'uxCount' represents the number of descriptors given to DMA for transmission.
      * After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */
-
     Descriptor = (ETH_DMADescTypeDef *)PHY_TO_UNCACHED_VIRT(DMATxDescToClear);
 
     while( ( uxCount > 0 ) && ( ( Descriptor->Status & ETH_DMATXDESC_OWN ) == 0 ) ) {
@@ -425,7 +443,7 @@ static void vClearTXBuffers()
         Descriptor = (ETH_DMADescTypeDef *)PHY_TO_UNCACHED_VIRT(DMATxDescToClear);
         uxCount--;
         /* Tell the counting semaphore that one more TX descriptor is available. */
-        xSemaphoreGive( xTXDescriptorSemaphore );
+        xQueueSendFromISR(xTXDescriptorSemaphore, NULL, pxHigherPriorityTaskWoken);
     }
 }
 
@@ -443,7 +461,7 @@ static void prvEMACHandlerTask(void * pvParameters)
         ulISREvents = 0;
         if (xTXDescriptorSemaphore != NULL) {
             static UBaseType_t uxLowestSemCount = ( UBaseType_t ) ETH_TXBUFNB - 1;
-            uxCurrentCount = uxSemaphoreGetCount( xTXDescriptorSemaphore );
+            uxCurrentCount = uxQueueMessagesWaiting(xTXDescriptorSemaphore);
             if( uxLowestSemCount > uxCurrentCount ) {
                 uxLowestSemCount = uxCurrentCount;
                 printf( "TX DMA buffers: lowest %lu\n", uxLowestSemCount);
@@ -460,12 +478,6 @@ static void prvEMACHandlerTask(void * pvParameters)
             xResult = ethernetif_input((void *)netif);
         }
 
-        if (( ulISREvents & EMAC_IF_TX_EVENT) != 0) {
-            /* Code to release TX buffers in case zero-copy is used. */
-            /* Check if DMA packets have been delivered. */
-            vClearTXBuffers();
-        }
-
         if ((ulISREvents & EMAC_IF_ERR_EVENT) != 0) {
             /* Future extension: logging about errors that occurred. */
         }
@@ -490,6 +502,18 @@ static void prvEMACHandlerTask(void * pvParameters)
     }
 }
 
+#if ETH_VLAN_EN
+static int ETH_TxFrameAddVlanTag(uint8_t *txbuf)
+{
+    txbuf[0] = 0x81;
+    txbuf[1] = 0x00;
+    txbuf[2] = ((ETH_VLAN_PRIORITY & 0x7) << 5) | ((ETH_VLAN_ID & 0xfff) >> 8);
+    txbuf[3] = (ETH_VLAN_ID & 0xff);
+
+    return 0;
+}
+#endif
+
 /*
   Length: max length = ETH_TX_BUF_SIZE
  */
@@ -504,14 +528,23 @@ static int ETH_TransmitFrame(const uint8_t *Data, uint32_t Length)
 
     if (!Data || !Length) {
         printf("[%s] Data = NULL or Length = 0\n", __func__);
-        return ERR_TIMEOUT;
+        return ERR_BUF;
+    }
+
+#if ETH_VLAN_EN
+    if ((Length + 4) > ETH_TX_BUF_SIZE)
+#else
+    if (Length > ETH_TX_BUF_SIZE)
+#endif
+    {
+        printf("[%s] TX Length Error!\n", __func__);
+        return ERR_BUF;
     }
 
     /* Open a do {} while ( 0 ) loop to be able to call break. */
     do {
-        if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS ) {
-            /* Time-out waiting for a free TX descriptor. */
-            printf("xTXDescriptorSemaphore take fail!\n");
+        if (xQueuePeek(xTXDescriptorSemaphore, NULL, xBlockTimeTicks) != pdPASS) {
+            printf("txbuf full!\n");
             break;
         }
 
@@ -523,15 +556,20 @@ static int ETH_TransmitFrame(const uint8_t *Data, uint32_t Length)
         configASSERT( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 );
 
         /* Get bytes in current buffer. */
+#if ETH_VLAN_EN
+        ulTransmitSize = Length + 4;
+        memcpy((void *)pxDmaTxDesc->Buffer1Addr, Data, 12);
+        ETH_TxFrameAddVlanTag((uint8_t *)(pxDmaTxDesc->Buffer1Addr + 12));
+        memcpy((void *)(pxDmaTxDesc->Buffer1Addr + 12 + 4), Data + 12, Length - 12);
+        pxDmaTxDesc->Status |= ETH_DMATXDESC_VF;
+#else
         ulTransmitSize = Length;
-
-        if( ulTransmitSize > ETH_TX_BUF_SIZE ){
-            ulTransmitSize = ETH_TX_BUF_SIZE;
-        }
-
         memcpy((void *)pxDmaTxDesc->Buffer1Addr, Data, ulTransmitSize);
+#endif
         dma_flush_range((uint32_t)(pxDmaTxDesc->Buffer1Addr), (uint32_t)(pxDmaTxDesc->Buffer1Addr) + ulTransmitSize);
 
+        /* Ask to set the IPv4 checksum.
+         * Also need an Interrupt on Completion so that 'vClearTXBuffersFromISR()' will be called.. */
         if( xETH.Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE ) {
             pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL;
         } else {
@@ -539,7 +577,6 @@ static int ETH_TransmitFrame(const uint8_t *Data, uint32_t Length)
         }
         pxDmaTxDesc->Status |= ETH_DMATXDESC_IC;
 
-
         /* Prepare transmit descriptors to give to DMA. */
 
         /* Set LAST and FIRST segment */
@@ -547,13 +584,16 @@ static int ETH_TransmitFrame(const uint8_t *Data, uint32_t Length)
         /* Set frame size */
         pxDmaTxDesc->ControlBufferSize = ( ulTransmitSize & ETH_DMATXDESC_TBS1 );
 
+        vPortEnterCritical();
         /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
         pxDmaTxDesc->Status |= ETH_DMATXDESC_OWN;
-
         /* Point to next descriptor */
-        xETH.TxDesc = ( ETH_DMADescTypeDef * ) ( pxDmaTxDesc->Buffer2NextDescAddr );
+        xETH.TxDesc = (ETH_DMADescTypeDef *) (pxDmaTxDesc->Buffer2NextDescAddr);
         /* Ensure completion of memory access */
         __DSB();
+        /* Update the counting semaphore */
+        xQueueReceive(xTXDescriptorSemaphore, NULL, 0);
+        vPortExitCritical();
 
         /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
         if (((xETH.Instance)->DMASR & ETH_DMASR_TBUS) != 0) {
@@ -568,6 +608,11 @@ static int ETH_TransmitFrame(const uint8_t *Data, uint32_t Length)
     return xReturn;
 }
 
+static int ETH_RxFrameVlanTagHandle(const uint8_t *vlan_tag)
+{
+    return 0;
+}
+
 static struct pbuf *ETH_ReceivedFrame(void)
 {
     BaseType_t xReceivedLength = 0;
@@ -579,8 +624,6 @@ static struct pbuf *ETH_ReceivedFrame(void)
 
     if (( pxDMARxDescriptor->Status & ETH_DMARXDESC_OWN ) == 0u)
     {
-        BaseType_t xAccepted = pdTRUE;
-
         /* Get the Frame Length of the received packet: subtract 4 bytes of the CRC */
         xReceivedLength = ( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4;
 
@@ -597,29 +640,36 @@ static struct pbuf *ETH_ReceivedFrame(void)
         /* In order to make the code easier and faster, only packets in a single buffer
          * will be accepted.  This can be done by making the buffers large enough to
          * hold a complete Ethernet packet, minus ipBUFFER_PADDING.
-         * Therefore, two sanity checks: */
-        configASSERT( xReceivedLength <= ETH_RX_BUF_SIZE );
-
-        if( xAccepted != pdFALSE )
-        {
-            /* The packet will be accepted, but check first if a new Network Buffer can
-             * be obtained. If not, the packet will still be dropped. */
-            Buf = pbuf_alloc(PBUF_RAW, xReceivedLength, PBUF_RAM);
-
-            if( Buf == NULL ) {
-                /* A new descriptor can not be allocated now. This packet will be dropped. */
-                printf("-------------- get NetworkBuffer fail! -----------\n");
-                xAccepted = pdFALSE;
-            } else if (Buf->len < xReceivedLength) {
-                printf("-------------- NewBuf->xDataLength != xReceivedLength! -----------\n");
+         * Therefore, sanity checks: */
+        if (xReceivedLength <= ETH_RX_BUF_SIZE) {
+#if !ETH_VLAN_EN
+            if (!(pxDMARxDescriptor->Status & ETH_DMARXDESC_VLAN))
+#endif
+            {
+                /* The packet will be accepted, but check first if a new Network Buffer can
+                 * be obtained. If not, the packet will still be dropped. */
+                Buf = pbuf_alloc(PBUF_RAW, xReceivedLength, PBUF_RAM);
+
+                if( Buf == NULL ) {
+                    /* A new descriptor can not be allocated now. This packet will be dropped. */
+                    printf("-------------- get NetworkBuffer fail! -----------\n");
+                } else if (Buf->len < xReceivedLength) {
+                    printf("-------------- NewBuf->xDataLength != xReceivedLength! -----------\n");
+                }
             }
         }
-
         if( Buf != NULL ) {
           /* The packet is accepted and a new Network Buffer was created,
            * copy data to the Network Buffer. */
-            memcpy(Buf->payload, pucBuffer, xReceivedLength );
-            Buf->len = xReceivedLength;
+            if (pxDMARxDescriptor->Status & ETH_DMARXDESC_VLAN) {
+                ETH_RxFrameVlanTagHandle((const uint8_t *)(pucBuffer + 12));
+                memcpy(Buf->payload, pucBuffer, 12);
+                memcpy((uint8_t *)(Buf->payload) + 12, pucBuffer + 12 + 4, xReceivedLength - 12 - 4);
+                Buf->len = xReceivedLength - 4;
+            } else {
+                memcpy(Buf->payload, pucBuffer, xReceivedLength);
+                Buf->len = xReceivedLength;
+            }
         }
 
         /* Release descriptors to DMA */
@@ -658,6 +708,7 @@ static struct pbuf *ETH_ReceivedFrame(void)
  */
 static err_t low_level_init(struct netif *netif)
 {
+    int i;
     struct ethernetif *ethernetif = netif->state;
     //int ret = -1;
     const uint8_t mac[6] = {0x02, 0x53, 0x4C, 0x00, 0x00, 0x15};
@@ -699,11 +750,19 @@ static err_t low_level_init(struct netif *netif)
 
 
     /* Do whatever else is needed to initialize interface. */
-    xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );
+    xTXDescriptorSemaphore = xQueueCreate((UBaseType_t )ETH_TXBUFNB, 0);
     if (!xTXDescriptorSemaphore) {
-        printf("%s - Semaphore Create fail!\n", __func__);
+        printf("%s - Queue Create fail!\n", __func__);
         return ERR_IF;
     }
+    for (i = 0; i < ETH_TXBUFNB; i++) {
+        if (xQueueSend(xTXDescriptorSemaphore, NULL, 0) != pdPASS) {
+            printf("fill xTXDescriptorSemaphore fail!\n");
+            vQueueDelete(xTXDescriptorSemaphore);
+            xTXDescriptorSemaphore = NULL;
+            return ERR_IF;
+        }
+    }
 
     /* Initialise ETH */
     xETH.Instance = (ETH_TypeDef *)REGS_ETH_BASE;
@@ -733,18 +792,18 @@ static err_t low_level_init(struct netif *netif)
     request_irq(ETH_IRQn, 0, (ISRFunction_t)HAL_ETH_IRQHandler, (void *)&xETH);
 
     /* Set the TxDesc and RxDesc pointers. */
-    xETH.TxDesc = DMATxDscrTab;
-    xETH.RxDesc = DMARxDscrTab;
+    xETH.TxDesc = (ETH_DMADescTypeDef *)DMATxDscrTab;
+    xETH.RxDesc = (ETH_DMADescTypeDef *)DMARxDscrTab;
 
     /* Make sure that all unused fields are cleared. */
-    memset(&DMATxDscrTab, '\0', sizeof(DMATxDscrTab));
-    memset(&DMARxDscrTab, '\0', sizeof(DMARxDscrTab));
+    memset(DMATxDscrTab, '\0', sizeof(DMATxDscrTab));
+    memset(DMARxDscrTab, '\0', sizeof(DMARxDscrTab));
 
     dma_flush_range((uint32_t)DMATxDscrTab, (uint32_t)DMATxDscrTab + sizeof(DMATxDscrTab));
     dma_flush_range((uint32_t)DMARxDscrTab, (uint32_t)DMARxDscrTab + sizeof(DMARxDscrTab));
 
     /* Initialize Tx Descriptors list: Chain Mode */
-    DMATxDescToClear = DMATxDscrTab;
+    DMATxDescToClear = (ETH_DMADescTypeDef *)DMATxDscrTab;
 
     /* Initialise TX-descriptors. */
     prvDMATxDescListInit();

+ 8 - 0
amt630hv160-mcu/amt630hv160-mcu-iram/src/ArkmicroFiles/libcpu-amt630hv160/source/amt630hv160_rtc.c

@@ -301,6 +301,14 @@ void RTC_SetWakeup(eRTCWakeupSource src, eRTCWakeupMode mode, int enable)
 			val |= 1 << (mbit - 1);
 			break;
 		}
+
+		//CANx force disable of filter to prevent failure to wake up.
+		if ((src == RTC_WAKEUP_CAN1) || (src == RTC_WAKEUP_CAN0)) {
+			mbit = 18 + RTC_WAKEUP_CAN0 - src;
+			val = RTC->RAM_L;
+			val |= (1 << mbit);
+			RTC_WriteReg(RTC_RAML, &RTC->RAM_L, val);
+		}
 	}
 
 	enbit = 26 + (src - RTC_WAKEUP_GPIO1);

+ 1 - 1
amt630hv160-mcu/amt630hv160-mcu-iram/src/lib/sfud/src/sfud.c

@@ -1325,7 +1325,7 @@ sfud_err sfud_read_register(const sfud_flash *flash, uint32_t addr, uint8_t *val
                     return result;
                 }
                 *value = (((tmp_data[0] << 16) | (tmp_data[1] << 8) | tmp_data[2]) >> (16 - dummy_cycles_cnt)) & 0xff;
-                if ((*value & 0xf) != dummy_cycles_cnt) {
+                if ((addr == 0x00000003) && ((*value & 0xf) != dummy_cycles_cnt)) {
                     return SFUD_ERR_READ;
                 }
             }

+ 18 - 0
amt630hv160-mcu/amt630hv160-mcu-iram/src/main.c

@@ -539,6 +539,24 @@ static void MainTask(void *pvParameters)
 				}
 			}
 
+			//prevent the bit 3 of CFG3x from being 1.
+			result = sfud_read_register(sflash, 0x00800004, &status, SFUD_CMD_READ_REGISTER_INFINEON);
+			if (result != SFUD_SUCCESS) {
+				printf("sfud read CFR3N status register fail\n");
+				vTaskDelete(NULL);
+				return;
+			}
+			//printf("CFR3N status:0x%x.\n", status);
+			if (status & (1 << 3)) {
+				status &= ~(1 << 3);	//forceclear
+				result = sfud_write_register(sflash, 0x00000004, status, SFUD_CMD_WRITE_REGISTER_INFINEON);
+				if (result != SFUD_SUCCESS) {
+					printf("sfud write CFR3N status register fail\n");
+					vTaskDelete(NULL);
+					return;
+				}
+			}
+
 			/* 为了兼容其它型号的nor flash,将dummy cycle由原默认值 8 配置为 4 (非易失)*/
 			//read CFRV2
 			result = sfud_read_register(sflash, 0x00000003, &status, SFUD_CMD_READ_REGISTER_INFINEON);

+ 8 - 0
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/ArkmicroFiles/libcpu-amt630hv160/source/amt630hv160_rtc.c

@@ -301,6 +301,14 @@ void RTC_SetWakeup(eRTCWakeupSource src, eRTCWakeupMode mode, int enable)
 			val |= 1 << (mbit - 1);
 			break;
 		}
+
+		//CANx force disable of filter to prevent failure to wake up.
+		if ((src == RTC_WAKEUP_CAN1) || (src == RTC_WAKEUP_CAN0)) {
+			mbit = 18 + RTC_WAKEUP_CAN0 - src;
+			val = RTC->RAM_L;
+			val |= (1 << mbit);
+			RTC_WriteReg(RTC_RAML, &RTC->RAM_L, val);
+		}
 	}
 
 	enbit = 26 + (src - RTC_WAKEUP_GPIO1);

+ 1 - 1
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/lib/sfud/src/sfud.c

@@ -1325,7 +1325,7 @@ sfud_err sfud_read_register(const sfud_flash *flash, uint32_t addr, uint8_t *val
                     return result;
                 }
                 *value = (((tmp_data[0] << 16) | (tmp_data[1] << 8) | tmp_data[2]) >> (16 - dummy_cycles_cnt)) & 0xff;
-                if ((*value & 0xf) != dummy_cycles_cnt) {
+                if ((addr == 0x00000003) && ((*value & 0xf) != dummy_cycles_cnt)) {
                     return SFUD_ERR_READ;
                 }
             }

+ 16 - 0
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/main.c

@@ -299,6 +299,22 @@ int main(void)
 				}
 			}
 
+			//prevent the bit 3 of CFG3x from being 1.
+			result = sfud_read_register(sflash, 0x00800004, &status, SFUD_CMD_READ_REGISTER_INFINEON);
+			if (result != SFUD_SUCCESS) {
+				printf("sfud read CFR3N status register fail\n");
+				while(1);
+			}
+			//printf("CFR3N status:0x%x.\n", status);
+			if (status & (1 << 3)) {
+				status &= ~(1 << 3);	//forceclear
+				result = sfud_write_register(sflash, 0x00000004, status, SFUD_CMD_WRITE_REGISTER_INFINEON);
+				if (result != SFUD_SUCCESS) {
+					printf("sfud write CFR3N status register fail\n");
+					while(1);
+				}
+			}
+
 			/* 为了兼容其它型号的nor flash,将dummy cycle由原默认值 8 配置为 4 (非易失)*/
 			//read CFRV2
 			result = sfud_read_register(sflash, 0x00000003, &status, SFUD_CMD_READ_REGISTER_INFINEON);