| Age | Commit message (Collapse) | Author |
|
# Conflicts:
# .claude/skills/hil/SKILL.md
# test/hil/hil_test.py
|
|
nrf_clock_is_running() was added in nrfx 2.1.0 (MDK 8.30.2), but the
version autodetect puts 2.0.0 (MDK 8.29.0) in the v2 bucket, so
hfclk_running() fails to compile on that nrfx.
Route v2 through nrf_clock_hf_is_running(), which all of 2.x provides.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
|
USBD drops tasks during EasyDMA without the 0x40027C1C latch (anomaly 199);
matches the nrfx reference driver.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
|
|
* license: use SPDX identifiers for src/ headers
Replace the full ~20-line MIT license boilerplate on every src/ file with a
two-line SPDX tag (SPDX-FileCopyrightText + SPDX-License-Identifier), following
the REUSE convention used by CircuitPython and the Linux kernel. Removes ~3500
lines of duplicated boilerplate.
|
|
USB_EVT_DETECTED runs hfclk_enable() which, when SoftDevice is not yet
enabled, starts HFXO via direct CLOCK register access. After
sd_softdevice_enable() takes over CLOCK, HFXO is physically off again
and SD's HFCLK reference count is 0.
If USB_EVT_READY is fired post-SD (e.g. on nRF52 via Bluefruit's
usb_softdevice_post_enable() when the pre-SD nrfx_power READY callback
didn't get to run before nrfx_power was uninited), the wait loop
'while (!hfclk_running()) {}' calls sd_clock_hfclk_is_running() which
returns false forever -> deadlock that blocks both USB enumeration and
any further app code on the calling thread.
Call hfclk_enable() right before the wait so HFCLK is requested in
whichever context (SD or direct) is current. hfclk_enable() is
idempotent.
Reproduces reliably with bleuart on Feather nRF52840 Express flashed
via JLink: chip wedges in sd_clock_hfclk_is_running SVC, no USB
enumeration, no BLE advertising. With the fix, USB enumerates and BLE
advertises as expected.
|
|
|
|
|
|
copilot/fix-dcd-edpt-xfer-issue
Signed-off-by: HiFiPhile <[email protected]>
|
|
as default driver implementation. dcd_edpt_close() is deprecated and will be removed from all driver in the future.
|
|
Co-authored-by: Copilot <[email protected]>
|
|
Co-authored-by: HiFiPhile <[email protected]>
|
|
|
|
* change TUD_EPBUF_TYPE_DEF order
* add and fix -Wmissing-prototypes warnings for cmake (skip make)
|
|
|
|
consistent
|
|
|
|
|
|
|
|
|
|
|
|
needs DI/EI at one point
|
|
|
|
|
|
- compile nrf with __STARTUP_CLEAR_BSS and link flag -nostartfiles
|
|
|
|
- allow to force nrfx version with CFG_TUD_NRF_NRFX_VERSION=1
|
|
|
|
|
|
|
|
|
|
|
|
NRF5x USB controller can detect ISO OUT CRC errors.
In such case USBEVENT is signaled with EVENTCAUSE_ISOOUTCRC set.
Even if controller detects corrupted ISO OUT packet it allows
to data transfer from ednpoint to RAM however packet is corrupted
and code could just as well drop packet altogether.
With current implementation incoming ISO OUT packets were put in
FIFO and exact information how much data already in FIFO is correct
was hard to keep track of.
If was observed that on certain configurations HS hub when FS device
was connected occasionally sent invalid (short) packet. In such case
if packet length was reported odd audio stream was not recognizable any
more.
With this change corrupted packets are not passed to upper layers
and are silently dropped.
|
|
When ISO endpoint handling was introduced two lines that
clear stall and data toggle bit were left unchanged and they
were effective for ISO enadpoint as well.
This is incorrect behavior since EPSTALL and DTOGGLE registers
have only 3 bits for address.
Leaving code that clears toggle bit results in endpoint 0 toggle bit
being reset when iso endpoint (8) is opened.
Now code that clears stall and toggle bit is applied to non-iso endpoint only
as it was done before iso handling was introduced.
|
|
|
|
temporarily disable codespell
|
|
For incoming ISO OUT packets it was possible to start
DMA from endpoint to RAM before transfer was started
resulting in unrelated memory corruption.
This is scenario that causes memory corruption:
- ISO OUT packet is received
- Packet is transferred by DMA to transfer buffer
- xfer->started is cleared and xfer->buffer is updated as
it is in every case
- Application takes to long to handle it (it happens when debugger
is connected breakpoint is hit slowing down software).
- Next ISO OUT packet arrives
At this point there was no check if transfer was started and packet
was copied by DMA to location beyond previous data, possibly overwriting
unrelated memory.
This solves the issue by checking that transfer was
started and there is buffer ready for incoming packet.
|
|
|
|
ISO packet size is up to 1023 for full speed device.
Upon completion of ISO reception, reported length of incoming packet
was truncated to one byte only.
This results in incorrect data stream for higher bit rates
48 samples * 4 bytes per sample * 2 channels = 384 bytes of data
and 128 was reported.
There is no change in logic extending xact_len to uint16_t fixes the issue.
|
|
Field started (regardind transfer) was only cleaed when transfer
was finished.
For audio devices set interface is called many times.
When there is no audio (silence) set interface requests zero
lenght bandwithd that in turn calls dcd_edpt_close().
When endpoint is closed due to set interface request transfer
should not longer be started since it will block next start transfer
with assert.
This just sets 'started' to false when endpoint is closed.
|
|
There were two problems:
- dma_running flag could be checked in USB interrupt (not set yet) then higher priority
interrupt could start transfer, check dma_running (not set yet) set it to true start
DMA; then when USB interrupt continues it starts another DMA that is not allowed
- when DMA is started some registers can't be safely accessed, read can yield invalid
values (SIZE.EPOUT, SIZE.EPISO)
current implementation could start DMA for one OUT endpoint then check that another
endpoint also has data and while DMA was not started right away, SIZE.EPOUT was copied
already to MAXCNT register. Later on when DMA was started not all data was read from
endpoint due to incorrect DMA size previously set.
To prevent both cases dma_running is changed in atomic way.
Only code that actually set this value to true starts DMA, code that tried and
had dma_running flag already set simply defers DMA start to USB task.
This eliminates also need to have mutex that was there to limit access to dma_running flag
to one task only.
transfer also now has started flag that is set only after dcd_edpt_xfer() sets up total_len
and actua_len. Previously USB interrupt was disabled when total_len and actual_len were
setup to prevent race condition when data arrived to ednpoint before transfer was setup
was finished.
|
|
|
|
TUSB_OPT_DEVICE_ENABLED still usable for backward compatible
|
|
When two tasks entered dcd_edpt_xfer() it was possible that
first disabled interrupt to setup total_len and actual_len
but second task for another endpoint enabled interrupt
between total_len and actual_len resulting in race
condition with interrupt, hence mutex is added on top of interrupt being blocked.
|
|
In multi-thread mode starting DMA in thread mode was
prone to race condition resulting in infinite loop.
It may happen on single core CPU with strict priority based
tasks scheduler where ready high prio task never yields to
ready low prio task (Mynewt).
Sequence that failed (T1 - low priority task, T2 - high priority task)
- T1 called start_dma()
- T1 set _dcd.dma_running (DMA not started yet, context switch happens)
- T2 took CPU and saw that _dcd.dma_running is set, so waits for _dcd.dma_running to be 0
- T1 never gets CPU again, DMA is not started T2 waits forever
OSAL mutex resolves problem of DMA starting from thread-context.
|
|
nrf5x: Fix EP OUT race conditions
|
|
Mynewt (similar to Soft Device) has its own reference counting for
HFXO oscillator.
So far TinyUSB requested HFXO when VBUS was detected and stopped when
VBUS was removed.
But with Mynewt running HFXO can be stopped when other interested parties
don't require HFXO anymore. This results in very difficult to track
USB transmission errors.
This change enables Mynewt specific HFXO management in Soft Device fashion.
|
|
When dcd_edpt_xfer() starts new transfer two separate problems were observed.
For both problems stream of OUT packets was pouring from host.
First problem was that total_len and actual_len were not atomic.
In case where incoming OUT packets are less (63) than MPS (64), actual_len and total_len
are set 63.
Then transfer complete from USBD is called that will schedule next 64 bytes transfer.
At that point incoming packet would start DMA if there is place in RAM, normally
it does not happen since actual_len == total_len.
If packets arrives and interrupt is raised after total_len is set (64) but actual_len is still 63 from
previous transfer, interrupt code sees that there is place in ram (1 byte) and transfer this 1 byte
to buffer that was already filled with previous packet.
To remedy this USB interrupt is blocked during transfer setup.
Second problem can happen when dcd_edpt_xfer setups xfer->total_len and actual_len correctly
but then context switch happens before xfer->data_received is checked.
If during this time two packets arrive one will be copied to RAM second will stay in endpoint with
data_received set to 1.
Then when xfer_edpt_xfer() checks data_receive flag it starts DMA again overwriting data.
To remedy this, data_received is checked together with check if data was already transferred.
If transfer was complete, there is no need to start DMA yet.
In such case data_received will be handled in same place by next xfer_edpt_xfer() correctly.
|
|
When NRF5x device is reset by software (after DFU for example),
power event is ready from the beginning.
When power interrupt is triggered before tud_init() finished
USBD_IRQn is enabled before it would be enabled in tud_init().
This in turn may result in BUS RESET event being sent from
USB interrupt to USB task when queue is not initialized yet.
This scenario often happens in Mynewt build where queue creation
takes more time.
To prevent this scenario USBD_IRQn is not enabled in power event
interrupt handler before dcd_init() was called.
|
|
|
|
|