Commit Graph
200 Commits
Author SHA1 Message Date
d00f 6e394300c8 Merge upstream/main into the Spanning Tree branch
Only httpd.c conflicted: main added the buffered configuration upload
next to the pointers this branch had moved into xdata to free internal
RAM. Both belong, so the new globals sit above declarations that keep
their storage class.
2026-08-25 23:28:09 +02:00
logicog f582576b10 Merge pull request #345 from DrDoof/fix/sfp-i2c-error
sfp: notice when an I2C read fails
2026-08-25 05:13:47 +02:00
René van Dorst fe2bcc7f2d Merge pull request #356 from bloqaudio/fix/config-post-race
httpd: buffer a configuration upload before touching the flash
2026-08-24 23:35:19 +00:00
d00f a0628c7df5 sfp: read the EEPROM in blocks instead of a byte at a time
The I2C controller transfers up to sixteen bytes per transaction and
page_impl.c already used that for sfp_send_data(), while sfp_read_reg()
asked for one byte and every caller looped. Reading a module therefore
cost one address phase per byte: 87 transactions when a module is
inserted, 52 for the sfp command, 36 for the vendor block in status.json.

sfp_read_block() replaces sfp_read_reg() and the callers that already
wanted a run of registers ask for it once: the vendor fields as three
16 byte pages, the diagnostics as one transfer, rate and encoding
together. That drops the three paths above to 8, 6 and 3 transactions,
and sfp_send_data() loses its copy of the transfer.

The vendor loops now run over 16..63 rather than 20..59 so the page base
is a multiple of sixteen and the index into the buffer is a single AND.
The four extra bytes at each end are read and discarded. The diagnostics
read asks for 16 bytes rather than the 15 it uses, because 16 is a width
the shipped firmware already exercises and 15 is not.

The device address, the bus selection and the start bit go into the
control register in one write now that the memory address is written
first, so a transfer touches that register once instead of three times.
The register reads take their result from the SFRs directly rather than
through the sfr_data mirror. The result is a bool and the destination is
sfp_buf, so a caller that cares about a failed transfer looks at the
return value instead of a flag.

Every caller gives up on the first failed read rather than carrying a
flag to the end, which is why the module read moved out of handle_sfp
into a function of its own. A module whose read fails is left marked as
absent, so the next poll retries it instead of configuring the SerDes
from bytes that never arrived.

BANK1 -194 bytes, BANK2 +382, common segment +44, xdata +15 for the
buffer, and one byte more of internal RAM free than before the series.
Built for all 25 machine definitions on sdcc 4.5.0; the tightest common
segment is 98 bytes free on SWTG024AS_V2_0, against 54 before this
series.
2026-08-25 01:09:20 +02:00
d00f 9a96c80af2 sfp: move the I2C transfer to the banked pins module
sfp_read_reg() sat in rtlplayground.c, so it occupied the common 16 KB
window that every bank shares, even though nothing outside the SFP paths
calls it. That window is the tightest resource in the image:
SWTG024AS_V2_0 and SWTG024AS_A_2_0_1_5C_1SFP had 54 bytes left in it.

rtl837x_pins.c is already in BANK2 and already holds the I2C bus helpers
this function calls, so the transfer belongs there. The function moves
verbatim and becomes __banked; the prototype in rtl837x_common.h says so,
which is what keeps the callers in BANK1 and BANK2 honest.

No behaviour change. The common segment gains 200 bytes on every machine:
159 to 359 free on SWTGW218AS, 54 to 254 on the two variants above.
BANK1 +6 bytes, BANK2 +336. Built on sdcc 4.5.0.
2026-08-24 02:34:39 +02:00
bloqaudio 772e9dc526 httpd: parse a configuration upload once the whole request has arrived
Saving the configuration works in Chrome and fails in Firefox, and the
difference is only how each browser splits the request. The handler
erased the config sector as soon as the request started and then parsed
the multipart body one TCP segment at a time, which requires every
boundary and every part header to fall inside a single segment. Firefox
splits inside a part header, so the parser lost its place and the
erased sector was left holding a truncated body or nothing at all. A
single-burst scripted post lost the whole body the same way.

The configuration is limited to two kilobytes, so the whole request body
now accumulates in xdata and is parsed only after the closing boundary
has arrived. The parts are walked in one pass, the part carrying a
filename is written to a freshly erased sector, and the client receives
a 200 instead of the previous silent close. No segmentation can confuse
this, since the parser only ever sees a complete body.

