mp_flipper_modflipperzero.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. #include <stdio.h>
  2. #include "py/objint.h"
  3. #include "py/objfun.h"
  4. #include "py/obj.h"
  5. #include "py/runtime.h"
  6. #include "mp_flipper_modflipperzero.h"
  7. typedef struct {
  8. uint8_t button;
  9. uint8_t type;
  10. } on_input_arg_t;
  11. static void* mp_flipper_on_input_callback = NULL;
  12. static mp_obj_t flipperzero_light_set(mp_obj_t light_obj, mp_obj_t brightness_obj) {
  13. mp_int_t light = mp_obj_get_int(light_obj);
  14. mp_int_t brightness = mp_obj_get_int(brightness_obj);
  15. mp_flipper_light_set(light, brightness);
  16. return mp_const_none;
  17. }
  18. static MP_DEFINE_CONST_FUN_OBJ_2(flipperzero_light_set_obj, flipperzero_light_set);
  19. static mp_obj_t flipperzero_light_blink_start(size_t n_args, const mp_obj_t* args) {
  20. if(n_args != 4) {
  21. return mp_const_none;
  22. }
  23. mp_int_t light = mp_obj_get_int(args[0]);
  24. mp_int_t brightness = mp_obj_get_int(args[1]);
  25. mp_int_t on_time = mp_obj_get_int(args[2]);
  26. mp_int_t period = mp_obj_get_int(args[3]);
  27. mp_flipper_light_blink_start(light, brightness, on_time, period);
  28. return mp_const_none;
  29. }
  30. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_light_blink_start_obj, 4, 4, flipperzero_light_blink_start);
  31. static mp_obj_t flipperzero_light_blink_stop() {
  32. mp_flipper_light_blink_stop();
  33. return mp_const_none;
  34. }
  35. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_light_blink_stop_obj, flipperzero_light_blink_stop);
  36. static mp_obj_t flipperzero_light_blink_set_color(mp_obj_t light_obj) {
  37. mp_int_t light = mp_obj_get_int(light_obj);
  38. mp_flipper_light_blink_set_color(light);
  39. return mp_const_none;
  40. }
  41. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_light_blink_set_color_obj, flipperzero_light_blink_set_color);
  42. static mp_obj_t flipperzero_vibro_set(mp_obj_t state) {
  43. bool state_bool = mp_obj_is_true(state);
  44. mp_flipper_vibro(state_bool);
  45. return state_bool ? mp_const_true : mp_const_false;
  46. }
  47. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_vibro_set_obj, flipperzero_vibro_set);
  48. static mp_obj_t flipperzero_speaker_start(mp_obj_t frequency_obj, mp_obj_t volume_obj) {
  49. mp_float_t frequency = mp_obj_get_float(frequency_obj);
  50. mp_float_t volume = mp_obj_get_float(volume_obj);
  51. return mp_flipper_speaker_start(frequency, volume) ? mp_const_true : mp_const_false;
  52. }
  53. static MP_DEFINE_CONST_FUN_OBJ_2(flipperzero_speaker_start_obj, flipperzero_speaker_start);
  54. static mp_obj_t flipperzero_speaker_set_volume(mp_obj_t volume_obj) {
  55. mp_float_t volume = mp_obj_get_float(volume_obj);
  56. return mp_flipper_speaker_set_volume(volume) ? mp_const_true : mp_const_false;
  57. }
  58. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_speaker_set_volume_obj, flipperzero_speaker_set_volume);
  59. static mp_obj_t flipperzero_speaker_stop() {
  60. mp_flipper_speaker_stop();
  61. return mp_flipper_speaker_stop() ? mp_const_true : mp_const_false;
  62. }
  63. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_speaker_stop_obj, flipperzero_speaker_stop);
  64. static mp_obj_t flipperzero_canvas_width() {
  65. uint8_t width = mp_flipper_canvas_width();
  66. return mp_obj_new_int(width);
  67. }
  68. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_canvas_width_obj, flipperzero_canvas_width);
  69. static mp_obj_t flipperzero_canvas_height() {
  70. uint8_t height = mp_flipper_canvas_height();
  71. return mp_obj_new_int(height);
  72. }
  73. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_canvas_height_obj, flipperzero_canvas_height);
  74. static mp_obj_t flipperzero_canvas_text_width(mp_obj_t text_obj) {
  75. const char* text = mp_obj_str_get_str(text_obj);
  76. uint8_t width = mp_flipper_canvas_text_width(text);
  77. return mp_obj_new_int(width);
  78. }
  79. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_canvas_text_width_obj, flipperzero_canvas_text_width);
  80. static mp_obj_t flipperzero_canvas_text_height() {
  81. uint8_t height = mp_flipper_canvas_text_height();
  82. return mp_obj_new_int(height);
  83. }
  84. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_canvas_text_height_obj, flipperzero_canvas_text_height);
  85. static mp_obj_t flipperzero_canvas_draw_dot(mp_obj_t x_obj, mp_obj_t y_obj) {
  86. mp_int_t x = mp_obj_get_int(x_obj);
  87. mp_int_t y = mp_obj_get_int(y_obj);
  88. mp_flipper_canvas_draw_dot(x, y);
  89. return mp_const_none;
  90. }
  91. static MP_DEFINE_CONST_FUN_OBJ_2(flipperzero_canvas_draw_dot_obj, flipperzero_canvas_draw_dot);
  92. static mp_obj_t flipperzero_canvas_draw_box(size_t n_args, const mp_obj_t* args) {
  93. if(n_args < 4) {
  94. return mp_const_none;
  95. }
  96. mp_int_t x = mp_obj_get_int(args[0]);
  97. mp_int_t y = mp_obj_get_int(args[1]);
  98. mp_int_t width = mp_obj_get_int(args[2]);
  99. mp_int_t height = mp_obj_get_int(args[3]);
  100. mp_int_t radius = n_args == 5 ? mp_obj_get_int(args[4]) : 0;
  101. mp_flipper_canvas_draw_box(x, y, width, height, radius);
  102. return mp_const_none;
  103. }
  104. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_canvas_draw_box_obj, 4, 5, flipperzero_canvas_draw_box);
  105. static mp_obj_t flipperzero_canvas_draw_frame(size_t n_args, const mp_obj_t* args) {
  106. if(n_args < 4) {
  107. return mp_const_none;
  108. }
  109. mp_int_t x = mp_obj_get_int(args[0]);
  110. mp_int_t y = mp_obj_get_int(args[1]);
  111. mp_int_t width = mp_obj_get_int(args[2]);
  112. mp_int_t height = mp_obj_get_int(args[3]);
  113. mp_int_t radius = n_args == 5 ? mp_obj_get_int(args[4]) : 0;
  114. mp_flipper_canvas_draw_frame(x, y, width, height, radius);
  115. return mp_const_none;
  116. }
  117. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_canvas_draw_frame_obj, 4, 5, flipperzero_canvas_draw_frame);
  118. static mp_obj_t flipperzero_canvas_draw_line(size_t n_args, const mp_obj_t* args) {
  119. if(n_args != 4) {
  120. return mp_const_none;
  121. }
  122. mp_int_t x0 = mp_obj_get_int(args[0]);
  123. mp_int_t y0 = mp_obj_get_int(args[1]);
  124. mp_int_t x1 = mp_obj_get_int(args[2]);
  125. mp_int_t y1 = mp_obj_get_int(args[3]);
  126. mp_flipper_canvas_draw_line(x0, y0, x1, y1);
  127. return mp_const_none;
  128. }
  129. static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(flipperzero_canvas_draw_line_obj, 4, 4, flipperzero_canvas_draw_line);
  130. static mp_obj_t flipperzero_canvas_draw_circle(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t r_obj) {
  131. mp_int_t x = mp_obj_get_int(x_obj);
  132. mp_int_t y = mp_obj_get_int(y_obj);
  133. mp_int_t r = mp_obj_get_int(r_obj);
  134. mp_flipper_canvas_draw_circle(x, y, r);
  135. return mp_const_none;
  136. }
  137. static MP_DEFINE_CONST_FUN_OBJ_3(flipperzero_canvas_draw_circle_obj, flipperzero_canvas_draw_circle);
  138. static mp_obj_t flipperzero_canvas_draw_disc(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t r_obj) {
  139. mp_int_t x = mp_obj_get_int(x_obj);
  140. mp_int_t y = mp_obj_get_int(y_obj);
  141. mp_int_t r = mp_obj_get_int(r_obj);
  142. mp_flipper_canvas_draw_disc(x, y, r);
  143. return mp_const_none;
  144. }
  145. static MP_DEFINE_CONST_FUN_OBJ_3(flipperzero_canvas_draw_disc_obj, flipperzero_canvas_draw_disc);
  146. static mp_obj_t flipperzero_canvas_set_font(mp_obj_t font_obj) {
  147. mp_int_t font = mp_obj_get_int(font_obj);
  148. mp_flipper_canvas_set_font(font);
  149. return mp_const_none;
  150. }
  151. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_canvas_set_font_obj, flipperzero_canvas_set_font);
  152. static mp_obj_t flipperzero_canvas_set_color(mp_obj_t color_obj) {
  153. mp_int_t color = mp_obj_get_int(color_obj);
  154. mp_flipper_canvas_set_color(color);
  155. return mp_const_none;
  156. }
  157. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_canvas_set_color_obj, flipperzero_canvas_set_color);
  158. static mp_obj_t flipperzero_canvas_set_text(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t str_obj) {
  159. mp_int_t x = mp_obj_get_int(x_obj);
  160. mp_int_t y = mp_obj_get_int(y_obj);
  161. const char* str = mp_obj_str_get_str(str_obj);
  162. mp_flipper_canvas_set_text(x, y, str);
  163. return mp_const_none;
  164. }
  165. static MP_DEFINE_CONST_FUN_OBJ_3(flipperzero_canvas_set_text_obj, flipperzero_canvas_set_text);
  166. static mp_obj_t flipperzero_canvas_set_text_align(mp_obj_t x_obj, mp_obj_t y_obj) {
  167. mp_int_t x = mp_obj_get_int(x_obj);
  168. mp_int_t y = mp_obj_get_int(y_obj);
  169. mp_flipper_canvas_set_text_align(x, y);
  170. return mp_const_none;
  171. }
  172. static MP_DEFINE_CONST_FUN_OBJ_2(flipperzero_canvas_set_text_align_obj, flipperzero_canvas_set_text_align);
  173. static mp_obj_t flipperzero_canvas_update() {
  174. mp_flipper_canvas_update();
  175. return mp_const_none;
  176. }
  177. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_canvas_update_obj, flipperzero_canvas_update);
  178. static mp_obj_t flipperzero_canvas_clear() {
  179. mp_flipper_canvas_clear();
  180. return mp_const_none;
  181. }
  182. static MP_DEFINE_CONST_FUN_OBJ_0(flipperzero_canvas_clear_obj, flipperzero_canvas_clear);
  183. static mp_obj_t flipperzero_on_input(mp_obj_t callback_obj) {
  184. mp_flipper_on_input_callback = callback_obj;
  185. return callback_obj;
  186. }
  187. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_on_input_obj, flipperzero_on_input);
  188. static mp_obj_t flipperzero_input_trigger_handler(mp_obj_t flags_obj) {
  189. if(mp_flipper_on_input_callback != NULL) {
  190. mp_int_t flags = mp_obj_get_int(flags_obj);
  191. mp_obj_t button_obj = mp_obj_new_int(flags & MP_FLIPPER_INPUT_BUTTON);
  192. mp_obj_t type_obj = mp_obj_new_int(flags & MP_FLIPPER_INPUT_TYPE);
  193. mp_call_function_2_protected(mp_flipper_on_input_callback, button_obj, type_obj);
  194. }
  195. return mp_const_none;
  196. }
  197. static MP_DEFINE_CONST_FUN_OBJ_1(flipperzero_input_trigger_handler_obj, flipperzero_input_trigger_handler);
  198. void mp_flipper_on_input(uint16_t button, uint16_t type) {
  199. if(mp_flipper_on_input_callback != NULL) {
  200. uint16_t flags = button | type;
  201. mp_obj_t flags_obj = mp_obj_new_int_from_uint(flags);
  202. mp_sched_schedule(&flipperzero_input_trigger_handler_obj, flags_obj);
  203. }
  204. }
  205. static const mp_rom_map_elem_t flipperzero_module_globals_table[] = {
  206. {MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_flipperzero)},
  207. {MP_ROM_QSTR(MP_QSTR_LIGHT_RED), MP_ROM_INT(MP_FLIPPER_LED_RED)},
  208. {MP_ROM_QSTR(MP_QSTR_LIGHT_GREEN), MP_ROM_INT(MP_FLIPPER_LED_GREEN)},
  209. {MP_ROM_QSTR(MP_QSTR_LIGHT_BLUE), MP_ROM_INT(MP_FLIPPER_LED_BLUE)},
  210. {MP_ROM_QSTR(MP_QSTR_LIGHT_BACKLIGHT), MP_ROM_INT(MP_FLIPPER_LED_BACKLIGHT)},
  211. {MP_ROM_QSTR(MP_QSTR_light_set), MP_ROM_PTR(&flipperzero_light_set_obj)},
  212. {MP_ROM_QSTR(MP_QSTR_light_blink_start), MP_ROM_PTR(&flipperzero_light_blink_start_obj)},
  213. {MP_ROM_QSTR(MP_QSTR_light_blink_set_color), MP_ROM_PTR(&flipperzero_light_blink_set_color_obj)},
  214. {MP_ROM_QSTR(MP_QSTR_light_blink_stop), MP_ROM_PTR(&flipperzero_light_blink_stop_obj)},
  215. {MP_ROM_QSTR(MP_QSTR_vibro_set), MP_ROM_PTR(&flipperzero_vibro_set_obj)},
  216. {MP_ROM_QSTR(MP_QSTR_speaker_start), MP_ROM_PTR(&flipperzero_speaker_start_obj)},
  217. {MP_ROM_QSTR(MP_QSTR_speaker_set_volume), MP_ROM_PTR(&flipperzero_speaker_set_volume_obj)},
  218. {MP_ROM_QSTR(MP_QSTR_speaker_stop), MP_ROM_PTR(&flipperzero_speaker_stop_obj)},
  219. {MP_ROM_QSTR(MP_QSTR_CANVAS_BLACK), MP_ROM_INT(MP_FLIPPER_COLOR_BLACK)},
  220. {MP_ROM_QSTR(MP_QSTR_CANVAS_WHITE), MP_ROM_INT(MP_FLIPPER_COLOR_WHITE)},
  221. {MP_ROM_QSTR(MP_QSTR_canvas_width), MP_ROM_PTR(&flipperzero_canvas_width_obj)},
  222. {MP_ROM_QSTR(MP_QSTR_canvas_height), MP_ROM_PTR(&flipperzero_canvas_height_obj)},
  223. {MP_ROM_QSTR(MP_QSTR_canvas_text_width), MP_ROM_PTR(&flipperzero_canvas_text_width_obj)},
  224. {MP_ROM_QSTR(MP_QSTR_canvas_text_height), MP_ROM_PTR(&flipperzero_canvas_text_height_obj)},
  225. {MP_ROM_QSTR(MP_QSTR_canvas_draw_dot), MP_ROM_PTR(&flipperzero_canvas_draw_dot_obj)},
  226. {MP_ROM_QSTR(MP_QSTR_canvas_draw_box), MP_ROM_PTR(&flipperzero_canvas_draw_box_obj)},
  227. {MP_ROM_QSTR(MP_QSTR_canvas_draw_frame), MP_ROM_PTR(&flipperzero_canvas_draw_frame_obj)},
  228. {MP_ROM_QSTR(MP_QSTR_canvas_draw_line), MP_ROM_PTR(&flipperzero_canvas_draw_line_obj)},
  229. {MP_ROM_QSTR(MP_QSTR_canvas_draw_circle), MP_ROM_PTR(&flipperzero_canvas_draw_circle_obj)},
  230. {MP_ROM_QSTR(MP_QSTR_canvas_draw_disc), MP_ROM_PTR(&flipperzero_canvas_draw_disc_obj)},
  231. {MP_ROM_QSTR(MP_QSTR_CANVAS_FONT_PRIMARY), MP_ROM_INT(MP_FLIPPER_CANVAS_FONT_PRIMARY)},
  232. {MP_ROM_QSTR(MP_QSTR_CANVAS_FONT_SECONDARY), MP_ROM_INT(MP_FLIPPER_CANVAS_FONT_SECONDARY)},
  233. {MP_ROM_QSTR(MP_QSTR_canvas_set_font), MP_ROM_PTR(&flipperzero_canvas_set_font_obj)},
  234. {MP_ROM_QSTR(MP_QSTR_canvas_set_color), MP_ROM_PTR(&flipperzero_canvas_set_color_obj)},
  235. {MP_ROM_QSTR(MP_QSTR_canvas_set_text), MP_ROM_PTR(&flipperzero_canvas_set_text_obj)},
  236. {MP_ROM_QSTR(MP_QSTR_CANVAS_ALIGN_BEGIN), MP_ROM_INT(MP_FLIPPER_CANVAS_ALIGN_BEGIN)},
  237. {MP_ROM_QSTR(MP_QSTR_CANVAS_ALIGN_CENTER), MP_ROM_INT(MP_FLIPPER_CANVAS_ALIGN_CENTER)},
  238. {MP_ROM_QSTR(MP_QSTR_CANVAS_ALIGN_END), MP_ROM_INT(MP_FLIPPER_CANVAS_ALIGN_END)},
  239. {MP_ROM_QSTR(MP_QSTR_canvas_set_text_align), MP_ROM_PTR(&flipperzero_canvas_set_text_align_obj)},
  240. {MP_ROM_QSTR(MP_QSTR_canvas_update), MP_ROM_PTR(&flipperzero_canvas_update_obj)},
  241. {MP_ROM_QSTR(MP_QSTR_canvas_clear), MP_ROM_PTR(&flipperzero_canvas_clear_obj)},
  242. {MP_ROM_QSTR(MP_QSTR_on_input), MP_ROM_PTR(&flipperzero_on_input_obj)},
  243. {MP_ROM_QSTR(MP_QSTR__input_trigger_handler), MP_ROM_PTR(&flipperzero_input_trigger_handler_obj)},
  244. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_BACK), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_BACK)},
  245. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_OK), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_OK)},
  246. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_LEFT), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_LEFT)},
  247. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_RIGHT), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_RIGHT)},
  248. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_UP), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_UP)},
  249. {MP_ROM_QSTR(MP_QSTR_INPUT_BUTTON_DOWN), MP_ROM_INT(MP_FLIPPER_INPUT_BUTTON_DOWN)},
  250. {MP_ROM_QSTR(MP_QSTR_INPUT_TYPE_PRESS), MP_ROM_INT(MP_FLIPPER_INPUT_TYPE_PRESS)},
  251. {MP_ROM_QSTR(MP_QSTR_INPUT_TYPE_RELEASE), MP_ROM_INT(MP_FLIPPER_INPUT_TYPE_RELEASE)},
  252. {MP_ROM_QSTR(MP_QSTR_INPUT_TYPE_SHORT), MP_ROM_INT(MP_FLIPPER_INPUT_TYPE_SHORT)},
  253. {MP_ROM_QSTR(MP_QSTR_INPUT_TYPE_LONG), MP_ROM_INT(MP_FLIPPER_INPUT_TYPE_LONG)},
  254. {MP_ROM_QSTR(MP_QSTR_INPUT_TYPE_REPEAT), MP_ROM_INT(MP_FLIPPER_INPUT_TYPE_REPEAT)},
  255. };
  256. static MP_DEFINE_CONST_DICT(flipperzero_module_globals, flipperzero_module_globals_table);
  257. const mp_obj_module_t flipperzero_module = {
  258. .base = {&mp_type_module},
  259. .globals = (mp_obj_dict_t*)&flipperzero_module_globals,
  260. };
  261. MP_REGISTER_MODULE(MP_QSTR_flipperzero, flipperzero_module);