The millisecond timeout was multiplied by the external clock
frequency in 32-bit arithmetic, overflowing for timeouts above
131 seconds and programming a much shorter period than requested.
Do the conversion in 64-bit.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
In the zero-copy TX path, nxp_wifi_internal_tx() copies the Ethernet
header into the outbuf structure but keeps the original ETH header
net_buf attached to the net_pkt. This wastes one tx_buf slot per
packet while it sits in the WMM queue waiting to be transmitted.
Under heavy TX backpressure (e.g. during roaming with continuous
traffic), this doubles the effective tx_buf consumption per queued
packet, leading to premature tx_buf pool exhaustion.
After copying the ETH header, use net_pkt_frag_del() to release the
first fragment when it contains exactly the ETH header. The payload
fragment remains attached and the cursor position is unaffected since
it already points past the ETH header.
Assisted-by: WChat:Claude
Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
The counter API declares optional clock calibration ops in signed
parts-per-billion, but the Kinetis RTC counter driver did not
implement them, so counter_set/get_calibration returned -ENOSYS.
Implement them using the RTC Time Compensation Register. TCR[7:0]
configures the number of 32.768 kHz cycles per second as
(32768 - value) with value a two's-complement -128..+127, so a
positive value shortens the second and speeds the counter up,
matching the counter API sign convention. TCR[15:8] (CIR, interval
minus one) is kept at 0 to compensate every second, giving
ppb = value * 1e9 / 32768 (~30518 ppb per LSB, range ~+/-3.9M ppb).
set() rejects out-of-range values with -EINVAL and get() reports the
programmed (quantized) TCR/CIR value so a set()/get() round-trips at
the hardware resolution. The register is double buffered and safe to
write while the counter runs. Compensation counts oscillator cycles,
so the ops return -ENOTSUP when the prescaler runs from the LPO
clock.
Validated on frdm_k64f with tests/drivers/counter/counter_basic_api
(CONFIG_COUNTER_CALIBRATION=y): suite passes including the new
set/get calibration case sweeping +/-200000 ppb.
Link: K64 Sub-Family Reference Manual Rev.2 - ch44 RTC_TCR (44.2.4)
Signed-off-by: Holt Sun <holt.sun@nxp.com>
The write loop read the retained row state from digit_buf[py] but
stored the updated segment back to digit_buf[y], so only the first
row of the shadow buffer was ever updated and later partial writes
merged against stale row data. Store at the loop index.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The HSYNC polarity was computed from the vsync-active timing
property, a copy-paste from the VSYNC line above, so a panel with
different sync polarities got the wrong HSYNC polarity. Use
hsync-active.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
flash_si32_valid_range() returns bool, but the write alignment
checks returned -EINVAL, which converts to true and marks
misaligned writes as valid. An odd size then made the write loop
read one byte past the source buffer. Return false as the other
checks do.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The API table referenced ad405x_adc_read_async, which does not exist;
the function is adc_ad405x_read_async, so builds with
CONFIG_ADC_ASYNC failed.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
num_channels is a count and channels are used as 0-based CC indices,
but both guards used '>', letting channel == num_channels index one
element past the valid range. Use '>='.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Valid channels are 0 to MAX31790_CHANNEL_COUNT - 1, but both checks
used '>', accepting channel 6 and addressing registers beyond the
per-channel ranges. Use '>='.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The clock source mux update used the encoded field width (in bits)
directly as the clear mask, so only part of a multi-bit source field
was cleared and stale select bits could survive. Convert the width to
a bit mask with BIT_MASK().
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The memcpy used sizeof(pin_cfg), reading a whole pinctrl_soc_pin from
a single pinmux array element and past the end for the last pin. Use
sizeof(pin_cfg.pinmux).
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The PIN_POSEL case AND-ed the two disjoint bit masks, producing 0, so
the old POC0/POCSEL0 values were never cleared and could not be set
back to zero. OR the masks, matching the POC2/POC3 cases.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The invalid divider-combination path returned !EINVAL, which is 0, so
rejected FRQCR combinations were reported as success without
programming the register. Return -EINVAL.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The async completion path handed the driver data pointer to
spi_smartbond_pm_policy_state_lock_put(), which expects the device and
forwards it to pm_device_runtime_put(). Pass dev, as every other call
site does.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The FIRC async div1 case was guarded by a misspelled
FSL_FEATURE_FSL_FEATURE_SCG_HAS_FIRCDIV1 macro that never exists, so
the clock was compiled out on every SoC and rate queries returned
-EINVAL. Use the correct feature macro name.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The fallback condition used ||, which is always true for two different
constants, so every interrupt was forced to IOAPIC_LOW delivery and a
requested IOAPIC_FIXED mode was discarded. Use &&.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Four functions validated the pin index with '>' against
ARRAY_SIZE(pin_pint_id), letting pin == ARRAY_SIZE read one element
past the end of the array. Use '>=', matching nxp_pint_pin_enable().
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The STM32F413/F423 PLL configuration merged the R divider and post-R
divider into one macro argument due to a missing comma, so
LL_RCC_PLL_ConfigDomain_SAI() received four arguments instead of five
and the branch did not compile when selected.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The SPI1 rate query passed an SPI clock-source selector to
LL_RCC_GetUARTClockFreq(), returning a bogus frequency. Call
LL_RCC_GetSPIClockFreq() like the other SPI cases and the mp1/mp2
drivers.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The APB2 timer clock computed its rate from apb1_clock while testing
the APB2 prescaler, so APB2 timers reported APB1's frequency whenever
the prescaler exceeded the threshold. Use apb2_clock, as the H7RS
branch and every sibling series driver do.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
icm40627_init() logged a failed bus check through an undeclared
'config' pointer and a nonexistent bus.bus member, breaking the build
when the driver is compiled. Point LOG_ERR_DEVICE_NOT_READY at the
underlying I2C bus device.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The SENSOR_CHAN_DIE_TEMP case sat inside the CONFIG_MPU9250_MAGN_EN
guard, so temperature reads returned -ENOTSUP with the magnetometer
disabled even though the register is always fetched.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The angle conversion divided by 65635 instead of the 16-bit full
scale 65535, and raw_val * 36000 overflows signed 32-bit for large
readings. Use 65535 and widen to uint32_t.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
CFG2 was written with the CFG1 bit pattern so the AGAINMAX/AGAINL
bits were never programmed, and the 128x case loaded the CFG2
register value (20) into the lux gain instead of TSL2540_AGAIN_S128
(140).
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The 2000G A3-A5 OTP addresses jumped from 0x29 to 0x30-0x32 instead
of continuing at 0x2A-0x2C, pointing at the wrong registers.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The GPIO_INPUT branch wrote adp5585_pin_output into the direction
register, so pins requested as inputs were driven as outputs.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The phase3 clamp tested phase0, so phase3 could overflow its one-byte
register field. Test phase3.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
uart_silabs_async_rx_buf_rsp() returned -EBUSY/-EACCES without
releasing the irq_lock taken at entry, leaving interrupts disabled.
Unlock before the early returns.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
eusart_async_rx_buf_rsp() returned -EBUSY/-EACCES without releasing
the irq_lock taken at entry, leaving interrupts disabled. Unlock
before the early returns.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The enum index guard used '>' against ARRAY_SIZE, allowing a read one
element past the end of baud_settings[]. Use '>='.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The button callback runs only for buttons whose status bit is set but
reported value 0, so presses were never delivered. Report 1 like the
renesas_rx_ctsu driver.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The reconfigure path detected an auto_sr change but programmed the
old value, so the attribute never took effect. Pass the new value.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The dual-frequency assertion placed '== 0' inside the DT_INST_PROP
property-name argument. Move the comparison outside the macro call,
matching the assertion below it.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Replace fixed retry polling (~500 us) with WAIT_FOR() and a configurable
idle timeout defaulting to 1 s, so slow PHY bring-up on some platforms
can complete before read/write operations fail with -ETIMEDOUT
Signed-off-by: Venkatesh Odela <venkatesh.odela@amd.com>
Default to the larger MTU when using a nRF93M1, the default size fails
to boot `samples/net/cellular_modem` due to dropped frames.
Signed-off-by: Jordan Yates <jordan@embeint.com>
Move the PPP instance pointer from the `struct modem_cellular_data`
object to `struct modem_cellular_config`. The pointer is automatically
discovered in the `MODEM_CELLULAR_DEFINE_INSTANCE` macro through
`&MODEM_CELLULAR_INST_NAME(ppp, inst)`, which works for all in-tree
modems.
As a result, there are no longer any fields in
`struct modem_cellular_data` that are set at compile time. This saves
~4kB on ROM (for nRF93M1) as the variable no longer needs to exist in
`.data`.
Signed-off-by: Jordan Yates <jordan@embeint.com>
Move the specification of the chat delimiter and filter strings to the
vendor configuration strings. This is a step towards removing all
compile time field setting of the `struct modem_cellular_data` object
in drivers.
Signed-off-by: Jordan Yates <jordan@embeint.com>
The `lex10q1` driver was merged without any tests, and therefore no
longer compiles. Fix the driver, and add tests.
Signed-off-by: Jordan Yates <jordan@embeint.com>
Add AT+QENG="servingcell" to the Quectel EG25-G periodic script and decode
the LTE serving-cell report into the generic network-status event, so
consumers receive cell identity (MCC/MNC/CI/PCI/TAC), EARFCN, band and
RSRP/RSRQ rather than only registration state and RSSI.
The handler fills struct cellular_evt_network_status and reports it via
modem_cellular_emit_network_status(). Only the LTE report is decoded;
other radio access technologies use a different field layout and a shorter
report (state SEARCH/LIMSRV) is ignored via an argument-count guard.
Signed-off-by: Paulo Santos <pauloxrms@gmail.com>
Route the nrf93m1 %BCINFO handler through
modem_cellular_emit_network_status() so the periodic poll raises
CELLULAR_EVENT_NETWORK_STATUS_CHANGED only when the serving cell differs
from the last report.
Signed-off-by: Paulo Santos <pauloxrms@gmail.com>
Cache the last reported serving-cell status and add an optional
get_network_status driver op plus cellular_get_network_status(), so it can
be read on demand rather than only through the
CELLULAR_EVENT_NETWORK_STATUS_CHANGED callback. The snapshot is returned
under the API lock; -ENODATA before the first report or after a
registration change until the next poll, -ENOSYS where unimplemented.
modem_cellular_emit_network_status() stores the latest status and emits the
event only when it changed, ignoring signal quality (rsrp/rsrq) so periodic
pollers do not re-fire it on signal fluctuation. The cache is dropped on a
registration change so a stale serving cell is not reported after
re-registering.
Signed-off-by: Paulo Santos <pauloxrms@gmail.com>
Add an optional `period_ms` argument to the `read` command of adc shell
that makes the `read` command periodcially read and print until any key is
pressed.
Signed-off-by: Aric Radzin <aric.radzin@gmail.com>
- Updates the driver to support families which have only one
IRQ line for all the channel interrupts and overflow interrupt
- Adds single ISR for handling the interrupts for such cases.
- Updates custom return values to standard return values
Signed-off-by: Muhammed Asif <asifp3104@gmail.com>
The kernel re-evaluates its earliest timeout on every add and abort; a
timeslice reset is one of each, so a syscall-heavy thread produces a
sustained stream of sys_clock_set_timeout() calls, most of them landing
on the same tick boundary as the previous one. For a RELOAD backend
every reprogram restarts the hardware counter, so such a stream keeps
any period from ever completing and can postpone the announce for the
stream's duration; it also multiplies the reprogram windows in which
emulated timers misbehave (QEMU's SysTick holds VAL at zero around a
reprogram, and its cancelled-period callbacks race the vCPU).
Two guards in timer_core_arm(), both cheap and backend-agnostic:
- Deadline dedup: cache the armed tick-aligned deadline and program the
hardware only when it moves. The announce invalidates the cache, as
do the drivers whose sys_clock_unused() stops or reprograms the
hardware behind the core's back (cortex_m_systick, cmsdk_apb).
- Catch-up latch: when the reload is floored at TIMER_CORE_MIN_DELAY
(deadline due, or the un-announced span about to overrun
TIMER_CORE_CYCLES_MAX), leave an already in-flight floored reload
alone instead of restarting it, so the fire that resolves the
catch-up gets through even under a rearm stream faster than the
floor. Cleared by the announce.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Writing TTMR clears a pending TTMR.IP. The kernel rearms the comparator
on every timeout add and abort (a timeslice reset is one of each), so
under a rearm-heavy workload the write that follows a comparator match
can eat the match before the exception is taken. Announces then only
happen when a later target is reached cleanly; with the 28-bit compare
domain a long enough streak of eaten matches lets the masked elapsed
delta saturate and alias, and uptime drifts behind real time.
Write TTMR with IP set when arming (IP is cleared by writing 0 and
unaffected by writing 1) so a match that raced the rewrite stays
pending, and acknowledge only in the ISR, which now clears the pending
bit in both the tickless and the tickful case.
The rearm catch-up loop in this driver has a livelock of its own,
addressed separately (it also affects mips_cp0 and xtensa).
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Same omission as the one fixed for apic_tsc, hpet and
riscv_machine_timer: the driver reads the 64-bit "time" CSR and
declares TIMER_CORE_64BIT_CYCLES, but without TIMER_CORE_CYCLES_WIDTH
the generic core masks deltas at the native register width, so an RV32
build aliases any delta beyond 2^32 cycles and the SBI deadline ends up
a whole 2^32-cycle period behind the counter.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
The generic timer core masks announce deltas to TIMER_CORE_CYCLES_WIDTH,
which defaults to the native register width. The hpet, riscv_machine
and apic_tsc conversions kept their genuinely 64-bit counters but did
not declare the width, so a 32-bit build silently masks every delta to
32 bits (TIMER_CORE_64BIT_CYCLES only emits sys_clock_cycle_get_64(),
it does not widen the mask). The pre-conversion drivers all carried
full 64-bit tick math.
On 32-bit x86 with the HPET this is fatal as soon as more than 2^32
cycles (43 s at 100 MHz) elapse without an announce: the masked delta
aliases modulo 2^32, the announce reports ~0 ticks, and the re-armed
deadline lands a whole 2^32-cycle period behind the counter. The
comparator helper checks its target against the full 64-bit count, so
it treats the deadline as past and pins the comparator to "now",
firing immediately; the following announce again aliases to 0 ticks
and re-arms behind. The result is a permanent interrupt storm with
kernel time frozen at tick zero.
Declare TIMER_CORE_CYCLES_WIDTH 64 in all three drivers, as the
arm_arch, intel_adsp and esp32 conversions already do. For riscv
(64-bit mtime on RV32) and apic_tsc (64-bit TSC) the aliasing is the
same latent defect awaiting a long enough gap.
Assisted by Claude (claude-opus-4-8).
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The generic-core conversions gave the equality-match COMPARE drivers
(openrisc_tick_timer, mips_cp0_timer, xtensa_sys_timer) a catch-up
loop that pushes a too-near target ahead of the counter:
while (diff(next, now) < MIN_DELAY) {
next = now + MIN_DELAY;
set_compare(next);
now = get_count();
}
The exit condition demands the target still be a full MIN_DELAY ahead
after re-reading the counter, but the counter keeps moving between the
compare write and the re-read, and each retry re-arms exactly
MIN_DELAY ahead of the previous, already stale, read. The loop can
therefore only exit if the counter advances zero cycles per iteration.
Wherever it advances every iteration the loop spins forever: under
QEMU icount (qemu_or1k runs with -icount shift=6, advancing TTCR ~1.3
cycles per instruction) entry means a deterministic livelock, and on
real hardware whose count runs at CPU speed (Xtensa CCOUNT) the same
holds.
An equality comparator only requires that the target was still ahead
of the count when the compare register was written, and a post-write
count read that is still behind the target proves exactly that. Relax
the exit check to accept any strictly-future target, the same
convergent form hpet.c already uses; a retry then lands MIN_DELAY
ahead of a fresh read and is confirmed by the next one. The other
COMPARE conversions are unaffected: hpet already checks this way, and
esp32/intel_adsp bump once before the write against >=-style alarms.
Assisted by Claude (claude-opus-4-8).
Signed-off-by: Anas Nashif <anas.nashif@intel.com>