Locating the closing boundary first also bounds the walk over the parts,
since none can lie beyond it, so the length of the buffer is no longer
the bound and the test for the two trailing dashes is unnecessary.

The walk matches at offsets inside a buffer that is not terminated, so
neither existing helper fits: strcmp() goes on to compare the byte after
the match and is_word_x() demands a separator there. Add strstart() and
strstart_x() for that case, and use strlen_x() for the boundary length.

The firmware upload path still streams, since a megabyte cannot be
buffered, and is untouched.
2026-08-23 18:11:46 -05:00
logicog 025f72c876 Merge pull request #258 from bennydiamond/newline-on-uip-serial-print
Automatically print newline on serial interface
2026-08-22 19:14:45 +02:00
d00f 62f80f0ad2 nic: report a transfer that does not complete instead of carrying on
The bounded waits were silent: on timeout the code went straight back to
its caller, and handle_rx() then read a frame the DMA may never have
delivered, which is worse than waiting longer.

Each of the three transfers now says so on the console, the two RX ones
report failure to handle_rx(), and handle_rx() acknowledges the packet
and gives up on it rather than parsing whatever is in the buffer. The
guard variable moved to the top of its function, so the block that held
it and its indentation are gone.
2026-08-19 16:20:34 +02:00
d00f 803d9c1242 nic: do not claim a cause for the bounded TX wait
The comment said the ASIC never completes a TX when the egress port is in a
non-forwarding MSTP state. The guard is worth keeping either way, since an
unbounded spin in the DMA wait takes the whole main loop down, but the
mechanism is more than the evidence supports and the DMA into the TX ring
has no business knowing the egress port at all.
2026-08-18 23:32:33 +02:00
d00f ec069a5bcc stp: rename stpEnabled and take the comments out of the header
The variable lives in rtlplayground.c, so it is declared in rtl837x_common.h
with the others there, and it follows the naming of the rest.

The header carried comments on the externs that the definitions in
rtl837x_stp.c repeat, sometimes differently, which is one place too many to
keep in step. What only the header had, the value ranges and what the
designated arrays hold, moved to the definitions; the rest is gone. Function
declarations lost their comments too.

The status printer only prints, so its running commentary went. A define
replaces the bare 33 in stp_in(), and the note on the loop check is down to
what applies at that line.
2026-08-18 23:32:25 +02:00
d00f f9d3dec50f Do not insert the management VLAN tag into a CPU-tagged frame
tcpip_output() splices the 802.1Q tag in right behind the source address,
which is exactly where the ASIC expects the RTL tag of a frame the CPU
addressed to a port itself. The tag then ends up behind the VLAN tag, the
ASIC does not find it, and the frame goes out flooded with the 0x8899
header still on it instead of being sent to the port that was asked for.

Whether a frame is CPU-tagged is a property of the frame, so decide it
here from the ether-type rather than having every sender of such a frame
clear management_vlan around its tcpip_output() call. stp_cnf_send() did
that, and no longer has to.
2026-08-18 23:31:00 +02:00
d00f a9af466702 stp: drop the management failsafe
The window could be armed from the serial console but only ever disarmed
by an HTTP request. save_cmd, which gates arming, is cleared only while
execute_config() replays the startup config, so every interactive command
armed it wherever it was typed, while mgmt_alive, which disarms it, was
written in exactly one place, on HTTP traffic. An operator working
entirely on the serial console therefore lost STP 180 seconds after
enabling it however much they typed, which is what makes the mechanism
impossible to test from a console.

The documentation described the behaviour that was intended rather than
the one that was built, and in both directions: it said a command on the
serial console also confirms, and it said a reboot with STP in the
startup config disables it again three minutes later. Neither held. The
replay path never armed the window at all.

Repairing the asymmetry would have kept a mechanism whose premise is
contested anyway. A watchdog that switches the protection off in response
to silence adds a second failure mode on top of the first: where the
network is misconfigured and STP is the thing holding a storm back,
restoring forwarding removes the last reason management still answers.

Gone with it: the stp failsafe command, the fs and fsT fields of
/stp.json, the input and the tripped banner on the Spanning Tree page,
the two persistence patterns in config.js, the documentation section, and
mgmt_alive itself, which had no other reader.

