![]() |
LambLisp 01 Red Fox Alpha
From AI to Actuator
|
Classes | |
| struct | LLArduinoBackend |
| struct | LLGpiodPin |
| struct | LLGpiodLine |
Macros | |
| #define | LL_LLA_NPINS 256 |
Functions | |
| bool | ll_gpiod_available () |
| void | ll_gpiod_pin_mode (int, int) |
| void | ll_gpiod_digital_write (int, int) |
| int | ll_gpiod_digital_read (int) |
| void | ll_gpiod_analog_write (int, int) |
| int | ll_gpiod_analog_read (int) |
| void | ll_gpiod_tone_on (int, unsigned int) |
| void | ll_gpiod_tone_off (int) |
| int | ll_gpiod_pin_mode_get (int) |
| int | ll_gpiod_pin_duty_get (int) |
| int | ll_gpiod_pin_tone_get (int) |
| int | ll_gpiod_npins () |
| void | pinMode (int pin, int mode) |
| void | digitalWrite (int pin, int val) |
| int | digitalRead (int pin) |
| void | analogWrite (int pin, int val) |
| int | analogRead (int pin) |
| void | tone (int pin, unsigned int freq) |
| void | tone (int pin, unsigned int freq, unsigned long dur) |
| void | noTone (int pin) |
| int | ll_llarduino_pin_mode (int pin) |
| int | ll_llarduino_pin_duty (int pin) |
| int | ll_llarduino_pin_tone (int pin) |
| int | ll_llarduino_npins () |
| const char * | ll_llarduino_backend () |
| virtual size_t | Print::write (const uint8_t *buf, size_t n) |
| size_t | Print::write (const char *s) |
| size_t | Print::print (char c) |
| size_t | Print::print (const char *s) |
| size_t | Print::print (const String &s) |
| size_t | Print::print (long n, int base=10) |
| size_t | Print::print (int n, int base=10) |
| size_t | Print::print (unsigned long n, int base=10) |
| size_t | Print::print (double v, int digits=2) |
| size_t | Print::println () |
| size_t | Print::println (char c) |
| size_t | Print::println (const char *s) |
| size_t | Print::println (const String &s) |
| size_t | Print::println (int n, int base=10) |
| size_t | Print::println (long n, int base=10) |
| size_t | Print::println (unsigned long n, int base=10) |
| size_t | Print::println (double v, int digits=2) |
| size_t | Print::printf (const char *fmt,...) CHECKPRINTF_pos2 |
| void | LLArduinoSerial::begin (unsigned long baud=115200) |
| void | LLArduinoSerial::end () |
| int | LLArduinoSerial::availableForWrite () |
| void | LLArduinoSerial::flush () override |
| size_t | LLArduinoSerial::write (uint8_t c) override |
| int | LLArduinoSerial::available () override |
| int | LLArduinoSerial::read () override |
| int | LLArduinoSerial::peek () override |
Variables | |
| LLArduinoSerial | Serial |
The NULL (simulated) backend: pin state in memory, no hardware.
Print / Stream / Serial – REAL character I/O, not a simulation.
libgpiod backend – REAL pins on a Raspberry Pi or Jetson.
This is the backend that runs where there is no GPIO to drive – a developer laptop, an x86 host, a container – so that the 26 commonio procedures (pinMode, digitalWrite, digitalRead, analogRead/Write, tone, ...) can be CALLED AND ASSERTED ON without a board.
WHY THAT MATTERS HERE, concretely: of the seven boards where commonio is compiled in, most are unavailable most of the time – shared with other sessions, unplugged to save power, or in a failed USB port. On one occasion exactly ONE of seven was reachable. Anything that can only be tested with a board in hand is, in practice, tested rarely; a recent Arduino 3.x WiFi ( regression) reached customers as a boot loop for that reason.
IT ANNOUNCES ITSELF AS SIMULATED. A simulated backend is honest only while nobody can mistake it for hardware, so llarduino-backend returns 'null here and the loopback semantics are documented below rather than left to be discovered. The rule – never invent a plausible sensor reading – still binds the REAL backends: on a Pi or Jetson, analogRead has no ADC behind it and must say so instead of returning a number. Here every value is one the caller itself wrote, which is a different thing from a fabricated measurement.
This is what makes LLArduino a port rather than a simulation: (digitalWrite 18 1) in Scheme drives an actual header pin. Selected at RUNTIME (see the dispatch table in ll_llarduino_null.cpp) because whether real pins exist is a property of the MACHINE, not the build – the same aarch64 binary runs on a Jetson with a 40-pin header and on a box whose gpiochips are not header pins at all.
libgpiod v1 API, PINNED DELIBERATELY. v1.6.3 is what both this workstation and the Jetson carry, and libgpiod v2 is SOURCE-INCOMPATIBLE with v1 (different handle types, different request API). A distro upgrade that silently moved to v2 would break this file, which is the same class of trap as the esptool 4.x/5.x subcommand split and the Arduino 2.x/3.x break behind If v2 support is wanted it goes beside this, not through it.
Print and Stream are pure character I/O, and LambStdio already implements exactly that on POSIX, so this is a facade over working plumbing rather than a stand-in. That is the same footing as millis(): genuinely implemented on the host, not faked.
ARDUINO'S QUIRKS ARE MATCHED ON PURPOSE. Each of these is a place where a host test could pass while a device disagrees, which is the failure criterion 3 is designed to catch:
| #define LL_LLA_NPINS 256 |
Simulated pin file. LL_LLA_NPINS is generous because pin NUMBERING is board-specific (a Pi's BCM numbers, an ESP32's GPIO numbers) and this backend must not reject a number that is legal somewhere. Out-of-range is CLAMPED AWAY FROM MEMORY, never written: a bad pin number is a caller error, not a reason to corrupt the heap.
|
extern |
The libgpiod backend lives in ll_llarduino_gpiod.cpp; only its entry points are needed here.
|
extern |
NO ADC AND NO PWM HERE, AND THEY MUST NOT PRETEND. Neither a Pi nor a Jetson has an ADC on the header – analogRead conventionally means an EXTERNAL converter (MCP3008 over SPI, ADS1115 over I2C) – and analogWrite needs a PWM chip wired to that specific pin. The rule holds: a fabricated sensor reading is worse than an error, because it is plausible. -1 says "unsupported on this backend"; it is never a measurement.
| void pinMode | ( | int | pin, |
| int | mode ) |
Public Arduino surface – one line each, straight through the table.
| int ll_llarduino_pin_mode | ( | int | pin | ) |
Backend inspection – lets a test assert on state the Arduino API cannot report (mode, duty, tone) and name which backend answered. See ll_llarduino_null.cpp.
| size_t Print::print | ( | double | v, |
| int | digits = 2 ) |
Arduino's default is TWO decimal places, not g and not full precision.
| size_t Print::println | ( | ) |
CRLF, as Arduino does – not "\n".
CRLF – Arduino's println has always emitted "\r\n". A host that emits bare "\n" looks correct in a terminal and differs from the device, which is exactly the silent divergence to avoid.
| size_t Print::printf | ( | const char * | fmt, |
| ... ) |
HardwareSerial::printf, used by LL itself.
HardwareSerial::printf is not standard Arduino Print, but LambLisp's own Stdio layer calls it (ll_platform_Stdio.cpp), so the facade owes it.
< truncate, never overrun
|
overridevirtual |
Implements Print.
|
override |
available() must count the pushed-back byte, or peek() would hide input from a caller that polls available() before reading – the classic Stream bug.
|
override |
One byte of pushback, which is all Stream promises. LambStdioClass has no peek of its own.