Wire the RTL8720F to the shared Ameba I2C master driver
(arch/arm/src/common/ameba/ameba_i2c.c), reusing it unchanged.
Add the per-chip header arch/arm/src/rtl8720f/ameba_i2c_chip.h supplying
the chip's I2C wiring: two controllers (I2C0/I2C1) on their non-secure
register aliases (0x401c8000 / 0x401c9000), the APBPeriph function/clock
masks, the crossbar SCL/SDA pad-mux codes (59/60 and 61/62), and
AMEBA_I2C_HAS_DMA_FIELDS=1 (the chip's I2C_InitTypeDef carries the DMA
request-level fields).
Add the board glue: rtl8720f_i2c.c registers I2C0 at /dev/i2c0
(PA22/PA23) and I2C1 at /dev/i2c1 (PA24/PA25), plus the build wiring
(Make.defs / CMakeLists.txt / ameba_board.mk pull in the common driver
and the fwlib ram_common/ameba_i2c.c data-table source), the bringup
registration hook and the board header declaration.
Add the i2c defconfig (minimal NSH with the i2ctool) and document the
config in the board index.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
Wire the shared common UART driver
(arch/arm/src/common/ameba/ameba_uart.c) into RTL8720F. Add an
ameba_uart_chip.h supplying the per-chip UART parameters: two
general-purpose controllers (UART0/UART1), their non-secure register
bases (0x401C3000 / 0x401C4000 -- the fwlib UART_DEV_TABLE points at
the non-secure alias), NVIC vectors, APBPeriph function/clock masks
and the crossbar TX/RX pad-mux function codes.
The fwlib ROM UART routines index data tables (UART_DEV_TABLE,
APBPeriph_UARTx) that live in fwlib ram_common/ameba_uart.c, so that
source is compiled in when CONFIG_AMEBA_UART is set. Wire
CONFIG_AMEBA_UART into Make.defs/CMakeLists/ameba_board.mk, add the
board port table (UART0 at /dev/ttyS1, PA22 TX / PA23 RX, 115200 8N1)
with bringup registration, a uart config and board documentation.
Hardware-verified on rtl8720f_evb: serialrx/serialblaster over a
PA22-to-PA23 TX/RX loopback transferred all 2600 bytes intact.
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
RTL8720F drives all GPIO through a single 32-pin port A controller
served by one NVIC vector, unlike RTL8721Dx (ports A/B) or RTL8721F
(ports A/B/C). Add an ameba_gpio_chip.h that configures the shared
common GPIO driver (arch/arm/src/common/ameba/ameba_gpio.c) for a
single port: AMEBA_GPIO_NPORTS=1, AMEBA_GPIO_PORT_IRQS={GPIOA} and
the APBPeriph_GPIO gate bits.
GPIO_INTStatusGet/ClearEdge live in the RTL8720F ROM symbol table, so
no fwlib ram_common object needs compiling in. Wire CONFIG_AMEBA_GPIO
into Make.defs/CMakeLists/Kconfig, add the board pin table (PA22 out,
PA23 in, PA24 interrupt) with bringup registration and a gpio config.
Hardware-verified on rtl8720f_evb: output, input and (falling-edge)
interrupt all confirmed via a PA22-to-PA24 loopback.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
stm32_waitresponse() polls SDIO_STA bounded only by an iteration
counter, set to 0x7fffffff for all R1/R1B/R2/R4/R5/R6 commands. The
hardware CTIMEOUT flag is the intended exit for a missing response,
but it is only generated while the card clock is running and the CPSM
has reached its Wait state. If the card clock stops or the peripheral
fails, SDIO_STA never updates and the loop spins for INT32_MAX
iterations while holding the FAT filesystem lock, at the caller's
priority-inheritance boosted priority if higher priority tasks block
on the filesystem. Since the mmcsd layer retries failed commands,
the driver's recovery paths are never reached and the system never
recovers.
Bound the wait by time instead: 250 ms for response-bearing commands
(the largest timeout the SD specification allows for any operation)
and 10 ms for the no-response/R3/R7 cases. CTIMEOUT remains the
normal error exit within microseconds; the software bound only fires
when the peripheral itself is dead, converting an unbounded spin into
-ETIMEDOUT so the existing mmcsd retry logic can run.
Signed-off-by: Luka Filipović <filipovicluka3@gmail.com>
Assisted-by: Claude Code:claude-fable-5
Wire the shared Ameba I2C master lower-half (arch/arm/src/common/
ameba/ameba_i2c.c) into the RTL8721F (amebagreen2) build through a
per-chip header (ameba_i2c_chip.h), and register the RTL8721F EVB
buses at /dev/i2cN.
Per-chip differences from the other Ameba SoCs (non-secure register
bases, crossbar pinmux codes, APB clock masks and the fwlib
I2C_InitTypeDef layout) are isolated in ameba_i2c_chip.h; no change to
the shared driver is needed.
Verified end-to-end on hardware against a second Ameba board acting
as an I2C slave: address ACK, register write and read-back over
repeated-START, and bus scan all pass on I2C0 (PA22/PA23).
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Add a shared NuttX I2C master lower-half for the Realtek Ameba I2C
controllers (I2C0/I2C1) in arch/arm/src/common/ameba, driven through
the SDK fwlib in polling mode. Per-chip wiring (controller count,
register bases, clock masks, crossbar pad-mux codes and the fwlib
I2C_InitTypeDef layout) lives in arch/arm/src/rtl8721dx/ameba_i2c_chip.h
so a port to the other Ameba chips only supplies a same-named header.
Each controller registers as /dev/i2cN from pke8721daf bring-up through
the stock I2C character driver; a dedicated `i2c` defconfig drives the
i2ctool for validation.
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Correct the number of GPIO ports (STM32_NPORTS) from 8 to 9 and include
GPIOI in the g_gpiobase array. Also fix the comparison that would
prevent the GPIOI clock from being enabled (this is really a no-op,
though).
Signed-off-by: Darryl Ring <darryl@bluerobotics.com>
Expose the RTL8721F general-purpose UARTs through the shared Ameba serial
driver in arch/arm/src/common/ameba. Only the chip-specific glue is added:
a new ameba_uart_chip.h supplying the green2 register bases, IRQs, clock
masks and UART TX/RX pin-mux function codes, plus the build wiring and a
board port table registering UART0 at /dev/ttyS1. The common serial layer
is reused unchanged.
A new "uart" board config enables the driver with the serialrx and
serialblaster examples and runtime TERMIOS support.
Verified on RTL8721F EVB hardware with a PA24/PA25 loopback: single-message
echo, 2600-byte serialrx/serialblaster throughput with no loss, and TERMIOS
reconfiguration (CS7 data-bit truncation, parity and stop-bit ioctl
round-trip, and 9600 baud reprogramming) all pass.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
In a kernel build the cloning primitives are reached through a system call,
and armv7-a dispatches one by re-pointing the caller's own exception frame at
dispatch_syscall() and switching to the task's kernel stack. The snapshot the
entry point in fork.S takes for itself therefore describes the kernel-side
stub, and the frames below it are on a stack the child gets no copy of: a
child built from that snapshot resumes at a kernel address with a stack
pointer into its own user stack. It faulted with a prefetch abort at PC 0 on
qemu-armv7a:knsh, which is why the fork family had never been run there.
Record what the caller was actually doing instead. arm_syscall() stores the
exception frame of the outermost system call in xcp.sregs, mirroring
riscv_swint.c, and arm_fork() chooses where the caller's registers live:
arm_fork_syscall() when a user stack pointer is saved, rebuilding the child
from xcp.sregs so that it returns from the very same SVC
as the parent, in the same mode, on its own stack and
with no inherited system call nesting;
arm_fork_direct() otherwise -- the flat build, a kernel thread in any
build, and a build without a kernel stack, where the
call is dispatched on the caller's own stack so the
caller's frames are copied along with the kernel-side
ones.
Note that the discriminator is xcp.ustkptr rather than TCB_FLAG_SYSCALL. On
armv7-a the caller is the task that runs the kernel side of its own system
call, so being in a system call is not by itself a reason to distrust the
snapshot; the switch to the kernel stack is. Because arm_syscall() has
already re-pointed the frame by the time arm_fork() runs, the caller's PC,
CPSR and SP come from where arm_syscall() put them -- syscall[0].sysreturn,
syscall[0].cpsr and ustkptr -- and the rest from the frame itself.
Nothing selects the primitives on an ARM kernel build yet, so this commit
changes no configuration; it is what the next one needs to be correct.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
NuttX implemented fork() and vfork() as the same function. Both were libc
wrappers around a single up_fork() syscall; vfork() differed only by a
trailing waitpid(). Underneath, the child joined the parent's address
environment -- the same addrenv_join() that pthread_create() uses -- and got
a private copy of the stack. So the child shared .data, .bss and the heap
with its parent and ran concurrently with it.
That is not fork(). It is vfork()-with-a-private-stack under fork()'s name,
and the history says so: today's fork() is NuttX's old vfork(), renamed in
c33d1c9c97 (2023) without any change of behaviour. The failure was silent --
a program written against POSIX fork() compiled, ran, and had its child's
writes land in the parent's variables.
Separate them into two primitives, chosen by which function the caller
called rather than by what the hardware happens to be:
fork() child gets its own copy of the parent's memory at the same
virtual addresses; runs concurrently. Only where an address
environment can be duplicated -- elsewhere it is not declared at
all, so calling it is a build error naming the function.
vfork() child shares the parent's memory; parent suspended until the
child _exit()s or exec()s. Implementable everywhere.
Below libc there is still one syscall. up_fork() gains a bool saying which
primitive the caller used, since the per-architecture register snapshot is
the same for both, and passes it to nxtask_setup_fork(), which is the single
place the memory semantics are decided. The argument arrives in the first
argument register and is never touched: each architecture's snapshot takes
some other call-clobbered register for its scratch, so the flag is simply
still there when the C worker is called.
The vfork() parent suspension moves out of libc into nxtask_start_fork(),
released from nxsched_release_tcb() by nxtask_resume_vfork(). Two things
follow: the parent is resumed at exec(), since exec_swap() has already handed
the child's pid to the loaded program by the time the vfork stub exits, and
vfork() no longer depends on CONFIG_SCHED_WAITPID.
Releasing there requires one fix in nxtask_exit(). It raises rtcb->lockcount
directly rather than through sched_lock() while it tears the TCB down, so the
nxsem_post() that wakes the vfork() parent leaves it queued where a blocked
task collects while pre-emption is off -- g_pendingtasks, or g_readytorun on
SMP -- and the matching raw lockcount-- does not publish it the way
sched_unlock() would, leaving the parent stranded with nothing to move it on.
The fix mirrors sched_unlock() for each case: nxsched_merge_pending(), or
nxsched_deliver_task() under CONFIG_SMP. Both are no-ops while pre-emption is
still disabled, and up_exit() re-reads this_task() afterwards, so a change of
the ready-to-run head is honoured. Without it vfork() deadlocks wherever no
other task happens to call sched_unlock() afterwards -- rv-virt:nsh64 and
rv-virt:pnsh64, where NSH is blocked in waitpid() holding the lock, and
qemu-armv8a:citest_smp, which hangs the moment the vfork() test runs.
fork() is built on a new addrenv_fork(), backed by an up_addrenv_fork() hook
that duplicates an address environment into freshly allocated pages mapped at
the same virtual addresses -- unlike up_addrenv_clone(), which copies only
the representation and leaves both pointing at the same page tables. The
child then adopts the parent's stack geometry rather than being given a
relocated copy: a pointer to a stack local taken before fork() must name the
same object in the child that it named in the parent, and the parent's stack
is already in the duplicate, with its contents, at the parent's address.
No architecture implements up_addrenv_fork() yet, so this commit leaves
fork() unavailable everywhere. That is the intended state. It withdraws
fork() from ARCH_ARM, flat ARCH_ARM64, ARCH_RISCV, ARCH_SIM and ARCH_X86_64,
where until now it named the sharing primitive; per-architecture patches
restore it, with POSIX semantics, as up_addrenv_fork() lands. In the
meantime the sharing primitive is still there under the name that describes
it: vfork() for a child that runs a program, pthread_create() for a second
flow of control that shares memory, posix_spawn() for both at once.
Kconfig: ARCH_HAVE_VFORK inherits ARCH_HAVE_FORK's select lines, conditions
included, so no configuration gains machinery; ARCH_HAVE_FORK is redefined to
mean "can provide POSIX fork() semantics" and now depends on ARCH_ADDRENV.
There is one deliberate departure from "verbatim". ARCH_ARM selected the
fork family unconditionally, BUILD_KERNEL included, and that has never
worked: on a kernel build the architecture's fork entry point sees the
kernel's return address and stack pointer rather than the caller's, so the
child resumes at a kernel address. On qemu-armv7a:knsh master faults in
ostest's fork case with "Child did not run" and then a data abort; without
the condition this change faults the same way through vfork(). ARCH_ARM64
and ARCH_X86_64 already carried "if !BUILD_KERNEL" for exactly this reason --
ARM was the outlier. Conditioning it turns a runtime fault into an honest
absence, which is the whole point of the change; arch/arm takes the condition
off again in the patch that adds its saved-syscall-frame path. Only the
MMU-capable ARM ports are affected, since Cortex-M cannot build BUILD_KERNEL
at all.
Also fixes two latent syntax errors found on the way: a missing comma in
riscv_fork.c and mips_fork.c, both in *_FRAMEPOINTER && !SAVE_GP branches
that are never compiled today.
BREAKING CHANGE: fork() is withdrawn from every architecture. It is no
longer declared in unistd.h, so code that calls it fails to build with an error
naming the function, and the sharing behaviour it used to have is gone rather
than renamed. CONFIG_ARCH_HAVE_FORK no longer means "fork() exists"; it means
"this configuration can provide POSIX fork() semantics", and no architecture
selects it yet.
Quick fix, chosen by why the call was made:
to run a program vfork() + exec*(), or better posix_spawn()
a second flow of control that pthread_create()
shares the caller's memory
a genuinely independent copy keep fork(), and wait for the per-arch patch
of the process that implements up_addrenv_fork() and selects
CONFIG_ARCH_HAVE_FORK
Out-of-tree code that tests CONFIG_ARCH_HAVE_FORK to decide whether a
fork-then-exec path is available wants CONFIG_ARCH_HAVE_VFORK instead, which is
selected in exactly the places CONFIG_ARCH_HAVE_FORK used to be. The full
migration guide is Documentation/guides/fork_vfork_migration.rst.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
This change fixes NuttX’s CMake support when NuttX is embedded
in another project via add_subdirectory(). CMake’s CMAKE_SOURCE_DIR
and CMAKE_BINARY_DIR refer to the outermost project, causing NuttX
to access its .config, generated files, host tools, and build artifacts
in the parent project’s directories. The fix introduces NUTTX_DIR and
NUTTX_BINARY_DIR, based on CMAKE_CURRENT_SOURCE_DIR and
CMAKE_CURRENT_BINARY_DIR, and consistently uses them for NuttX
self-references while preserving existing standalone builds. It fixes
the Kconfig initialization failure reported in #19697 and allows an
embedded sim:nsh build to configure, build, and boot successfully.
The change affects only the CMake build system (not Make or Kconfig
defaults), requires the corresponding nuttx-apps change, and does not
extend add_subdirectory() support to cross-compiled non-sim boards due
to CMake’s toolchain-file limitation.
Fixes#19697.
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Alan Carvalho de Assis <acassis@gmail.com>
Add CONFIG_NRF52_SAADC_CONTINUOUS for gapless timer-triggered sampling
with double-buffered EasyDMA. The SAADC is auto-restarted directly from
the END event through a PPI channel (no CPU in the loop) and each
completed buffer is delivered to the ADC upper half via the batch
interface. Enables high-rate single-channel streaming.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
A packet received while the request queue was empty was silently dropped
and the transfer deadlocked. Hold it in the endpoint buffer until the
class driver submits a read request.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
A data IN endpoint has a single hardware buffer, but the driver armed
the next packet before the host had read the previous one, silently
overwriting it and dropping data under sustained bulk IN traffic. Track
an armed-packet-in-flight state per endpoint (epinflight) and defer
re-arming until the host read completes (EPDATASTATUS), sending the next
packet from nrf52_epdatainterrupt(). Also release the DMA lock right
after the busy-wait for ENDEPIN on data endpoints so other endpoints do
not stall on an interrupt round-trip.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
STM32_STM32L0 does not select STM32_HAVE_SYSCFG, so STM32_SYSCFG does not
exist for this family and the clock of the peripheral is never enabled. The
mapping of a pin to an EXTI line lives in SYSCFG_EXTICR, so every write to it
was dropped and a GPIO interrupt on any port other than port A never fired.
STM32_SYSCFG is default y, so no configuration changes.
Assisted-by: Claude Code 4.8
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
Allow zero-length I2C transfers when DEBUGASSERT is enabled.
Zero-length transfers (used for I2C bus scanning) never access the
transfer buffer, so any EasyDMA pointer is valid.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
stm32_i2c_init() and stm32_i2c_deinit() hardcoded APB1LENR/APB1LRSTR
while taking the enable and reset bits from the per-instance config.
That is correct for I2C1-3, but I2C4 is on APB4: its clk_bit and
reset_bit are RCC_APB4ENR_I2C4EN and RCC_APB4RSTR_I2C4RST, both bit 7,
and bit 7 of APB1LENR/APB1LRSTR is TIM13.
So for I2C4 the driver enabled and pulsed the reset of TIM13 instead,
and never reset the I2C4 peripheral at all. I2C4 still works because
rcc_enableapb4() enables I2C4EN at boot, but the peripheral reset that
stm32_i2c_reset() (CONFIG_I2C_RESET) relies on to clear a wedged I2C
state machine never happens, and deinit gates TIM13 while leaving the
I2C4 clock running.
Store the clock enable and reset register addresses in
struct stm32_i2c_config_s next to the bits, and use them in
stm32_i2c_init() and stm32_i2c_deinit().
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
Use CONFIG_STM32_UART8_SERIALDRIVER so g_uart8rxbuffer and
g_uart8txbuffer are compiled when UART8 is enabled.
Signed-off-by: Joao Mario Lago <joao.mario.lago@hotmail.com>
ARM PIC has used r10 as the base register, but the tree has never been
consistent about it. Toolchain.defs gives CONFIG_BUILD_PIC
-mpic-register=r9 and CONFIG_PIC -mpic-register=r10, twenty-five lines
apart, and arm_initialstate.c sets REG_R9 from inline assembly under one
and REG_PIC under the other, with a comment reading "Set the PIC base
register (probably R10)". This settles it on r9 for all of PIC: NXFLAT,
ELF PIC and CONFIG_BUILD_PIC alike.
r9 is the right choice rather than an arbitrary one. It is the AAPCS
platform register, the "static base", and it is what GCC itself picks
for -msingle-pic-base on an EABI target; r10 is the non-EABI default.
It also removes a combination that cannot build today. Stack checking
adds -ffixed-r10 in armv7-m/Toolchain.defs and armv8-m/Toolchain.defs,
while CONFIG_PIC adds -mpic-register=r10, and GCC rejects the pair with
"unable to use 'r10' for PIC register". The comment above REG_PIC has
always said the register "can be R9 if stack checking is enabled", but
the definition was unconditionally REG_R10, so it would have named the
wrong register even had the build succeeded.
The thunk generator moves with the firmware. NXFLAT import stubs had
the register baked in as "add ip,ip,sl", so a module built for r9 would
load and then branch to a wild address on its first call out. The stubs
now come from NXFLAT_PIC_REG in the in-tree tool, which is built only
when CONFIG_NXFLAT is set, following the
CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE precedent in tools/Unix.mk.
That leaves modules built before this change, and they are the reason
for the ABI marker. The NXFLAT header cannot carry a version: h_magic
is written by ldnxflat, which is GPL, derived from elf2flt, and stays
out of this repository, so it can never be changed in step with the
loader. The import table can, because both of its ends are in-tree --
mknxflat emits it and nxflat_bindimports() reads it -- and ldnxflat
passes it through untouched. So every module now imports
__nxflat_abi_v2, the base firmware defines it, and a module that does
not import it is refused.
Making the marker a real exported symbol rather than a name the loader
special-cases is what keeps it out of the build system's way: a board's
symbol table picks it up exactly as it picks up printf, so mksymtab.sh
and its equivalents need no change. It also gives the reverse direction
a diagnosis for free -- a module built against a newer ABI than its
firmware fails with "Exported symbol __nxflat_abi_v2 not found".
Most of the remaining churn is boards restating a default. ARCHPICFLAGS
is a "?=" default so that a board only speaks up when it differs, and
twenty-six were assigning the value the default already had. MKNXFLAT
gets the same treatment: thirteen boards named the same tool, and the
only thing that varies is ARM versus Thumb-2, which falls out of
CONFIG_ARM_THUMB. LDNXFLAT gains a default too -- it stays an
out-of-tree PATH lookup, but naming it centrally fixes boards that never
assigned it, where it expanded to nothing and handed make a recipe
beginning "-e", whose leading dash make ate as "ignore errors".
The non-ARM boards carrying -mpic-register=r10 lose it: it is an
ARM-only option, reachable only through CPICFLAGS, which is only used to
build NXFLAT modules, and no non-ARM board enables NXFLAT.
Boards keep nothing about PIC flags any more. ARCHPICFLAGS was set by
sixty-three of them and only ever fed CPICFLAGS, which is only used to
build NXFLAT modules; no board outside arch/arm enables NXFLAT, so every
non-ARM copy was setting a variable nothing read. Those are removed
rather than moved somewhere more central, which would only make dead
text look load-bearing. LDNXFLAT goes the same way as MKNXFLAT, for the
same reason: thirteen boards named the same tool that Toolchain.defs now
names once.
One of them was not merely redundant. am67/t3-gem-o1 asked for
"-mpic-register=r10 -ffixed-r10", which GCC refuses outright with
"unable to use 'r10' for PIC register" -- the very combination the
filter-out machinery in Toolchain.defs exists to prevent. It has
survived because that board does not build NXFLAT modules, so the flags
are never handed to a compiler. Renaming the register would have
carried the fault forward unchanged, so the line goes.
Tested on lm3s6965-ek:qemu-nxflat under QEMU, configured and built with
no overrides. The nxflat example runs the errno, hello and struct
modules with output identical to the same config built from master.
Built with the old out-of-tree thunk generator instead, the same
firmware refuses all three with ENOEXEC rather than locking up in a
HardFault, which is what this change is for. mps3-an547:picostest,
which is CONFIG_PIC without CONFIG_NXFLAT, builds clean and does not
build the thunk generator.
The .def files pick up two cosmetic changes here alongside the register:
a "Dyanamic" typo that codespell rejects, and a reworded comment in each
thunk_*.c. Neither appears in the emitted thunk -- both are in C
comments -- so the generated text is still what the upstream tool
produces, modulo the register itself.
BREAKING CHANGE: ARM PIC moves from r10 to r9. An NXFLAT module built
before this change has r10 baked into its import stubs and will not run
against a firmware carrying it; the two cannot be mixed. The module is
refused with ENOEXEC rather than branching to a wild address, by way of the
__nxflat_abi_v2 marker described below.
Quick fix: rebuild the module against this tree. Its source needs no
change. A board that reserved r10 by hand, or that assigned ARCHPICFLAGS
or MKNXFLAT to restate a default, should drop those assignments; nothing
else is affected, and CONFIG_PIC without CONFIG_NXFLAT needs no action.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Include STM32_HAVE_USART_H5 in the UART7/UART8 driver choice
depends so CONFIG_STM32_UART*_SERIALDRIVER can be selected on
STM32H5.
Signed-off-by: Joao Mario Lago <joao.mario.lago@hotmail.com>
g_rtc_lock is used by the up_rtc_settime, a base RTC function.
Therefore, it should be available even for this procedure, not just when
CONFIG_RTC_HIRES.
Signed-off-by: Jiri Vlasak <jvlasak@elektroline.cz>
- Zero initialize union in s32k3xx_transmit()
- Allow setting BRS from frame flags
Signed-off-by: Takashi Furuya <takashi.furuya@nttedt.co.jp>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Zero initialize union in s32k1xx_transmit()
- Allow setting BRS from frame flags
Signed-off-by: Takashi Furuya <takashi.furuya@nttedt.co.jp>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Zero initialize union in kinetis_transmit()
- Allow setting BRS from frame flags
Signed-off-by: Takashi Furuya <takashi.furuya@nttedt.co.jp>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Zero initialize union in imx9_transmit()
- Allow setting BRS from frame flags
Signed-off-by: Takashi Furuya <takashi.furuya@nttedt.co.jp>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
chromakey is a uint32_t, so printing it with %d warns. The line is only
compiled when CONFIG_STM32_FB_CMAP is enabled, which is why it has gone
unnoticed.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
Wire the shared Ameba GPIO driver into the RTL8721F (amebagreen2) build and
add the EVB board glue:
- arch/arm/src/rtl8721f: build ameba_gpio.c (CMake/Make.defs), source the
common Ameba Kconfig, and add ameba_gpio_chip.h describing the chip's
three GPIO ports (A/B/C), their IRQs and the APBPeriph clock bit.
- arch/arm/src/common/ameba: teach the driver that amebagreen2's ROM
GPIO_Init does not call PAD_PullCtrl or GPIO_INTMode, so call both
explicitly after GPIO_Init; on RTL8721Dx (ram_common) these are harmless
redundant writes. Add the AMEBA_PORT_C / AMEBA_PC() helpers.
- boards/arm/rtl8721f/rtl8721f_evb: register output/input/interrupt demo
pins, add the bringup hook, and provide a minimal 'gpio' NSH defconfig.
- Documentation: add a GPIO section for the RTL8721F EVB and fix a
rising/falling typo in the PKE8721DAF page.
Hardware-verified on the RTL8721F EVB: output, input, and all interrupt
trigger/polarity combinations (rising/falling edge, level high/low).
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
The shared port ISR clears interrupt status with GPIO_INTStatusClearEdge(),
which only clears edge latches. For a level-triggered pin the status stays
asserted as long as the level is active, so the ISR re-enters forever once
the level fires -- the system hangs before the application can even service
the event.
Remember at configure time whether a pin is level-triggered, and in the ISR
mask such a pin (GPIO_INTConfig DISABLE) before invoking the callback. The
application re-enables it via go_enable() after servicing. Edge pins are
left unmasked, so their behaviour is unchanged.
This fixes a hang reproducible on RTL8721Dx and RTL8721F when a
level-high/level-low interrupt pin is used.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
The fix was ported from the STM32G0 to all the STM32 platforms,
as the code is mostly the same hence presents the same failure
Signed-off-by: Javier Alonso <javieralonso@geotab.com>
When the interrupts get disabled, the callback(s) are still attached.
That structure is never cleared, causing several calls to attach/detach
to eventually fail as the callback queue gets full.
When the error occurs, the registration fails with error 12 (ENOMEM).
By detaching the IRQ and clearing the callbacks, this error doesn't
happen again
Signed-off-by: Javier Alonso <javieralonso@geotab.com>
Bring up the last two RTL8721F feature blocks and wire them into the
nsh board configuration:
- littlefs on the on-chip flash MTD region (P2).
- WHC/INIC WiFi with the on-chip IPC control plane, NuttX net stack,
DHCP client and the wapi command tool (P3).
Two porting fixes were required for the WiFi control plane:
- ameba_ipc.c: the AP IPC device base (IPCAP_DEV) was carried over
verbatim from the RTL8720F template (0x40804000). On this SoC IPC0
lives at 0x40815000; using the wrong base makes ipc_table_init()
program the RX-full mask in the wrong register block, so the NP->AP
interrupt never fires and WiFi bring-up hangs waiting for the device
to answer. Point IPCAP_DEV at the correct 0x40815000 base.
- ameba_board.mk: the EVB silicon is B-cut, so link against the
ameba_rom_symbol_bcut*.ld ROM symbol tables (the A-cut tables resolve
the WiFi ROM helpers to the wrong addresses and fault at run time).
Validated on hardware: NSH comes up, wapi scan lists real APs, a WPA2
connect succeeds, the DHCP client obtains a lease and ICMP to the
public internet round-trips.
The board defconfig keeps SSID/passphrase as placeholders; real
credentials are supplied at run time via the wapi commands.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Wire the RTL8721F km4tz core up to a working NuttShell:
- irq.h: renumber the KM4TZ external vector table to the RTL8721F
APIRQn map (UART_LOG=24, IPC=5, +GPIOB/C, TIMER7/8, ...).
- ameba_loguart.c: fix the LOG-UART base to 0x40810000. The former
0x401C6000 belongs to a different Ameba part; the wrong base bus-
faulted on the RX interrupt-enable write while TX still worked
(LOGUART_PutChar uses its own ROM-internal base).
- ameba_app_start.c: adjust the MPU read-only / RAM regions for the
RTL8721F memory map and seed the RTC on first power-on so the
SDM32K-clocked SYSTIMER comes up (mirrors the SDK app_rtc_init).
- ameba_ipc.c: move the km4tz<->km4ns IPC to APIRQn 5 (IPC_CPU0).
- ameba_board.mk: pull in fwlib ameba_rtc.c for the RTC_* symbols.
- defconfig: RTL8721F RAM map, enable TIMER/TIMER_ARCH/ARMV8M_SYSTICK
for a live system tick, and drop the WiFi/NET stack for now.
- scripts/Make.defs: use the RTL8721F_NOR flash profile.
Boots cleanly to nsh> on hardware; tick, RX and builtin apps verified.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Add a P0 skeleton port for the Realtek RTL8721F (SDK codename Green2 /
amebagreen2). Structurally the RTL8721F is a twin of the RTL8720F -- the
AP/host core is km4tz (ARMv8-M.main, TrustZone secure) and the WiFi MAC/PHY
runs on the km4ns network-processor core -- so this port is modelled on the
RTL8720F one and shares the IC-agnostic ameba glue in
arch/arm/src/common/ameba.
This is the "configures and links" skeleton (rtl8721f_evb:nsh builds an
image end to end). Four differences from the RTL8720F template were needed
to make the empty shell link against amebagreen2:
* km4tz has no FPU (cmsis_cpu.h defines __FPU_PRESENT 0), so the chip does
not select ARCH_HAVE_FPU and the image is built soft-float.
* ameba_app_start.c matches amebagreen2's ram_km4tz silicon init: the
nocache MPU map, the non-secure ROM BSS clear, OSC4M (not OSC2M)
calibration gated on EFUSE cut >= B and CHIP_TYPE_ASIC_POSTSIM.
* amebagreen2 ships no lib_rom.a, so the ROM archive whole-archive link is
dropped; the WiFi/OS/non-secure ROM symbols come from the SDK
ameba_rom_symbol_acut{,_wifi,_os}.ld maps appended to the image2 linker
script, exactly as green2's own image2 link does.
* the AP WiFi security lib is lib_wifi_common.a (was lib_wifi_com_sec.a).
The per-chip IRQ vector table (irq.h) and the RAM_START/RAM_SIZE layout
still carry RTL8720F values and are refined in the follow-up bring-up work.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rp2040_update_buffer_control()/rp23xx_update_buffer_control() re-arm an
endpoint buffer by setting the AVAILABLE bit in the buffer-control word,
which lives in DPSRAM. When a buffer is re-armed from the completion
path (rp2040_usbintr_buffstat/rp23xx_usbintr_buffstat), that runs after
the handler has cleared the endpoint's bit in BUFF_STATUS, which lives in
the USB controller register block -- a different peripheral region.
The bus fabric may reorder those two stores. If the controller observes
the AVAILABLE re-arm before the BUFF_STATUS clear lands, it can transmit
the next IN packet and latch its completion in BUFF_STATUS before the
clear arrives; the late clear then wipes that just-set completion bit.
The lost completion edge stops all further buffer interrupts for the
endpoint, so the class driver's write-complete callback never runs and
TX wedges permanently.
This is most visible on RP2350 (Cortex-M33) under dense/bursty IN traffic
such as CDC-NCM with TCP write buffers. Add a UP_DMB() at the top of the
AVAILABLE re-arm so the preceding BUFF_STATUS clear is ordered ahead of
it. (Non-SMP builds reduce spin_lock_irqsave to a barrier-free
up_irq_save, so nothing else orders these two stores.)
Assisted-by: Claude (Anthropic Claude Code)
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
During the Toybox port to NuttX, Claude noticed that changes in the
menuconfig weren't taking affect. This issue exists for a long time on
NuttX, in fact BayLibre's presentation from 2017 make jokes about our
building system not been reliable:
https://www.youtube.com/watch?v=XUJK2htXxKw&t=320s
Stale archive members from $(AR)'s additive-only behavior can linger
after Kconfig toggles change which files provide a symbol, causing dead
weight or "multiple definition" link errors on incremental builds.
Fixed by splitting ARCHIVE into two macros: ARCHIVE keeps the original
additive behavior for apps/libapps.a, which many independent
subdirectories contribute to across a build, while the new
ARCHIVE_REBUILD deletes then archives for the far more common case
of a single Makefile building its own self-contained $(OBJS)
- all 39 such call sites now use it.
Assisted-By: Claude Sonnet 5
Signed-off-by: Alan C. Assis <acassis@gmail.com>
In a protected build arm_svcall.c treats the caller's CONTROL as part of
the saved system call state: it stores it in xcp.syscall[].ctrlreturn on
entry and restores it from there on SYS_syscall_return. All three
Cortex-M profiles do this -- armv6-m, armv7-m and armv8-m each define the
field in arch/arm/include/<arch>/irq.h and use it symmetrically.
arm_fork_direct() copied sysreturn and excreturn to the child but not
ctrlreturn. The child's TCB comes from kmm_zalloc(), so the field was
zero, and CONTROL == 0 is nPRIV clear: the child returned to user space
privileged while its parent returned unprivileged. The child ran out its
life with the MPU restrictions its parent is under silently lifted, which
is the isolation BUILD_PROTECTED exists to provide.
Nothing faults, and that is why this survived. CONTROL == 0 also selects
MSP, which sounds like it should crash immediately, but NuttX already
runs Cortex-M threads on MSP -- the parent's saved value is 0x1, nPRIV
set and SPSEL clear -- so the two differ only in the privilege bit and
there is no stack change to trip over. Privileged code then passes every
test unprivileged code passes, so ostest cannot see it either.
Measured on an RP2350 (Cortex-M33) in BUILD_PROTECTED, breaking at the
nxtask_start_fork() call in arm_fork_direct() during task_fork_test:
parent ctrlreturn 0x00000001, child ctrlreturn 0x00000000. With this
change both read 0x00000001.
BUILD_FLAT is unaffected: without CONFIG_LIB_SYSCALL, nsyscalls is 0 and
the whole block is skipped. armv7-a and armv7-r are unaffected too; they
carry cpsr instead, and that is already copied.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Two device-controller defects that break standard host error recovery,
found while root-causing why macOS never mounts a NuttX mass-storage
function (full analysis and host traces in apache/nuttx#19435):
1. epsubmit() aborted (-EBUSY) any IN request submitted while the
endpoint was halted. The mass storage class halts bulk-IN for a
failed device-to-host command (BOT-legal) and then submits the CSW;
the CSW was dropped on the floor, so after the host's Clear-Halt the
endpoint NAKed forever and the host timed out (macOS: 30 s, then a
Bulk-Only-reset/device-reset spiral until it disables the port).
This is exactly the race documented for years in the usbmsc_scsi.c
header (David Hewson's analysis); the USBMSC_STALL_RACEWAR sleep
workaround only survives hosts that clear the halt within 100 ms --
Linux does, macOS does not, which is why Linux testing never saw it.
Implement the stall-queueing contract instead: requests submitted
while an endpoint is halted are queued without arming the hardware
(arming rewrites the buffer control word and would silently clear
the STALL bit); a halt terminates any in-flight IN transfer (its
hardware buffer is disarmed by the STALL write and would never
complete); clearing the halt resets the data toggle and re-arms the
head of the queue; stale buffer completions latched for transfers
aborted by a halt are ignored. RP2040/RP23XX now select
ARCH_USBDEV_STALLQUEUE, which also retires the RACEWAR's two 100 ms
sleeps per failed command.
2. The USB_REQ_GETSTATUS handler in ep0setup() validated the request
but never queued the two-byte response, for all three recipients
(device/interface/endpoint), so EP0 NAKed the host's data stage
forever and every GET STATUS timed out. macOS issues GetPipeStatus
= GET STATUS(endpoint) on a halted pipe before running Bulk-Only
reset recovery and hit this on every probe; lsusb -v's device-status
query hangs on it as well. Send the response: endpoint recipient
reports the halt bit, device recipient reports self-powered,
interface reports zeros; the status stage is armed by handle_zlp()
exactly as for class-dispatched IN transfers.
Validated on RP2350 silicon (Raspberry Pi Pico 2 W, composite
CDC-ACM + CDC-NCM + USBMSC): pre-fix, a raw-usbfs replay of macOS's
sequence and timing reproduced both defects deterministically (CSW read
ETIMEDOUT after a delayed clear-halt; all GET STATUS variants
ETIMEDOUT). Post-fix: the CSW survives the halt and is delivered after
Clear-Halt with correct tag/status/residue across a post-stall delay
sweep of 0-1000 ms; all GET STATUS variants answer immediately with
correct halt reporting; no regressions in the exact-length SCSI suite,
Bulk-Only reset, FAT mount and full reads, CDC-NCM/ACM, or warm
reboots; and macOS now mounts the volume (together with the companion
usbmsc fixes). The rp2040 driver shares the code and receives the
identical fix (build-tested).
Assisted-by: Claude (Anthropic Claude Code)
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
The TRNG driver waited for EHR_VALID and copied the block out without
checking the CryptoCell health-test result, so a sample that failed the
on-chip von-Neumann, CRNGT or autocorrelation test was served as entropy.
Check RNG_ISR before consuming a block: on a health-test error, discard
the block and re-arm the source; only a block that passed is returned.
Add a small startup self-test that draws a few conditioned blocks and, if
the source is stuck (identical blocks), latches /dev/random and /dev/urandom
to fail with -EIO rather than emit predictable output that would silently
weaken every derived key.
Builds on the driver added in 52e84e0c0a.
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Assisted-by: Claude (Anthropic Claude Code)
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Extract the chip-specific UART constants (controller count, register
bases, NVIC vectors, APBPeriph function/clock masks and crossbar TX/RX
pad-mux codes) out of the shared driver into a new per-chip header,
arch/arm/src/rtl8721dx/ameba_uart_chip.h, and include it from
arch/arm/src/common/ameba/ameba_uart.c. This drops the
#if CONFIG_ARCH_CHIP_RTL8721DX block from the shared source: other Ameba
ARM chips port UART by supplying a same-named header on their chip
include path.
The RCC clock argument is split from a single "clk" into separate
"periph" and "clk" APBPeriph masks so RCC_PeriphClockCmd() gets its two
distinct arguments; the two lists are equal on RTL8721Dx but differ on
chips such as amebasmart.
No functional change: the macros expand to the same values previously
hard-coded in the driver.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Add a shared Ameba high-speed UART driver on top of the GPIO driver's
common/ameba/ infrastructure, exposing UART0/UART1 through the NuttX
serial upper half.
- arch/arm/src/common/ameba/ameba_uart.c/.h: serial lower-half driver
built on the SDK fwlib UART register layer (ROM symbol table). RX/TX
dispatch through NuttX-native interrupts; TERMIOS get/set supported.
The pins are muxed to the direction-specific UART crossbar function
codes (TXD/RXD per controller) required by the amebadplus pinmux, and
RX is pulled high through the SDK ROM.
- arch/arm/src/common/ameba/Kconfig: AMEBA_UART option (selects SERIAL
and ARCH_HAVE_SERIAL_TERMIOS) plus RX/TX buffer-size knobs.
- arch/arm/src/rtl8721dx: wire ameba_uart.c into the Make/CMake builds
and pull the fwlib ram_common UART table into the fwlib link set.
- boards/arm/rtl8721dx/pke8721daf: board UART port table registering
UART0 at /dev/ttyS1 (PB18/PB19, 115200), bring-up hook, and a uart
NSH config with the serialrx/serialblaster examples.
- Documentation: describe the driver and the uart board config.
Verified on hardware (PKE8721DAF): pinmux routing, TX/RX and interrupt
paths, and the TERMIOS ioctl path via loopback.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Provide the transport half of the bcmf FullMAC driver on RP2350, so that
boards carrying an Infineon CYW43439 (or the Raspberry Pi RM2 module that
houses one) can bring up a wlan0 interface. The chip's half-duplex gSPI bus
is driven by a six-instruction PIO program with DMA in both directions, and
the driver fills in the gspi_dev_t operations that bcmf_gspi_initialize()
expects.
This is a port of the equivalent rp2040 driver. Three differences in the
RP2350 hardware and its NuttX support had to be accounted for:
- The GPIO_STATUS register no longer has an OEFROMPERI field, so the wait
for the PIO program to release the shared data line watches OETOPAD
instead. No override is configured on that pad, so the two fields carry
the same value.
- rp23xx GPIO interrupt modes are enumerated as indices rather than as the
bitmask rp2040 uses, so passing the rp2040 constant would have selected
the wrong trigger.
- RP23XX_PIO_NUM is three, and the DREQ definitions live in
hardware/rp23xx_dreq.h.
The data and clock lines are also explicitly pulled down rather than left on
the reset default. The data line doubles as the chip's active-high interrupt
request and is serviced with a level-high interrupt, so it must read low
whenever the CYW43439 has released it.
Finally, the state machine returned by rp23xx_pio_claim_unused_sm() is
collected in a signed temporary before being stored, so that the "no state
machine available" test is not defeated by an unsigned comparison.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
The rp2350 holds 4096 rows of 24 bit one-time-programmable memory, which
the port did not expose at all. This adds a driver on the NuttX efuse
interface, registered by the common board bringup as /dev/efuse.
The driver uses the ECC interpretation of a row, in which 16 bits carry
data and the remaining 8 carry a Hamming code, so the OTP appears as a
flat space of 4096 * 16 bits for the efuse field descriptors to index: a
descriptor at bit offset N refers to bit N % 16 of row N / 16. That
matches the row numbers already listed in hardware/rp23xx_otp_data.h.
Reads come from the chip's ECC-translated window and have no side
effects. Rows are locked in pages of 64; a page locked against reads
would raise a bus fault, so the lock is checked first and reported as an
error instead.
Programming needs the separate RP23XX_OTP_WRITE option, which defaults to
off; without it a write returns EPERM and no programming code is built at
all. When enabled, a row is programmed as a whole through the bootrom,
since the ECC bits cover the whole row. For the same reason a row that
already holds data cannot be modified, and such a write is rejected
rather than left to corrupt the row's ECC.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
on_hci() ran the host upcall with g_sdc_dev.lock held. On nrf53 this
deadlocks the BLE link: the upcall waits for the app core,
which cannot answer while bt_hci_send() blocks on the same lock.
nrf52 modified for consistency, deadlock is not possible there.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
The rp23xx hardware headers define a register address macro for every
register, then a block of register bit definitions. In three headers a bit
definition reuses the name of a register address macro, so the register
address is silently redefined as a bit mask:
RP23XX_POWMAN_BADPASSWD address 0x40100000 -> (1 << 0)
RP23XX_POWMAN_BOD_CTRL address 0x40100018 -> (1 << 12)
RP23XX_POWMAN_DBG_PWRCFG address 0x401000a4 -> (1 << 0)
RP23XX_BUSCTRL_BUS_PRIORITY_ACK address 0x40068004 -> (1 << 0)
RP23XX_BUSCTRL_PERFCTR_EN address 0x40068008 -> (1 << 0)
RP23XX_PADS_QSPI_VOLTAGE_SELECT address 0x40040000 -> (1 << 0)
None of these headers has an in-tree user yet, which is why this has gone
unnoticed; each clash appears as a "macro redefined" warning as soon as a
driver includes the header. Code that included one of them and used the
register by name would have dereferenced 1 or 0x1000 instead of the register.
Two of the POWMAN clashes were plain duplicates. Per the RP2350 datasheet
BOD_CTRL bit 12 is ISOLATE and DBG_PWRCFG bit 0 is IGNORE, and the correctly
named RP23XX_POWMAN_BOD_CTRL_ISOLATE and RP23XX_POWMAN_DBG_PWRCFG_IGNORE were
already defined with the same values on the following lines, so the bare names
are simply removed. The blank line separating the VREG_LP_EXIT and BOD_CTRL
groups is restored at the same time; its absence is what let the duplicate
hide inside the preceding group.
The other four are single field registers whose field carries no separate name
(the datasheet and the SDK describe each as a one bit register), so their bit
definitions are renamed to <REGISTER>_MASK, following the _MASK spelling these
headers already use for a field extent, and written in hex like their peers.
The rp23xx-rv copies of the three headers are identical to the arm ones and
carry the same clashes, so they get the same change and stay in sync.
No functional change: none of the six names has any user in the tree.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Add DMA support for DAC output with configurable double-buffering
via ioctl interface:
- ANIOC_DAC_DMABUFF_INIT: Copy full buffer into DMA buffer (memcpy)
- ANIOC_DAC_DMA_START: Start DMA with optional half-transfer interrupts
- ANIOC_DAC_DMA_STOP: Stop DMA and timer
- ANIOC_DAC_DMA_GET_EVENT: Wait for half-transfer complete event
- ANIOC_DAC_DMA_WRITE_HBUF: Write half-buffer into DMA buffer
- ANIOC_DAC_INFO: Query DAC capabilities (resolution, DMA, buffer size)
Stream mode: when halfint=1, both HTIF and TCIF generate events
via a ring buffer and semaphore. User writes the completed half
while DMA fills the other half. TCIF indicates h=1, HTIF h=0.
DMA priority is configurable per-channel via Kconfig choice
(Low/Medium/High/VeryHigh), defaulting to Medium.
Signed-off-by: Andrey Sobol <andrey.sobol.nn@gmail.com>