Skip to content
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

Add CompositeEMAC and use it to rewrite STM32 Ethernet MAC driver #438

Open
wants to merge 46 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
e2de1c0
Start on EMAC rewrite, but realized I can't do zero copy Tx
multiplemonomials Nov 1, 2024
9d65ab2
multicast test working now!
multiplemonomials Jan 20, 2025
9705115
Working with no hacky workarounds!!!11!11!
multiplemonomials Jan 20, 2025
80b2514
Update Nanostack memory manager, run formatter, make tests test nanos…
multiplemonomials Jan 22, 2025
dfcd9eb
Fix build
multiplemonomials Jan 22, 2025
60372ea
Keep workin' on CompositeEMAC
multiplemonomials Jan 30, 2025
2bdca41
Implement GenericEthPhy
multiplemonomials Feb 3, 2025
c849812
Implement Tx DMA
multiplemonomials Feb 10, 2025
693d111
Start on Rx DMA
multiplemonomials Feb 10, 2025
f9686ed
Finish Rx DMA and multicast subscribes
multiplemonomials Feb 11, 2025
599fc10
Progress on MAC driver
multiplemonomials Feb 13, 2025
8f30f73
Initial implementation of MAC driver complete!
multiplemonomials Feb 14, 2025
7b0d534
CompositeEMAC inits!
multiplemonomials Feb 16, 2025
1a2df8b
Phy task and Tx seem to work!
multiplemonomials Feb 16, 2025
26d4a22
Rx kinda working
multiplemonomials Feb 16, 2025
aeff333
Almost working! Just missing memory freed callback
multiplemonomials Feb 16, 2025
8ed9b44
Woring! Add initial support for STM32H5 as well
multiplemonomials Feb 16, 2025
733b1c0
Fix STM32H5 init
multiplemonomials Feb 18, 2025
c94b760
Ethernet working on STM32H5!
multiplemonomials Feb 18, 2025
5c65117
Run formatter
multiplemonomials Feb 18, 2025
eb03e12
Fix us ticker build error
multiplemonomials Feb 18, 2025
997ae9c
Start on MAC v1 driver
multiplemonomials Feb 20, 2025
0e78241
Working on v1 DMA
multiplemonomials Feb 24, 2025
34999a3
Initial implementation of v1 DMA
multiplemonomials Feb 24, 2025
56ad53a
Fix some bugs, Tx DMA working but no packets are getting transmitted
multiplemonomials Feb 24, 2025
baa5b76
Tx and Rx working!
multiplemonomials Feb 25, 2025
42eb490
Update F2 and F4 eth inits
multiplemonomials Feb 25, 2025
5e27b23
Try to fix bank test
multiplemonomials Feb 25, 2025
8080467
Disable Ethernet in HALs
multiplemonomials Feb 25, 2025
b4e04f8
Apparently old GCC can't do attribute packed + alignas
multiplemonomials Feb 25, 2025
df8ebd7
Add RMII watchdog, add power test, fix unittests build
multiplemonomials Feb 27, 2025
126bfd5
Debugging EMAC reboot test
multiplemonomials Mar 2, 2025
a0145e5
Fix deinit crash on STM32F7
multiplemonomials Mar 2, 2025
7deab95
Fix a couple issues with the power down test
multiplemonomials Mar 12, 2025
292d566
Start on docs
multiplemonomials Mar 12, 2025
0b76925
Oops missed diagram
multiplemonomials Mar 12, 2025
64a973b
Fix typo
multiplemonomials Mar 13, 2025
6b0411f
Bugfix, improve docs
multiplemonomials Mar 16, 2025
2ad785e
Fix PNG
multiplemonomials Mar 16, 2025
65be6a8
More docs, renames
multiplemonomials Mar 17, 2025
491c063
More renames, fix !=
multiplemonomials Mar 23, 2025
0776a75
Document Tx DMA
multiplemonomials Mar 23, 2025
6bc2ef3
Fix some DMA bugs:
multiplemonomials Mar 23, 2025
c8ae2e4
Make EMAC memory test smarter. It now disables pool allocations when …
multiplemonomials Mar 23, 2025
1dc339c
Document most of Rx DMA, do rename
multiplemonomials Mar 23, 2025
3a77ce0
Reformat, fix STM32 Eth v2 potential to have issues when the Tx ring …
multiplemonomials Mar 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion connectivity/drivers/emac/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ if(NOT "DEVICE_EMAC=1" IN_LIST MBED_TARGET_DEFINITIONS)
return()
endif()

add_library(mbed-emac STATIC EXCLUDE_FROM_ALL)
add_library(mbed-emac STATIC EXCLUDE_FROM_ALL
sources/CompositeEMAC.cpp
sources/GenericEthPhy.cpp
sources/PhyDrivers.cpp)

target_include_directories(mbed-emac PUBLIC include)

