There are two schemes for accessing the packet buffer area (PMA) from the CPU:
- 2 x 16 bit/word access scheme where two 16-bit half-words per word can be accessed. With this scheme the access can be half-word aligned and the PMA address offset corresponds therefore to the local USB IP address. The size of the PMA SRAM is usually 1024 byte.
- 1 x 16 bit/word access scheme where one 16-bit half word per word can be accessed. With this scheme the access can only be word-aligned and the PMA address offset to a half-word is therefore twice the local USB IP address. The size of the PMA SRAM is usually 512 byte.
Which access scheme is used depends on the STM32 model.
The addressing of the Packet buffer Memory Area (PMA) is done locally in the USB IP core in half-words with 16-bit. The `_ep_in_buf` and `_ep_out_buf` arrays which hold these USB IP local addresses in the PMA for initialized EPs therefore always use `uint16_t`.
If the MCU does not have an internal D+ pullup and there is no dedicated GPIO to simulate a USB disconnect, the D+ GPIO is temporarily configured as an output and pushed down to simulate a disconnect/connect cycle to allow the host to recognize the device. However, this requires an external pullup on D+ signal to work
If `RCC_CFGR_USBPRE` is defined, the USB device FS clock of 48 MHz is derived from the PLL clock. In this case the PLL clock must be configured and must be either 48 MHz or 72 MHz. If the PLL clock is 72 MHz it is pre-divided by 1.5, the PLL clock of 48 MHz is used directly.
For a number of STM32 MCUs with the USB-FS device interface the signals USB_DP and USB_DM are not defined as GPIO alternative function but as additional function. Additional functions are directly selected/enabled through peripheral registers hand have not to be configured. In this case, the configuration defines GIO_AF_UNDEF as alternative function.
Add tracing support via GPIOs to trace the basic state of the Ethernet
peripheral. The following signals are provided:
- One GPIO pin is toggled on entry of the Ethernet ISR
- On TX start an GPIO is set, on TX completion it is cleared
- On RX complete an GPIO is set, once this is passed to the upper layer
the GPIO is cleared again
In order to reduce the overhead, GPIO LL is used. By default the
on-board LEDs are used as tracing GPIOs. This makes it easy to debug
when the state machine gets stuck without the need to attach a scope or
logic analyzer.
A single character type resulted in way fewer TX descriptors being
available than allocated. Not only resulted this in wasting memory,
but also when more iolist chunks than descriptors are send, the
```C
assert(iolist_count(iolist) <= ETH_TX_DESCRIPTOR_COUNT);
```
does not trigger. As a result, old TX descriptors are being overwritten
in this case.
Make sure in `_usbdev_new_ep()` that `usbdev_ep_t::buf` is always aligned to 4
bytes. With this in mind, add intermediate casts to `uintptr_t` before casting
`usbdev_ep_t::buf` to `uint32_t *` to silence `-Wcast-align`, as we now manually
enforced correct alignment.
Fix compilation with module `stm32_eth_link_up` when `stm32_eth_auto`
is not used by relying on the compiler to optimize unused functions
and variables out, rather than using the preprocessor.
- Clear the PTP timer interrupt *after* the user callback is executed
- Otherwise it would be possible that the ISR sets another super
short timeout that triggers during ISR, which also gets cleared
- This is a pretty nasty race condition :-/
- The debug output was a bit too verbose to be generally useful. Some
noise is now silenced unless `DEBUG_VERBOSE` is `#define`d to 1
Deep-sleep was based on using rx pin as external interrupt to be able to
wake up from stop mode. If rx pin cannot be used as interrupt or user
does not need to wake up from stop from the CAN, an option is now
present. If en_deep_sleep_wake_up is set to false, setting the device to
sleep simply unblock stop mode. Otherwise the behavior is unchanged.
In case a non-gpio EXTI (>= 16) is pending, the isr_exti() used to clear
the flag and try to call a callback, which was out-of-bouds, thus
generating a hard fault.
This fixes it by masking the pending_isr variables with 0xFFFF.
Add ENABLE_DEBUG_VERBOSE flag, so that the noise during debugging can be
reduced. This is super helpful when testing under load, as otherwise there is
just too much noise in the output.
An earlier version of periph_eth used to always pack the first chunk of the
outgoing frame to the first DMA descriptor by telling the DMA to jump back
to the first descriptor within the last descriptor. This worked fine unless
the frame was send in one chunk (as e.g. lwip does), which resulted due to a
hardware bug in a frame being send out twice. For that reason, the behavior was
changed to cycle throw the linked DMA descriptor list in round-robin fashion.
However, the error checking was not updated accordingly. Hence, the error
check might run over (parts of) unrelated frames and fail to detect errors
correctly.
This commit fixes the issue and also provides proper return codes for errors.
Additionally, an DMA reset is performed on detected errors during RX/TX. I'm
not sure if/when this is needed, as error conditions are neigh impossible to
produce. But better be safe than sorry.
This commits adds a common type for the block writes to the flash of the
stm32. Depending on the family, the type has a different size. This
allows the removal of a number of ifdefs to track the differences
between families, simplifying the flashpage code
In Engineering mode (BOOT0 off and BOOT2 on), only the Cortex-M4
core is running. It means that all clocks have to be setup
by the Cortex-M4 core.
In other modes, the clocks are setup by the Cortex-A7 and then should
not be setup by Cortex-M4.
stm32mp1_eng_mode pseudomodule have to be used in Engineering mode
to ensure clocks configuration with IS_USED(MODULE_STM32MP1_ENG_MODE)
macro.
This macro can also be used in periph_conf.h to define clock source
for each peripheral.
Signed-off-by: Gilles DOFFE <gilles.doffe@savoirfairelinux.com>
STM32_PM_STOP and STM32_PM_STANDBY are always defined in periph_cpu.h,
Thus it is not needed to test them.
Signed-off-by: Gilles DOFFE <gilles.doffe@savoirfairelinux.com>
According to stm32mp157 documentation:
* "The CStop mode is entered for MCU when the SLEEPDEEP bit in the Cortex®-M4 System Control
register is set." Thus set PM_STOP_CONFIG to 0.
* "The CStandby mode applies only to the MPU sub-system."
Set PM_STANDBY_CONFIG to (0) and do not enter standby mode for
stm32mp1.
As PM_STOP_CONFIG is already defined before for CPU_FAM_STM32WB, replace
it with CPU_FAM_STM32MP1.
Signed-off-by: Gilles DOFFE <gilles.doffe@savoirfairelinux.com>
stm32mp1 is configuring gpio slightly differently that common stm32:
* port_num is computed differently, thus test MCU family to apply
the good calculation.
* Rising and falling edge state on interrupts. Do not test if falling
or rising edge, just launch the callback in all cases.
Signed-off-by: Gilles DOFFE <gilles.doffe@savoirfairelinux.com>
The reception code hands RX DMA descriptors back to the DMA right after its
contents were copied into the network stack internal buffer. This increases
the odds that the DMA never runs out of DMA descriptors to fill, even under
high load. However, the loop fetching the Ethernet frame stops to iterate at the
end of the frame. If the DMA used one more descriptor to store the FCS, this
was not returned back to the DMA. This commit fixes it.
Expose the auto-negotiation feature of the Ethernet device via the
pseudo-module stm32_eth_auto. With this enabled, the static speed configuration
set in the boards periph_conf.h will only be used if the PHY lacks
auto-negotiation capabilities - which is unlikely to ever happen.
Previously, only an link-up event was triggered, not an link down event. And
additionally, once the link-up event was sent, the link status was no longer
monitored. As a result, once a link-up was sent, no further link event were
triggered.
The methods to read from / write to MII registers had an address argument to
allow specifying the PHY to communicate with. However, only a single PHY is
available on all boards supported and the driver is not able to operate with
multiple PHYs anyway - thus, drop this parameter for ease of use.
This fixes a bug in the _get_link_status() function, which used hard coded the
address 0; which might not be correct for all boards.
The link status was previously not returned via the value parameter, as required
by the netdev_driver_t API. As a result, e.g. the `ifconfig` shell command
showed garbage.