Constants and System Info (FmrbConst / FmrbHw)¶
FmrbConst¶
A module that provides constants referenced throughout the system.
Platform Information¶
| Constant | Value |
|---|---|
FmrbConst::PLATFORM |
"linux" or "esp32" |
FmrbConst::BOARD |
"tab5", "naryav4", "atom_display", "narya_v3" or "linux". Finer-grained than PLATFORM and CHIP_MODEL: use it to pick board-specific wiring |
FmrbConst::HW_FAMILY |
"modern" or "retro". The coarsest of the three, and the one to ask when a feature exists on one family and not the other |
FmrbConst::OS_VERSION |
OS version string |
FmrbConst::GA_VERSION |
fmruby-graphics-audio version |
FmrbConst::LINK_VERSION |
UART link protocol version |
FmrbConst::IDF_VERSION |
ESP-IDF version |
FmrbConst::BUILD_DATE |
When this firmware was compiled, as "Mmm dd yyyy hh:mm:ss" |
FmrbConst::LANGUAGE |
The UI language from system_conf.toml, "en" or "ja". FmrbApp.language reads it through a call that works on both engines |
Hardware Information¶
| Constant | Description |
|---|---|
FmrbConst::MAC_ADDRESS |
MAC address string |
FmrbConst::CHIP_MODEL |
e.g. "ESP32-S3" |
FmrbConst::CHIP_REVISION |
Revision number |
FmrbConst::CHIP_CORES |
Number of cores |
FmrbConst::FLASH_SIZE_MB |
Flash capacity (MB) |
FmrbConst::PSRAM_SIZE_MB |
PSRAM capacity (MB) |
FmrbConst::RESET_REASON |
Why the machine last restarted, as a string: POWERON, EXT, SW, PANIC, INT_WDT, TASK_WDT, WDT, DEEPSLEEP, BROWNOUT, SDIO, USB, JTAG, EFUSE, PWR_GLITCH, CPU_LOCKUP or UNKNOWN |
FmrbConst::HAS_WIFI |
true on a machine that can join a network. See Network |
FmrbConst::WHEEL_LINES |
How many text rows one notch of the mouse wheel moves, from system_conf.toml |
Process Management¶
| Constant | Purpose |
|---|---|
FmrbConst::PROC_ID_KERNEL |
Kernel process ID |
FmrbConst::PROC_ID_HOST |
Host process ID |
FmrbConst::PROC_ID_SYSTEM_APP |
System app ID |
FmrbConst::PROC_ID_USER_APP0 … USER_APP4 |
User app slots. There are five; how many fill depends on the memory the machine has |
Process States¶
The state of each entry FmrbApp.ps returns:
| Constant | Value | Meaning |
|---|---|---|
PROC_STATE_FREE |
0 | The slot is empty |
PROC_STATE_INIT |
1 | Allocated and its VM built, not started yet. The kernel announces a spawn at this point, so an app already has a window here |
PROC_STATE_RUNNING |
2 | Running |
PROC_STATE_SUSPENDED |
3 | Temporarily suspended — a fullscreen app parked by Ctrl + Tab is in this state, and still answers from the taskbar |
PROC_STATE_STOPPING |
4 | Asked to stop, still winding down |
Messaging¶
| Constant | Purpose |
|---|---|
MSG_TYPE_APP_CONTROL |
App control message |
MSG_TYPE_APP_GFX |
Graphics message |
MSG_TYPE_APP_AUDIO |
Audio message |
MSG_TYPE_HID_EVENT |
HID event (keyboard, etc.) |
App Control Commands¶
The subtype of an MSG_TYPE_APP_CONTROL message sent to the kernel:
| Constant | Value | Meaning |
|---|---|---|
APP_CTRL_SPAWN |
1 | Start an app |
APP_CTRL_KILL |
2 | Stop one |
APP_CTRL_SUSPEND |
3 | Suspend one |
APP_CTRL_RESUME |
4 | Let it run again |
An ordinary app rarely sends these itself: request_run, request_fullscreen and the rest
of FmrbApp build the message for it.
Status LED¶
What the board's LED is showing. The kernel sets it; these name the patterns.
| Constant | Value | Meaning |
|---|---|---|
LED_ERR_NONE |
0 | Nothing wrong |
LED_ERR_FATAL |
1 | Solid red. The system stopped |
LED_ERR_VERSION_MISMATCH |
2 | Three quick red pulses, then a gap. The two chips are on different versions (Retro) |
Theme Colors (System-wide Color Scheme)¶
| Constant | Purpose |
|---|---|
THEME_DESKTOP_BG |
Desktop background |
THEME_MENU_BG |
Menu background |
THEME_WINDOW_BG |
Window background |
THEME_TEXT |
Normal text |
THEME_TEXT_LIGHT |
Light text |
THEME_HIGHLIGHT |
Highlight |
THEME_BORDER |
Border |
THEME_BUTTON |
Button |
THEME_DIR_COLOR |
Directory names, where a file list distinguishes them from files |
These are all RGB332 values. Use them when you want your app's UI to match the OS color scheme.
Input Device: Keyboard (KEY_*)¶
USB HID Usage IDs. Compare with ev[:scancode] in on_event(ev).
| Category | Constants |
|---|---|
| Letters | KEY_A .. KEY_Z |
| Numbers | KEY_1 .. KEY_9, KEY_0 |
| Control | KEY_ENTER, KEY_ESC, KEY_BACKSPACE, KEY_TAB, KEY_SPACE |
| Symbols | KEY_MINUS, KEY_EQUAL, KEY_LBRACKET, KEY_RBRACKET, KEY_BACKSLASH, KEY_SEMICOLON, KEY_QUOTE, KEY_GRAVE, KEY_COMMA, KEY_PERIOD, KEY_SLASH |
| Locks | KEY_CAPSLOCK, KEY_SCROLLLOCK, KEY_NUMLOCK |
| Function | KEY_F1 .. KEY_F12 |
| Editing | KEY_INSERT, KEY_HOME, KEY_PGUP, KEY_DELETE, KEY_END, KEY_PGDN |
| Arrow | KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN |
| Other | KEY_PRINTSCREEN, KEY_PAUSE |
| Modifier keys (individual) | KEY_LCTRL, KEY_LSHIFT, KEY_LALT, KEY_LMETA, KEY_RCTRL, KEY_RSHIFT, KEY_RALT, KEY_RMETA |
Input Device: Modifier Key Masks (MOD_*)¶
Use bitwise AND with ev[:modifier] in on_event(ev) to check modifier state.
| Constant | Bit | Meaning |
|---|---|---|
MOD_LSHIFT |
0x01 | Left Shift |
MOD_RSHIFT |
0x02 | Right Shift |
MOD_LCTRL |
0x04 | Left Ctrl |
MOD_RCTRL |
0x08 | Right Ctrl |
MOD_LALT |
0x10 | Left Alt |
MOD_RALT |
0x20 | Right Alt |
MOD_SHIFT |
0x03 | Either Shift |
MOD_CTRL |
0x0C | Either Ctrl |
MOD_ALT |
0x30 | Either Alt |
These are this firmware's own bits, not the USB HID modifier byte, so do not write the
numbers out by hand — 0x01 is Left Shift here and Left Ctrl in the HID standard.
There is no mask for the Meta (Windows / Command) key: the modifier byte the firmware
delivers has six bits and Meta is not one of them. A press still arrives as an ordinary key
event with scancode KEY_LMETA or KEY_RMETA.
ev_ctrl?(ev) / ev_shift?(ev) / ev_alt?(ev)
You can also check modifiers using FmrbApp helpers. Using MOD_* directly is only needed for special cases; normally use the helpers instead.
Input Device: Gamepad (GP_*)¶
In on_event(ev), when ev[:type] == :gamepad_down / :gamepad_up, ev[:button] holds the button number. When ev[:type] == :gamepad_axis, ev[:axis] holds the axis number.
Buttons¶
| Constant | Value | Meaning |
|---|---|---|
GP_SQUARE |
0 | Square |
GP_CROSS |
1 | Cross |
GP_CIRCLE |
2 | Circle |
GP_TRIANGLE |
3 | Triangle |
GP_L1 |
4 | Left shoulder |
GP_R1 |
5 | Right shoulder |
GP_L2 |
6 | Left trigger |
GP_R2 |
7 | Right trigger |
GP_SELECT |
8 | Select |
GP_START |
9 | Start |
GP_L3 |
10 | Left stick press |
GP_R3 |
11 | Right stick press |
GP_UP |
12 | D-pad up |
GP_DOWN |
13 | D-pad down |
GP_LEFT |
14 | D-pad left |
GP_RIGHT |
15 | D-pad right |
Axes¶
| Constant | Value | Meaning |
|---|---|---|
GP_AXIS_LX |
0 | Left stick X |
GP_AXIS_LY |
1 | Left stick Y |
GP_AXIS_RX |
2 | Right stick X |
GP_AXIS_RY |
3 | Right stick Y |
Sample: Key Detection¶
def on_event(ev)
super
if ev[:type] == :key_down
case ev[:scancode]
when FmrbConst::KEY_LEFT then @x -= 4
when FmrbConst::KEY_RIGHT then @x += 4
when FmrbConst::KEY_SPACE then shoot
when FmrbConst::KEY_ESC then stop
end
if (ev[:modifier] || 0) & FmrbConst::MOD_CTRL != 0 &&
ev[:scancode] == FmrbConst::KEY_S
save_state
end
elsif ev[:type] == :gamepad_down
case ev[:button]
when FmrbConst::GP_CROSS then jump
when FmrbConst::GP_START then pause
end
end
end
Other¶
| Constant | Description |
|---|---|
MAX_PATH_LEN |
Maximum path length |
Sample: Display Version and Environment¶
class SysInfo < FmrbApp
def on_create
clear_user_area(FmrbGfx::WHITE)
x = @user_area_x0 + 4
y = @user_area_y0 + 4
@gfx.draw_text(x, y, "OS: #{FmrbConst::OS_VERSION}", FmrbGfx::BLACK)
@gfx.draw_text(x, y + 10, "Chip: #{FmrbConst::CHIP_MODEL}", FmrbGfx::BLACK)
@gfx.draw_text(x, y + 20, "PSRAM: #{FmrbConst::PSRAM_SIZE_MB}MB", FmrbGfx::BLACK)
@gfx.draw_text(x, y + 30, "MAC: #{FmrbConst::MAC_ADDRESS}", FmrbGfx::BLACK)
draw_window_frame
@gfx.present
end
end
SysInfo.new.start
FmrbHw¶
A module for querying the usage status of hardware resources (especially GPIO pins).
| Method | Return Value |
|---|---|
FmrbHw.pin_status(pin) |
Pin usage state (Integer, 0 = unused, other = usage-specific identifier) |
FmrbHw.pin_available?(pin) |
true if unused |
FmrbHw.pin_status_all |
Array<Integer> (index = pin number, value = status) |
FmrbHw.pin_count |
Total number of pins |
What pin_status returns is one of these, and they are constants on FmrbHw:
| Constant | Value | Meaning |
|---|---|---|
FmrbHw::PIN_UNUSED |
0 | Free |
FmrbHw::PIN_SYSTEM_EXCLUSIVE |
1 | Reserved by the system and never available — USB, PSRAM, the display link |
FmrbHw::PIN_USER_GPIO |
2 | Taken by an app as a GPIO |
FmrbHw::PIN_USER_I2C |
3 | Taken by an I2C |
FmrbHw::PIN_USER_RMT |
4 | Taken by an RMT |
FmrbHw::PIN_USER_SPI |
5 | Taken by SPI |
FmrbHw::PIN_USER_PWM |
6 | Taken by PWM |
FmrbHw::PIN_USER_UART |
7 | Taken by a UART |
The I2C buses the system itself uses are named too, so an app can talk on one without hardcoding a board's numbers (ESP32 only):
| Constant | |
|---|---|
FmrbHw::PIN_I2C1_SDA / PIN_I2C1_SCL |
The first bus |
FmrbHw::PIN_I2C2_SDA / PIN_I2C2_SCL |
The second |
Sample: Display All Pins¶
status = FmrbHw.pin_status_all
status.each_with_index do |s, i|
Log.info("pin #{i}: #{s == 0 ? 'free' : 'used'}")
end
Sample: Check Before Use¶
PIN = 10
unless FmrbHw.pin_available?(PIN)
Log.error("Pin #{PIN} is in use (status=#{FmrbHw.pin_status(PIN)})")
return
end
gpio = GPIO.new(PIN, GPIO::OUT)
There is a sample in tool/gpio_viewer.app.rb that visualizes pin states with a GUI.
Related¶
- For pin specifications (electrical characteristics, external connections), see Hardware
- For GPIO usage, see Hardware Control