Skip to main content

m5unified_sys/
lib.rs

1#![allow(non_camel_case_types)]
2#![allow(non_snake_case)]
3#![allow(non_upper_case_globals)]
4#![allow(clippy::missing_safety_doc)]
5
6//! Raw bindings for a small C ABI shim over M5Unified.
7//!
8//! This crate intentionally does not bind M5Unified's C++ classes directly.
9//! Instead, `native/m5u_shim.cpp` exposes stable `extern "C"` functions that
10//! Rust can call from the higher-level `m5unified` crate. On non-ESP-IDF host
11//! targets these functions are stubbed so the safe wrapper and translated
12//! samples can be checked in CI without hardware.
13//!
14//! Firmware projects targeting ESP-IDF must provide the native shim component
15//! from this crate's `native/` directory in their ESP-IDF component graph. The
16//! host stubs are compile-time conveniences only and do not simulate M5Stack
17//! hardware behavior.
18
19use core::ffi::{c_char, c_float, c_int, c_void};
20
21pub type m5u_log_callback_t = Option<unsafe extern "C" fn(c_int, bool, *const c_char, *mut c_void)>;
22
23#[repr(C)]
24#[derive(Debug, Copy, Clone, PartialEq, Eq)]
25pub struct m5u_sd_spi_config_t {
26    pub pin_sclk: c_int,
27    pub pin_mosi: c_int,
28    pub pin_miso: c_int,
29    pub pin_cs: c_int,
30    pub host_id: c_int,
31    pub frequency_khz: u32,
32    pub max_files: c_int,
33    pub format_if_mount_failed: u8,
34}
35
36impl Default for m5u_sd_spi_config_t {
37    fn default() -> Self {
38        Self {
39            pin_sclk: -1,
40            pin_mosi: -1,
41            pin_miso: -1,
42            pin_cs: -1,
43            host_id: -1,
44            frequency_khz: 20_000,
45            max_files: 5,
46            format_if_mount_failed: 0,
47        }
48    }
49}
50
51#[repr(C)]
52#[derive(Debug, Copy, Clone, PartialEq, Eq)]
53pub struct m5u_config_t {
54    pub serial_baudrate: u32,
55    pub external_speaker_value: u8,
56    pub external_display_value: u16,
57    pub clear_display: u8,
58    pub output_power: u8,
59    pub pmic_button: u8,
60    pub internal_imu: u8,
61    pub internal_rtc: u8,
62    pub internal_mic: u8,
63    pub internal_spk: u8,
64    pub external_imu: u8,
65    pub external_rtc: u8,
66    pub disable_rtc_irq: u8,
67    pub led_brightness: u8,
68    pub fallback_board: c_int,
69}
70
71impl Default for m5u_config_t {
72    fn default() -> Self {
73        Self {
74            serial_baudrate: 0,
75            external_speaker_value: 0x00,
76            external_display_value: 0xFFFF,
77            clear_display: 1,
78            output_power: 1,
79            pmic_button: 1,
80            internal_imu: 1,
81            internal_rtc: 1,
82            internal_mic: 1,
83            internal_spk: 1,
84            external_imu: 0,
85            external_rtc: 0,
86            disable_rtc_irq: 1,
87            led_brightness: 0,
88            fallback_board: -1,
89        }
90    }
91}
92
93#[repr(C)]
94#[derive(Debug, Copy, Clone, PartialEq, Eq)]
95pub struct m5u_mic_config_t {
96    pub pin_data_in: c_int,
97    pub pin_bck: c_int,
98    pub pin_mck: c_int,
99    pub pin_ws: c_int,
100    pub sample_rate: u32,
101    pub left_channel: u8,
102    pub stereo: u8,
103    pub over_sampling: u8,
104    pub magnification: u8,
105    pub noise_filter_level: u8,
106    pub use_adc: u8,
107    pub dma_buf_len: usize,
108    pub dma_buf_count: usize,
109    pub task_priority: u8,
110    pub task_pinned_core: u8,
111    pub i2s_port: c_int,
112}
113
114impl Default for m5u_mic_config_t {
115    fn default() -> Self {
116        Self {
117            pin_data_in: -1,
118            pin_bck: -1,
119            pin_mck: -1,
120            pin_ws: -1,
121            sample_rate: 16_000,
122            left_channel: 0,
123            stereo: 0,
124            over_sampling: 2,
125            magnification: 16,
126            noise_filter_level: 0,
127            use_adc: 0,
128            dma_buf_len: 128,
129            dma_buf_count: 8,
130            task_priority: 2,
131            task_pinned_core: u8::MAX,
132            i2s_port: 0,
133        }
134    }
135}
136
137#[repr(C)]
138#[derive(Debug, Copy, Clone, PartialEq, Eq)]
139pub struct m5u_speaker_config_t {
140    pub pin_data_out: c_int,
141    pub pin_bck: c_int,
142    pub pin_mck: c_int,
143    pub pin_ws: c_int,
144    pub sample_rate: u32,
145    pub stereo: u8,
146    pub buzzer: u8,
147    pub use_dac: u8,
148    pub dac_zero_level: u8,
149    pub magnification: u8,
150    pub dma_buf_len: usize,
151    pub dma_buf_count: usize,
152    pub task_priority: u8,
153    pub task_pinned_core: u8,
154    pub i2s_port: c_int,
155}
156
157impl Default for m5u_speaker_config_t {
158    fn default() -> Self {
159        Self {
160            pin_data_out: -1,
161            pin_bck: -1,
162            pin_mck: -1,
163            pin_ws: -1,
164            sample_rate: 48_000,
165            stereo: 0,
166            buzzer: 0,
167            use_dac: 0,
168            dac_zero_level: 0,
169            magnification: 16,
170            dma_buf_len: 256,
171            dma_buf_count: 8,
172            task_priority: 2,
173            task_pinned_core: u8::MAX,
174            i2s_port: 0,
175        }
176    }
177}
178
179#[repr(C)]
180#[derive(Debug, Copy, Clone, PartialEq, Eq)]
181pub struct m5u_power_ext_port_bus_t {
182    pub voltage_mv: u16,
183    pub current_limit_ma: u8,
184    pub enable: bool,
185    pub direction_output: bool,
186}
187
188impl Default for m5u_power_ext_port_bus_t {
189    fn default() -> Self {
190        Self {
191            voltage_mv: 5_000,
192            current_limit_ma: 0,
193            enable: false,
194            direction_output: false,
195        }
196    }
197}
198
199#[repr(C)]
200#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
201pub struct m5u_led_color_t {
202    pub r: u8,
203    pub g: u8,
204    pub b: u8,
205}
206
207#[repr(C)]
208#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
209pub struct m5u_touch_detail_t {
210    pub x: c_int,
211    pub y: c_int,
212    pub prev_x: c_int,
213    pub prev_y: c_int,
214    pub base_x: c_int,
215    pub base_y: c_int,
216    pub base_msec: u32,
217    pub state: u8,
218    pub is_pressed: bool,
219    pub was_pressed: bool,
220    pub was_released: bool,
221    pub was_clicked: bool,
222    pub was_hold: bool,
223    pub is_holding: bool,
224    pub click_count: c_int,
225}
226
227#[repr(C)]
228#[derive(Debug, Copy, Clone, PartialEq, Eq)]
229pub struct m5u_rtc_datetime_t {
230    pub year: c_int,
231    pub month: c_int,
232    pub day: c_int,
233    pub weekday: c_int,
234    pub hour: c_int,
235    pub minute: c_int,
236    pub second: c_int,
237}
238
239impl Default for m5u_rtc_datetime_t {
240    fn default() -> Self {
241        Self {
242            year: 2026,
243            month: 1,
244            day: 1,
245            weekday: 4,
246            hour: 0,
247            minute: 0,
248            second: 0,
249        }
250    }
251}
252
253#[repr(C)]
254#[derive(Debug, Copy, Clone, Default, PartialEq)]
255pub struct m5u_imu_data_t {
256    pub usec: u32,
257    pub accel_x: f32,
258    pub accel_y: f32,
259    pub accel_z: f32,
260    pub gyro_x: f32,
261    pub gyro_y: f32,
262    pub gyro_z: f32,
263    pub mag_x: f32,
264    pub mag_y: f32,
265    pub mag_z: f32,
266}
267
268#[cfg(target_os = "espidf")]
269extern "C" {
270    pub fn m5u_begin() -> bool;
271    pub fn m5u_begin_with_config(config: *const m5u_config_t) -> bool;
272    pub fn m5u_update();
273    pub fn m5u_delay_ms(ms: u32);
274    pub fn m5u_millis() -> u32;
275    pub fn m5u_micros() -> u32;
276    pub fn m5u_get_update_msec() -> u32;
277    pub fn m5u_get_board() -> c_int;
278    pub fn m5u_get_pin(name: c_int) -> c_int;
279    pub fn m5u_set_primary_display_index(index: usize) -> bool;
280    pub fn m5u_set_primary_display_type(kind: c_int) -> bool;
281    pub fn m5u_set_primary_display_types(kinds: *const c_int, len: usize) -> bool;
282    pub fn m5u_set_log_display_index(index: usize);
283    pub fn m5u_set_log_display_type(kind: c_int);
284    pub fn m5u_set_log_display_types(kinds: *const c_int, len: usize);
285    pub fn m5u_set_touch_button_height(pixel: u16);
286    pub fn m5u_set_touch_button_height_by_ratio(ratio: u8);
287    pub fn m5u_get_touch_button_height() -> u16;
288
289    pub fn m5u_i2c_set_port(bus: c_int, port_num: c_int, pin_sda: c_int, pin_scl: c_int);
290    pub fn m5u_i2c_begin(bus: c_int) -> bool;
291    pub fn m5u_i2c_begin_with_port(
292        bus: c_int,
293        port_num: c_int,
294        pin_sda: c_int,
295        pin_scl: c_int,
296    ) -> bool;
297    pub fn m5u_i2c_release(bus: c_int) -> bool;
298    pub fn m5u_i2c_is_enabled(bus: c_int) -> bool;
299    pub fn m5u_i2c_get_port(bus: c_int) -> c_int;
300    pub fn m5u_i2c_get_sda(bus: c_int) -> c_int;
301    pub fn m5u_i2c_get_scl(bus: c_int) -> c_int;
302    pub fn m5u_i2c_start(bus: c_int, address: u8, read: bool, freq: u32) -> bool;
303    pub fn m5u_i2c_restart(bus: c_int, address: u8, read: bool, freq: u32) -> bool;
304    pub fn m5u_i2c_stop(bus: c_int) -> bool;
305    pub fn m5u_i2c_write_byte(bus: c_int, data: u8) -> bool;
306    pub fn m5u_i2c_write(bus: c_int, data: *const u8, length: usize) -> bool;
307    pub fn m5u_i2c_read(bus: c_int, result: *mut u8, length: usize, last_nack: bool) -> bool;
308    pub fn m5u_i2c_write_register(
309        bus: c_int,
310        address: u8,
311        reg: u8,
312        data: *const u8,
313        length: usize,
314        freq: u32,
315    ) -> bool;
316    pub fn m5u_i2c_read_register(
317        bus: c_int,
318        address: u8,
319        reg: u8,
320        result: *mut u8,
321        length: usize,
322        freq: u32,
323    ) -> bool;
324    pub fn m5u_i2c_write_register8(bus: c_int, address: u8, reg: u8, data: u8, freq: u32) -> bool;
325    pub fn m5u_i2c_read_register8(bus: c_int, address: u8, reg: u8, freq: u32) -> u8;
326    pub fn m5u_i2c_bit_on(bus: c_int, address: u8, reg: u8, data: u8, freq: u32) -> bool;
327    pub fn m5u_i2c_bit_off(bus: c_int, address: u8, reg: u8, data: u8, freq: u32) -> bool;
328    pub fn m5u_i2c_scan(bus: c_int, result: *mut bool, freq: u32);
329    pub fn m5u_i2c_scan_address(bus: c_int, address: u8, freq: u32) -> bool;
330
331    pub fn m5u_display_width() -> c_int;
332    pub fn m5u_display_height() -> c_int;
333    pub fn m5u_display_fill_screen(color: u16);
334    pub fn m5u_display_set_cursor(x: c_int, y: c_int);
335    pub fn m5u_display_set_text_size(size: c_int);
336    pub fn m5u_display_set_text_color(fg: u16, bg: u16);
337    pub fn m5u_display_print(text: *const c_char);
338    pub fn m5u_display_println(text: *const c_char);
339    pub fn m5u_display_draw_line(x0: c_int, y0: c_int, x1: c_int, y1: c_int, color: u16);
340    pub fn m5u_display_draw_rect(x: c_int, y: c_int, w: c_int, h: c_int, color: u16);
341    pub fn m5u_display_fill_rect(x: c_int, y: c_int, w: c_int, h: c_int, color: u16);
342    pub fn m5u_display_draw_circle(x: c_int, y: c_int, r: c_int, color: u16);
343    pub fn m5u_display_fill_circle(x: c_int, y: c_int, r: c_int, color: u16);
344    pub fn m5u_display_set_rotation(rotation: c_int);
345
346    pub fn m5u_btn_a_is_pressed() -> bool;
347    pub fn m5u_btn_a_was_pressed() -> bool;
348    pub fn m5u_btn_a_was_released() -> bool;
349    pub fn m5u_btn_b_is_pressed() -> bool;
350    pub fn m5u_btn_b_was_pressed() -> bool;
351    pub fn m5u_btn_b_was_released() -> bool;
352    pub fn m5u_btn_c_is_pressed() -> bool;
353    pub fn m5u_btn_c_was_pressed() -> bool;
354    pub fn m5u_btn_c_was_released() -> bool;
355
356    pub fn m5u_mic_begin() -> bool;
357    pub fn m5u_mic_record_i16(buffer: *mut i16, samples: usize) -> bool;
358    pub fn m5u_mic_record_u8(buffer: *mut u8, samples: usize) -> bool;
359    pub fn m5u_speaker_begin() -> bool;
360    pub fn m5u_speaker_set_volume(volume: u8);
361    pub fn m5u_speaker_tone(frequency_hz: u32, duration_ms: u32) -> bool;
362    pub fn m5u_speaker_play_i16(samples: *const i16, len: usize, sample_rate_hz: u32) -> bool;
363
364    pub fn m5u_imu_begin() -> bool;
365    pub fn m5u_imu_begin_for_board(board: c_int) -> bool;
366    pub fn m5u_imu_get_accel(x: *mut f32, y: *mut f32, z: *mut f32) -> bool;
367    pub fn m5u_imu_get_gyro(x: *mut f32, y: *mut f32, z: *mut f32) -> bool;
368    pub fn m5u_imu_get_mag(x: *mut f32, y: *mut f32, z: *mut f32) -> bool;
369    pub fn m5u_imu_get_data(out: *mut m5u_imu_data_t) -> bool;
370    pub fn m5u_imu_get_temp_c(temp: *mut f32) -> bool;
371
372    pub fn m5u_touch_count() -> c_int;
373    pub fn m5u_touch_get(index: c_int, x: *mut c_int, y: *mut c_int) -> bool;
374    pub fn m5u_touch_get_raw(index: c_int, x: *mut c_int, y: *mut c_int) -> bool;
375
376    pub fn m5u_rtc_is_enabled() -> bool;
377    pub fn m5u_rtc_get_volt_low() -> bool;
378    pub fn m5u_rtc_get_datetime(
379        year: *mut c_int,
380        month: *mut c_int,
381        day: *mut c_int,
382        hour: *mut c_int,
383        minute: *mut c_int,
384        second: *mut c_int,
385    ) -> bool;
386    pub fn m5u_rtc_get_datetime_detail(out: *mut m5u_rtc_datetime_t) -> bool;
387    pub fn m5u_rtc_get_date_detail(out: *mut m5u_rtc_datetime_t) -> bool;
388    pub fn m5u_rtc_get_time_detail(out: *mut m5u_rtc_datetime_t) -> bool;
389    pub fn m5u_rtc_set_datetime(
390        year: c_int,
391        month: c_int,
392        day: c_int,
393        hour: c_int,
394        minute: c_int,
395        second: c_int,
396    ) -> bool;
397    pub fn m5u_rtc_set_datetime_detail(datetime: *const m5u_rtc_datetime_t) -> bool;
398    pub fn m5u_rtc_set_date_detail(date: *const m5u_rtc_datetime_t) -> bool;
399    pub fn m5u_rtc_set_time_detail(time: *const m5u_rtc_datetime_t) -> bool;
400
401    pub fn m5u_battery_level() -> c_int;
402    pub fn m5u_battery_voltage_mv() -> c_int;
403    pub fn m5u_power_begin() -> bool;
404    pub fn m5u_power_get_type() -> c_int;
405    pub fn m5u_power_get_charge_state() -> c_int;
406    pub fn m5u_power_is_charging() -> bool;
407    pub fn m5u_power_set_led(brightness: u8);
408    pub fn m5u_power_set_ext_output(enable: bool, port_mask: u16);
409    pub fn m5u_power_get_ext_output() -> bool;
410    pub fn m5u_power_set_usb_output(enable: bool);
411    pub fn m5u_power_get_usb_output() -> bool;
412    pub fn m5u_power_set_battery_charge(enable: bool);
413    pub fn m5u_power_set_charge_current(max_ma: u16);
414    pub fn m5u_power_set_charge_voltage(max_mv: u16);
415    pub fn m5u_power_get_vbus_voltage_mv() -> c_int;
416    pub fn m5u_power_get_battery_current_ma() -> c_int;
417    pub fn m5u_power_get_ext_voltage_mv(port_mask: u16) -> c_float;
418    pub fn m5u_power_get_ext_current_ma(port_mask: u16) -> c_float;
419    pub fn m5u_power_get_key_state() -> u8;
420    pub fn m5u_power_set_ext_port_bus_config(config: *const m5u_power_ext_port_bus_t);
421    pub fn m5u_power_set_vibration(level: u8);
422    pub fn m5u_power_power_off();
423    pub fn m5u_power_timer_sleep_seconds(seconds: c_int);
424    pub fn m5u_power_timer_sleep_time(time: *const m5u_rtc_datetime_t);
425    pub fn m5u_power_timer_sleep_date_time(
426        date: *const m5u_rtc_datetime_t,
427        time: *const m5u_rtc_datetime_t,
428    );
429    pub fn m5u_power_deep_sleep_us(micro_seconds: u64, touch_wakeup: bool);
430    pub fn m5u_power_light_sleep_us(micro_seconds: u64, touch_wakeup: bool);
431
432    pub fn m5u_display_get_rotation() -> c_int;
433    pub fn m5u_display_set_brightness(brightness: u8);
434    pub fn m5u_display_set_epd_fastest();
435    pub fn m5u_display_set_epd_mode(mode: c_int);
436    pub fn m5u_display_set_text_scroll(scroll: bool);
437    pub fn m5u_display_set_font(font: c_int) -> bool;
438    pub fn m5u_display_start_write();
439    pub fn m5u_display_end_write();
440    pub fn m5u_display_display();
441    pub fn m5u_display_display_busy() -> bool;
442    pub fn m5u_display_wait_display();
443    pub fn m5u_display_get_cursor_y() -> c_int;
444    pub fn m5u_display_font_height() -> c_int;
445    pub fn m5u_display_get_base_color() -> u16;
446    pub fn m5u_display_set_color(color: u16);
447    pub fn m5u_display_set_text_wrap(wrap_x: bool, wrap_y: bool);
448    pub fn m5u_display_set_text_datum(datum: c_int);
449    pub fn m5u_display_draw_string(text: *const c_char, x: c_int, y: c_int) -> c_int;
450    pub fn m5u_display_write_pixel(x: c_int, y: c_int, color: u16);
451    pub fn m5u_display_write_fast_vline(x: c_int, y: c_int, h: c_int, color: u16);
452    pub fn m5u_display_set_clip_rect(x: c_int, y: c_int, w: c_int, h: c_int);
453    pub fn m5u_display_clear_clip_rect();
454    pub fn m5u_display_color888(r: u8, g: u8, b: u8) -> u16;
455    pub fn m5u_display_count() -> c_int;
456    pub fn m5u_display_index_for_kind(kind: c_int) -> c_int;
457    pub fn m5u_display_index_for_kinds(kinds: *const c_int, len: usize) -> c_int;
458    pub fn m5u_display_width_at(index: c_int) -> c_int;
459    pub fn m5u_display_height_at(index: c_int) -> c_int;
460    pub fn m5u_display_fill_screen_at(index: c_int, color: u16);
461    pub fn m5u_display_set_cursor_at(index: c_int, x: c_int, y: c_int);
462    pub fn m5u_display_set_text_size_at(index: c_int, size: c_int);
463    pub fn m5u_display_set_text_color_at(index: c_int, fg: u16, bg: u16);
464    pub fn m5u_display_get_rotation_at(index: c_int) -> c_int;
465    pub fn m5u_display_set_rotation_at(index: c_int, rotation: c_int);
466    pub fn m5u_display_set_color_at(index: c_int, color: u16);
467    pub fn m5u_display_start_write_at(index: c_int);
468    pub fn m5u_display_end_write_at(index: c_int);
469    pub fn m5u_display_print_at(index: c_int, text: *const c_char);
470    pub fn m5u_display_println_at(index: c_int, text: *const c_char);
471    pub fn m5u_display_draw_string_at(
472        index: c_int,
473        text: *const c_char,
474        x: c_int,
475        y: c_int,
476    ) -> c_int;
477    pub fn m5u_display_draw_line_at(
478        index: c_int,
479        x0: c_int,
480        y0: c_int,
481        x1: c_int,
482        y1: c_int,
483        color: u16,
484    );
485    pub fn m5u_display_draw_rect_at(
486        index: c_int,
487        x: c_int,
488        y: c_int,
489        w: c_int,
490        h: c_int,
491        color: u16,
492    );
493    pub fn m5u_display_fill_rect_at(
494        index: c_int,
495        x: c_int,
496        y: c_int,
497        w: c_int,
498        h: c_int,
499        color: u16,
500    );
501    pub fn m5u_display_draw_circle_at(index: c_int, x: c_int, y: c_int, r: c_int, color: u16);
502    pub fn m5u_display_fill_circle_at(index: c_int, x: c_int, y: c_int, r: c_int, color: u16);
503    pub fn m5u_display_write_pixel_at(index: c_int, x: c_int, y: c_int, color: u16);
504    pub fn m5u_display_draw_pixel_at(index: c_int, x: c_int, y: c_int, color: u16);
505
506    pub fn m5u_button_is_pressed(button: c_int) -> bool;
507    pub fn m5u_button_was_pressed(button: c_int) -> bool;
508    pub fn m5u_button_was_released(button: c_int) -> bool;
509    pub fn m5u_button_was_clicked(button: c_int) -> bool;
510    pub fn m5u_button_was_hold(button: c_int) -> bool;
511    pub fn m5u_button_is_holding(button: c_int) -> bool;
512    pub fn m5u_button_was_decide_click_count(button: c_int) -> bool;
513    pub fn m5u_button_get_click_count(button: c_int) -> c_int;
514    pub fn m5u_button_was_single_clicked(button: c_int) -> bool;
515    pub fn m5u_button_was_double_clicked(button: c_int) -> bool;
516    pub fn m5u_button_was_change_pressed(button: c_int) -> bool;
517    pub fn m5u_button_is_released(button: c_int) -> bool;
518    pub fn m5u_button_was_released_after_hold(button: c_int) -> bool;
519    pub fn m5u_button_was_release_for(button: c_int, ms: u32) -> bool;
520    pub fn m5u_button_pressed_for(button: c_int, ms: u32) -> bool;
521    pub fn m5u_button_released_for(button: c_int, ms: u32) -> bool;
522    pub fn m5u_button_set_debounce_thresh(button: c_int, ms: u32);
523    pub fn m5u_button_set_hold_thresh(button: c_int, ms: u32);
524    pub fn m5u_button_set_raw_state(button: c_int, msec: u32, press: bool);
525    pub fn m5u_button_set_state(button: c_int, msec: u32, state: u8);
526    pub fn m5u_button_get_state(button: c_int) -> u8;
527    pub fn m5u_button_last_change(button: c_int) -> u32;
528    pub fn m5u_button_get_debounce_thresh(button: c_int) -> u32;
529    pub fn m5u_button_get_hold_thresh(button: c_int) -> u32;
530    pub fn m5u_button_get_update_msec(button: c_int) -> u32;
531
532    pub fn m5u_mic_is_enabled() -> bool;
533    pub fn m5u_mic_is_running() -> bool;
534    pub fn m5u_mic_is_recording() -> bool;
535    pub fn m5u_mic_recording_state() -> usize;
536    pub fn m5u_mic_end();
537    pub fn m5u_mic_record_i16_at(buffer: *mut i16, samples: usize, sample_rate_hz: u32) -> bool;
538    pub fn m5u_mic_record_i16_ex(
539        buffer: *mut i16,
540        samples: usize,
541        sample_rate_hz: u32,
542        stereo: bool,
543    ) -> bool;
544    pub fn m5u_mic_record_u8_ex(
545        buffer: *mut u8,
546        samples: usize,
547        sample_rate_hz: u32,
548        stereo: bool,
549    ) -> bool;
550    pub fn m5u_mic_set_sample_rate(sample_rate_hz: u32);
551    pub fn m5u_mic_get_config(out: *mut m5u_mic_config_t) -> bool;
552    pub fn m5u_mic_set_config(config: *const m5u_mic_config_t) -> bool;
553    pub fn m5u_mic_get_noise_filter_level() -> c_int;
554    pub fn m5u_mic_set_noise_filter_level(level: c_int) -> bool;
555
556    pub fn m5u_speaker_is_enabled() -> bool;
557    pub fn m5u_speaker_is_running() -> bool;
558    pub fn m5u_speaker_end();
559    pub fn m5u_speaker_get_volume() -> u8;
560    pub fn m5u_speaker_get_config(out: *mut m5u_speaker_config_t) -> bool;
561    pub fn m5u_speaker_set_config(config: *const m5u_speaker_config_t) -> bool;
562    pub fn m5u_speaker_tone_ex(frequency_hz: c_float, duration_ms: u32, channel: c_int) -> bool;
563    pub fn m5u_speaker_tone_options(
564        frequency_hz: c_float,
565        duration_ms: u32,
566        channel: c_int,
567        stop_current_sound: bool,
568    ) -> bool;
569    pub fn m5u_speaker_tone_full(
570        frequency_hz: c_float,
571        duration_ms: u32,
572        channel: c_int,
573        stop_current_sound: bool,
574        raw_data: *const u8,
575        len: usize,
576        stereo: bool,
577    ) -> bool;
578    pub fn m5u_speaker_play_u8(samples: *const u8, len: usize, sample_rate_hz: u32) -> bool;
579    pub fn m5u_speaker_play_u8_ex(
580        samples: *const u8,
581        len: usize,
582        sample_rate_hz: u32,
583        stereo: bool,
584        repeat: u32,
585        channel: c_int,
586        stop_current_sound: bool,
587    ) -> bool;
588    pub fn m5u_speaker_play_i8_ex(
589        samples: *const i8,
590        len: usize,
591        sample_rate_hz: u32,
592        stereo: bool,
593        repeat: u32,
594        channel: c_int,
595        stop_current_sound: bool,
596    ) -> bool;
597    pub fn m5u_speaker_play_i16_ex(
598        samples: *const i16,
599        len: usize,
600        sample_rate_hz: u32,
601        stereo: bool,
602        repeat: u32,
603        channel: c_int,
604        stop_current_sound: bool,
605    ) -> bool;
606    pub fn m5u_speaker_play_wav(data: *const u8, len: usize) -> bool;
607    pub fn m5u_speaker_play_wav_ex(
608        data: *const u8,
609        len: usize,
610        repeat: u32,
611        channel: c_int,
612        stop_current_sound: bool,
613    ) -> bool;
614    pub fn m5u_speaker_is_playing(channel: c_int) -> bool;
615    pub fn m5u_speaker_playing_channels() -> usize;
616    pub fn m5u_speaker_channel_playing_state(channel: c_int) -> usize;
617    pub fn m5u_speaker_stop(channel: c_int);
618    pub fn m5u_speaker_get_channel_volume(channel: c_int) -> u8;
619    pub fn m5u_speaker_set_channel_volume(channel: c_int, volume: u8);
620    pub fn m5u_speaker_set_all_channel_volume(volume: u8);
621
622    pub fn m5u_imu_is_enabled() -> bool;
623    pub fn m5u_imu_get_type() -> c_int;
624    pub fn m5u_imu_update() -> bool;
625    pub fn m5u_imu_update_mask() -> c_int;
626    pub fn m5u_imu_sleep() -> bool;
627    pub fn m5u_imu_set_clock(freq: u32);
628    pub fn m5u_imu_set_axis_order(axis0: c_int, axis1: c_int, axis2: c_int) -> bool;
629    pub fn m5u_imu_set_axis_order_right_handed(axis0: c_int, axis1: c_int) -> bool;
630    pub fn m5u_imu_set_axis_order_left_handed(axis0: c_int, axis1: c_int) -> bool;
631    pub fn m5u_imu_set_int_pin_active_logic(level: bool) -> bool;
632    pub fn m5u_imu_load_offset_from_nvs() -> bool;
633    pub fn m5u_imu_save_offset_to_nvs() -> bool;
634    pub fn m5u_imu_get_offset_data(index: c_int) -> c_float;
635    pub fn m5u_imu_set_calibration(x: c_float, y: c_float, z: c_float);
636    pub fn m5u_imu_set_calibration_strength(accel: u8, gyro: u8, mag: u8);
637    pub fn m5u_imu_clear_offset_data();
638    pub fn m5u_imu_set_offset_data(index: usize, value: i32);
639    pub fn m5u_imu_get_offset_data_i32(index: usize) -> i32;
640    pub fn m5u_imu_get_raw_data(index: usize) -> i16;
641
642    pub fn m5u_touch_get_detail(index: c_int, out: *mut m5u_touch_detail_t) -> bool;
643    pub fn m5u_touch_is_enabled() -> bool;
644    pub fn m5u_touch_set_hold_thresh(ms: u16);
645    pub fn m5u_touch_set_flick_thresh(distance: u16);
646    pub fn m5u_rtc_set_system_time_from_rtc();
647    pub fn m5u_rtc_set_timer_irq(timer_msec: u32) -> u32;
648    pub fn m5u_rtc_set_alarm_irq_after_seconds(after_seconds: c_int) -> c_int;
649    pub fn m5u_rtc_set_alarm_irq_datetime(datetime: *const m5u_rtc_datetime_t) -> c_int;
650    pub fn m5u_rtc_set_alarm_irq_time(time: *const m5u_rtc_datetime_t) -> c_int;
651    pub fn m5u_rtc_get_irq_status() -> bool;
652    pub fn m5u_rtc_clear_irq();
653    pub fn m5u_rtc_disable_irq();
654
655    pub fn m5u_power_axp2101_disable_irq(mask: u64) -> bool;
656    pub fn m5u_power_axp2101_enable_irq(mask: u64) -> bool;
657    pub fn m5u_power_axp2101_clear_irq_statuses() -> bool;
658    pub fn m5u_power_axp2101_get_irq_statuses() -> u64;
659    pub fn m5u_power_axp2101_is_bat_charger_under_temperature_irq() -> bool;
660    pub fn m5u_power_axp2101_is_bat_charger_over_temperature_irq() -> bool;
661    pub fn m5u_power_axp2101_is_vbus_insert_irq() -> bool;
662    pub fn m5u_power_axp2101_is_vbus_remove_irq() -> bool;
663
664    pub fn m5u_led_begin() -> bool;
665    pub fn m5u_led_display();
666    pub fn m5u_led_set_auto_display(enable: bool);
667    pub fn m5u_led_count() -> usize;
668    pub fn m5u_led_set_brightness(brightness: u8);
669    pub fn m5u_led_set_color_rgb(index: usize, r: u8, g: u8, b: u8);
670    pub fn m5u_led_set_all_color_rgb(r: u8, g: u8, b: u8);
671    pub fn m5u_led_set_colors_rgb(colors: *const m5u_led_color_t, index: usize, length: usize);
672    pub fn m5u_led_get_type(index: usize) -> c_int;
673    pub fn m5u_led_is_enabled() -> bool;
674
675    pub fn m5u_log_print(text: *const c_char);
676    pub fn m5u_log_println(text: *const c_char);
677    pub fn m5u_log_println_empty();
678    pub fn m5u_log_level(level: c_int, text: *const c_char);
679    pub fn m5u_log_dump(addr: *const c_void, len: u32, level: c_int);
680    pub fn m5u_log_path_to_file_name(path: *const c_char) -> *const c_char;
681    pub fn m5u_log_set_callback(callback: m5u_log_callback_t, user_data: *mut c_void) -> bool;
682    pub fn m5u_log_set_enable_color(target: c_int, enable: bool) -> bool;
683    pub fn m5u_log_get_enable_color(target: c_int) -> bool;
684    pub fn m5u_log_set_level(target: c_int, level: c_int) -> bool;
685    pub fn m5u_log_get_level(target: c_int) -> c_int;
686    pub fn m5u_log_set_suffix(target: c_int, suffix: *const c_char) -> bool;
687    pub fn m5u_sd_begin() -> bool;
688    pub fn m5u_sd_begin_spi(config: *const m5u_sd_spi_config_t) -> bool;
689    pub fn m5u_sd_is_mounted() -> bool;
690    pub fn m5u_sd_end();
691}
692
693#[cfg(not(target_os = "espidf"))]
694mod host_stubs {
695    use super::*;
696    use core::ptr;
697
698    pub unsafe fn m5u_begin() -> bool {
699        true
700    }
701    pub unsafe fn m5u_begin_with_config(_config: *const m5u_config_t) -> bool {
702        true
703    }
704    pub unsafe fn m5u_update() {}
705    pub unsafe fn m5u_delay_ms(_ms: u32) {}
706    pub unsafe fn m5u_millis() -> u32 {
707        0
708    }
709    pub unsafe fn m5u_micros() -> u32 {
710        0
711    }
712    pub unsafe fn m5u_get_update_msec() -> u32 {
713        0
714    }
715    pub unsafe fn m5u_get_board() -> c_int {
716        0
717    }
718    pub unsafe fn m5u_get_pin(_name: c_int) -> c_int {
719        -1
720    }
721    pub unsafe fn m5u_set_primary_display_index(index: usize) -> bool {
722        index == 0
723    }
724    pub unsafe fn m5u_set_primary_display_type(_kind: c_int) -> bool {
725        false
726    }
727    pub unsafe fn m5u_set_primary_display_types(_kinds: *const c_int, _len: usize) -> bool {
728        false
729    }
730    pub unsafe fn m5u_set_log_display_index(_index: usize) {}
731    pub unsafe fn m5u_set_log_display_type(_kind: c_int) {}
732    pub unsafe fn m5u_set_log_display_types(_kinds: *const c_int, _len: usize) {}
733    pub unsafe fn m5u_set_touch_button_height(_pixel: u16) {}
734    pub unsafe fn m5u_set_touch_button_height_by_ratio(_ratio: u8) {}
735    pub unsafe fn m5u_get_touch_button_height() -> u16 {
736        0
737    }
738
739    pub unsafe fn m5u_i2c_set_port(
740        _bus: c_int,
741        _port_num: c_int,
742        _pin_sda: c_int,
743        _pin_scl: c_int,
744    ) {
745    }
746    pub unsafe fn m5u_i2c_begin(_bus: c_int) -> bool {
747        false
748    }
749    pub unsafe fn m5u_i2c_begin_with_port(
750        _bus: c_int,
751        _port_num: c_int,
752        _pin_sda: c_int,
753        _pin_scl: c_int,
754    ) -> bool {
755        false
756    }
757    pub unsafe fn m5u_i2c_release(_bus: c_int) -> bool {
758        false
759    }
760    pub unsafe fn m5u_i2c_is_enabled(_bus: c_int) -> bool {
761        false
762    }
763    pub unsafe fn m5u_i2c_get_port(_bus: c_int) -> c_int {
764        -1
765    }
766    pub unsafe fn m5u_i2c_get_sda(_bus: c_int) -> c_int {
767        -1
768    }
769    pub unsafe fn m5u_i2c_get_scl(_bus: c_int) -> c_int {
770        -1
771    }
772    pub unsafe fn m5u_i2c_start(_bus: c_int, _address: u8, _read: bool, _freq: u32) -> bool {
773        false
774    }
775    pub unsafe fn m5u_i2c_restart(_bus: c_int, _address: u8, _read: bool, _freq: u32) -> bool {
776        false
777    }
778    pub unsafe fn m5u_i2c_stop(_bus: c_int) -> bool {
779        false
780    }
781    pub unsafe fn m5u_i2c_write_byte(_bus: c_int, _data: u8) -> bool {
782        false
783    }
784    pub unsafe fn m5u_i2c_write(_bus: c_int, _data: *const u8, _length: usize) -> bool {
785        false
786    }
787    pub unsafe fn m5u_i2c_read(
788        _bus: c_int,
789        result: *mut u8,
790        length: usize,
791        _last_nack: bool,
792    ) -> bool {
793        if !result.is_null() {
794            for i in 0..length {
795                ptr::write(result.add(i), 0);
796            }
797        }
798        false
799    }
800    pub unsafe fn m5u_i2c_write_register(
801        _bus: c_int,
802        _address: u8,
803        _reg: u8,
804        _data: *const u8,
805        _length: usize,
806        _freq: u32,
807    ) -> bool {
808        false
809    }
810    pub unsafe fn m5u_i2c_read_register(
811        _bus: c_int,
812        _address: u8,
813        _reg: u8,
814        result: *mut u8,
815        length: usize,
816        _freq: u32,
817    ) -> bool {
818        if !result.is_null() {
819            for i in 0..length {
820                ptr::write(result.add(i), 0);
821            }
822        }
823        false
824    }
825    pub unsafe fn m5u_i2c_write_register8(
826        _bus: c_int,
827        _address: u8,
828        _reg: u8,
829        _data: u8,
830        _freq: u32,
831    ) -> bool {
832        false
833    }
834    pub unsafe fn m5u_i2c_read_register8(_bus: c_int, _address: u8, _reg: u8, _freq: u32) -> u8 {
835        0
836    }
837    pub unsafe fn m5u_i2c_bit_on(
838        _bus: c_int,
839        _address: u8,
840        _reg: u8,
841        _data: u8,
842        _freq: u32,
843    ) -> bool {
844        false
845    }
846    pub unsafe fn m5u_i2c_bit_off(
847        _bus: c_int,
848        _address: u8,
849        _reg: u8,
850        _data: u8,
851        _freq: u32,
852    ) -> bool {
853        false
854    }
855    pub unsafe fn m5u_i2c_scan(_bus: c_int, result: *mut bool, _freq: u32) {
856        if !result.is_null() {
857            for i in 0..120 {
858                ptr::write(result.add(i), false);
859            }
860        }
861    }
862    pub unsafe fn m5u_i2c_scan_address(_bus: c_int, _address: u8, _freq: u32) -> bool {
863        false
864    }
865
866    pub unsafe fn m5u_display_width() -> c_int {
867        320
868    }
869    pub unsafe fn m5u_display_height() -> c_int {
870        240
871    }
872    pub unsafe fn m5u_display_fill_screen(_color: u16) {}
873    pub unsafe fn m5u_display_set_cursor(_x: c_int, _y: c_int) {}
874    pub unsafe fn m5u_display_set_text_size(_size: c_int) {}
875    pub unsafe fn m5u_display_set_text_color(_fg: u16, _bg: u16) {}
876    pub unsafe fn m5u_display_print(_text: *const c_char) {}
877    pub unsafe fn m5u_display_println(_text: *const c_char) {}
878    pub unsafe fn m5u_display_draw_line(
879        _x0: c_int,
880        _y0: c_int,
881        _x1: c_int,
882        _y1: c_int,
883        _color: u16,
884    ) {
885    }
886    pub unsafe fn m5u_display_draw_rect(_x: c_int, _y: c_int, _w: c_int, _h: c_int, _color: u16) {}
887    pub unsafe fn m5u_display_fill_rect(_x: c_int, _y: c_int, _w: c_int, _h: c_int, _color: u16) {}
888    pub unsafe fn m5u_display_draw_circle(_x: c_int, _y: c_int, _r: c_int, _color: u16) {}
889    pub unsafe fn m5u_display_fill_circle(_x: c_int, _y: c_int, _r: c_int, _color: u16) {}
890    pub unsafe fn m5u_display_set_rotation(_rotation: c_int) {}
891
892    pub unsafe fn m5u_btn_a_is_pressed() -> bool {
893        false
894    }
895    pub unsafe fn m5u_btn_a_was_pressed() -> bool {
896        false
897    }
898    pub unsafe fn m5u_btn_a_was_released() -> bool {
899        false
900    }
901    pub unsafe fn m5u_btn_b_is_pressed() -> bool {
902        false
903    }
904    pub unsafe fn m5u_btn_b_was_pressed() -> bool {
905        false
906    }
907    pub unsafe fn m5u_btn_b_was_released() -> bool {
908        false
909    }
910    pub unsafe fn m5u_btn_c_is_pressed() -> bool {
911        false
912    }
913    pub unsafe fn m5u_btn_c_was_pressed() -> bool {
914        false
915    }
916    pub unsafe fn m5u_btn_c_was_released() -> bool {
917        false
918    }
919
920    pub unsafe fn m5u_mic_begin() -> bool {
921        true
922    }
923    pub unsafe fn m5u_mic_record_i16(buffer: *mut i16, samples: usize) -> bool {
924        if !buffer.is_null() {
925            for i in 0..samples {
926                ptr::write(buffer.add(i), 0);
927            }
928        }
929        true
930    }
931    pub unsafe fn m5u_mic_record_u8(buffer: *mut u8, samples: usize) -> bool {
932        if !buffer.is_null() {
933            for i in 0..samples {
934                ptr::write(buffer.add(i), 0);
935            }
936        }
937        true
938    }
939    pub unsafe fn m5u_speaker_begin() -> bool {
940        true
941    }
942    pub unsafe fn m5u_speaker_set_volume(_volume: u8) {}
943    pub unsafe fn m5u_speaker_tone(_frequency_hz: u32, _duration_ms: u32) -> bool {
944        true
945    }
946    pub unsafe fn m5u_speaker_play_i16(
947        _samples: *const i16,
948        _len: usize,
949        _sample_rate_hz: u32,
950    ) -> bool {
951        true
952    }
953
954    pub unsafe fn m5u_imu_begin() -> bool {
955        true
956    }
957    pub unsafe fn m5u_imu_begin_for_board(_board: c_int) -> bool {
958        false
959    }
960    pub unsafe fn m5u_imu_get_accel(x: *mut f32, y: *mut f32, z: *mut f32) -> bool {
961        if !x.is_null() {
962            *x = 0.0;
963        }
964        if !y.is_null() {
965            *y = 0.0;
966        }
967        if !z.is_null() {
968            *z = 1.0;
969        }
970        true
971    }
972    pub unsafe fn m5u_imu_get_gyro(x: *mut f32, y: *mut f32, z: *mut f32) -> bool {
973        if !x.is_null() {
974            *x = 0.0;
975        }
976        if !y.is_null() {
977            *y = 0.0;
978        }
979        if !z.is_null() {
980            *z = 0.0;
981        }
982        true
983    }
984    pub unsafe fn m5u_imu_get_mag(x: *mut f32, y: *mut f32, z: *mut f32) -> bool {
985        if !x.is_null() {
986            *x = 0.0;
987        }
988        if !y.is_null() {
989            *y = 0.0;
990        }
991        if !z.is_null() {
992            *z = 0.0;
993        }
994        true
995    }
996    pub unsafe fn m5u_imu_get_data(out: *mut m5u_imu_data_t) -> bool {
997        if !out.is_null() {
998            *out = m5u_imu_data_t {
999                accel_z: 1.0,
1000                ..m5u_imu_data_t::default()
1001            };
1002        }
1003        true
1004    }
1005    pub unsafe fn m5u_imu_get_temp_c(temp: *mut f32) -> bool {
1006        if !temp.is_null() {
1007            *temp = 25.0;
1008        }
1009        true
1010    }
1011
1012    pub unsafe fn m5u_touch_count() -> c_int {
1013        0
1014    }
1015    pub unsafe fn m5u_touch_get(_index: c_int, _x: *mut c_int, _y: *mut c_int) -> bool {
1016        false
1017    }
1018    pub unsafe fn m5u_touch_get_raw(_index: c_int, _x: *mut c_int, _y: *mut c_int) -> bool {
1019        false
1020    }
1021
1022    pub unsafe fn m5u_rtc_is_enabled() -> bool {
1023        true
1024    }
1025    pub unsafe fn m5u_rtc_get_volt_low() -> bool {
1026        false
1027    }
1028    pub unsafe fn m5u_rtc_get_datetime(
1029        year: *mut c_int,
1030        month: *mut c_int,
1031        day: *mut c_int,
1032        hour: *mut c_int,
1033        minute: *mut c_int,
1034        second: *mut c_int,
1035    ) -> bool {
1036        if !year.is_null() {
1037            *year = 2026;
1038        }
1039        if !month.is_null() {
1040            *month = 1;
1041        }
1042        if !day.is_null() {
1043            *day = 1;
1044        }
1045        if !hour.is_null() {
1046            *hour = 0;
1047        }
1048        if !minute.is_null() {
1049            *minute = 0;
1050        }
1051        if !second.is_null() {
1052            *second = 0;
1053        }
1054        true
1055    }
1056    pub unsafe fn m5u_rtc_get_datetime_detail(out: *mut m5u_rtc_datetime_t) -> bool {
1057        if !out.is_null() {
1058            *out = m5u_rtc_datetime_t::default();
1059        }
1060        true
1061    }
1062    pub unsafe fn m5u_rtc_get_date_detail(out: *mut m5u_rtc_datetime_t) -> bool {
1063        m5u_rtc_get_datetime_detail(out)
1064    }
1065    pub unsafe fn m5u_rtc_get_time_detail(out: *mut m5u_rtc_datetime_t) -> bool {
1066        m5u_rtc_get_datetime_detail(out)
1067    }
1068    pub unsafe fn m5u_rtc_set_datetime(
1069        _year: c_int,
1070        _month: c_int,
1071        _day: c_int,
1072        _hour: c_int,
1073        _minute: c_int,
1074        _second: c_int,
1075    ) -> bool {
1076        true
1077    }
1078    pub unsafe fn m5u_rtc_set_datetime_detail(datetime: *const m5u_rtc_datetime_t) -> bool {
1079        !datetime.is_null()
1080    }
1081    pub unsafe fn m5u_rtc_set_date_detail(date: *const m5u_rtc_datetime_t) -> bool {
1082        !date.is_null()
1083    }
1084    pub unsafe fn m5u_rtc_set_time_detail(time: *const m5u_rtc_datetime_t) -> bool {
1085        !time.is_null()
1086    }
1087
1088    pub unsafe fn m5u_battery_level() -> c_int {
1089        100
1090    }
1091    pub unsafe fn m5u_battery_voltage_mv() -> c_int {
1092        4200
1093    }
1094    pub unsafe fn m5u_power_begin() -> bool {
1095        false
1096    }
1097    pub unsafe fn m5u_power_get_type() -> c_int {
1098        0
1099    }
1100    pub unsafe fn m5u_power_get_charge_state() -> c_int {
1101        2
1102    }
1103    pub unsafe fn m5u_power_is_charging() -> bool {
1104        false
1105    }
1106    pub unsafe fn m5u_power_set_led(_brightness: u8) {}
1107    pub unsafe fn m5u_power_set_ext_output(_enable: bool, _port_mask: u16) {}
1108    pub unsafe fn m5u_power_get_ext_output() -> bool {
1109        false
1110    }
1111    pub unsafe fn m5u_power_set_usb_output(_enable: bool) {}
1112    pub unsafe fn m5u_power_get_usb_output() -> bool {
1113        false
1114    }
1115    pub unsafe fn m5u_power_set_battery_charge(_enable: bool) {}
1116    pub unsafe fn m5u_power_set_charge_current(_max_ma: u16) {}
1117    pub unsafe fn m5u_power_set_charge_voltage(_max_mv: u16) {}
1118    pub unsafe fn m5u_power_get_vbus_voltage_mv() -> c_int {
1119        -1
1120    }
1121    pub unsafe fn m5u_power_get_battery_current_ma() -> c_int {
1122        0
1123    }
1124    pub unsafe fn m5u_power_get_ext_voltage_mv(_port_mask: u16) -> c_float {
1125        0.0
1126    }
1127    pub unsafe fn m5u_power_get_ext_current_ma(_port_mask: u16) -> c_float {
1128        0.0
1129    }
1130    pub unsafe fn m5u_power_get_key_state() -> u8 {
1131        0
1132    }
1133    pub unsafe fn m5u_power_set_ext_port_bus_config(_config: *const m5u_power_ext_port_bus_t) {}
1134    pub unsafe fn m5u_power_set_vibration(_level: u8) {}
1135    pub unsafe fn m5u_power_power_off() {}
1136    pub unsafe fn m5u_power_timer_sleep_seconds(_seconds: c_int) {}
1137    pub unsafe fn m5u_power_timer_sleep_time(_time: *const m5u_rtc_datetime_t) {}
1138    pub unsafe fn m5u_power_timer_sleep_date_time(
1139        _date: *const m5u_rtc_datetime_t,
1140        _time: *const m5u_rtc_datetime_t,
1141    ) {
1142    }
1143    pub unsafe fn m5u_power_deep_sleep_us(_micro_seconds: u64, _touch_wakeup: bool) {}
1144    pub unsafe fn m5u_power_light_sleep_us(_micro_seconds: u64, _touch_wakeup: bool) {}
1145
1146    pub unsafe fn m5u_display_get_rotation() -> c_int {
1147        0
1148    }
1149    pub unsafe fn m5u_display_set_brightness(_brightness: u8) {}
1150    pub unsafe fn m5u_display_set_epd_fastest() {}
1151    pub unsafe fn m5u_display_set_epd_mode(_mode: c_int) {}
1152    pub unsafe fn m5u_display_set_text_scroll(_scroll: bool) {}
1153    pub unsafe fn m5u_display_set_font(font: c_int) -> bool {
1154        (0..=3).contains(&font)
1155    }
1156    pub unsafe fn m5u_display_start_write() {}
1157    pub unsafe fn m5u_display_end_write() {}
1158    pub unsafe fn m5u_display_display() {}
1159    pub unsafe fn m5u_display_display_busy() -> bool {
1160        false
1161    }
1162    pub unsafe fn m5u_display_wait_display() {}
1163    pub unsafe fn m5u_display_get_cursor_y() -> c_int {
1164        0
1165    }
1166    pub unsafe fn m5u_display_font_height() -> c_int {
1167        16
1168    }
1169    pub unsafe fn m5u_display_get_base_color() -> u16 {
1170        0
1171    }
1172    pub unsafe fn m5u_display_set_color(_color: u16) {}
1173    pub unsafe fn m5u_display_set_text_wrap(_wrap_x: bool, _wrap_y: bool) {}
1174    pub unsafe fn m5u_display_set_text_datum(_datum: c_int) {}
1175    pub unsafe fn m5u_display_draw_string(_text: *const c_char, _x: c_int, _y: c_int) -> c_int {
1176        0
1177    }
1178    pub unsafe fn m5u_display_write_pixel(_x: c_int, _y: c_int, _color: u16) {}
1179    pub unsafe fn m5u_display_write_fast_vline(_x: c_int, _y: c_int, _h: c_int, _color: u16) {}
1180    pub unsafe fn m5u_display_set_clip_rect(_x: c_int, _y: c_int, _w: c_int, _h: c_int) {}
1181    pub unsafe fn m5u_display_clear_clip_rect() {}
1182    pub unsafe fn m5u_display_color888(r: u8, g: u8, b: u8) -> u16 {
1183        ((u16::from(r & 0xF8)) << 8) | ((u16::from(g & 0xFC)) << 3) | u16::from(b >> 3)
1184    }
1185    pub unsafe fn m5u_display_count() -> c_int {
1186        1
1187    }
1188    pub unsafe fn m5u_display_index_for_kind(_kind: c_int) -> c_int {
1189        -1
1190    }
1191    pub unsafe fn m5u_display_index_for_kinds(_kinds: *const c_int, _len: usize) -> c_int {
1192        -1
1193    }
1194    pub unsafe fn m5u_display_width_at(_index: c_int) -> c_int {
1195        320
1196    }
1197    pub unsafe fn m5u_display_height_at(_index: c_int) -> c_int {
1198        240
1199    }
1200    pub unsafe fn m5u_display_fill_screen_at(_index: c_int, _color: u16) {}
1201    pub unsafe fn m5u_display_set_cursor_at(_index: c_int, _x: c_int, _y: c_int) {}
1202    pub unsafe fn m5u_display_set_text_size_at(_index: c_int, _size: c_int) {}
1203    pub unsafe fn m5u_display_set_text_color_at(_index: c_int, _fg: u16, _bg: u16) {}
1204    pub unsafe fn m5u_display_get_rotation_at(_index: c_int) -> c_int {
1205        0
1206    }
1207    pub unsafe fn m5u_display_set_rotation_at(_index: c_int, _rotation: c_int) {}
1208    pub unsafe fn m5u_display_set_color_at(_index: c_int, _color: u16) {}
1209    pub unsafe fn m5u_display_start_write_at(_index: c_int) {}
1210    pub unsafe fn m5u_display_end_write_at(_index: c_int) {}
1211    pub unsafe fn m5u_display_print_at(_index: c_int, _text: *const c_char) {}
1212    pub unsafe fn m5u_display_println_at(_index: c_int, _text: *const c_char) {}
1213    pub unsafe fn m5u_display_draw_string_at(
1214        _index: c_int,
1215        _text: *const c_char,
1216        _x: c_int,
1217        _y: c_int,
1218    ) -> c_int {
1219        0
1220    }
1221    pub unsafe fn m5u_display_draw_line_at(
1222        _index: c_int,
1223        _x0: c_int,
1224        _y0: c_int,
1225        _x1: c_int,
1226        _y1: c_int,
1227        _color: u16,
1228    ) {
1229    }
1230    pub unsafe fn m5u_display_draw_rect_at(
1231        _index: c_int,
1232        _x: c_int,
1233        _y: c_int,
1234        _w: c_int,
1235        _h: c_int,
1236        _color: u16,
1237    ) {
1238    }
1239    pub unsafe fn m5u_display_fill_rect_at(
1240        _index: c_int,
1241        _x: c_int,
1242        _y: c_int,
1243        _w: c_int,
1244        _h: c_int,
1245        _color: u16,
1246    ) {
1247    }
1248    pub unsafe fn m5u_display_draw_circle_at(
1249        _index: c_int,
1250        _x: c_int,
1251        _y: c_int,
1252        _r: c_int,
1253        _color: u16,
1254    ) {
1255    }
1256    pub unsafe fn m5u_display_fill_circle_at(
1257        _index: c_int,
1258        _x: c_int,
1259        _y: c_int,
1260        _r: c_int,
1261        _color: u16,
1262    ) {
1263    }
1264    pub unsafe fn m5u_display_write_pixel_at(_index: c_int, _x: c_int, _y: c_int, _color: u16) {}
1265    pub unsafe fn m5u_display_draw_pixel_at(_index: c_int, _x: c_int, _y: c_int, _color: u16) {}
1266
1267    pub unsafe fn m5u_button_is_pressed(_button: c_int) -> bool {
1268        false
1269    }
1270    pub unsafe fn m5u_button_was_pressed(_button: c_int) -> bool {
1271        false
1272    }
1273    pub unsafe fn m5u_button_was_released(_button: c_int) -> bool {
1274        false
1275    }
1276    pub unsafe fn m5u_button_was_clicked(_button: c_int) -> bool {
1277        false
1278    }
1279    pub unsafe fn m5u_button_was_hold(_button: c_int) -> bool {
1280        false
1281    }
1282    pub unsafe fn m5u_button_is_holding(_button: c_int) -> bool {
1283        false
1284    }
1285    pub unsafe fn m5u_button_was_decide_click_count(_button: c_int) -> bool {
1286        false
1287    }
1288    pub unsafe fn m5u_button_get_click_count(_button: c_int) -> c_int {
1289        0
1290    }
1291    pub unsafe fn m5u_button_was_single_clicked(_button: c_int) -> bool {
1292        false
1293    }
1294    pub unsafe fn m5u_button_was_double_clicked(_button: c_int) -> bool {
1295        false
1296    }
1297    pub unsafe fn m5u_button_was_change_pressed(_button: c_int) -> bool {
1298        false
1299    }
1300    pub unsafe fn m5u_button_is_released(_button: c_int) -> bool {
1301        true
1302    }
1303    pub unsafe fn m5u_button_was_released_after_hold(_button: c_int) -> bool {
1304        false
1305    }
1306    pub unsafe fn m5u_button_was_release_for(_button: c_int, _ms: u32) -> bool {
1307        false
1308    }
1309    pub unsafe fn m5u_button_pressed_for(_button: c_int, _ms: u32) -> bool {
1310        false
1311    }
1312    pub unsafe fn m5u_button_released_for(_button: c_int, _ms: u32) -> bool {
1313        true
1314    }
1315    pub unsafe fn m5u_button_set_debounce_thresh(_button: c_int, _ms: u32) {}
1316    pub unsafe fn m5u_button_set_hold_thresh(_button: c_int, _ms: u32) {}
1317    pub unsafe fn m5u_button_set_raw_state(_button: c_int, _msec: u32, _press: bool) {}
1318    pub unsafe fn m5u_button_set_state(_button: c_int, _msec: u32, _state: u8) {}
1319    pub unsafe fn m5u_button_get_state(_button: c_int) -> u8 {
1320        0
1321    }
1322    pub unsafe fn m5u_button_last_change(_button: c_int) -> u32 {
1323        0
1324    }
1325    pub unsafe fn m5u_button_get_debounce_thresh(_button: c_int) -> u32 {
1326        10
1327    }
1328    pub unsafe fn m5u_button_get_hold_thresh(_button: c_int) -> u32 {
1329        500
1330    }
1331    pub unsafe fn m5u_button_get_update_msec(_button: c_int) -> u32 {
1332        0
1333    }
1334
1335    pub unsafe fn m5u_mic_is_enabled() -> bool {
1336        true
1337    }
1338    pub unsafe fn m5u_mic_is_running() -> bool {
1339        false
1340    }
1341    pub unsafe fn m5u_mic_is_recording() -> bool {
1342        false
1343    }
1344    pub unsafe fn m5u_mic_recording_state() -> usize {
1345        0
1346    }
1347    pub unsafe fn m5u_mic_end() {}
1348    pub unsafe fn m5u_mic_record_i16_at(
1349        buffer: *mut i16,
1350        samples: usize,
1351        _sample_rate_hz: u32,
1352    ) -> bool {
1353        m5u_mic_record_i16(buffer, samples)
1354    }
1355    pub unsafe fn m5u_mic_record_i16_ex(
1356        buffer: *mut i16,
1357        samples: usize,
1358        _sample_rate_hz: u32,
1359        _stereo: bool,
1360    ) -> bool {
1361        m5u_mic_record_i16(buffer, samples)
1362    }
1363    pub unsafe fn m5u_mic_record_u8_ex(
1364        buffer: *mut u8,
1365        samples: usize,
1366        _sample_rate_hz: u32,
1367        _stereo: bool,
1368    ) -> bool {
1369        m5u_mic_record_u8(buffer, samples)
1370    }
1371    pub unsafe fn m5u_mic_set_sample_rate(_sample_rate_hz: u32) {}
1372    pub unsafe fn m5u_mic_get_noise_filter_level() -> c_int {
1373        0
1374    }
1375    pub unsafe fn m5u_mic_set_noise_filter_level(_level: c_int) -> bool {
1376        true
1377    }
1378    pub unsafe fn m5u_mic_get_config(out: *mut m5u_mic_config_t) -> bool {
1379        if !out.is_null() {
1380            *out = m5u_mic_config_t::default();
1381        }
1382        true
1383    }
1384    pub unsafe fn m5u_mic_set_config(config: *const m5u_mic_config_t) -> bool {
1385        !config.is_null()
1386    }
1387
1388    pub unsafe fn m5u_speaker_is_enabled() -> bool {
1389        true
1390    }
1391    pub unsafe fn m5u_speaker_is_running() -> bool {
1392        false
1393    }
1394    pub unsafe fn m5u_speaker_end() {}
1395    pub unsafe fn m5u_speaker_get_volume() -> u8 {
1396        64
1397    }
1398    pub unsafe fn m5u_speaker_get_config(out: *mut m5u_speaker_config_t) -> bool {
1399        if !out.is_null() {
1400            *out = m5u_speaker_config_t::default();
1401        }
1402        true
1403    }
1404    pub unsafe fn m5u_speaker_set_config(config: *const m5u_speaker_config_t) -> bool {
1405        !config.is_null()
1406    }
1407    pub unsafe fn m5u_speaker_tone_ex(
1408        _frequency_hz: c_float,
1409        _duration_ms: u32,
1410        _channel: c_int,
1411    ) -> bool {
1412        true
1413    }
1414    pub unsafe fn m5u_speaker_tone_options(
1415        _frequency_hz: c_float,
1416        _duration_ms: u32,
1417        _channel: c_int,
1418        _stop_current_sound: bool,
1419    ) -> bool {
1420        true
1421    }
1422    pub unsafe fn m5u_speaker_tone_full(
1423        _frequency_hz: c_float,
1424        _duration_ms: u32,
1425        _channel: c_int,
1426        _stop_current_sound: bool,
1427        _raw_data: *const u8,
1428        _len: usize,
1429        _stereo: bool,
1430    ) -> bool {
1431        true
1432    }
1433    pub unsafe fn m5u_speaker_play_u8(
1434        _samples: *const u8,
1435        _len: usize,
1436        _sample_rate_hz: u32,
1437    ) -> bool {
1438        true
1439    }
1440    pub unsafe fn m5u_speaker_play_u8_ex(
1441        _samples: *const u8,
1442        _len: usize,
1443        _sample_rate_hz: u32,
1444        _stereo: bool,
1445        _repeat: u32,
1446        _channel: c_int,
1447        _stop_current_sound: bool,
1448    ) -> bool {
1449        true
1450    }
1451    pub unsafe fn m5u_speaker_play_i8_ex(
1452        _samples: *const i8,
1453        _len: usize,
1454        _sample_rate_hz: u32,
1455        _stereo: bool,
1456        _repeat: u32,
1457        _channel: c_int,
1458        _stop_current_sound: bool,
1459    ) -> bool {
1460        true
1461    }
1462    pub unsafe fn m5u_speaker_play_i16_ex(
1463        _samples: *const i16,
1464        _len: usize,
1465        _sample_rate_hz: u32,
1466        _stereo: bool,
1467        _repeat: u32,
1468        _channel: c_int,
1469        _stop_current_sound: bool,
1470    ) -> bool {
1471        true
1472    }
1473    pub unsafe fn m5u_speaker_play_wav(_data: *const u8, _len: usize) -> bool {
1474        true
1475    }
1476    pub unsafe fn m5u_speaker_play_wav_ex(
1477        _data: *const u8,
1478        _len: usize,
1479        _repeat: u32,
1480        _channel: c_int,
1481        _stop_current_sound: bool,
1482    ) -> bool {
1483        true
1484    }
1485    pub unsafe fn m5u_speaker_is_playing(_channel: c_int) -> bool {
1486        false
1487    }
1488    pub unsafe fn m5u_speaker_playing_channels() -> usize {
1489        0
1490    }
1491    pub unsafe fn m5u_speaker_channel_playing_state(_channel: c_int) -> usize {
1492        0
1493    }
1494    pub unsafe fn m5u_speaker_stop(_channel: c_int) {}
1495    pub unsafe fn m5u_speaker_get_channel_volume(_channel: c_int) -> u8 {
1496        255
1497    }
1498    pub unsafe fn m5u_speaker_set_channel_volume(_channel: c_int, _volume: u8) {}
1499    pub unsafe fn m5u_speaker_set_all_channel_volume(_volume: u8) {}
1500
1501    pub unsafe fn m5u_imu_is_enabled() -> bool {
1502        true
1503    }
1504    pub unsafe fn m5u_imu_get_type() -> c_int {
1505        0
1506    }
1507    pub unsafe fn m5u_imu_update() -> bool {
1508        true
1509    }
1510    pub unsafe fn m5u_imu_update_mask() -> c_int {
1511        0
1512    }
1513    pub unsafe fn m5u_imu_sleep() -> bool {
1514        true
1515    }
1516    pub unsafe fn m5u_imu_set_clock(_freq: u32) {}
1517    pub unsafe fn m5u_imu_set_axis_order(_axis0: c_int, _axis1: c_int, _axis2: c_int) -> bool {
1518        true
1519    }
1520    pub unsafe fn m5u_imu_set_axis_order_right_handed(_axis0: c_int, _axis1: c_int) -> bool {
1521        true
1522    }
1523    pub unsafe fn m5u_imu_set_axis_order_left_handed(_axis0: c_int, _axis1: c_int) -> bool {
1524        true
1525    }
1526    pub unsafe fn m5u_imu_set_int_pin_active_logic(_level: bool) -> bool {
1527        true
1528    }
1529    pub unsafe fn m5u_imu_load_offset_from_nvs() -> bool {
1530        false
1531    }
1532    pub unsafe fn m5u_imu_save_offset_to_nvs() -> bool {
1533        false
1534    }
1535    pub unsafe fn m5u_imu_get_offset_data(_index: c_int) -> c_float {
1536        0.0
1537    }
1538    pub unsafe fn m5u_imu_set_calibration(_x: c_float, _y: c_float, _z: c_float) {}
1539    pub unsafe fn m5u_imu_set_calibration_strength(_accel: u8, _gyro: u8, _mag: u8) {}
1540    pub unsafe fn m5u_imu_clear_offset_data() {}
1541    pub unsafe fn m5u_imu_set_offset_data(_index: usize, _value: i32) {}
1542    pub unsafe fn m5u_imu_get_offset_data_i32(_index: usize) -> i32 {
1543        0
1544    }
1545    pub unsafe fn m5u_imu_get_raw_data(_index: usize) -> i16 {
1546        0
1547    }
1548
1549    pub unsafe fn m5u_touch_get_detail(_index: c_int, out: *mut m5u_touch_detail_t) -> bool {
1550        if !out.is_null() {
1551            *out = m5u_touch_detail_t::default();
1552        }
1553        false
1554    }
1555    pub unsafe fn m5u_touch_is_enabled() -> bool {
1556        false
1557    }
1558    pub unsafe fn m5u_touch_set_hold_thresh(_ms: u16) {}
1559    pub unsafe fn m5u_touch_set_flick_thresh(_distance: u16) {}
1560    pub unsafe fn m5u_rtc_set_system_time_from_rtc() {}
1561    pub unsafe fn m5u_rtc_set_timer_irq(timer_msec: u32) -> u32 {
1562        timer_msec
1563    }
1564    pub unsafe fn m5u_rtc_set_alarm_irq_after_seconds(after_seconds: c_int) -> c_int {
1565        after_seconds
1566    }
1567    pub unsafe fn m5u_rtc_set_alarm_irq_datetime(datetime: *const m5u_rtc_datetime_t) -> c_int {
1568        if datetime.is_null() {
1569            -1
1570        } else {
1571            0
1572        }
1573    }
1574    pub unsafe fn m5u_rtc_set_alarm_irq_time(time: *const m5u_rtc_datetime_t) -> c_int {
1575        if time.is_null() {
1576            -1
1577        } else {
1578            0
1579        }
1580    }
1581    pub unsafe fn m5u_rtc_get_irq_status() -> bool {
1582        false
1583    }
1584    pub unsafe fn m5u_rtc_clear_irq() {}
1585    pub unsafe fn m5u_rtc_disable_irq() {}
1586
1587    pub unsafe fn m5u_power_axp2101_disable_irq(_mask: u64) -> bool {
1588        false
1589    }
1590    pub unsafe fn m5u_power_axp2101_enable_irq(_mask: u64) -> bool {
1591        false
1592    }
1593    pub unsafe fn m5u_power_axp2101_clear_irq_statuses() -> bool {
1594        false
1595    }
1596    pub unsafe fn m5u_power_axp2101_get_irq_statuses() -> u64 {
1597        0
1598    }
1599    pub unsafe fn m5u_power_axp2101_is_bat_charger_under_temperature_irq() -> bool {
1600        false
1601    }
1602    pub unsafe fn m5u_power_axp2101_is_bat_charger_over_temperature_irq() -> bool {
1603        false
1604    }
1605    pub unsafe fn m5u_power_axp2101_is_vbus_insert_irq() -> bool {
1606        false
1607    }
1608    pub unsafe fn m5u_power_axp2101_is_vbus_remove_irq() -> bool {
1609        false
1610    }
1611
1612    pub unsafe fn m5u_led_begin() -> bool {
1613        false
1614    }
1615    pub unsafe fn m5u_led_display() {}
1616    pub unsafe fn m5u_led_set_auto_display(_enable: bool) {}
1617    pub unsafe fn m5u_led_count() -> usize {
1618        0
1619    }
1620    pub unsafe fn m5u_led_set_brightness(_brightness: u8) {}
1621    pub unsafe fn m5u_led_set_color_rgb(_index: usize, _r: u8, _g: u8, _b: u8) {}
1622    pub unsafe fn m5u_led_set_all_color_rgb(_r: u8, _g: u8, _b: u8) {}
1623    pub unsafe fn m5u_led_set_colors_rgb(
1624        _colors: *const m5u_led_color_t,
1625        _index: usize,
1626        _length: usize,
1627    ) {
1628    }
1629    pub unsafe fn m5u_led_get_type(_index: usize) -> c_int {
1630        0
1631    }
1632    pub unsafe fn m5u_led_is_enabled() -> bool {
1633        false
1634    }
1635
1636    pub unsafe fn m5u_log_print(_text: *const c_char) {}
1637    pub unsafe fn m5u_log_println(_text: *const c_char) {}
1638    pub unsafe fn m5u_log_println_empty() {}
1639    pub unsafe fn m5u_log_level(_level: c_int, _text: *const c_char) {}
1640    pub unsafe fn m5u_log_dump(_addr: *const c_void, _len: u32, _level: c_int) {}
1641    pub unsafe fn m5u_log_path_to_file_name(path: *const c_char) -> *const c_char {
1642        if path.is_null() {
1643            return path;
1644        }
1645        let mut current = path;
1646        let mut file = path;
1647        while *current != 0 {
1648            if *current == b'/' as c_char || *current == b'\\' as c_char {
1649                file = current.add(1);
1650            }
1651            current = current.add(1);
1652        }
1653        file
1654    }
1655    pub unsafe fn m5u_log_set_callback(
1656        _callback: m5u_log_callback_t,
1657        _user_data: *mut c_void,
1658    ) -> bool {
1659        true
1660    }
1661    pub unsafe fn m5u_log_set_enable_color(target: c_int, _enable: bool) -> bool {
1662        (0..=2).contains(&target)
1663    }
1664    pub unsafe fn m5u_log_get_enable_color(target: c_int) -> bool {
1665        (0..=2).contains(&target)
1666    }
1667    pub unsafe fn m5u_log_set_level(target: c_int, level: c_int) -> bool {
1668        (0..=2).contains(&target) && (0..=5).contains(&level)
1669    }
1670    pub unsafe fn m5u_log_get_level(target: c_int) -> c_int {
1671        if (0..=2).contains(&target) {
1672            3
1673        } else {
1674            -1
1675        }
1676    }
1677    pub unsafe fn m5u_log_set_suffix(target: c_int, suffix: *const c_char) -> bool {
1678        (0..=2).contains(&target) && !suffix.is_null()
1679    }
1680    pub unsafe fn m5u_sd_begin() -> bool {
1681        false
1682    }
1683    pub unsafe fn m5u_sd_begin_spi(_config: *const m5u_sd_spi_config_t) -> bool {
1684        false
1685    }
1686    pub unsafe fn m5u_sd_is_mounted() -> bool {
1687        false
1688    }
1689    pub unsafe fn m5u_sd_end() {}
1690}
1691
1692#[cfg(not(target_os = "espidf"))]
1693pub use host_stubs::*;