|
各位大佬,我使用STM32H743IIT6的以太网外设,软件使用了SOEM实现EtherCAT的主站,当然也使用了UCOSIII+LVGL+SD+FATFS一系列的中间件,USB HOST使用了ST官方的中间件。现在的问题是开机后系统能正常启动SOEM主站,带8台从站没有压力,但是一插U盘多数情况下就会死机,极少数情况不死机,也会导致从站掉线,报通信错误。开机前插上u盘没问题,可以正常识别u盘,但是拔下来再插上就会死机。我检查了ETH的DMA地址,是0x30040000开始,USB HOST使用了全速模式,好像没有使用DMA,不知道哪里的问题,已经困扰我有一段时间了,不知哪位大佬也碰到过类似问题,能否指点一下,小弟不胜感激。/**
******************************************************************************
* @file eth.c
* @brief This file provides code for the configuration
* of the ETH instances.
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "eth.h"
#include "lan8742.h"
#include "string.h"
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma location=0x30040000
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
#pragma location=0x30040060
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
#pragma location=0x30040200
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_MAX_PACKET_SIZE]; /* Ethernet Receive Buffers */
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
//0x30000000~0x30040000Ç°ÃæµÄ256KBÄÚ´æÎ´Ê¹ÓÃ
//ETH_DMADescTypeDef Êý¾Ý½á¹¹Õ¼Óà 6*SIZEOF(UINT32) = 24×Ö½Ú
__attribute__((at(0x30040000))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors ETH_RX_DESC_CNT = 4 */
__attribute__((at(0x30040060))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors ETH_TX_DESC_CNT = 4 */
__attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_MAX_PACKET_SIZE]; /* Ethernet Receive Buffer ETH_MAX_PACKET_SIZE = 1528×Ö½Ú ½ÓÊÕ»º³åÇø×Ü¼Æ 1528 * 4 = 6112×Ö½Ú */
__attribute__((at(0x30042000))) uint8_t Tx_Buff[ETH_TX_DESC_CNT][ETH_MAX_PACKET_SIZE]; /* Ethernet Receive Buffer ETH_MAX_PACKET_SIZE = 1528×Ö½Ú ·¢ËÍ»º³åÇø×Ü¼Æ 1528 * 4 = 6112×Ö½Ú */
// __attribute__((at(0x30044000))) char IOmap[8192]; //Õ¼ÓõØÖ·0x30044000~0x30045fff, ÔÚecatuser.cÎļþÀïÃæ¶¨Òå
#elif defined ( __GNUC__ ) /* GNU Compiler */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_MAX_PACKET_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */
#endif
//#define ETH_USE_POLL
#define ETH_USE_INT //ʹÓÃec_dcsync0µÄCycle_Shift²ÎÊýÉèΪSYNC0TIME/3
#if defined (ETH_USE_INT)
volatile uint8_t sendfinishflag = 0;
#endif
ETH_TxPacketConfig TxConfig;
/* USER CODE BEGIN 0 */
uint8_t RecvLength=0;
uint32_t current_pbuf_idx =0;
/* USER CODE END 0 */
ETH_HandleTypeDef heth;
/* ETH init function */
static void MX_ETH_Init(void)
{
/* USER CODE BEGIN ETH_Init 0 */
HAL_ETH_MspDeInit(&heth);
HAL_Delay(10);
__HAL_RCC_ETH1MAC_FORCE_RESET();
__HAL_RCC_ETH1MAC_RELEASE_RESET();
__HAL_ETH_DMA_CLEAR_IT(&heth, ETH_DMACSR_RI | ETH_DMACSR_NIS);
__HAL_ETH_DMA_CLEAR_IT(&heth, ETH_DMACSR_TI | ETH_DMACSR_NIS);
__HAL_ETH_DMA_CLEAR_IT(&heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
ETH_DMACSR_RBU | ETH_DMACSR_AIS));
/* USER CODE END ETH_Init 0 */
/* USER CODE BEGIN ETH_Init 1 */
//ÔÚstm32h7xx_hal_conf.hÀïÃæ¶¨Òå
// #define ETH_MAC_ADDR0 ((uint8_t)0x02)
// #define ETH_MAC_ADDR1 ((uint8_t)0x00)
// #define ETH_MAC_ADDR2 ((uint8_t)0x00)
// #define ETH_MAC_ADDR3 ((uint8_t)0x00)
// #define ETH_MAC_ADDR4 ((uint8_t)0x00)
// #define ETH_MAC_ADDR5 ((uint8_t)0x00)
/* USER CODE END ETH_Init 1 */
heth.Instance = ETH;
heth.Init.MACAddr[0] = ETH_MAC_ADDR0;
heth.Init.MACAddr[1] = ETH_MAC_ADDR1;
heth.Init.MACAddr[2] = ETH_MAC_ADDR2;
heth.Init.MACAddr[3] = ETH_MAC_ADDR3;
heth.Init.MACAddr[4] = ETH_MAC_ADDR4;
heth.Init.MACAddr[5] = ETH_MAC_ADDR5;
heth.Init.MediaInterface = HAL_ETH_RMII_MODE;
heth.Init.TxDesc = DMATxDscrTab;
heth.Init.RxDesc = DMARxDscrTab;
heth.Init.RxBuffLen = 1524;
/* USER CODE BEGIN MACADDRESS */
/* USER CODE END MACADDRESS */
if (HAL_ETH_Init(&heth) != HAL_OK)
{
Error_Handler();
}
memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));
TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
/* USER CODE BEGIN ETH_Init 2 */
/* USER CODE END ETH_Init 2 */
}
void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle)
{
GPIO_InitTypeDef GPIO_Initure = {0};
if(ethHandle->Instance==ETH)
{
/* USER CODE BEGIN ETH_MspInit 0 */
/* USER CODE END ETH_MspInit 0 */
/* ETH clock enable */
__HAL_RCC_ETH1MAC_CLK_ENABLE();
__HAL_RCC_ETH1TX_CLK_ENABLE();
__HAL_RCC_ETH1RX_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/**ETH GPIO Configuration
PB13 ------> ETH_TXD1
PB12 ------> ETH_TXD0
PB11 ------> ETH_TX_EN
PC1 ------> ETH_MDC
PA1 ------> ETH_REF_CLK
PC4 ------> ETH_RXD0
PA2 ------> ETH_MDIO
PC5 ------> ETH_RXD1
PA7 ------> ETH_CRS_DV
PH6 ------> ETH_RESET CM101S_V1.10
PH8 ------> ETH_RESET CM101S_V1.07
*/
GPIO_Initure.Pin=LAN8720A_RESET_Pin; //PH6
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //ÍÆÍìÊä³ö
GPIO_Initure.Pull=GPIO_PULLUP; //ÉÏÀ­
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH; //¸ßËÙ
HAL_GPIO_Init(LAN8720A_RESET_Port,&GPIO_Initure); //³õʼ»¯ H8
GPIO_Initure.Pin=GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7;
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //ÍÆÍ츴ÓÃ
GPIO_Initure.Pull=GPIO_NOPULL; //²»´øÉÏÏÂÀ­
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH; //¸ßËÙ
GPIO_Initure.Alternate=GPIO_AF11_ETH; //¸´ÓÃΪETH¹¦ÄÜ
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //³õʼ»¯
//PB11,PB12,PB13
GPIO_Initure.Pin=GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13; //PB11,PB12,PB13
HAL_GPIO_Init(GPIOB,&GPIO_Initure); //³õʼ»¯
//PC1,4,5
GPIO_Initure.Pin=GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5; //PC1,4,5
HAL_GPIO_Init(GPIOC,&GPIO_Initure); //³õʼ»¯
#if defined (ETH_USE_INT)
HAL_NVIC_SetPriority(ETH_IRQn, 1, 0); //ÍøÂçÖжÏÓÅÏȼ¶Ó¦¸Ã¸ßÒ»µã
HAL_NVIC_EnableIRQ(ETH_IRQn);
#endif
/* USER CODE BEGIN ETH_MspInit 1 */
/* USER CODE END ETH_MspInit 1 */
}
}
void HAL_ETH_MspDeInit(ETH_HandleTypeDef* ethHandle)
{
if(ethHandle->Instance==ETH)
{
/* USER CODE BEGIN ETH_MspDeInit 0 */
/* USER CODE END ETH_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ETH1MAC_CLK_DISABLE();
__HAL_RCC_ETH1TX_CLK_DISABLE();
__HAL_RCC_ETH1RX_CLK_DISABLE();
/**ETH GPIO Configuration
PB13 ------> ETH_TXD1
PB12 ------> ETH_TXD0
PB11 ------> ETH_TX_EN
PC1 ------> ETH_MDC
PA1 ------> ETH_REF_CLK
PC4 ------> ETH_RXD0
PA2 ------> ETH_MDIO
PC5 ------> ETH_RXD1
PA7 ------> ETH_CRS_DV
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13);
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7);
/* USER CODE BEGIN ETH_MspDeInit 1 */
HAL_GPIO_DeInit(LAN8720A_RESET_Port, LAN8720A_RESET_Pin); //PH8
/* USER CODE END ETH_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
void PHY_Init(void)
{
uint32_t idx, duplex, speed = 0;
int32_t PHYLinkState;
ETH_MACConfigTypeDef MACConf;
ETH_MACFilterConfigTypeDef filterDef;
MX_ETH_Init(); //³õʼ»¯MCUµÄMACµØÖ·,ETHÍâÉè¿ÚÏߣ¬¼¤»îʱÖÓ£¬È·¶¨LAN8720AÕâ¸öоƬÒѾ­º¸½ÓÁË¡£
HAL_ETH_GetMACFilterConfig(&heth,&filterDef);
filterDef.PromiscuousMode = ENABLE;
HAL_ETH_SetMACFilterConfig(&heth,&filterDef);
for(idx = 0; idx < ETH_RX_DESC_CNT; idx ++)
{
HAL_ETH_DescAssignMemory(&heth, idx, Rx_Buff[idx], NULL);
}
LAN8742_Init();
do
{
HAL_Delay(100);
PHYLinkState = LAN8742_GetLinkState();
printf("LAN8720A_GetLinkState = %d \r\n",PHYLinkState);
speed++;
if(speed > 60) //6ÃëºóÍ˳ö
{
PHYLinkState = LAN8742_STATUS_100MBITS_FULLDUPLEX;
break;
}
}while(PHYLinkState <= LAN8742_STATUS_LINK_DOWN);
switch (PHYLinkState)
{
case LAN8742_STATUS_100MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_100M;
printf("LAN8720A_STATUS_100MBITS_FULLDUPLEX \r\n");
break;
case LAN8742_STATUS_100MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_100M;
printf("LAN8720A_STATUS_100MBITS_HALFDUPLEX \r\n");
break;
case LAN8742_STATUS_10MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_10M;
printf("LAN8720A_STATUS_10MBITS_FULLDUPLEX \r\n");
break;
case LAN8742_STATUS_10MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_10M;
printf("LAN8720A_STATUS_10MBITS_HALFDUPLEX \r\n");
break;
default:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_100M;
printf("ETH_FULLDUPLEX_MODE ETH_SPEED_100M\r\n");
break;
}
/* Get MAC Config MAC */
HAL_ETH_GetMACConfig(&heth, &MACConf);
MACConf.DuplexMode = duplex;
MACConf.Speed = speed;
MACConf.TransmitQueueMode = ETH_TRANSMITTHRESHOLD_128;
HAL_ETH_SetMACConfig(&heth, &MACConf);
#if defined (ETH_USE_POLL)
HAL_ETH_Start(&heth);
#elif defined (ETH_USE_INT)
HAL_ETH_Start_IT(&heth);
#endif
HAL_ETH_BuildRxDescriptors(&heth);
}
void low_level_output(uint8_t *p,uint32_t length)
{
uint32_t framelen = 0;
ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef));
Txbuffer[0].buffer = p;
Txbuffer[0].len = length;
framelen += length;
TxConfig.Length = framelen;
TxConfig.TxBuffer = Txbuffer;
SCB_CleanInvalidateDCache();
#if defined (ETH_USE_POLL)
//BLOCK·½Ê½·¢ËÍ£¬³¬Ê±Ê±¼ä0~5ms
HAL_ETH_Transmit(&heth, &TxConfig, 2);
#elif defined (ETH_USE_INT)
//ÖжϷ½Ê½
while( sendfinishflag == 1 );
HAL_ETH_Transmit_IT(&heth, &TxConfig);
sendfinishflag = 1;
#endif
}
void low_level_input()
{
}
//±»ecx_outframe·¢Ëͺ¯Êýµ÷ÓÃ, ÔÚnicdrv.cÎļþÀﶨÒå
int bfin_EMAC_send (void *packet, int length)
{
memcpy(&Tx_Buff[0][0],packet,length);
low_level_output(Tx_Buff[0],length);
return 0;
}
//±»ecx_recvpkt½ÓÊÕº¯Êýµ÷ÓÃ, ÔÚnicdrv.cÎļþÀﶨÒå
int bfin_EMAC_recv (uint8_t * packet, size_t size)
{
ETH_BufferTypeDef RxBuff;
uint32_t framelength = 0;
SCB_CleanInvalidateDCache();
HAL_StatusTypeDef status = HAL_ETH_GetRxDataBuffer(&heth, &RxBuff);
if( status == HAL_OK)
{
HAL_ETH_GetRxDataLength(&heth, &framelength);
SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_MAX_PACKET_SIZE));
// printf("Recv = %d current_pbuf_idx=%d\r\n",framelength,current_pbuf_idx);
// printfBuffer(&Rx_Buff[current_pbuf_idx][0],framelength);
memcpy(packet, Rx_Buff[current_pbuf_idx], framelength);
if(current_pbuf_idx < (ETH_RX_DESC_CNT -1))
{
current_pbuf_idx++;
}
else
{
current_pbuf_idx = 0;
}
/* Invalidate data cache for ETH Rx Buffers */
HAL_ETH_BuildRxDescriptors(&heth);
return framelength;
}
return -1;
}
#if defined (ETH_USE_INT)
//½ÓÊջص÷º¯Êý
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
{
//// low_level_input();
//// printf("rx isr\r\n");
}
//·¢Ëͻص÷º¯Êý
void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
{
sendfinishflag = 0;
//// printf("tx isr\r\n");
}
//ÖжϷþÎñº¯Êý
void ETH_IRQHandler(void)
{
//// //Çå³ýÖжϱê־λ
//// __HAL_ETH_DMA_CLEAR_IT(&heth,ETH_DMA_NORMAL_IT); //Çå³ýDMAÖжϱê־λ
//// __HAL_ETH_DMA_CLEAR_IT(&heth,ETH_DMA_RX_IT); //Çå³ýDMA½ÓÊÕÖжϱê־λ
//// __HAL_ETH_DMA_CLEAR_IT(&heth,ETH_DMA_TX_IT); //Çå³ýDMA½ÓÊÕÖжϱê־λ
HAL_ETH_IRQHandler(&heth);
}
#endif
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|