-
Notifications
You must be signed in to change notification settings - Fork 3k
STM32 EMAC : add configuration choice and connection check #12464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1b40076
c3653c6
89a537b
c3c0928
01a186a
b15dffa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,4 @@ | |
|
||
#define ETH_IP_VERSION_V1 | ||
|
||
#define THREAD_STACKSIZE 512 | ||
|
||
#endif // #define STM32XX_EMAC_CONFIG_H__ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,4 @@ | |
|
||
#define ETH_IP_VERSION_V1 | ||
|
||
#define THREAD_STACKSIZE 512 | ||
|
||
#endif // #define STM32XX_EMAC_CONFIG_H__ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,4 @@ | |
|
||
#define ETH_IP_VERSION_V1 | ||
|
||
#define THREAD_STACKSIZE 512 | ||
|
||
#endif // #define STM32XX_EMAC_CONFIG_H__ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,4 @@ | |
|
||
#define ETH_IP_VERSION_V2 | ||
|
||
#define THREAD_STACKSIZE 512 | ||
|
||
#endif // #define STM32XX_EMAC_CONFIG_H__ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,22 @@ | |
#include "stm32xx_emac_config.h" | ||
#include "stm32xx_emac.h" | ||
|
||
#include "mbed-trace/mbed_trace.h" | ||
|
||
#if defined(ETH_IP_VERSION_V2) | ||
#define TRACE_GROUP "STE2" | ||
#else | ||
#define TRACE_GROUP "STE1" | ||
#endif | ||
|
||
/* mbed trace feature is supported */ | ||
/* ex in mbed_app.json */ | ||
/* "mbed-trace.enable": "1" */ | ||
|
||
/* mbed_trace: debug traces (tr_debug) can be disabled here with no change in mbed_app.json */ | ||
// #undef TRACE_LEVEL_DEBUG | ||
// #define TRACE_LEVEL_DEBUG 0 | ||
|
||
#if defined(ETH_IP_VERSION_V2) | ||
#include "lan8742/lan8742.h" | ||
#include "lwip/memp.h" | ||
|
@@ -43,7 +59,6 @@ | |
#define THREAD_PRIORITY (osPriorityHigh) | ||
|
||
#define PHY_TASK_PERIOD_MS 200 | ||
#define ETH_PHY_ADDRESS MBED_CONF_STM32_EMAC_ETH_PHYADDR | ||
|
||
#define STM_HWADDR_SIZE (6) | ||
#define STM_ETH_MTU_SIZE 1500 | ||
|
@@ -276,13 +291,15 @@ static osThreadId_t create_new_thread(const char *threadName, void (*thread)(voi | |
bool STM32_EMAC::low_level_init_successful() | ||
#ifndef ETH_IP_VERSION_V2 | ||
{ | ||
uint32_t PHY_ID; | ||
|
||
/* Init ETH */ | ||
uint8_t MACAddr[6]; | ||
EthHandle.Instance = ETH; | ||
EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE; | ||
EthHandle.Init.Speed = ETH_SPEED_100M; | ||
EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX; | ||
EthHandle.Init.PhyAddress = ETH_PHY_ADDRESS; | ||
EthHandle.Init.AutoNegotiation = MBED_CONF_STM32_EMAC_ETH_PHY_AUTONEGOTIATION; | ||
EthHandle.Init.Speed = MBED_CONF_STM32_EMAC_ETH_PHY_SPEED; | ||
EthHandle.Init.DuplexMode = MBED_CONF_STM32_EMAC_ETH_PHY_DUPLEXMODE; | ||
EthHandle.Init.PhyAddress = MBED_CONF_STM32_EMAC_ETH_PHY_ADDRESS; | ||
#if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE) | ||
MACAddr[0] = MBED_MAC_ADDR_0; | ||
MACAddr[1] = MBED_MAC_ADDR_1; | ||
|
@@ -297,20 +314,48 @@ bool STM32_EMAC::low_level_init_successful() | |
EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE; | ||
EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE; | ||
EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII; | ||
HAL_ETH_Init(&EthHandle); | ||
tr_info("PHY Addr %u AutoNegotiation %u", EthHandle.Init.PhyAddress, EthHandle.Init.AutoNegotiation); | ||
tr_debug("MAC Addr %02x:%02x:%02x:%02x:%02x:%02x", MACAddr[0], MACAddr[1], MACAddr[2], MACAddr[3], MACAddr[4], MACAddr[5]); | ||
tr_info("ETH buffers : %u Rx %u Tx", ETH_RXBUFNB, ETH_TXBUFNB); | ||
|
||
if (HAL_ETH_Init(&EthHandle) != HAL_OK) { | ||
tr_error("HAL_ETH_Init issue"); | ||
return false; | ||
} | ||
|
||
uint32_t TempRegisterValue; | ||
if (HAL_ETH_ReadPHYRegister(&EthHandle, 2, &TempRegisterValue) != HAL_OK) { | ||
tr_error("HAL_ETH_ReadPHYRegister 2 issue"); | ||
} | ||
PHY_ID = (TempRegisterValue << 16); | ||
if (HAL_ETH_ReadPHYRegister(&EthHandle, 3, &TempRegisterValue) != HAL_OK) { | ||
tr_error("HAL_ETH_ReadPHYRegister 3 issue"); | ||
} | ||
PHY_ID |= (TempRegisterValue & 0XFFF0); | ||
tr_info("PHY ID %#X", PHY_ID); | ||
|
||
/* Initialize Tx Descriptors list: Chain Mode */ | ||
HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); | ||
if (HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB) != HAL_OK) { | ||
tr_error("HAL_ETH_DMATxDescListInit issue"); | ||
return false; | ||
} | ||
|
||
/* Initialize Rx Descriptors list: Chain Mode */ | ||
HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); | ||
if (HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB) != HAL_OK) { | ||
tr_error("HAL_ETH_DMARxDescListInit issue"); | ||
return false; | ||
} | ||
|
||
/* Configure MAC */ | ||
_eth_config_mac(&EthHandle); | ||
|
||
/* Enable MAC and DMA transmission and reception */ | ||
HAL_ETH_Start(&EthHandle); | ||
if (HAL_ETH_Start(&EthHandle) != HAL_OK) { | ||
tr_error("HAL_ETH_Start issue"); | ||
return false; | ||
} | ||
|
||
tr_info("low_level_init_successful"); | ||
return true; | ||
} | ||
#else // ETH_IP_VERSION_V2 | ||
|
@@ -338,6 +383,9 @@ bool STM32_EMAC::low_level_init_successful() | |
EthHandle.Init.TxDesc = DMATxDscrTab; | ||
EthHandle.Init.RxBuffLen = 1524; | ||
|
||
tr_debug("MAC Addr %02x:%02x:%02x:%02x:%02x:%02x", MACAddr[0], MACAddr[1], MACAddr[2], MACAddr[3], MACAddr[4], MACAddr[5]); | ||
tr_info("ETH buffers : %u Rx %u Tx", ETH_RX_DESC_CNT, ETH_TX_DESC_CNT); | ||
|
||
if (HAL_ETH_Init(&EthHandle) != HAL_OK) { | ||
return false; | ||
} | ||
|
@@ -351,6 +399,7 @@ bool STM32_EMAC::low_level_init_successful() | |
HAL_ETH_DescAssignMemory(&EthHandle, idx, Rx_Buff[idx], NULL); | ||
} | ||
|
||
tr_info("low_level_init_successful"); | ||
return _phy_init(); | ||
} | ||
#endif // ETH_IP_VERSION_V2 | ||
|
@@ -371,7 +420,7 @@ bool STM32_EMAC::low_level_init_successful() | |
bool STM32_EMAC::link_out(emac_mem_buf_t *buf) | ||
#ifndef ETH_IP_VERSION_V2 | ||
{ | ||
bool success; | ||
bool success = true; | ||
emac_mem_buf_t *q; | ||
uint8_t *buffer = reinterpret_cast<uint8_t *>(EthHandle.TxDesc->Buffer1Addr); | ||
__IO ETH_DMADescTypeDef *DmaTxDesc; | ||
|
@@ -425,9 +474,10 @@ bool STM32_EMAC::link_out(emac_mem_buf_t *buf) | |
} | ||
|
||
/* Prepare transmit descriptors to give to DMA */ | ||
HAL_ETH_TransmitFrame(&EthHandle, framelength); | ||
|
||
success = true; | ||
if (HAL_ETH_TransmitFrame(&EthHandle, framelength) != HAL_OK) { | ||
tr_error("HAL_ETH_TransmitFrame issue"); | ||
success = false; | ||
} | ||
|
||
error: | ||
|
||
|
@@ -465,7 +515,7 @@ bool STM32_EMAC::link_out(emac_mem_buf_t *buf) | |
/* copy frame from pbufs to driver buffers */ | ||
for (q = p; q != NULL; q = q->next) { | ||
if (i >= ETH_TX_DESC_CNT) { | ||
printf("Error : ETH_TX_DESC_CNT not sufficient\n"); | ||
tr_error("Error : ETH_TX_DESC_CNT not sufficient"); | ||
goto error; | ||
} | ||
|
||
|
@@ -491,7 +541,7 @@ bool STM32_EMAC::link_out(emac_mem_buf_t *buf) | |
if (status == HAL_OK) { | ||
success = 1; | ||
} else { | ||
printf("Error returned by HAL_ETH_Transmit (%d)\n", status); | ||
tr_error("Error returned by HAL_ETH_Transmit (%d)", status); | ||
success = 0; | ||
} | ||
|
||
|
@@ -530,6 +580,7 @@ int STM32_EMAC::low_level_input(emac_mem_buf_t **buf) | |
|
||
/* get received frame */ | ||
if (HAL_ETH_GetReceivedFrame_IT(&EthHandle) != HAL_OK) { | ||
tr_debug("low_level_input no frame"); | ||
return -1; | ||
} | ||
|
||
|
@@ -541,6 +592,7 @@ int STM32_EMAC::low_level_input(emac_mem_buf_t **buf) | |
dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc; | ||
|
||
if (len > 0 && len <= ETH_RX_BUF_SIZE) { | ||
tr_debug("low_level_input len %u", len); | ||
/* Allocate a memory buffer chain from buffer pool */ | ||
*buf = memory_manager->alloc_pool(len, 0); | ||
} | ||
|
@@ -599,7 +651,7 @@ int STM32_EMAC::low_level_input(emac_mem_buf_t **buf) | |
|
||
if (HAL_ETH_GetRxDataBuffer(&EthHandle, &RxBuff) == HAL_OK) { | ||
if (HAL_ETH_GetRxDataLength(&EthHandle, &frameLength) != HAL_OK) { | ||
printf("Error: returned by HAL_ETH_GetRxDataLength\n"); | ||
tr_error("Error: returned by HAL_ETH_GetRxDataLength"); | ||
return -1; | ||
} | ||
|
||
|
@@ -669,14 +721,18 @@ void STM32_EMAC::phy_task() | |
uint32_t status; | ||
|
||
if (HAL_ETH_ReadPHYRegister(&EthHandle, PHY_BSR, &status) == HAL_OK) { | ||
if (emac_link_state_cb) { | ||
if ((emac_link_state_cb) && (status != 0xFFFF)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Edit: |
||
if ((status & PHY_LINKED_STATUS) && !(phy_status & PHY_LINKED_STATUS)) { | ||
tr_info("emac_link_state_cb set to true"); | ||
emac_link_state_cb(true); | ||
} else if (!(status & PHY_LINKED_STATUS) && (phy_status & PHY_LINKED_STATUS)) { | ||
tr_info("emac_link_state_cb set to false"); | ||
emac_link_state_cb(false); | ||
} | ||
} | ||
phy_status = status; | ||
} else { | ||
tr_error("HAL_ETH_ReadPHYRegister issue"); | ||
} | ||
|
||
} | ||
|
@@ -713,8 +769,10 @@ void STM32_EMAC::phy_task() | |
if (emac_link_state_cb) { | ||
if (is_up && !was_up) { | ||
emac_link_state_cb(true); | ||
tr_info("emac_link_state_cb set to true"); | ||
} else if (!is_up && was_up) { | ||
emac_link_state_cb(false); | ||
tr_info("emac_link_state_cb set to false"); | ||
} | ||
} | ||
|
||
|
@@ -821,6 +879,8 @@ void mbed_default_mac_address(char *mac) | |
|
||
bool STM32_EMAC::power_up() | ||
{ | ||
tr_info("power_up"); | ||
|
||
sleep_manager_lock_deep_sleep(); | ||
|
||
/* Initialize the hardware */ | ||
|
@@ -829,13 +889,13 @@ bool STM32_EMAC::power_up() | |
} | ||
|
||
/* Worker thread */ | ||
thread = create_new_thread("stm32_emac_thread", &STM32_EMAC::thread_function, this, THREAD_STACKSIZE, THREAD_PRIORITY, &thread_cb); | ||
thread = create_new_thread("stm32_emac_thread", &STM32_EMAC::thread_function, this, MBED_CONF_STM32_EMAC_THREAD_STACKSIZE, THREAD_PRIORITY, &thread_cb); | ||
|
||
phy_task_handle = mbed::mbed_event_queue()->call_every(PHY_TASK_PERIOD_MS, mbed::callback(this, &STM32_EMAC::phy_task)); | ||
|
||
#if defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx)\ | ||
|| defined (STM32F779xx) | ||
rmii_watchdog_thread = create_new_thread("stm32_rmii_watchdog", &STM32_EMAC::rmii_watchdog_thread_function, this, THREAD_STACKSIZE, THREAD_PRIORITY, &rmii_watchdog_thread_cb); | ||
rmii_watchdog_thread = create_new_thread("stm32_rmii_watchdog", &STM32_EMAC::rmii_watchdog_thread_function, this, 128, THREAD_PRIORITY, &rmii_watchdog_thread_cb); | ||
#endif | ||
|
||
/* Allow the PHY task to detect the initial link state and set up the proper flags */ | ||
|
@@ -904,6 +964,8 @@ void STM32_EMAC::set_all_multicast(bool all) | |
|
||
void STM32_EMAC::power_down() | ||
{ | ||
tr_info("power_down"); | ||
|
||
/* No-op at this stage */ | ||
sleep_manager_unlock_deep_sleep(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about increasing the value automatically when the trace is enabled? I think for an user it is difficult to guess a valid stacksize when it is configurable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During my tests, I didn't see any big difference...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the adjustable stacksize come in from this:
#12416 (comment)
usually its a system thread and should have a fixed threadsize. Are there other cases than this special with trace enabled where stacksize can be a problem?