mp_flipper_modflipperzero.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include "py/mperrno.h"
  4. #include "py/objint.h"
  5. #include "py/objfun.h"
  6. #include "py/obj.h"
  7. #include "py/stream.h"
  8. #include "py/runtime.h"
  9. #include <string.h>
  10. #include "mp_flipper_modflipperzero.h"
  11. static mp_obj_t flipperzero_light_set(mp_obj_t light_obj, mp_obj_t brightness_obj) {
  12. mp_int_t light = mp_obj_get_int(light_obj);
  13. mp_int_t brightness = mp_obj_get_int(brightness_obj);
  14. mp_flipper_light_set(light, brightness);
  15. return mp_const_none;
  16. }
  17. static MP_DEFINE_CONST_FUN_OBJ_2(flipperzero_light_set_obj, flipperzero_light_set);
  18. static mp_obj_t flipperzero_light_blink_start(size_t n_args, const mp_obj_t* args) {
  19. if(n_args != 4) {
  20. return mp_const_none;
  21. }
  22. mp_int_t light = mp_obj_get_int(args[0]);
  23. mp_int_t brightness = mp_obj_get_int(args[1]);
  24. mp_int_t on_time = mp_obj_get_int(args[2]);
  25. mp_int_t period = mp_obj_get_int(args[3]);
  26. mp_flipper_light_blink_start(light, brightness, on_time, period);
  27. return mp_const_none;
  28. }
  29. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_light_blink_start_obj, 4, 4, flipperzero_light_blink_start);
  30. static mp_obj_t flipperzero_light_blink_stop() {
  31. mp_flipper_light_blink_stop();
  32. return mp_const_none;
  33. }
  34. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_light_blink_stop_obj, flipperzero_light_blink_stop);
  35. static mp_obj_t flipperzero_light_blink_set_color(mp_obj_t light_obj) {
  36. mp_int_t light = mp_obj_get_int(light_obj);
  37. mp_flipper_light_blink_set_color(light);
  38. return mp_const_none;
  39. }
  40. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_light_blink_set_color_obj, flipperzero_light_blink_set_color);
  41. static mp_obj_t flipperzero_vibro_set(mp_obj_t state) {
  42. bool state_bool = mp_obj_is_true(state);
  43. mp_flipper_vibro(state_bool);
  44. return state_bool ? mp_const_true : mp_const_false;
  45. }
  46. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_vibro_set_obj, flipperzero_vibro_set);
  47. typedef struct _mp_obj_float_t {
  48. mp_obj_base_t base;
  49. mp_float_t value;
  50. } mp_obj_float_t;
  51. static const struct _mp_obj_float_t flipperzero_speaker_volume_min_obj = {
  52. {&mp_type_float},
  53. (mp_float_t)MP_FLIPPER_SPEAKER_VOLUME_MIN};
  54. static const struct _mp_obj_float_t flipperzero_speaker_volume_max_obj = {
  55. {&mp_type_float},
  56. (mp_float_t)MP_FLIPPER_SPEAKER_VOLUME_MAX};
  57. static mp_obj_t flipperzero_speaker_start(mp_obj_t frequency_obj, mp_obj_t volume_obj) {
  58. mp_float_t frequency = mp_obj_get_float(frequency_obj);
  59. mp_float_t volume = mp_obj_get_float(volume_obj);
  60. return mp_flipper_speaker_start(frequency, volume) ? mp_const_true : mp_const_false;
  61. }
  62. static MP_DEFINE_CONST_FUN_OBJ_2(flipperzero_speaker_start_obj, flipperzero_speaker_start);
  63. static mp_obj_t flipperzero_speaker_set_volume(mp_obj_t volume_obj) {
  64. mp_float_t volume = mp_obj_get_float(volume_obj);
  65. return mp_flipper_speaker_set_volume(volume) ? mp_const_true : mp_const_false;
  66. }
  67. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_speaker_set_volume_obj, flipperzero_speaker_set_volume);
  68. static mp_obj_t flipperzero_speaker_stop() {
  69. mp_flipper_speaker_stop();
  70. return mp_flipper_speaker_stop() ? mp_const_true : mp_const_false;
  71. }
  72. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_speaker_stop_obj, flipperzero_speaker_stop);
  73. static mp_obj_t flipperzero_canvas_width() {
  74. uint8_t width = mp_flipper_canvas_width();
  75. return mp_obj_new_int(width);
  76. }
  77. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_canvas_width_obj, flipperzero_canvas_width);
  78. static mp_obj_t flipperzero_canvas_height() {
  79. uint8_t height = mp_flipper_canvas_height();
  80. return mp_obj_new_int(height);
  81. }
  82. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_canvas_height_obj, flipperzero_canvas_height);
  83. static mp_obj_t flipperzero_canvas_text_width(mp_obj_t text_obj) {
  84. const char* text = mp_obj_str_get_str(text_obj);
  85. uint8_t width = mp_flipper_canvas_text_width(text);
  86. return mp_obj_new_int(width);
  87. }
  88. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_canvas_text_width_obj, flipperzero_canvas_text_width);
  89. static mp_obj_t flipperzero_canvas_text_height() {
  90. uint8_t height = mp_flipper_canvas_text_height();
  91. return mp_obj_new_int(height);
  92. }
  93. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_canvas_text_height_obj, flipperzero_canvas_text_height);
  94. static mp_obj_t flipperzero_canvas_draw_dot(mp_obj_t x_obj, mp_obj_t y_obj) {
  95. mp_int_t x = mp_obj_get_int(x_obj);
  96. mp_int_t y = mp_obj_get_int(y_obj);
  97. mp_flipper_canvas_draw_dot(x, y);
  98. return mp_const_none;
  99. }
  100. static MP_DEFINE_CONST_FUN_OBJ_2(flipperzero_canvas_draw_dot_obj, flipperzero_canvas_draw_dot);
  101. static mp_obj_t flipperzero_canvas_draw_box(size_t n_args, const mp_obj_t* args) {
  102. if(n_args < 4) {
  103. return mp_const_none;
  104. }
  105. mp_int_t x = mp_obj_get_int(args[0]);
  106. mp_int_t y = mp_obj_get_int(args[1]);
  107. mp_int_t width = mp_obj_get_int(args[2]);
  108. mp_int_t height = mp_obj_get_int(args[3]);
  109. mp_int_t radius = n_args == 5 ? mp_obj_get_int(args[4]) : 0;
  110. mp_flipper_canvas_draw_box(x, y, width, height, radius);
  111. return mp_const_none;
  112. }
  113. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_canvas_draw_box_obj, 4, 5, flipperzero_canvas_draw_box);
  114. static mp_obj_t flipperzero_canvas_draw_frame(size_t n_args, const mp_obj_t* args) {
  115. if(n_args < 4) {
  116. return mp_const_none;
  117. }
  118. mp_int_t x = mp_obj_get_int(args[0]);
  119. mp_int_t y = mp_obj_get_int(args[1]);
  120. mp_int_t width = mp_obj_get_int(args[2]);
  121. mp_int_t height = mp_obj_get_int(args[3]);
  122. mp_int_t radius = n_args == 5 ? mp_obj_get_int(args[4]) : 0;
  123. mp_flipper_canvas_draw_frame(x, y, width, height, radius);
  124. return mp_const_none;
  125. }
  126. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_canvas_draw_frame_obj, 4, 5, flipperzero_canvas_draw_frame);
  127. static mp_obj_t flipperzero_canvas_draw_line(size_t n_args, const mp_obj_t* args) {
  128. if(n_args != 4) {
  129. return mp_const_none;
  130. }
  131. mp_int_t x0 = mp_obj_get_int(args[0]);
  132. mp_int_t y0 = mp_obj_get_int(args[1]);
  133. mp_int_t x1 = mp_obj_get_int(args[2]);
  134. mp_int_t y1 = mp_obj_get_int(args[3]);
  135. mp_flipper_canvas_draw_line(x0, y0, x1, y1);
  136. return mp_const_none;
  137. }
  138. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_canvas_draw_line_obj, 4, 4, flipperzero_canvas_draw_line);
  139. static mp_obj_t flipperzero_canvas_draw_circle(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t r_obj) {
  140. mp_int_t x = mp_obj_get_int(x_obj);
  141. mp_int_t y = mp_obj_get_int(y_obj);
  142. mp_int_t r = mp_obj_get_int(r_obj);
  143. mp_flipper_canvas_draw_circle(x, y, r);
  144. return mp_const_none;
  145. }
  146. static MP_DEFINE_CONST_FUN_OBJ_3(flipperzero_canvas_draw_circle_obj, flipperzero_canvas_draw_circle);
  147. static mp_obj_t flipperzero_canvas_draw_disc(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t r_obj) {
  148. mp_int_t x = mp_obj_get_int(x_obj);
  149. mp_int_t y = mp_obj_get_int(y_obj);
  150. mp_int_t r = mp_obj_get_int(r_obj);
  151. mp_flipper_canvas_draw_disc(x, y, r);
  152. return mp_const_none;
  153. }
  154. static MP_DEFINE_CONST_FUN_OBJ_3(flipperzero_canvas_draw_disc_obj, flipperzero_canvas_draw_disc);
  155. static mp_obj_t flipperzero_canvas_set_font(mp_obj_t font_obj) {
  156. mp_int_t font = mp_obj_get_int(font_obj);
  157. mp_flipper_canvas_set_font(font);
  158. return mp_const_none;
  159. }
  160. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_canvas_set_font_obj, flipperzero_canvas_set_font);
  161. static mp_obj_t flipperzero_canvas_set_color(mp_obj_t color_obj) {
  162. mp_int_t color = mp_obj_get_int(color_obj);
  163. mp_flipper_canvas_set_color(color);
  164. return mp_const_none;
  165. }
  166. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_canvas_set_color_obj, flipperzero_canvas_set_color);
  167. static mp_obj_t flipperzero_canvas_set_text(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t str_obj) {
  168. mp_int_t x = mp_obj_get_int(x_obj);
  169. mp_int_t y = mp_obj_get_int(y_obj);
  170. const char* str = mp_obj_str_get_str(str_obj);
  171. mp_flipper_canvas_set_text(x, y, str);
  172. return mp_const_none;
  173. }
  174. static MP_DEFINE_CONST_FUN_OBJ_3(flipperzero_canvas_set_text_obj, flipperzero_canvas_set_text);
  175. static mp_obj_t flipperzero_canvas_set_text_align(mp_obj_t x_obj, mp_obj_t y_obj) {
  176. mp_int_t x = mp_obj_get_int(x_obj);
  177. mp_int_t y = mp_obj_get_int(y_obj);
  178. mp_flipper_canvas_set_text_align(x, y);
  179. return mp_const_none;
  180. }
  181. static MP_DEFINE_CONST_FUN_OBJ_2(flipperzero_canvas_set_text_align_obj, flipperzero_canvas_set_text_align);
  182. static mp_obj_t flipperzero_canvas_update() {
  183. mp_flipper_canvas_update();
  184. return mp_const_none;
  185. }
  186. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_canvas_update_obj, flipperzero_canvas_update);
  187. static mp_obj_t flipperzero_canvas_clear() {
  188. mp_flipper_canvas_clear();
  189. return mp_const_none;
  190. }
  191. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_canvas_clear_obj, flipperzero_canvas_clear);
  192. static void* mp_flipper_on_input_callback = NULL;
  193. static mp_obj_t flipperzero_on_input(mp_obj_t callback_obj) {
  194. mp_flipper_on_input_callback = callback_obj;
  195. return callback_obj;
  196. }
  197. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_on_input_obj, flipperzero_on_input);
  198. static mp_obj_t flipperzero_input_trigger_handler(mp_obj_t flags_obj) {
  199. if(mp_flipper_on_input_callback != NULL) {
  200. mp_int_t flags = mp_obj_get_int(flags_obj);
  201. mp_obj_t button_obj = mp_obj_new_int(flags & MP_FLIPPER_INPUT_BUTTON);
  202. mp_obj_t type_obj = mp_obj_new_int(flags & MP_FLIPPER_INPUT_TYPE);
  203. mp_call_function_2_protected(mp_flipper_on_input_callback, button_obj, type_obj);
  204. }
  205. return mp_const_none;
  206. }
  207. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_input_trigger_handler_obj, flipperzero_input_trigger_handler);
  208. static mp_obj_t flipperzero_dialog_message_set_text(size_t n_args, const mp_obj_t* args) {
  209. if(n_args < 3) {
  210. return mp_const_none;
  211. }
  212. const char* text = mp_obj_str_get_str(args[0]);
  213. mp_int_t x = mp_obj_get_int(args[1]);
  214. mp_int_t y = mp_obj_get_int(args[2]);
  215. mp_int_t h = n_args > 3 ? mp_obj_get_int(args[3]) : MP_FLIPPER_ALIGN_BEGIN;
  216. mp_int_t v = n_args > 4 ? mp_obj_get_int(args[4]) : MP_FLIPPER_ALIGN_BEGIN;
  217. mp_flipper_dialog_message_set_text(text, x, y, h, v);
  218. return mp_const_none;
  219. }
  220. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_dialog_message_set_text_obj, 3, 5, flipperzero_dialog_message_set_text);
  221. static mp_obj_t flipperzero_dialog_message_set_header(size_t n_args, const mp_obj_t* args) {
  222. if(n_args < 3) {
  223. return mp_const_none;
  224. }
  225. const char* text = mp_obj_str_get_str(args[0]);
  226. mp_int_t x = mp_obj_get_int(args[1]);
  227. mp_int_t y = mp_obj_get_int(args[2]);
  228. mp_int_t h = n_args > 3 ? mp_obj_get_int(args[3]) : MP_FLIPPER_ALIGN_BEGIN;
  229. mp_int_t v = n_args > 4 ? mp_obj_get_int(args[4]) : MP_FLIPPER_ALIGN_BEGIN;
  230. mp_flipper_dialog_message_set_header(text, x, y, h, v);
  231. return mp_const_none;
  232. }
  233. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_dialog_message_set_header_obj, 3, 5, flipperzero_dialog_message_set_header);
  234. static mp_obj_t flipperzero_dialog_message_set_button(mp_obj_t text_obj, mp_obj_t button_obj) {
  235. const char* text = mp_obj_str_get_str(text_obj);
  236. mp_int_t button = mp_obj_get_int(button_obj);
  237. mp_flipper_dialog_message_set_button(text, button);
  238. return mp_const_none;
  239. }
  240. static MP_DEFINE_CONST_FUN_OBJ_2(flipperzero_dialog_message_set_button_obj, flipperzero_dialog_message_set_button);
  241. static mp_obj_t flipperzero_dialog_message_show() {
  242. mp_int_t button = mp_flipper_dialog_message_show();
  243. return mp_obj_new_int(button);
  244. }
  245. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_dialog_message_show_obj, flipperzero_dialog_message_show);
  246. static mp_obj_t flipperzero_dialog_message_clear() {
  247. mp_flipper_dialog_message_clear();
  248. return mp_const_none;
  249. }
  250. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_dialog_message_clear_obj, flipperzero_dialog_message_clear);
  251. static void* mp_flipper_on_gpio_callback = NULL;
  252. static mp_obj_t flipperzero_gpio_init_pin(size_t n_args, const mp_obj_t* args) {
  253. if(n_args < 2) {
  254. return mp_const_false;
  255. }
  256. mp_int_t pin = mp_obj_get_int(args[0]);
  257. mp_int_t mode = mp_obj_get_int(args[1]);
  258. mp_int_t pull = n_args > 2 ? mp_obj_get_int(args[2]) : MP_FLIPPER_GPIO_PULL_NO;
  259. mp_int_t speed = n_args > 3 ? mp_obj_get_int(args[3]) : MP_FLIPPER_GPIO_SPEED_LOW;
  260. bool success = mp_flipper_gpio_init_pin(pin, mode, pull, speed);
  261. return success ? mp_const_true : mp_const_false;
  262. }
  263. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_gpio_init_pin_obj, 2, 4, flipperzero_gpio_init_pin);
  264. static mp_obj_t flipperzero_gpio_deinit_pin(mp_obj_t pin_obj) {
  265. mp_int_t pin = mp_obj_get_int(pin_obj);
  266. mp_flipper_gpio_deinit_pin(pin);
  267. return mp_const_none;
  268. }
  269. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_gpio_deinit_pin_obj, flipperzero_gpio_deinit_pin);
  270. static mp_obj_t flipperzero_gpio_set_pin(mp_obj_t pin_obj, mp_obj_t state_obj) {
  271. mp_int_t pin = mp_obj_get_int(pin_obj);
  272. bool state = mp_obj_is_true(state_obj);
  273. mp_flipper_gpio_set_pin(pin, state);
  274. return mp_const_none;
  275. }
  276. static MP_DEFINE_CONST_FUN_OBJ_2(flipperzero_gpio_set_pin_obj, flipperzero_gpio_set_pin);
  277. static mp_obj_t flipperzero_gpio_get_pin(mp_obj_t pin_obj) {
  278. mp_int_t pin = mp_obj_get_int(pin_obj);
  279. bool state = mp_flipper_gpio_get_pin(pin);
  280. return state ? mp_const_true : mp_const_false;
  281. }
  282. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_gpio_get_pin_obj, flipperzero_gpio_get_pin);
  283. static mp_obj_t flipperzero_on_gpio(mp_obj_t callback_obj) {
  284. mp_flipper_on_gpio_callback = callback_obj;
  285. return callback_obj;
  286. }
  287. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_on_gpio_obj, flipperzero_on_gpio);
  288. static mp_obj_t flipperzero_gpio_trigger_handler(mp_obj_t pin_obj) {
  289. if(mp_flipper_on_gpio_callback != NULL) {
  290. mp_call_function_1_protected(mp_flipper_on_gpio_callback, pin_obj);
  291. }
  292. return mp_const_none;
  293. }
  294. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_gpio_trigger_handler_obj, flipperzero_gpio_trigger_handler);
  295. static mp_obj_t flipperzero_adc_read_pin_value(mp_obj_t pin_obj) {
  296. mp_int_t pin = mp_obj_get_int(pin_obj);
  297. mp_int_t value = mp_flipper_adc_read_pin(pin);
  298. return mp_obj_new_int(value);
  299. }
  300. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_adc_read_pin_value_obj, flipperzero_adc_read_pin_value);
  301. static mp_obj_t flipperzero_adc_read_pin_voltage(mp_obj_t pin_obj) {
  302. mp_int_t pin = mp_obj_get_int(pin_obj);
  303. uint16_t value = mp_flipper_adc_read_pin(pin);
  304. float voltage = mp_flipper_adc_convert_to_voltage(value);
  305. return mp_obj_new_float(voltage);
  306. }
  307. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_adc_read_pin_voltage_obj, flipperzero_adc_read_pin_voltage);
  308. static mp_obj_t flipperzero_pwm_start(mp_obj_t pin_obj, mp_obj_t frequency_obj, mp_obj_t duty_obj) {
  309. mp_int_t pin = mp_obj_get_int(pin_obj);
  310. mp_int_t frequency = mp_obj_get_int(frequency_obj);
  311. mp_int_t duty = mp_obj_get_int(duty_obj);
  312. bool success = mp_flipper_pwm_start(pin, frequency, duty);
  313. return success ? mp_const_true : mp_const_false;
  314. }
  315. static MP_DEFINE_CONST_FUN_OBJ_3(flipperzero_pwm_start_obj, flipperzero_pwm_start);
  316. static mp_obj_t flipperzero_pwm_stop(mp_obj_t pin_obj) {
  317. mp_int_t pin = mp_obj_get_int(pin_obj);
  318. mp_flipper_pwm_stop(pin);
  319. return mp_const_none;
  320. }
  321. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_pwm_stop_obj, flipperzero_pwm_stop);
  322. static mp_obj_t flipperzero_pwm_is_running(mp_obj_t pin_obj) {
  323. mp_int_t pin = mp_obj_get_int(pin_obj);
  324. return mp_flipper_pwm_is_running(pin) ? mp_const_true : mp_const_false;
  325. }
  326. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_pwm_is_running_obj, flipperzero_pwm_is_running);
  327. static mp_obj_t flipperzero_infrared_receive(size_t n_args, const mp_obj_t* args) {
  328. mp_int_t timeout = n_args > 0 ? mp_obj_get_int(args[0]) : MP_FLIPPER_INFRARED_RX_DEFAULT_TIMEOUT;
  329. size_t length = 0;
  330. uint32_t* buffer = mp_flipper_infrared_receive(timeout, &length);
  331. mp_obj_t* signal = length > 0 ? malloc(length * sizeof(mp_obj_t)) : NULL;
  332. for(uint16_t i = 0; i < length; i++) {
  333. signal[i] = mp_obj_new_int(buffer[i]);
  334. }
  335. return mp_obj_new_list(length, signal);
  336. }
  337. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_infrared_receive_obj, 0, 1, flipperzero_infrared_receive);
  338. inline static uint32_t flipperzero_infrared_tx_signal_provider(mp_obj_t* signal, const size_t index) {
  339. return mp_obj_get_int(signal[index]);
  340. }
  341. static mp_obj_t flipperzero_infrared_transmit(size_t n_args, const mp_obj_t* args) {
  342. size_t length = 0;
  343. mp_obj_t* signal;
  344. mp_obj_get_array(args[0], &length, &signal);
  345. mp_int_t repeat = n_args > 1 ? mp_obj_get_int(args[1]) : 1;
  346. bool use_external_pin = n_args > 2 ? mp_obj_is_true(args[2]) : false;
  347. mp_int_t frequency = n_args > 3 ? mp_obj_get_int(args[3]) : MP_FLIPPER_INFRARED_TX_DEFAULT_FREQUENCY;
  348. mp_float_t duty_cycle = n_args > 4 ? mp_obj_get_float(args[4]) : MP_FLIPPER_INFRARED_TX_DEFAULT_DUTY_CYCLE;
  349. return mp_flipper_infrared_transmit(
  350. signal, length, flipperzero_infrared_tx_signal_provider, repeat, frequency, duty_cycle, use_external_pin) ?
  351. mp_const_true :
  352. mp_const_false;
  353. }
  354. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_infrared_transmit_obj, 1, 5, flipperzero_infrared_transmit);
  355. static mp_obj_t flipperzero_infrared_is_busy() {
  356. return mp_flipper_infrared_is_busy() ? mp_const_true : mp_const_false;
  357. }
  358. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_infrared_is_busy_obj, flipperzero_infrared_is_busy);
  359. extern const mp_obj_type_t flipperzero_uart_connection_type;
  360. typedef struct _flipperzero_uart_connection_t {
  361. mp_obj_base_t base;
  362. void* handle;
  363. mp_obj_t mode;
  364. mp_obj_t baud_rate;
  365. } flipperzero_uart_connection_t;
  366. static mp_obj_t flipperzero_uart_open(mp_obj_t raw_mode, mp_obj_t raw_baud_rate) {
  367. uint8_t mode = mp_obj_get_int(raw_mode);
  368. uint32_t baud_rate = mp_obj_get_int(raw_baud_rate);
  369. void* handle = mp_flipper_uart_open(mode, baud_rate);
  370. if(handle == NULL) {
  371. mp_flipper_raise_os_error(MP_EBUSY);
  372. return mp_const_none;
  373. }
  374. flipperzero_uart_connection_t* connection =
  375. mp_obj_malloc_with_finaliser(flipperzero_uart_connection_t, &flipperzero_uart_connection_type);
  376. connection->handle = handle;
  377. connection->mode = raw_mode;
  378. connection->baud_rate = raw_baud_rate;
  379. return connection;
  380. }
  381. static MP_DEFINE_CONST_FUN_OBJ_2(flipperzero_uart_open_obj, flipperzero_uart_open);
  382. static mp_uint_t flipperzero_uart_read(mp_obj_t self, void* buf, mp_uint_t size, int* errcode) {
  383. flipperzero_uart_connection_t* connection = MP_OBJ_TO_PTR(self);
  384. if(connection->handle == NULL) {
  385. *errcode = MP_EIO;
  386. return MP_STREAM_ERROR;
  387. }
  388. return mp_flipper_uart_read(connection->handle, buf, size, errcode);
  389. }
  390. static mp_uint_t flipperzero_uart_write(mp_obj_t self, const void* buf, mp_uint_t size, int* errcode) {
  391. flipperzero_uart_connection_t* connection = MP_OBJ_TO_PTR(self);
  392. if(connection->handle == NULL) {
  393. *errcode = MP_EIO;
  394. return MP_STREAM_ERROR;
  395. }
  396. return mp_flipper_uart_write(connection->handle, buf, size, errcode);
  397. }
  398. static mp_uint_t flipperzero_uart_ioctl(mp_obj_t self, mp_uint_t request, uintptr_t arg, int* errcode) {
  399. flipperzero_uart_connection_t* connection = MP_OBJ_TO_PTR(self);
  400. if(connection->handle == NULL) {
  401. return 0;
  402. }
  403. if(request == MP_STREAM_SEEK) {
  404. return 0;
  405. }
  406. if(request == MP_STREAM_FLUSH) {
  407. if(!mp_flipper_uart_sync(connection->handle)) {
  408. *errcode = MP_EIO;
  409. return MP_STREAM_ERROR;
  410. }
  411. return 0;
  412. }
  413. if(request == MP_STREAM_CLOSE) {
  414. if(!mp_flipper_uart_close(connection->handle)) {
  415. *errcode = MP_EIO;
  416. connection->handle = NULL;
  417. return MP_STREAM_ERROR;
  418. }
  419. connection->handle = NULL;
  420. return 0;
  421. }
  422. *errcode = MP_EINVAL;
  423. return MP_STREAM_ERROR;
  424. }
  425. static const mp_map_elem_t flipperzero_uart_connection_locals_dict_table[] = {
  426. {MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj)},
  427. {MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)},
  428. {MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj)},
  429. {MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj)},
  430. {MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj)},
  431. {MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj)},
  432. {MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj)},
  433. {MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj)},
  434. {MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&mp_stream___exit___obj)},
  435. };
  436. static MP_DEFINE_CONST_DICT(flipperzero_uart_connection_locals_dict, flipperzero_uart_connection_locals_dict_table);
  437. static const mp_stream_p_t flipperzero_uart_connection_stream_p = {
  438. .read = flipperzero_uart_read,
  439. .write = flipperzero_uart_write,
  440. .ioctl = flipperzero_uart_ioctl,
  441. .is_text = false,
  442. };
  443. MP_DEFINE_CONST_OBJ_TYPE(
  444. flipperzero_uart_connection_type,
  445. MP_QSTR_UART,
  446. MP_TYPE_FLAG_ITER_IS_STREAM,
  447. protocol,
  448. &flipperzero_uart_connection_stream_p,
  449. locals_dict,
  450. &flipperzero_uart_connection_locals_dict);
  451. static const char* notes = "CCDDEFFGGAAB";
  452. static const float base_frequency = 16.3515979;
  453. static const float const_factor = 1.05946309436;
  454. static inline float get_frequency_by_note(const uint8_t octave, const char note, const bool is_sharp) {
  455. float freq = base_frequency;
  456. for(size_t i = 0; i < octave; i++) {
  457. freq *= const_factor;
  458. }
  459. for(size_t j = 0; j < strlen(notes); j++) {
  460. if(notes[j] == note) {
  461. freq *= (is_sharp ? const_factor : 1.0);
  462. return freq;
  463. }
  464. freq *= const_factor;
  465. }
  466. return -1.0;
  467. }
  468. void flipperzero_module_attr(mp_obj_t self_in, qstr attr, mp_obj_t* dest) {
  469. if(dest[0] == MP_OBJ_NULL) {
  470. // load attribute
  471. const char* attribute = qstr_str(attr);
  472. if(strstr(attribute, "SPEAKER_NOTE_") == &attribute[0]) {
  473. size_t len = strlen(attribute);
  474. uint8_t octave = attribute[len - 1] - '0';
  475. bool is_sharp = attribute[len - 2] == 'S';
  476. size_t note_index = len - (is_sharp ? 3 : 2);
  477. uint8_t i_note = UINT8_MAX;
  478. float frequency = get_frequency_by_note(octave, attribute[note_index], is_sharp);
  479. if(octave > 8 || frequency < 0.0) {
  480. dest[0] = mp_const_none;
  481. } else {
  482. dest[0] = mp_obj_new_float(frequency);
  483. }
  484. return;
  485. }
  486. } else if(dest[1] == MP_OBJ_NULL) {
  487. // delete attribute
  488. } else {
  489. // store attribute
  490. }
  491. }
  492. static const mp_rom_map_elem_t flipperzero_module_globals_table[] = {
  493. // light
  494. {MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_flipperzero)},
  495. {MP_ROM_QSTR(MP_QSTR_LIGHT_RED), MP_ROM_INT(MP_FLIPPER_LED_RED)},
  496. {MP_ROM_QSTR(MP_QSTR_LIGHT_GREEN), MP_ROM_INT(MP_FLIPPER_LED_GREEN)},
  497. {MP_ROM_QSTR(MP_QSTR_LIGHT_BLUE), MP_ROM_INT(MP_FLIPPER_LED_BLUE)},
  498. {MP_ROM_QSTR(MP_QSTR_LIGHT_BACKLIGHT), MP_ROM_INT(MP_FLIPPER_LED_BACKLIGHT)},
  499. {MP_ROM_QSTR(MP_QSTR_light_set), MP_ROM_PTR(&flipperzero_light_set_obj)},
  500. {MP_ROM_QSTR(MP_QSTR_light_blink_start), MP_ROM_PTR(&flipperzero_light_blink_start_obj)},
  501. {MP_ROM_QSTR(MP_QSTR_light_blink_set_color), MP_ROM_PTR(&flipperzero_light_blink_set_color_obj)},
  502. {MP_ROM_QSTR(MP_QSTR_light_blink_stop), MP_ROM_PTR(&flipperzero_light_blink_stop_obj)},
  503. // vibro
  504. {MP_ROM_QSTR(MP_QSTR_vibro_set), MP_ROM_PTR(&flipperzero_vibro_set_obj)},
  505. // speaker
  506. {MP_ROM_QSTR(MP_QSTR_SPEAKER_VOLUME_MIN), MP_ROM_PTR(&flipperzero_speaker_volume_min_obj)},
  507. {MP_ROM_QSTR(MP_QSTR_SPEAKER_VOLUME_MAX), MP_ROM_PTR(&flipperzero_speaker_volume_max_obj)},
  508. {MP_ROM_QSTR(MP_QSTR_speaker_start), MP_ROM_PTR(&flipperzero_speaker_start_obj)},
  509. {MP_ROM_QSTR(MP_QSTR_speaker_set_volume), MP_ROM_PTR(&flipperzero_speaker_set_volume_obj)},
  510. {MP_ROM_QSTR(MP_QSTR_speaker_stop), MP_ROM_PTR(&flipperzero_speaker_stop_obj)},
  511. // canvas
  512. {MP_ROM_QSTR(MP_QSTR_CANVAS_BLACK), MP_ROM_INT(MP_FLIPPER_COLOR_BLACK)},
  513. {MP_ROM_QSTR(MP_QSTR_CANVAS_WHITE), MP_ROM_INT(MP_FLIPPER_COLOR_WHITE)},
  514. {MP_ROM_QSTR(MP_QSTR_canvas_width), MP_ROM_PTR(&flipperzero_canvas_width_obj)},
  515. {MP_ROM_QSTR(MP_QSTR_canvas_height), MP_ROM_PTR(&flipperzero_canvas_height_obj)},
  516. {MP_ROM_QSTR(MP_QSTR_canvas_text_width), MP_ROM_PTR(&flipperzero_canvas_text_width_obj)},
  517. {MP_ROM_QSTR(MP_QSTR_canvas_text_height), MP_ROM_PTR(&flipperzero_canvas_text_height_obj)},
  518. {MP_ROM_QSTR(MP_QSTR_canvas_draw_dot), MP_ROM_PTR(&flipperzero_canvas_draw_dot_obj)},
  519. {MP_ROM_QSTR(MP_QSTR_canvas_draw_box), MP_ROM_PTR(&flipperzero_canvas_draw_box_obj)},
  520. {MP_ROM_QSTR(MP_QSTR_canvas_draw_frame), MP_ROM_PTR(&flipperzero_canvas_draw_frame_obj)},
  521. {MP_ROM_QSTR(MP_QSTR_canvas_draw_line), MP_ROM_PTR(&flipperzero_canvas_draw_line_obj)},
  522. {MP_ROM_QSTR(MP_QSTR_canvas_draw_circle), MP_ROM_PTR(&flipperzero_canvas_draw_circle_obj)},
  523. {MP_ROM_QSTR(MP_QSTR_canvas_draw_disc), MP_ROM_PTR(&flipperzero_canvas_draw_disc_obj)},
  524. {MP_ROM_QSTR(MP_QSTR_FONT_PRIMARY), MP_ROM_INT(MP_FLIPPER_FONT_PRIMARY)},
  525. {MP_ROM_QSTR(MP_QSTR_FONT_SECONDARY), MP_ROM_INT(MP_FLIPPER_FONT_SECONDARY)},
  526. {MP_ROM_QSTR(MP_QSTR_canvas_set_font), MP_ROM_PTR(&flipperzero_canvas_set_font_obj)},
  527. {MP_ROM_QSTR(MP_QSTR_canvas_set_color), MP_ROM_PTR(&flipperzero_canvas_set_color_obj)},
  528. {MP_ROM_QSTR(MP_QSTR_canvas_set_text), MP_ROM_PTR(&flipperzero_canvas_set_text_obj)},
  529. {MP_ROM_QSTR(MP_QSTR_ALIGN_BEGIN), MP_ROM_INT(MP_FLIPPER_ALIGN_BEGIN)},
  530. {MP_ROM_QSTR(MP_QSTR_ALIGN_CENTER), MP_ROM_INT(MP_FLIPPER_ALIGN_CENTER)},
  531. {MP_ROM_QSTR(MP_QSTR_ALIGN_END), MP_ROM_INT(MP_FLIPPER_ALIGN_END)},
  532. {MP_ROM_QSTR(MP_QSTR_canvas_set_text_align), MP_ROM_PTR(&flipperzero_canvas_set_text_align_obj)},
  533. {MP_ROM_QSTR(MP_QSTR_canvas_update), MP_ROM_PTR(&flipperzero_canvas_update_obj)},
  534. {MP_ROM_QSTR(MP_QSTR_canvas_clear), MP_ROM_PTR(&flipperzero_canvas_clear_obj)},
  535. // input
  536. {MP_ROM_QSTR(MP_QSTR_on_input), MP_ROM_PTR(&flipperzero_on_input_obj)},
  537. {MP_ROM_QSTR(MP_QSTR__input_trigger_handler), MP_ROM_PTR(&flipperzero_input_trigger_handler_obj)},
  538. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_BACK), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_BACK)},
  539. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_OK), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_OK)},
  540. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_LEFT), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_LEFT)},
  541. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_RIGHT), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_RIGHT)},
  542. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_UP), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_UP)},
  543. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_DOWN), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_DOWN)},
  544. {MP_ROM_QSTR(MP_QSTR_INPUT_TYPE_PRESS), MP_ROM_INT(MP_FLIPPER_INPUT_TYPE_PRESS)},
  545. {MP_ROM_QSTR(MP_QSTR_INPUT_TYPE_RELEASE), MP_ROM_INT(MP_FLIPPER_INPUT_TYPE_RELEASE)},
  546. {MP_ROM_QSTR(MP_QSTR_INPUT_TYPE_SHORT), MP_ROM_INT(MP_FLIPPER_INPUT_TYPE_SHORT)},
  547. {MP_ROM_QSTR(MP_QSTR_INPUT_TYPE_LONG), MP_ROM_INT(MP_FLIPPER_INPUT_TYPE_LONG)},
  548. {MP_ROM_QSTR(MP_QSTR_INPUT_TYPE_REPEAT), MP_ROM_INT(MP_FLIPPER_INPUT_TYPE_REPEAT)},
  549. // dialog
  550. {MP_ROM_QSTR(MP_QSTR_dialog_message_set_text), MP_ROM_PTR(&flipperzero_dialog_message_set_text_obj)},
  551. {MP_ROM_QSTR(MP_QSTR_dialog_message_set_header), MP_ROM_PTR(&flipperzero_dialog_message_set_header_obj)},
  552. {MP_ROM_QSTR(MP_QSTR_dialog_message_set_button), MP_ROM_PTR(&flipperzero_dialog_message_set_button_obj)},
  553. {MP_ROM_QSTR(MP_QSTR_dialog_message_show), MP_ROM_PTR(&flipperzero_dialog_message_show_obj)},
  554. {MP_ROM_QSTR(MP_QSTR_dialog_message_clear), MP_ROM_PTR(&flipperzero_dialog_message_clear_obj)},
  555. // gpio - pins
  556. {MP_ROM_QSTR(MP_QSTR_GPIO_PIN_PC0), MP_ROM_INT(MP_FLIPPER_GPIO_PIN_PC0)},
  557. {MP_ROM_QSTR(MP_QSTR_GPIO_PIN_PC1), MP_ROM_INT(MP_FLIPPER_GPIO_PIN_PC1)},
  558. {MP_ROM_QSTR(MP_QSTR_GPIO_PIN_PC3), MP_ROM_INT(MP_FLIPPER_GPIO_PIN_PC3)},
  559. {MP_ROM_QSTR(MP_QSTR_GPIO_PIN_PB2), MP_ROM_INT(MP_FLIPPER_GPIO_PIN_PB2)},
  560. {MP_ROM_QSTR(MP_QSTR_GPIO_PIN_PB3), MP_ROM_INT(MP_FLIPPER_GPIO_PIN_PB3)},
  561. {MP_ROM_QSTR(MP_QSTR_GPIO_PIN_PA4), MP_ROM_INT(MP_FLIPPER_GPIO_PIN_PA4)},
  562. {MP_ROM_QSTR(MP_QSTR_GPIO_PIN_PA6), MP_ROM_INT(MP_FLIPPER_GPIO_PIN_PA6)},
  563. {MP_ROM_QSTR(MP_QSTR_GPIO_PIN_PA7), MP_ROM_INT(MP_FLIPPER_GPIO_PIN_PA7)},
  564. // gpio - modes
  565. {MP_ROM_QSTR(MP_QSTR_GPIO_MODE_INPUT), MP_ROM_INT(MP_FLIPPER_GPIO_MODE_INPUT)},
  566. {MP_ROM_QSTR(MP_QSTR_GPIO_MODE_OUTPUT_PUSH_PULL), MP_ROM_INT(MP_FLIPPER_GPIO_MODE_OUTPUT_PUSH_PULL)},
  567. {MP_ROM_QSTR(MP_QSTR_GPIO_MODE_OUTPUT_OPEN_DRAIN), MP_ROM_INT(MP_FLIPPER_GPIO_MODE_OUTPUT_OPEN_DRAIN)},
  568. {MP_ROM_QSTR(MP_QSTR_GPIO_MODE_ANALOG), MP_ROM_INT(MP_FLIPPER_GPIO_MODE_ANALOG)},
  569. {MP_ROM_QSTR(MP_QSTR_GPIO_MODE_INTERRUPT_RISE), MP_ROM_INT(MP_FLIPPER_GPIO_MODE_INTERRUPT_RISE)},
  570. {MP_ROM_QSTR(MP_QSTR_GPIO_MODE_INTERRUPT_FALL), MP_ROM_INT(MP_FLIPPER_GPIO_MODE_INTERRUPT_FALL)},
  571. // gpio - pull
  572. {MP_ROM_QSTR(MP_QSTR_GPIO_PULL_NO), MP_ROM_INT(MP_FLIPPER_GPIO_PULL_NO)},
  573. {MP_ROM_QSTR(MP_QSTR_GPIO_PULL_UP), MP_ROM_INT(MP_FLIPPER_GPIO_PULL_UP)},
  574. {MP_ROM_QSTR(MP_QSTR_GPIO_PULL_DOWN), MP_ROM_INT(MP_FLIPPER_GPIO_PULL_DOWN)},
  575. // gpio - speed
  576. {MP_ROM_QSTR(MP_QSTR_GPIO_SPEED_LOW), MP_ROM_INT(MP_FLIPPER_GPIO_SPEED_LOW)},
  577. {MP_ROM_QSTR(MP_QSTR_GPIO_SPEED_MEDIUM), MP_ROM_INT(MP_FLIPPER_GPIO_SPEED_MEDIUM)},
  578. {MP_ROM_QSTR(MP_QSTR_GPIO_SPEED_HIGH), MP_ROM_INT(MP_FLIPPER_GPIO_SPEED_HIGH)},
  579. {MP_ROM_QSTR(MP_QSTR_GPIO_SPEED_VERY_HIGH), MP_ROM_INT(MP_FLIPPER_GPIO_SPEED_VERY_HIGH)},
  580. // gpio - functions
  581. {MP_ROM_QSTR(MP_QSTR_gpio_init_pin), MP_ROM_PTR(&flipperzero_gpio_init_pin_obj)},
  582. {MP_ROM_QSTR(MP_QSTR_gpio_deinit_pin), MP_ROM_PTR(&flipperzero_gpio_deinit_pin_obj)},
  583. {MP_ROM_QSTR(MP_QSTR_gpio_set_pin), MP_ROM_PTR(&flipperzero_gpio_set_pin_obj)},
  584. {MP_ROM_QSTR(MP_QSTR_gpio_get_pin), MP_ROM_PTR(&flipperzero_gpio_get_pin_obj)},
  585. {MP_ROM_QSTR(MP_QSTR_on_gpio), MP_ROM_PTR(&flipperzero_on_gpio_obj)},
  586. {MP_ROM_QSTR(MP_QSTR__gpio_trigger_handler), MP_ROM_PTR(&flipperzero_gpio_trigger_handler_obj)},
  587. // adc - functions
  588. {MP_ROM_QSTR(MP_QSTR_adc_read_pin_value), MP_ROM_PTR(&flipperzero_adc_read_pin_value_obj)},
  589. {MP_ROM_QSTR(MP_QSTR_adc_read_pin_voltage), MP_ROM_PTR(&flipperzero_adc_read_pin_voltage_obj)},
  590. // pwm - functions
  591. {MP_ROM_QSTR(MP_QSTR_pwm_start), MP_ROM_PTR(&flipperzero_pwm_start_obj)},
  592. {MP_ROM_QSTR(MP_QSTR_pwm_stop), MP_ROM_PTR(&flipperzero_pwm_stop_obj)},
  593. {MP_ROM_QSTR(MP_QSTR_pwm_is_running), MP_ROM_PTR(&flipperzero_pwm_is_running_obj)},
  594. // infrared - functions
  595. {MP_ROM_QSTR(MP_QSTR_infrared_receive), MP_ROM_PTR(&flipperzero_infrared_receive_obj)},
  596. {MP_ROM_QSTR(MP_QSTR_infrared_transmit), MP_ROM_PTR(&flipperzero_infrared_transmit_obj)},
  597. {MP_ROM_QSTR(MP_QSTR_infrared_is_busy), MP_ROM_PTR(&flipperzero_infrared_is_busy_obj)},
  598. // UART
  599. {MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&flipperzero_uart_connection_type)},
  600. {MP_ROM_QSTR(MP_QSTR_UART_MODE_LPUART), MP_ROM_INT(MP_FLIPPER_UART_MODE_LPUART)},
  601. {MP_ROM_QSTR(MP_QSTR_UART_MODE_USART), MP_ROM_INT(MP_FLIPPER_UART_MODE_USART)},
  602. {MP_ROM_QSTR(MP_QSTR_uart_open), MP_ROM_PTR(&flipperzero_uart_open_obj)},
  603. };
  604. static MP_DEFINE_CONST_DICT(flipperzero_module_globals, flipperzero_module_globals_table);
  605. const mp_obj_module_t flipperzero_module = {
  606. .base = {&mp_type_module},
  607. .globals = (mp_obj_dict_t*)&flipperzero_module_globals,
  608. };
  609. MP_REGISTER_MODULE(MP_QSTR_flipperzero, flipperzero_module);
  610. MP_REGISTER_MODULE_DELEGATION(flipperzero_module, flipperzero_module_attr);
  611. void mp_flipper_on_input(uint16_t button, uint16_t type) {
  612. if(mp_flipper_on_input_callback != NULL) {
  613. uint16_t flags = button | type;
  614. mp_obj_t flags_obj = mp_obj_new_int_from_uint(flags);
  615. mp_sched_schedule(&flipperzero_input_trigger_handler_obj, flags_obj);
  616. }
  617. }
  618. void mp_flipper_on_gpio(void* ctx) {
  619. if(mp_flipper_on_gpio_callback != NULL) {
  620. mp_obj_t pin_obj = mp_obj_new_int_from_uint((uint8_t)ctx);
  621. mp_sched_schedule(&flipperzero_gpio_trigger_handler_obj, pin_obj);
  622. }
  623. }