550 bytes back, 145 of BANK1 and 405 of BANK2, and five of xdata, which
is the four counters and mgmt_alive and nothing else. Built for
SWTGW218AS and KP_9000_6XHML_X2 on sdcc 4.5.0.
2026-08-18 23:30:25 +02:00
d00f 024c8cef49 stp: arm the management failsafe only where an operator asked for it
Your console session shows the shape of this better than I could have. STP found
a loop, blocked the port, unblocked the other side of the pair, and then the
failsafe turned STP off. It had been disarmed by your first console command and
re-armed by the loop detection itself, so a mechanism that exists to protect
against a lockout ended up removing loop protection while a loop was physically
present. That is the part that did not make sense, and it wasn't the console.

Two changes, both narrowing.

Loop detection and root guard no longer arm the window. Those are the protocol
doing its job on evidence off the wire. Nothing an operator did needs undoing
there, and nobody is waiting to confirm anything.

Typing on the serial console no longer disarms it. The failsafe asks one
question, whether the operator can still reach management over the network, and
serial activity doesn't answer it. It proves somebody is standing at the box,
which is the one case where a lockout doesn't matter, and it took the safety net
away from a remote operator on behalf of someone not using it. HTTP activity
still confirms, because that is the path being measured, and the console in the
web interface counts for the same reason.

What is left arms on stp on, stp port N on and stp failsafe, each of them an
operator choosing something whose outcome the protocol then decides.

Gives back 61 bytes of BANK2, 31 of the common area and a byte of xdata.
2026-08-18 23:29:18 +02:00
d00f c72d36af36 stp: turn the management failsafe into a one-shot window
The failsafe used to watch management traffic for as long as STP ran, so
three minutes of nobody looking at the web UI took the tree down on any
quiet network. That made a standing STP config impractical, which is the
problem raised in the review of the original PR.

Enabling STP arms a window of stp_failsafe_s seconds. One HTTP request
inside it confirms that management survived the new tree and disarms the
watchdog; a silent window disables STP and restores forwarding. Both
outcomes print to the console and the syslog.

The window re-arms on any later event that newly takes a port out of
forwarding: a port rejoining via "stp port N on", root guard firing, the
loop latch. Those were covered by the old always-on surveillance and a
disarmed window would have left them able to cut management off for good.
If management traffic keeps flowing past the new block, the next request
confirms straight away, which is the correct verdict, the block did not
cut it. The arming deliberately does not refresh an already armed window:
root guard can re-fire on every hello, and refreshing the countdown on
each one would keep a cut-off window from ever expiring. A stable network
with nothing newly blocked never re-arms, which is the reviewed-for
behaviour.

The request or console command that causes the arming never counts as its
own confirmation: mgmt_alive is cleared when a command arms, and the
console hook only disarms when the window predates the command. Without
that, enabling from the web UI or the console would confirm the window
before the new tree had any chance to cut management off.

A command on the serial console confirms like HTTP does. An operator at
the console has out-of-band access that no tree can cut, so the automatic
restore only takes STP away from someone equipped to deal with the
situation. The hook sits on the interactive console path only, identified
by cmd_available, so neither the config replay at boot nor HTTP commands
pass through it.

After a confirmation STP runs unsupervised until something new blocks.
Headless installs where nobody will confirm should set stp failsafe 0;
doc/stp.md says so.

Costs two bytes of XDATA, the armed flag and the console-path snapshot;
stp.rel and rtlplayground.rel keep their segment sizes.
2026-08-18 23:29:08 +02:00
d00f 2110cf128a stp: management failsafe (commit-confirm) + bounded NIC waits
Enabling STP on a bridge whose management rides an in-band VLAN can cut
off that very management - and not only by our own blocking: on this
network the upstream TP-Link Easy Smart switch's "loop prevention"
reacted to our BPDU hellos by blocking ITS port towards us while our
ASIC was all-forwarding, isolating the whole segment until a power
cycle. Recoverable only by going quiet.

Add a commit-confirm watchdog: while STP is enabled, any HTTP request
re-arms a countdown ("stp failsafe <seconds>", default 180, 0 disables);
if management stays silent for the whole window, STP disables itself,
which also stops BPDU TX so a neighbour's loop protection can release
its block. The web UI polls /stp.json every 2 s, so an open browser
naturally keeps the watchdog re-armed. The trip is reported via
/stp.json (fs, fsT) and as a warning on the Spanning Tree page.

Deliberately not conditioned on our own MSTP port states - the incident
above proves the uplink can be dead while every local port forwards.

Also bound the NIC DMA busy-waits (nic_tx_packet, nic_rx_header,
nic_rx_packet): an unbounded spin on SFR_NIC_CTRL freezes the entire
main loop (timers, HTTP, ARP) if the ASIC ever fails to consume a
transfer; give up after ~65k polls and drop the frame instead.