if("ARM_FM" IN_LIST MBED_TARGET_LABELS)
add_subdirectory(TARGET_ARM_FM)
Expand Down
215 changes: 215 additions & 0 deletions connectivity/drivers/emac/CompositeEMAC.md

Large diffs are not rendered by default.

22 changes: 18 additions & 4 deletions connectivity/drivers/emac/TARGET_STM/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,28 @@ elseif("STM32F7" IN_LIST MBED_TARGET_LABELS)
add_subdirectory(TARGET_STM32F7)
elseif("STM32H7" IN_LIST MBED_TARGET_LABELS)
add_subdirectory(TARGET_STM32H7)
elseif("STM32H5" IN_LIST MBED_TARGET_LABELS)
add_subdirectory(TARGET_STM32H5)
endif()

target_include_directories(mbed-emac
PUBLIC
.
)

target_sources(mbed-emac
PRIVATE
stm32xx_emac.cpp
)
if("STM32H7" IN_LIST MBED_TARGET_LABELS OR "STM32H5" IN_LIST MBED_TARGET_LABELS)
target_sources(mbed-emac
PRIVATE
STM32EthMACv2.cpp
)
endif()

if("STM32F2" IN_LIST MBED_TARGET_LABELS OR "STM32F4" IN_LIST MBED_TARGET_LABELS OR "STM32F7" IN_LIST MBED_TARGET_LABELS)
target_sources(mbed-emac
PRIVATE
STM32EthMACv1.cpp
)
endif()


target_compile_options(mbed-emac PRIVATE -Wno-packed-bitfield-compat)
84 changes: 84 additions & 0 deletions connectivity/drivers/emac/TARGET_STM/STM32EthMACCommon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* Copyright (c) 2025 Jamie Smith
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include "device.h"
#include "CompositeEMAC.h"
#include "MbedCRC.h"

// Figure out the Ethernet IP version in use
#if defined(TARGET_STM32H5) || defined(TARGET_STM32H7)
#define ETH_IP_VERSION_V2
#else
#define ETH_IP_VERSION_V1
#endif

namespace mbed
{
constexpr auto MDIO_TRANSACTION_TIMEOUT = std::chrono::milliseconds(1); // used by STMicro HAL

inline constexpr size_t NUM_PERFECT_FILTER_REGS = 3;
static const std::pair<volatile uint32_t *, volatile uint32_t *> MAC_ADDR_PERF_FILTER_REGS[NUM_PERFECT_FILTER_REGS] = {
{&ETH->MACA1HR, &ETH->MACA1LR},
{&ETH->MACA2HR, &ETH->MACA2LR},
{&ETH->MACA3HR, &ETH->MACA3LR}
};

/// Write a MAC address into the given registers with the needed encoding
static inline void writeMACAddress(const CompositeEMAC::MACAddress & mac, volatile uint32_t *addrHighReg, volatile uint32_t *addrLowReg)
{
/* Set MAC addr bits 32 to 47 */
*addrHighReg = (static_cast<uint32_t>(mac[5]) << 8) | static_cast<uint32_t>(mac[4]) | ETH_MACA1HR_AE_Msk;
/* Set MAC addr bits 0 to 31 */
*addrLowReg = (static_cast<uint32_t>(mac[3]) << 24) | (static_cast<uint32_t>(mac[2]) << 16) |
(static_cast<uint32_t>(mac[1]) << 8) | static_cast<uint32_t>(mac[0]);
}

/// Add a MAC address to the multicast hash filter.
void addHashFilterMAC(ETH_TypeDef * base, const CompositeEMAC::MACAddress & mac) {
#if defined(ETH_IP_VERSION_V2)
uint32_t volatile * hashRegs[] = {
&base->MACHT0R,
&base->MACHT1R
};
#else
uint32_t volatile * hashRegs[] = {
&base->MACHTLR,
&base->MACHTHR
};
#endif

// Note: as always, the datasheet description of how to do this CRC was vague and slightly wrong.
// This forum thread figured it out: https://community.st.com/t5/stm32-mcus-security/calculating-ethernet-multicast-filter-hash-value/td-p/416984
// What the datasheet SHOULD say is:
// Compute the Ethernet CRC-32 of the MAC address, with initial value of 1s, final XOR of ones, and input reflection on but output reflection off
// Then, take the upper 6 bits and use that to index the hash table.

mbed::MbedCRC<POLY_32BIT_ANSI> crcCalc(0xFFFFFFFF, 0xFFFFFFFF, true, false);

// Compute Ethernet CRC-32 of the MAC address
uint32_t crc;
crcCalc.compute(mac.data(), mac.size(), &crc);

// Take upper 6 bits
uint32_t hashVal = crc >> 26;

// Set correct bit in hash filter
*hashRegs[hashVal >> 5] |= (1 << (hashVal & 0x1F));
}

}
Loading