main.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2013, 2014 Damien P. George
  7. * Copyright (c) 2015 Glenn Ruben Bakke
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. */
  27. #include <stdint.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include "py/nlr.h"
  31. #include "py/mperrno.h"
  32. #include "py/lexer.h"
  33. #include "py/parse.h"
  34. #include "py/obj.h"
  35. #include "py/runtime.h"
  36. #include "py/stackctrl.h"
  37. #include "py/gc.h"
  38. #include "py/compile.h"
  39. #include "lib/utils/pyexec.h"
  40. #include "readline.h"
  41. #include "gccollect.h"
  42. #include "modmachine.h"
  43. #include "modmusic.h"
  44. #include "modules/uos/microbitfs.h"
  45. #include "led.h"
  46. #include "uart.h"
  47. #include "nrf.h"
  48. #include "pin.h"
  49. #include "spi.h"
  50. #include "i2c.h"
  51. #include "adc.h"
  52. #include "rtcounter.h"
  53. #if MICROPY_PY_MACHINE_HW_PWM
  54. #include "pwm.h"
  55. #endif
  56. #include "timer.h"
  57. #if BLUETOOTH_SD
  58. #include "nrf_sdm.h"
  59. #endif
  60. #if (MICROPY_PY_BLE_NUS)
  61. #include "ble_uart.h"
  62. #endif
  63. #if MICROPY_PY_MACHINE_SOFT_PWM
  64. #include "ticker.h"
  65. #include "softpwm.h"
  66. #endif
  67. void do_str(const char *src, mp_parse_input_kind_t input_kind) {
  68. mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
  69. if (lex == NULL) {
  70. printf("MemoryError: lexer could not allocate memory\n");
  71. return;
  72. }
  73. nlr_buf_t nlr;
  74. if (nlr_push(&nlr) == 0) {
  75. qstr source_name = lex->source_name;
  76. mp_parse_tree_t pn = mp_parse(lex, input_kind);
  77. mp_obj_t module_fun = mp_compile(&pn, source_name, MP_EMIT_OPT_NONE, true);
  78. mp_call_function_0(module_fun);
  79. nlr_pop();
  80. } else {
  81. // uncaught exception
  82. mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
  83. }
  84. }
  85. extern uint32_t _heap_start;
  86. extern uint32_t _heap_end;
  87. int main(int argc, char **argv) {
  88. soft_reset:
  89. mp_stack_set_top(&_ram_end);
  90. // Stack limit should be less than real stack size, so we have a chance
  91. // to recover from limit hit. (Limit is measured in bytes.)
  92. mp_stack_set_limit((char*)&_ram_end - (char*)&_heap_end - 400);
  93. machine_init();
  94. gc_init(&_heap_start, &_heap_end);
  95. mp_init();
  96. mp_obj_list_init(mp_sys_path, 0);
  97. mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script)
  98. mp_obj_list_init(mp_sys_argv, 0);
  99. pyb_set_repl_info(MP_OBJ_NEW_SMALL_INT(0));
  100. readline_init0();
  101. #if MICROPY_PY_MACHINE_HW_SPI
  102. spi_init0();
  103. #endif
  104. #if MICROPY_PY_MACHINE_I2C
  105. i2c_init0();
  106. #endif
  107. #if MICROPY_PY_MACHINE_ADC
  108. adc_init0();
  109. #endif
  110. #if MICROPY_PY_MACHINE_HW_PWM
  111. pwm_init0();
  112. #endif
  113. #if MICROPY_PY_MACHINE_RTCOUNTER
  114. rtc_init0();
  115. #endif
  116. #if MICROPY_PY_MACHINE_TIMER
  117. timer_init0();
  118. #endif
  119. #if MICROPY_PY_MACHINE_UART
  120. uart_init0();
  121. #endif
  122. #if (MICROPY_PY_BLE_NUS == 0)
  123. {
  124. mp_obj_t args[2] = {
  125. MP_OBJ_NEW_SMALL_INT(0),
  126. MP_OBJ_NEW_SMALL_INT(115200),
  127. };
  128. MP_STATE_PORT(board_stdio_uart) = machine_hard_uart_type.make_new((mp_obj_t)&machine_hard_uart_type, MP_ARRAY_SIZE(args), 0, args);
  129. }
  130. #endif
  131. pin_init0();
  132. #if MICROPY_MBFS
  133. microbit_filesystem_init();
  134. #endif
  135. #if MICROPY_HW_HAS_SDCARD
  136. // if an SD card is present then mount it on /sd/
  137. if (sdcard_is_present()) {
  138. // create vfs object
  139. fs_user_mount_t *vfs = m_new_obj_maybe(fs_user_mount_t);
  140. if (vfs == NULL) {
  141. goto no_mem_for_sd;
  142. }
  143. vfs->str = "/sd";
  144. vfs->len = 3;
  145. vfs->flags = FSUSER_FREE_OBJ;
  146. sdcard_init_vfs(vfs);
  147. // put the sd device in slot 1 (it will be unused at this point)
  148. MP_STATE_PORT(fs_user_mount)[1] = vfs;
  149. FRESULT res = f_mount(&vfs->fatfs, vfs->str, 1);
  150. if (res != FR_OK) {
  151. printf("MPY: can't mount SD card\n");
  152. MP_STATE_PORT(fs_user_mount)[1] = NULL;
  153. m_del_obj(fs_user_mount_t, vfs);
  154. } else {
  155. // TODO these should go before the /flash entries in the path
  156. mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
  157. mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
  158. // use SD card as current directory
  159. f_chdrive("/sd");
  160. }
  161. no_mem_for_sd:;
  162. }
  163. #endif
  164. #if (MICROPY_HW_HAS_LED)
  165. led_init();
  166. do_str("import board\r\n" \
  167. "board.LED(1).on()",
  168. MP_PARSE_FILE_INPUT);
  169. #endif
  170. // Main script is finished, so now go into REPL mode.
  171. // The REPL mode can change, or it can request a soft reset.
  172. int ret_code = 0;
  173. #if MICROPY_PY_BLE_NUS
  174. ble_uart_init0();
  175. #endif
  176. #if MICROPY_PY_MACHINE_SOFT_PWM
  177. ticker_init0();
  178. softpwm_init0();
  179. #endif
  180. #if MICROPY_PY_MUSIC
  181. microbit_music_init0();
  182. #endif
  183. #if BOARD_SPECIFIC_MODULES
  184. board_modules_init0();
  185. #endif
  186. #if MICROPY_PY_MACHINE_SOFT_PWM
  187. ticker_start();
  188. pwm_start();
  189. #endif
  190. #if MICROPY_VFS || MICROPY_MBFS
  191. // run boot.py and main.py if they exist.
  192. if (mp_import_stat("boot.py") == MP_IMPORT_STAT_FILE) {
  193. pyexec_file("boot.py");
  194. }
  195. if (mp_import_stat("main.py") == MP_IMPORT_STAT_FILE) {
  196. pyexec_file("main.py");
  197. }
  198. #endif
  199. for (;;) {
  200. if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
  201. if (pyexec_raw_repl() != 0) {
  202. break;
  203. }
  204. } else {
  205. ret_code = pyexec_friendly_repl();
  206. if (ret_code != 0) {
  207. break;
  208. }
  209. }
  210. }
  211. mp_deinit();
  212. printf("MPY: soft reboot\n");
  213. #if BLUETOOTH_SD
  214. sd_softdevice_disable();
  215. #endif
  216. goto soft_reset;
  217. return 0;
  218. }
  219. #if !MICROPY_VFS
  220. #if MICROPY_MBFS
  221. // Use micro:bit filesystem
  222. mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
  223. return uos_mbfs_new_reader(filename);
  224. }
  225. mp_import_stat_t mp_import_stat(const char *path) {
  226. return uos_mbfs_import_stat(path);
  227. }
  228. STATIC mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args) {
  229. return uos_mbfs_open(n_args, args);
  230. }
  231. MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_open_obj, 1, 2, mp_builtin_open);
  232. #else
  233. // use dummy functions - no filesystem available
  234. mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
  235. mp_raise_OSError(MP_ENOENT);
  236. }
  237. mp_import_stat_t mp_import_stat(const char *path) {
  238. return MP_IMPORT_STAT_NO_EXIST;
  239. }
  240. STATIC mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
  241. mp_raise_OSError(MP_EPERM);
  242. }
  243. MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
  244. #endif
  245. #endif
  246. void HardFault_Handler(void)
  247. {
  248. #if defined(NRF52_SERIES)
  249. static volatile uint32_t reg;
  250. static volatile uint32_t reg2;
  251. static volatile uint32_t bfar;
  252. reg = SCB->HFSR;
  253. reg2 = SCB->CFSR;
  254. bfar = SCB->BFAR;
  255. for (int i = 0; i < 0; i++)
  256. {
  257. (void)reg;
  258. (void)reg2;
  259. (void)bfar;
  260. }
  261. #endif
  262. }
  263. void NORETURN __fatal_error(const char *msg) {
  264. while (1);
  265. }
  266. void nlr_jump_fail(void *val) {
  267. printf("FATAL: uncaught exception %p\n", val);
  268. mp_obj_print_exception(&mp_plat_print, (mp_obj_t)val);
  269. __fatal_error("");
  270. }
  271. void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
  272. printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
  273. __fatal_error("Assertion failed");
  274. }
  275. void _start(void) {main(0, NULL);}