Hardware-verified end to end: with priority 15 against a live RSTP
bridge the uplink died 6 s after "stp on" and the network recovered BY
ITSELF 66 s later (trip at 45 s + neighbour release), fsT=1, LACP and
LAN intact. Telemetry via syslog-to-edge-port host confirmed the full
chain: countdown 44->4, trip, hello TX stopping at the trip.

(cherry picked from commit 1fa9775156fd6d7ebfdda2382f73430b86601230)
2026-08-18 23:28:26 +02:00
d00f 524c37d7c7 stp: full RSTP configuration (bridge + per-port), CLI + GUI + persistence
Implements the standard 802.1D-2004/802.1w configuration surface:

Bridge:  priority (0-15 x4096), hello time, max age, forward delay,
         force-version (RSTP v2 / STP-compatible v0 Config BPDUs), tx hold
         count (per-port per-second BPDU budget).
Per port: enable, admin edge (forwarding immediately - no listen gap),
         auto edge (forwarding after 3 s of BPDU silence; DEFAULT, so
         host-facing ports no longer take the full forward delay),
         path cost (0=auto/20000), port priority, BPDU guard (port disabled
         on BPDU receipt), root guard (never accept a better root on the
         port), BPDU filter (no BPDUs in or out).

Engine additions: root max-age expiry (reclaim the tree when the root goes
silent), root path cost accounting (rx cost + root-port cost, advertised in
our BPDUs), loop detection (our own BPDU coming back blocks the port for a
listen period), topology-change counter, approximated per-port roles
(Root/Designated/Alternate) for diagnostics.

CLI: "stp prio|hello|maxage|fwd|txhold|version ..." and
"stp port <n> on|off|edge|cost|prio|guard|filter ..." (stp_parse, delegated
from cmd_parser); all forms accepted by the startup-config validator so the
whole configuration persists. /stp.json now reports config + status; the
Spanning Tree page exposes everything with immediate-apply controls and live
state/role columns (edit-in-flight guard against the 2 s refresh).

8051 memory: the module moves to code BANK2; internal-RAM pressure from
cross-bank calls resolved by xdata loop iterators/scratch, __reentrant on
the small helpers, and moving httpd's header-pointer globals to xdata.

Verified on hardware (SWTGW218AS): defaults land per standard; priority and
hello change live; admin-edge ports (the LACP bond uplinks) keep the LAN at
0% loss THROUGH "stp on"; auto-edge ports forward after 3 s; a port that
heard real BPDUs (a VM bridge behind physical port 6) correctly declined
auto-edge, sat out the full listen period and became Designated; tc counts
promotions; we win the root election at priority 16384 vs 32768.

(cherry picked from commit 09a34dc6acdc81ab9cab0727d2f4a59c68131a3e)
2026-08-18 23:28:23 +02:00
d00f 56fa96c494 igmp: only hand reports to the CPU while snooping is on
handle_rx() dispatched to igmp_packet_handler() on the destination
address alone, so an ordinary IGMPv3 report off the wire reached the
handler and could write a table entry whether or not anyone had asked
for snooping. The STP branch right above it is gated on stpEnabled;
this brings the IGMP branch in line.

Snooping state lived only in the per-port registers, and the receive
path cannot afford to read one per packet, so the flag shadows it:
igmp_enable() sets it, igmp_setup() clears it, and igmp_setup() runs
from both the boot path and "igmp off".

While here, igmp off becomes an explicit subcommand instead of the
fall-through, and an unrecognised igmp subcommand prints the usage
line rather than silently turning snooping off.

Six bytes of BANK1 and one of xdata, no internal RAM.
2026-08-16 23:42:46 +02:00
d00f 1d1e33f4d5 sfp: notice when an I2C read fails
sfp_read_reg() waited for the transfer to finish and then read the output
register whatever the outcome, so an address nothing acknowledged came back
as an ordinary byte and no caller could tell it apart from data. The vendor
SDK looks at bit 1 of the control register for exactly this, and we did
not.

A failure now sets sfp_i2c_fail and the read returns 0xff, which is already
the value sfp_apply_quirks() reads as either a failed transfer or a voltage
the spec does not allow, so that test starts being true when it should be.
The insertion path and the sfp command clear the flag first and say so
afterwards, rather than presenting the bytes as though they came from the
module.

