A bootloader may hand over with the ICACHE enabled, and nothing waits for
the invalidate that runs when the ICACHE is disabled. The driver also
polled BUSYF without a bound, so a stuck flag would hang the boot, and it
ignored an invalidate that never finished.
- stm32_enable_icache(): on first use, disable and invalidate the ICACHE
before the associativity and region registers are written (they are
only writable while EN=0), and wait for any pending invalidate before
enabling it (RM0481 8.4.5).
- stm32_disable_icache(): wait for the invalidate that EN=0 starts and
clear BSYENDF and ERRF.
- Bound every BUSYF wait with STM32_ICACHE_BUSY_TIMEOUT. RM0481 gives no
invalidate duration, so the value is a margin, not a measured limit.
- stm32_enable_icache() now returns OK or -ETIMEDOUT instead of void. On
a timeout the ICACHE is left disabled: with BUSYF stuck it would not
cache anything anyway (RM0481 8.4.5). Existing callers ignore the result
and keep working.
- __start: when CONFIG_STM32_ICACHE is not set, disable an ICACHE left on
by a bootloader, so reads of the OTP and UID cannot fault. On an
STM32H563 with the ICACHE left enabled this way, a 16-bit read of the
UID raised a precise bus fault and up_progmem_write() failed its
read-back check with -EIO.
Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ricardo Maurizio Paul <ricardopaul@geotab.com>
stm32_get_uniqueid() and flash_read_eccsafe16() (OTP and EDATA word
reads) disabled the ICACHE around their reads and enabled it again
afterwards, so that the read did not go through the ICACHE. The MPU
region added by the previous commit makes these areas non-cacheable, so
the reads bypass the ICACHE anyway.
Remove the disable/enable pairs. Each pair also invalidated the whole
ICACHE, and flash_read_eccsafe16() did it with interrupts disabled, twice
for every 32-bit OTP read.
The MPU is not applied in the HardFault and NMI handlers (HFNMIENA=0),
so a UID read from those handlers is no longer protected. Nothing in the
tree does that.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Ricardo Maurizio Paul <ricardopaul@geotab.com>
The OTP, read-only (UID, flash size, package) and high-cycle data (EDATA)
flash areas only accept 16/32-bit accesses and return a bus error
otherwise (RM0481 Table 77). The manual requires the MPU to disable local
cacheability for them (RM0481 7.3.2); with the ICACHE enabled and no such
region, reading them raises a precise bus error.
Until now this was worked around piecemeal: the driver disabled the
ICACHE around stm32_get_uniqueid() and the OTP and EDATA word reads, and
nucleo-h563zi mapped the 4 KB OTP/RO area non-cacheable in its board
code. Other reads, for example stm32_otp_read() or an application
reading the OTP on another board, still raised a precise bus error when
the ICACHE was enabled.
Map 0x08fff000-0x09017fff, which covers the three contiguous areas, as
Normal non-cacheable and execute-never with a single MPU region before
the ICACHE is enabled. STM32_ICACHE now selects ARM_MPU so that
stm32_mpuinitialize() has reset and enabled the MPU by then.
Remove the nucleo-h563zi OTP region in the same commit: the Armv8-M MPU
faults on an address that matches more than one region, so keeping both
would make OTP and UID reads fault on that board.
Assisted-by: Claude:claude-sonnet-5-5
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Ricardo Maurizio Paul <ricardopaul@geotab.com>
An ICACHE build with no ICACHE region configured warns about two unused
symbols:
- stm32_icache_setup_region() is only called when one of the
CONFIG_STM32_ICACHE_REGION0..3 options is set, so build it only then.
- 'regval' in stm32_icache_initialize() is only used with
CONFIG_STM32_ICACHE_DIRECT, so declare it only then. The interrupt
block gets its own local variable.
No functional change.
Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ricardo Maurizio Paul <ricardopaul@geotab.com>
Adds the Data Transfer Controller (DTC) as a generic register-triggered
DMA engine (ra_dtc.c/.h, hardware/ra8m1_dtc.h, CONFIG_RA_DTC, normal
mode only), and generalizes SCI_B's 16-stage FIFO and DTC support from
SCI9-only to every instance (SCI0-4, SCI9): CONFIG_RA_SCIn_FIFO and
CONFIG_RA_SCIn_TXDTC/RXDTC are mutually exclusive, not combinable --
TX DTC moves queued ring-buffer data in the background through
CONFIG_SERIAL_TXDMA, RX DTC moves each byte as it arrives, and measured
on hardware the FIFO's standing multi-byte buffer gives far better
high-baud overrun margin than this one-byte-per-activation RX DTC
design, which also had a real arming bug fixed here (up_rxint()'s old
"first enable" check could never fire, so the DTC was never armed),
alongside a FIFO register-clear/ordering fix. up_ioctl() also gains
TCGETS/TCSETS (baud rate, parity, stop bits), board.h gains SCI0's
GPIO pins (P609/P610) to exercise it on this board, and comments
throughout ra_serial.c/Kconfig are condensed from the narrative
debugging form they accumulated down to the essential fact each one
needs. Tested on hardware: SCI0 and SCI9 simultaneously, FIFO and DTC
independently and mutually exclusive; FIFO (TTRG=15/RTRG=0) holds up
cleanly to 3 Mbps for transfers within the RX ring buffer, well past
RX DTC's ceiling (see below).
A separate, more serious bug was also found and fixed while hardware-
testing the overrun path at high baud: up_erinterrupt() never cleared
its ICU IELSRn.IR flag (RA8M1 User's Manual section 13.5.1 is explicit
that this causes the NVIC to re-enter the handler indefinitely), which
livelocked the whole system on any receive error, in every
configuration, not something specific to this series. Fixed by
clearing it like the other two SCI interrupt handlers already did, by
draining RDR/the FIFO on an error before clearing it (SCIn_ERI fires
instead of SCIn_RXI for every receive error, so data already received
was otherwise never picked up), and by having the RX DTC path also
recognize a byte stuck via CSR.RDRF directly, not just its own
bookkeeping, since its event can be silently dropped by the ICU while
an earlier byte's IR is still pending. Also added CONFIG_SERIAL_
TIOCGICOUNT (frame/overrun/parity counters via the standard
TIOCGICOUNT ioctl), matching stm32's precedent, since nothing in the
generic NuttX serial core surfaces a receive error to an application
otherwise. Confirmed on hardware: nsh on SCI9 stays fully responsive
through a sustained 3 Mbps overrun on SCI0 that previously froze the
whole board.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: leocafonso <leocafonso@gmail.com>
Add an opt-in STM32N6_DEBUG setting to reopen the debug access port and
secure/non-secure debug at the current BSEC protection level. Enable the
BSEC clock and configure access before clock and memory initialization so
a debugger can attach to a flash-booted development image.
Assisted-by: Codex:GPT-6
Signed-off-by: raiden00pl <raiden00@railab.me>
In the nominal ROM clock configuration, flash boot leaves PLL1 driving
the CPU at 400 MHz. Skipping clock setup when PLL1 is already selected
makes SysTick run twice as fast as the board's 200 MHz configuration
expects.
Switch CPU and system clocks to HSI before reconfiguring PLL1, then apply
the board clock tree.
Remove the incorrect comments claiming CFGR1 and CFGR2 lock after the first
clock switch.
Assisted-by: Codex:GPT-6
Signed-off-by: raiden00pl <raiden00@railab.me>
Add stm32h7s8-dk board support for nsh running out of internal flash,
including LEDs and user button.
Signed-off-by: Peter Barada <peter.barada@gmail.com>
spi_setfrequency() in pic32mz_spi.c rounded the baud rate divisor down,
so the SCK frequency could be higher than the one requested by the
device driver (e.g. 20 MHz requested with a 100 MHz PBCLK2 gave 25 MHz).
A request above PBCLK/2 gave a zero divisor and a division by zero when
computing the actual frequency; the SST26 driver's default of 64 MHz
does that with any peripheral bus clock below 128 MHz.
Round the divisor up instead, so the actual frequency never exceeds the
requested one and the divisor is never zero. Boards whose requested
frequency is not an exact divisor of PBCLK/2 now run SPI at a lower
clock than before.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Indent the case labels of switch statements, wrap long lines, align
braces and add blank lines after declarations so that both files pass
checkpatch.sh. No functional change.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Re-indent the case labels of up_ioctl() and fix the remaining nxstyle
errors (long comment line, missing blank lines after declarations).
No functional change.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
The Config.K0 cache algorithm applies to both the I- and the D-Cache,
but the startup code only initialized the tags of the caches that were
selected in Kconfig. With only MIPS32_ICACHE the D-Cache was enabled
with indeterminate tags. Initialize the tags of both caches whenever
K0 is made cacheable (like the XC32 startup code does), and add the
missing hazard barrier after writing Config.
MIPS32_ICACHE now selects MIPS32_DCACHE when the chip has one, so that
the D-Cache maintenance needed for DMA is built whenever the D-Cache is
in use.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Several bugs made the MIPS32 cache functions unusable:
- The range functions rounded the end address down instead of up and
stopped before it, so the last line was never handled. A range
within a single line started a loop that only ended when the address
wrapped around 4 GB, which took seconds.
- HIT_WRITEBACK_D was 0x15, which is Hit_Writeback_Inv_D. Hit
Writeback D is 0x19. up_clean_dcache() now uses it and
up_flush_dcache() uses Hit_Writeback_Inv_D.
- The *_all functions used Hit operations over a KSEG0 range the size of
the cache, which only affects lines caching that range. Use index
operations instead: Index_Invalidate_I, Index_Writeback_Inv_D and, to
discard the D-Cache, Index_Store_Tag_D with a zero tag.
- With CONFIG_MIPS32_CACHE_AUTOINFO the line size was computed with a
right shift instead of a left shift.
- The CACHE_OP loop label was "1", the same label the callers use to
skip the operation, and the branch delay slot was left to whatever
instruction followed.
- up_coherent_dcache() called up_invalidate_icache_all() even when it is
not built.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
A carrier with a switch port wired MAC to MAC has no PHY on MDIO, and
ifup failed. With IMXRT_ENET_FIXED_LINK the configured PHY, or the
board's PHY list, is tried first; if none answers the MAC runs at
100 Mbps full duplex and SIOCGMIIREG reports the link up, so the
network monitor keeps the interface up.
Signed-off-by: Royyan Zahir <royzah@gmail.com>
This adds support for the OTP flash region in the STM32H5 via both
low-level functions and an eFuse lower half driver.
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Darryl Ring <darryl@bluerobotics.com>
Add CONFIG_STM32_DAC_LL_OPS support to the common STM32 DAC driver
(stm32_dac_m3m4_v1). This provides low-level ops (llops) and helper
macros (DAC_ENABLE, DAC_WRITE_DRO, DAC_START_DMA, DAC_STOP_DMA,
DAC_DUMP_REGS) matching the existing interface in stm32l4 and stm32h7.
This allows real-time control applications (such as power converters,
inverters, and function generators) to operate the DAC peripheral directly
without char driver VFS overhead.
Assisted-by: Antigravity:gemini-3.8-flash
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Add support for high-cycle flash which can be used for EEPROM emulation.
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Darryl Ring <darryl@bluerobotics.com>
Select the cache line size from either ARMV7M_DCACHE_LINESIZE or
ARMV8M_DCACHE_LINESIZE, so the driver can also be used with D-cache
enabled on the i.MX RT1180 Cortex-M33.
Also fix the imxrt1180-evk USB DMA allocator alignment. Pad the header
to the 32-byte DMA alignment, so that the buffer remains aligned.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Fix the usb phy pll bring-up sequence to match the imxrt1170 and
imxrt1180 RM:
1 enable the reference clock for the pll
2 enable the pll regulator
3 release the phy from reset
4 power up the pll
5 configure the pll_sic[pll_div_sel]
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Any ecall below CONFIG_SYS_RESERVED reached the context switch and signal
return paths from U-mode: a process could crash the kernel or return to
S-mode through a signal return nobody dispatched.
Signed-off-by: Royyan Zahir <royzah@gmail.com>
Any svc below CONFIG_SYS_RESERVED reached the context switch and signal
return paths from EL0: a process could crash the kernel or return to
EL1 through a signal return nobody dispatched.
Signed-off-by: Royyan Zahir <royzah@gmail.com>
STM32G0B1 devices provide SPI2, but their chip configuration does not
select STM32_HAVE_SPI2. Since STM32_SPI2 depends on that capability,
an explicit CONFIG_STM32_SPI2=y request is dropped by Kconfig.
Select the capability for STM32G0B1 so boards can enable the existing
SPI2 driver. SPI2 remains disabled unless requested. Other chip
families and the driver implementation are unchanged.
The STM32G0B1 datasheet DS13560, section 3.23, documents SPI2:
https://www.st.com/resource/en/datasheet/stm32g0b1re.pdf
Verified before/after configuration on STM32G0B1RE and STM32G0B1CE,
with STM32G071RB as an unchanged control. The same one-line fix is
included in the Golgi STM32G0B1CE firmware build 7248, whose build and
hardware acceptance were recorded on September 25, 2026.
Assisted-by: Codex:GPT-6
Signed-off-by: jsanchez-2g <jsanchez@2g-eng.com>
Add the General PWM Timer (GPT) as a generic timer, registered as
/dev/timerN through the upper-half timer driver. GPT0-7 are 32-bit,
GPT8-13 are 16-bit, and the timeout can be changed while running.
Give each ICU event used by GPT its own enum value instead of a
__COUNTER__-based macro, since the latter can hand out a different
number at every use.
Live period changes to the same prescaler now reload through GTPBR
(the buffered period register) instead of stopping the counter,
matching Renesas's own FSP driver, and fix a hardware-confirmed bug
where an uninitialized GTPBR silently corrupted the period after the
first cycle.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: leocafonso <leocafonso@gmail.com>
The LPSPI_CCR register is write only in imxrt1180. Therefore, the existing
modifyreg32 calls can't be used to set the fields. Use direct putreg8
writes to update the PCSSCK, SCKPCS, DBT and SCKDIV.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
At imxrt_lpspibus_initialize the code tried to read IMXRT_LPSPI_CR to
detect whether the SPI is already initialized. This doesn't work on
imxrt118x, if the LPSPI clock is still gated. But the gate is
opened only during the initialization. So this is a chicken-egg
problem.
Instead of reading the register, just have an "initialized" flag in
priv.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
The table index and the nesting depth were checked by DEBUGASSERT only,
and arm64 and risc-v let the first number past the table through.
Signed-off-by: Royyan Zahir <royzah@gmail.com>
pgalloc() is a syscall in a kernel build. Its start was checked by
DEBUGASSERT only and its end not at all, so a user task could map pages
past ARCH_ADDRENV_VEND.
Signed-off-by: Royyan Zahir <royzah@gmail.com>
Under FDPIC an .init_array or .fini_array entry is a code address, but a
C function pointer is a function descriptor. crt0 called each entry
through a function pointer, so it read the constructor's first
instructions as a descriptor and jumped to garbage.
Call each entry with fdpic_call() and the data base from fdpic_base(),
which is the module's own. Without CONFIG_FDPIC both are a direct call,
as before.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
set_intr_wrapper() allocates a new intr_handle_data_t from the kernel
heap each time the Wi-Fi driver calls it, and the driver calls it on
every esp_wifi_start() -- twice per start on esp32s3 -- not only the
first time. clear_intr_wrapper() is a no-op, so the IRQ still holds the
handle from the previous start: esp_set_handle() refuses to replace it
with -EINVAL, the return value is ignored, and the new block is lost.
Any application that stops and restarts Wi-Fi to save power therefore
loses a few bytes of kernel heap per cycle, without bound.
Look up the vector descriptor first, then reuse the handle already
registered for the IRQ and only allocate and register one when there is
none. A failed descriptor lookup no longer touches the registered
handle.
The same code is present in the esp32, esp32s2, esp32s3, esp32c3 and
esp32c6 Wi-Fi adapters; all five are fixed the same way.
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
A negative channel passed both checks, and TPM took one past the end,
so a caller could write FlexIO and TPM registers it does not own. TPM
also dropped the error and reported success.
Signed-off-by: Royyan Zahir <royzah@gmail.com>
There were some bits erroneously copied from imx9. For IMXRT1180, the
GPIO_AD* and GPIO_AON* pads should have SRE, DSE, PUE, PUS and ODE bits
on SW_PAD_CTL_PAD register.
The GPIO_EMC_*, GPIO_SD_*, GPIO_B1_* and GPIO_B2_* have a bit different fields,
PDRV, PULL and ODE.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
There was a mismatched EXTERN definition for ver3 in imxrt_periphclks.h,
and the extern definitions should be there in imxrt_clockconfig_ver3.h
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Two files each defined the same 16 byte constant, KSTACK_ALIGNMENT and
SIGTRAMP_STACK_ALIGN. Use STACKFRAME_ALIGN, which arch/xtensa/include/irq.h
already gives as 16, with the STACKFRAME_ALIGN_DOWN() of nuttx/irq.h.
STACK_ALIGNMENT is not the name to use here. It is TLS_STACK_ALIGN when
CONFIG_TLS_ALIGNED is set, which is the alignment of a thread stack and not
of a frame.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
The PMS grants and refuses physical addresses, so it never sees an access
that no MMU entry translates. The cache answered such an access with zeros
and raised nothing, and the task carried on with a value it never should
have had.
Enable EXTMEM_MMU_ENTRY_FAULT and route the Cache Invalid Access interrupt
to the handler that already serves the PMS monitors. An unprivileged task
that makes the access is terminated with SIGSEGV; a privileged one still
panics. The latch is level triggered, so it is cleared with the others.
Read the cause before the clear, so the log tells the two apart: a PMS
violation is a refused translation, an MMU entry fault is an access that was
never translated.
Give the kernel_oct configuration the addresses that examples/sandbox needs
to name its targets.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Reporting a fault can itself fault. syslog reaches memory the fault being
reported may have made unreachable, so esp32s3_pagefault_dispatch() is
re-entered from inside its own _alert() and never returns, and the console
fills with the same half-printed line forever. Found under Espressif's QEMU,
where PSRAM never initialises and the kernel build needs it; the board's
PSRAM works, so hardware does not take this path.
A fault repeating at the same address and PC is not helped by reporting it
again, so the dispatcher tries three times and then halts with interrupts
off. esp32s3_userfault_abort() clears the count through
esp32s3_pagefault_clear_repeat(): reaching it means the fault was contained,
so only unbroken recursion stops the machine, and three probes at one
address do not halt a healthy system.
Verified under QEMU: 12,958,521 bytes of output in 60 s before, four reports
and a halt after. On an ESP32-S3 DevKitC, esp32s3-devkit:kernel_oct, three
identical sandbox probes in one boot are all contained.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
When an unprivileged task takes a fault the system cannot recover from, it
now gets a fatal SIGSEGV and only that task ends. A fault in privileged code
still panics.
What decides it is the interrupted context, not the cause: the saved PS says
whether the fault was taken in User Mode. A list of causes would leave every
cause off the list as a way for a user task to stop the machine, and there
are many -- a divide by zero, a privileged instruction, a load/store error,
and an illegal instruction, which is how a refused fetch from kernel text
arrives on this chip (TRM v1.8 p.699: a denied external-memory access is
answered with 0xdeadbeaf instead of trapping). PS.UM is clear in a kernel
thread, in a system call made on the user's behalf and in an interrupt
handler, so those still panic. If the recoverable-fault dispatcher is
enabled it still gets first refusal on causes 28, 29 and 20, the only ones
re-executing can help.
esp32s3_userfault_abort() records the exception frame as the task's context,
dispatches SIGSEGV, and returns the redirected frame, so the vector's RFE
resumes the task in the signal trampoline, whose default action exits it.
CONFIG_ESP32S3_USERFAULT_ABORT enables it, default y wherever there is an
unprivileged world, and selects SIG_DEFAULT and SIG_SIGKILL_ACTION.
Verified on an ESP32-S3 DevKitC with a WROOM-2 module,
esp32s3-devkit:kernel_oct: a user task that writes through NULL, reads a wild
address, divides by zero, calls into a buffer of garbage or branches into
kernel text is terminated on its own, while an unrelated task keeps running.
Stack overflow is not contained. On the windowed ABI it faults inside the
window overflow handler and arrives as a double exception with PS.UM already
clear; guard pages are the answer, and separate work.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Separate the world split from the protected user image, give WORLD1 its own
vector table and its own PMS permissions -- including the PSRAM -- clean up
the user cache-MMU windows, and stop keeping the page pool mapped.
Folds in:
xtensa/esp32s3: separate the world split from the protected user image
xtensa/esp32s3: give the unprivileged world its own vector table
xtensa/esp32s3: give the unprivileged world its permissions
xtensa/esp32s3: clean up the user cache-MMU windows
xtensa/esp32s3: stop keeping the page pool mapped
xtensa/esp32s3: give the PSRAM its own PMS permissions
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
- Add conditional includes for both 117x/118x headers in hardware/imxrt_ocotp.h
- Add CHIP_ID and UNIQUE_ID addresses in imxrt118x_ocotp.h
- Remove access to those timing registers which don't exist on imxrt117x,
which don't exist on that chip, in imxrt_ocotp_initialize.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Implement the same initial clock configuration as what imxrt1176 has. Make an own table
for PLL and root clock configurations for m33 and m7 targets. For the PLLs the code still
only supports configuring the ARM_PLL.
The difference to imxrt1176 is, that instead of just boolean .enable field, this table
uses an .action field with 3 states: CONFIGURE, DISABLE and IGNORE. The reason is,
that some root clocks can't be just forcefully stopped, but need a root-clock-specific
sequence. This is solved by just leaving these clocks marked as IGNORE, so they retain
their current state.
Specifically, disabling the SEMC and NETC roots by M33 will prevent the M7 from booting.
Also FLEXSPI shouldn't be touched, if the code is being executed from there.
Also add a function for enabling 24 MHz oscillator clock, and an extendable function to
enable the clock sources based on the clock configuration table.
Assisted-by: Claude Code
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Add initial architecture support for the Renesas RA8M1 (Cortex-M85)
family: clock configuration, GPIO, ICU/IRQ handling, SCI serial,
system timer, option setting and start-up code, plus the Kconfig and
build system integration.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: leocafonso <leocafonso@gmail.com>
Indent the case labels of the esp_ioctl() switch one level deeper, as
nxstyle expects, fix the odd indentation of the TIOCSERGSTRUCT case
and add the missing blank lines after declarations. No functional
change.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Erik Englund <erik.englund@gmail.com>
In RS-485 mode the DIR (DE) pin was only released on TX_BRK_IDLE_DONE.
That interrupt is part of the UART break feature (UART_TXD_BRK), which
this driver never enables, so it does not fire after normal data: DIR
stayed asserted after the first transmit and the port never received
again.
TX_DONE is the right event, but the upper half calls txint(false) as
soon as its software buffer is empty, while the last bytes are still
in the FIFO (see #15888), so it has to outlive txint(false):
* txint(false) keeps TX_DONE enabled on an RS-485 port.
* On TX_DONE with the software buffer and TX FIFO empty, the handler
waits (bounded) for the transmitter to go idle, releases DIR and
disables TX_DONE.
* txempty() uses uart_hal_is_tx_idle() (FIFO count and FSM state).
The raw TXFIFO_EMPTY bit only means the FIFO is below its empty
threshold, so tcdrain() could return with data still in the FIFO.
Same approach as the ESP32-S3 fix in #20389.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Erik Englund <erik.englund@gmail.com>
The RS-485 tx_idle_num block in esp_setup() ends in a bare "else" that
binds to the next statement, which is now leave_critical_section(). On
an RS-485 port esp_setup() therefore returns with interrupts disabled.
uart_open() hides this behind its own critical section, but a
tcsetattr() that changes the line settings calls esp_setup() through
TCSETS and leaves the calling task running with interrupts off. On an
ESP32-C3 the system tick stops advancing in that task.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Erik Englund <erik.englund@gmail.com>