What this deliberately does not do is act on the failure. Skipping
sds_config() when the rate read failed is the obvious next step, but a
module that raises the bit spuriously would then never be configured at
all, which is worse than what happens today, and I have no way to judge how
often the bit is right. That decision belongs with someone holding the
board.

It also leaves the other half of the rewrite alone, reading and writing up
to sixteen bytes per transaction. doc/sfp.md describes only the single byte
path and does not name a length field, and guessing at a register I cannot
test is how the last attempt at this function went wrong.

40 bytes of the common segment, 51 of BANK2 and 1 of xdata, nothing in
BANK1 or internal RAM. Built for SWTGW218AS and KP_9000_6XHML_X2 on sdcc
4.5.0. Not tested on hardware: shorting the clock line, as in #342, should
now print the failure line instead of a plausible looking byte.
2026-08-15 23:14:53 +02:00
bloqaudio 3853a2701d machine: read a factory MAC from flash via mac_flash_offset
Adds an optional per-board mac_flash_offset. When non-zero, RTLPlayground
reads a 6-byte MAC from that flash address and uses it if it is a valid
globally-administered unicast address; otherwise it falls back to the
generated locally-administered MAC. Offset 0 (default for every board)
preserves current behaviour.

Enable it for the SWTGW218AS, whose stock firmware keeps the factory MAC
in nvcfg at 0x1FC000. RTLPlayground images and web upgrades only touch
flash below that region, so the factory MAC survives flashing.
2026-08-11 02:32:31 -05:00
René van Dorst 3f7db7e430 Merge pull request #297 from DrDoof/hostname
system: configurable hostname + show model on the System page
2026-08-07 18:10:34 +00:00
d00f 108ac9b8fc system: derive the default hostname after the startup config
Move the MAC-derived default name out of main() into its own function and
call it after execute_config(), returning early when the config already
set a name - a configured switch then does no work for it at all.

The body deliberately has no local variables. Locals here - counters and
pointers alike - land in the 8051's internal-RAM overlay, and on an image
with LACP and STP both enabled that overlay is exhausted: a loop makes the
linker fail with "Could not get 8 consecutive bytes in internal RAM for
area OSEG". Moving the code into its own function does not help, since the
overlay is shared across the whole image, and hoisting the locals to xdata
does not either, because itohex() is inline and brings its own frame. This
only shows up in an integrated build; the branch on its own links fine.

Suggested-by: vDorst
2026-08-05 16:48:36 +02:00
d00f 94716ceb5d system: derive the default hostname from the MAC address
Every switch came up as "RTLPlayground", so several of them on one
network were indistinguishable until someone configured a name. Append
the last three MAC octets (e.g. RTLPlayground-1ef924) - unique in
practice, still recognisable, and any "hostname ..." line in the startup
config overrides it as before.

Suggested-by: plaes
2026-08-04 05:43:05 +02:00
d00f f21b3a32bd system: configurable hostname (device identity)
Add a device hostname settable from the CLI (`hostname <text>`) and the
System Settings page. The value is sanitized on ingest to JSON-safe
printable ASCII (<=23 chars), stored in a shared __xdata buffer, seeded
to "RTLPlayground" at boot, persisted through the startup-config, and
reported in /information.json. It lives in the common header so other
modules can advertise it (LLDP uses it as the System Name TLV).
2026-07-25 13:07:09 +02:00
Sempr c473646389 Fix rate range for SDS_10GR return value
Broaden range of SFP+ rates mapped to SDS_10GR
A commonly used SFP+ form-factor 10GBASE-LR (Hisense LTF1303-BH+) reports 0x62(	BR Nominal: 9800MBd) at
power on and then switches to 0x64 after booting up.

0x62 -> 9.8gbps
0x63 -> 9.9gbps
0x64 -> 10gbps
0x6f -> 11.1gbps
0x70 -> 11.2gbps

These are outside of the previous 0x63-0x6f range which prevented the link from ever being brought up. So I changed the range to 0x62-0x6f
2026-07-24 16:02:20 +08:00
Matt Merhar 2221f0fa32 Add SFP quirk for devices that misreport DDM capability
On a QSFPTEK QT-SFP+-T (RTL8261C) 10GBase-T module, the diag type field
(92) comes back as 0x00, but there's actually some statistics available
like temperature. Other metrics may be hard-coded values.

Add a basic struct that allows matching on vendor and/or model, using a
bitfield to allow multiple quirks for a given SFP module. Only
SFP_QUIRK_DDM is implemented.

For modules matching SFP_QUIRK_DDM, attempt an I2C read of the MSB of
module voltage during probe if DDM is "unsupported" - if it's not 0xff,
override the reported options so we can pull the diagnostic data.

To allow simpler comparisons, convert the ASCII fields (vendor,
model, serial) from space-padded to standard NULL-terminated strings.

strcmp() is moved from httpd.c to rtlplayground.c alongside other string
functions and shared between them.

The __reentrant keyword is used for the new functions to avoid using up
additional OSEG space. This allocates the variables on the stack, which
is OK for this particular code path.

The JSON assembly in send_status() is slightly modified to treat the
sfp_module_* data as standard NULL-terminated strings, and a repeated
subtraction was moved into a uint8_t to declutter the code.
2026-07-13 01:31:29 -04:00
logicog 842d68af97 Add support for 100M on RTL8221B ports 2026-06-15 18:40:03 +02:00
bennydiamond 7a7ffd3bf8 Automatically print newline on serial interface
For some print_string
2026-06-07 14:52:56 -04:00
TylerDurden-23 62065875e3 Revert "Don't disable flash DIO operation before flashing" 2026-06-07 10:42:39 +02:00
feelfree69 4ca5b4e87a Don't disable flash DIO operation before flashing - it works fine with DIO 2026-06-01 15:07:37 +02:00
René van Dorst ad64e450e1 Merge pull request #246 from logicog/sfp_speed
Add support for configuring SFP modules speeds via CLI
2026-05-31 18:33:05 +00:00
logicog 1a457c29ac Add support for 100FX modules and forcing 100FX 2026-05-30 23:08:44 +02:00
logicog 8c61010a84 Add support for configuring SFP modules speeds 2026-05-29 20:46:08 +02:00
Matt Merhar 73b99b2f08 Broaden range of SFP+ rates mapped to SDS_10GR
A commonly used SFP+ form-factor XGS-PON ONT (WAS-110) reports 0x63 at
power on and then switches to 0x64 after booting up.

0x63 -> 9.9gbps
0x64 -> 10gbps

These are outside of the previous 0x66-0x69 range which prevented the
link from ever being brought up.
2026-05-25 21:45:42 -04:00
UAb5eSMn 2316ffd493 Support for executing multiple commands via /cmd 2026-05-15 13:27:09 +02:00
René van Dorst 09d90d6d97 Merge pull request #175 from logicog/ZX310S-4T2XH
10GBit Ethernet Switch support (Horaco ZX310S-4T2XH)
2026-05-02 17:22:52 +00:00
feelfree69 3f66a18104 Merge branch 'main' into syslog 2026-04-24 12:01:30 +02:00
logicog 441340a4d4 Add SMI configuration support for dual 10G Ethernet 2026-04-24 10:53:05 +02:00
logicog 4f4f69ecc1 Handle RTL8261BE SerDes configuration
The RTL8261BE uses a 10GBit QSGMII connection. Add handler for initial
configuration of the SerDes speed and upon link changes.
2026-04-24 10:52:24 +02:00
logicog e280ccd2f9 Use RTL descriptor definition 2026-04-24 08:42:00 +02:00
logicog baa4e5e142 Use header structures of TX and RX, add dot1q for management VLAN TX 2026-04-22 22:36:26 +02:00
feelfree69 da8ec8fe88 Merge branch 'logicog:main' into syslog 2026-04-21 21:26:45 +02:00
René van Dorst d2e79d4d80 Fix: In commit 8cbafaa cmd_tokenize() has changed. Missed that it also used
outside cmd_parser.c.
Fix the other location and headerfile.
2026-04-21 21:17:22 +02:00
feelfree69 f7989cc737 Merge branch 'logicog:main' into syslog 2026-04-21 14:29:44 +02:00
René van Dorst 52d943d5e4 rtlplayground: de-__gptrput()-call in read_reg_timer() 2026-04-19 22:18:39 +02:00
feelfree69 e130777b24 serial console cosmetic change 2026-04-13 14:55:50 +02:00
feelfree69 c1a414833d Various refactorings 2026-04-12 13:02:42 +02:00
feelfree69 d776118815 Revert unneeded changes 2026-04-12 13:02:42 +02:00
feelfree69 eaa21d5975 rebase First try to make use of uIP for sending syslog 2026-04-12 13:02:37 +02:00
feelfree69 b60811b984 initialize all vars; remove unused code 2026-04-12 12:58:02 +02:00
feelfree69 b21bfac917 rebase first prototype 2026-04-12 12:57:49 +02:00