blob: fc61962f16d3c7029c5a05ccb918093acb24a341 [file] [log] [blame]
Damien4b6e85c2013-10-21 09:56:56 +01001#include <stdio.h>
Damiened656052013-10-13 00:42:20 +01002#include <stm32f4xx.h>
3#include <stm32f4xx_rcc.h>
Damien00ff04f2013-10-19 14:40:54 +01004#include <stm32f4xx_gpio.h>
5#include <stm_misc.h>
Damiened656052013-10-13 00:42:20 +01006#include "std.h"
7
Damien995b8aa2013-10-18 23:44:05 +01008#include "misc.h"
Damien3f69aca2013-10-21 23:46:04 +01009#include "mpyconfig.h"
10#include "gc.h"
Damien00ff04f2013-10-19 14:40:54 +010011#include "systick.h"
Damien995b8aa2013-10-18 23:44:05 +010012#include "led.h"
Damien00ff04f2013-10-19 14:40:54 +010013#include "lcd.h"
Damien995b8aa2013-10-18 23:44:05 +010014#include "storage.h"
Damienafe12bc2013-10-19 18:13:48 +010015#include "mma.h"
Damienfb42ec12013-10-19 15:37:09 +010016#include "usb.h"
Damienfa2162b2013-10-20 17:42:00 +010017#include "ff.h"
Damiened656052013-10-13 00:42:20 +010018
Damien94186c82013-10-23 00:02:06 +010019static FATFS fatfs0;
20
Damien3f69aca2013-10-21 23:46:04 +010021extern uint32_t _heap_start;
22
Damien94186c82013-10-23 00:02:06 +010023void flash_error(int n) {
24 for (int i = 0; i < n; i++) {
25 led_state(PYB_LED_R1, 1);
26 led_state(PYB_LED_R2, 0);
27 sys_tick_delay_ms(250);
28 led_state(PYB_LED_R1, 0);
29 led_state(PYB_LED_R2, 1);
30 sys_tick_delay_ms(250);
31 }
32 led_state(PYB_LED_R2, 0);
33}
34
Damien4a175e12013-10-17 22:50:21 +010035static void impl02_c_version() {
Damiened656052013-10-13 00:42:20 +010036 int x = 0;
37 while (x < 400) {
38 int y = 0;
39 while (y < 400) {
40 volatile int z = 0;
41 while (z < 400) {
42 z = z + 1;
43 }
44 y = y + 1;
45 }
46 x = x + 1;
47 }
48}
49
Damiened656052013-10-13 00:42:20 +010050#define PYB_USRSW_PORT (GPIOA)
Damien00ff04f2013-10-19 14:40:54 +010051#define PYB_USRSW_PIN (GPIO_Pin_13)
Damiened656052013-10-13 00:42:20 +010052
53void sw_init() {
54 // make it an input with pull-up
Damien00ff04f2013-10-19 14:40:54 +010055 GPIO_InitTypeDef GPIO_InitStructure;
56 GPIO_InitStructure.GPIO_Pin = PYB_USRSW_PIN;
57 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
58 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
59 GPIO_Init(PYB_USRSW_PORT, &GPIO_InitStructure);
Damiened656052013-10-13 00:42:20 +010060}
61
62int sw_get() {
Damien00ff04f2013-10-19 14:40:54 +010063 if (PYB_USRSW_PORT->IDR & PYB_USRSW_PIN) {
Damiened656052013-10-13 00:42:20 +010064 // pulled high, so switch is not pressed
65 return 0;
66 } else {
67 // pulled low, so switch is pressed
68 return 1;
69 }
70}
71
Damiened656052013-10-13 00:42:20 +010072void __fatal_error(const char *msg) {
73 lcd_print_strn("\nFATAL ERROR:\n", 14);
74 lcd_print_strn(msg, strlen(msg));
Damiened656052013-10-13 00:42:20 +010075 for (;;) {
Damien94186c82013-10-23 00:02:06 +010076 flash_error(1);
Damiened656052013-10-13 00:42:20 +010077 }
78}
79
Damienfa2162b2013-10-20 17:42:00 +010080#include "nlr.h"
Damiened656052013-10-13 00:42:20 +010081#include "misc.h"
82#include "lexer.h"
Damienfa2162b2013-10-20 17:42:00 +010083#include "lexerstm.h"
Damiened656052013-10-13 00:42:20 +010084#include "mpyconfig.h"
85#include "parse.h"
86#include "compile.h"
87#include "runtime.h"
Damiene9f1e502013-10-22 23:09:25 +010088#include "repl.h"
89
Damien94186c82013-10-23 00:02:06 +010090static qstr pyb_config_source_dir = 0;
91static qstr pyb_config_main = 0;
92
Damiene9f1e502013-10-22 23:09:25 +010093py_obj_t pyb_source_dir(py_obj_t source_dir) {
Damien94186c82013-10-23 00:02:06 +010094 pyb_config_source_dir = py_get_qstr(source_dir);
Damiene9f1e502013-10-22 23:09:25 +010095 return py_const_none;
96}
97
98py_obj_t pyb_main(py_obj_t main) {
Damien94186c82013-10-23 00:02:06 +010099 pyb_config_main = py_get_qstr(main);
100 return py_const_none;
101}
102
103// sync all file systems
104py_obj_t pyb_sync() {
105 storage_flush();
Damiene9f1e502013-10-22 23:09:25 +0100106 return py_const_none;
107}
Damiened656052013-10-13 00:42:20 +0100108
Damiened656052013-10-13 00:42:20 +0100109py_obj_t pyb_delay(py_obj_t count) {
Damien94186c82013-10-23 00:02:06 +0100110 sys_tick_delay_ms(py_get_int(count));
Damiened656052013-10-13 00:42:20 +0100111 return py_const_none;
112}
113
114py_obj_t pyb_led(py_obj_t state) {
Damien995b8aa2013-10-18 23:44:05 +0100115 led_state(PYB_LED_G1, rt_is_true(state));
Damiened656052013-10-13 00:42:20 +0100116 return state;
117}
118
119py_obj_t pyb_sw() {
120 if (sw_get()) {
121 return py_const_true;
122 } else {
123 return py_const_false;
124 }
125}
Damiened656052013-10-13 00:42:20 +0100126
Damien4a175e12013-10-17 22:50:21 +0100127/*
Damien152568b2013-10-16 00:46:39 +0100128void g(uint i) {
129 printf("g:%d\n", i);
130 if (i & 1) {
131 nlr_jump((void*)(42 + i));
132 }
133}
134void f() {
135 nlr_buf_t nlr;
136 int i;
137 for (i = 0; i < 4; i++) {
138 printf("f:loop:%d:%p\n", i, &nlr);
139 if (nlr_push(&nlr) == 0) {
140 // normal
141 //printf("a:%p:%p %p %p %u\n", &nlr, nlr.ip, nlr.sp, nlr.prev, nlr.ret_val);
142 g(i);
143 printf("f:lp:%d:nrm\n", i);
144 nlr_pop();
145 } else {
146 // nlr
147 //printf("b:%p:%p %p %p %u\n", &nlr, nlr.ip, nlr.sp, nlr.prev, nlr.ret_val);
148 printf("f:lp:%d:nlr:%d\n", i, (int)nlr.ret_val);
149 }
150 }
151}
152void nlr_test() {
153 f(1);
154}
Damien4a175e12013-10-17 22:50:21 +0100155*/
156
Damien00ff04f2013-10-19 14:40:54 +0100157void fatality() {
158 led_state(PYB_LED_R1, 1);
159 led_state(PYB_LED_G1, 1);
160 led_state(PYB_LED_R2, 1);
161 led_state(PYB_LED_G2, 1);
162}
Damiened656052013-10-13 00:42:20 +0100163
Damienafe12bc2013-10-19 18:13:48 +0100164static const char fresh_boot_py[] =
Damien00ff04f2013-10-19 14:40:54 +0100165"# boot.py -- run on boot-up\n"
166"# can run arbitrary Python, but best to keep it minimal\n"
167"\n"
168"pyb.source_dir('/src')\n"
169"pyb.main('main.py')\n"
170"#pyb.usb_usr('VCP')\n"
171"#pyb.usb_msd(True, 'dual partition')\n"
172"#pyb.flush_cache(False)\n"
173"#pyb.error_log('error.txt')\n"
174;
Damiened656052013-10-13 00:42:20 +0100175
Damien00ff04f2013-10-19 14:40:54 +0100176// get lots of info about the board
Damiene9f1e502013-10-22 23:09:25 +0100177static py_obj_t pyb_info() {
Damiened656052013-10-13 00:42:20 +0100178 // get and print clock speeds
179 // SYSCLK=168MHz, HCLK=168MHz, PCLK1=42MHz, PCLK2=84MHz
Damiened656052013-10-13 00:42:20 +0100180 {
181 RCC_ClocksTypeDef rcc_clocks;
182 RCC_GetClocksFreq(&rcc_clocks);
Damien00ff04f2013-10-19 14:40:54 +0100183 printf("S=%lu\nH=%lu\nP1=%lu\nP2=%lu\n", rcc_clocks.SYSCLK_Frequency, rcc_clocks.HCLK_Frequency, rcc_clocks.PCLK1_Frequency, rcc_clocks.PCLK2_Frequency);
Damien4a175e12013-10-17 22:50:21 +0100184 }
185
Damien995b8aa2013-10-18 23:44:05 +0100186 // to print info about memory
Damien00ff04f2013-10-19 14:40:54 +0100187 {
Damien4a175e12013-10-17 22:50:21 +0100188 extern void *_sidata;
189 extern void *_sdata;
190 extern void *_edata;
191 extern void *_sbss;
192 extern void *_ebss;
193 extern void *_estack;
194 extern void *_etext;
Damien00ff04f2013-10-19 14:40:54 +0100195 printf("_sidata=%p\n", &_sidata);
196 printf("_sdata=%p\n", &_sdata);
197 printf("_edata=%p\n", &_edata);
198 printf("_sbss=%p\n", &_sbss);
199 printf("_ebss=%p\n", &_ebss);
200 printf("_estack=%p\n", &_estack);
201 printf("_etext=%p\n", &_etext);
202 printf("_heap_start=%p\n", &_heap_start);
203 }
204
Damien94186c82013-10-23 00:02:06 +0100205 // GC info
206 {
207 gc_info_t info;
208 gc_info(&info);
209 printf("GC:\n");
210 printf(" %lu total\n", info.total);
211 printf(" %lu : %lu\n", info.used, info.free);
212 printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block);
213 }
214
Damien00ff04f2013-10-19 14:40:54 +0100215 // free space on flash
216 {
217 DWORD nclst;
218 FATFS *fatfs;
219 f_getfree("0:", &nclst, &fatfs);
Damien94186c82013-10-23 00:02:06 +0100220 printf("LFS free: %u bytes\n", (uint)(nclst * fatfs->csize * 512));
Damien00ff04f2013-10-19 14:40:54 +0100221 }
Damien00ff04f2013-10-19 14:40:54 +0100222
Damiene9f1e502013-10-22 23:09:25 +0100223 return py_const_none;
Damien4b6e85c2013-10-21 09:56:56 +0100224}
225
Damiene9f1e502013-10-22 23:09:25 +0100226int readline(vstr_t *line, const char *prompt) {
227 usb_vcp_send_str(prompt);
228 int len = vstr_len(line);
229 for (;;) {
230 while (usb_vcp_rx_any() == 0) {
231 sys_tick_delay_ms(10);
232 }
233 char c = usb_vcp_rx_get();
234 if (c == 4 && vstr_len(line) == len) {
235 return 0;
236 } else if (c == '\r') {
237 usb_vcp_send_str("\r\n");
238 return 1;
239 } else if (c == 127) {
240 if (vstr_len(line) > len) {
241 vstr_cut_tail(line, 1);
242 usb_vcp_send_str("\b \b");
243 }
244 } else if (32 <= c && c <= 126) {
245 vstr_add_char(line, c);
246 usb_vcp_send_strn(&c, 1);
247 }
248 sys_tick_delay_ms(100);
249 }
250}
251
Damien4b6e85c2013-10-21 09:56:56 +0100252void do_repl() {
Damiene9f1e502013-10-22 23:09:25 +0100253 usb_vcp_send_str("Micro Python 0.5; STM32F405RG; PYBv2\r\n");
254 usb_vcp_send_str("Type \"help\" for more information.\r\n");
255
256 vstr_t line;
257 vstr_init(&line);
Damien4b6e85c2013-10-21 09:56:56 +0100258
259 for (;;) {
Damiene9f1e502013-10-22 23:09:25 +0100260 vstr_reset(&line);
261 int ret = readline(&line, ">>> ");
262 if (ret == 0) {
Damien4b6e85c2013-10-21 09:56:56 +0100263 // EOF
Damiene9f1e502013-10-22 23:09:25 +0100264 break;
Damien4b6e85c2013-10-21 09:56:56 +0100265 }
Damiene9f1e502013-10-22 23:09:25 +0100266
267 if (vstr_len(&line) == 0) {
268 continue;
269 }
270
271 if (py_repl_is_compound_stmt(vstr_str(&line))) {
Damien4b6e85c2013-10-21 09:56:56 +0100272 for (;;) {
Damiene9f1e502013-10-22 23:09:25 +0100273 vstr_add_char(&line, '\n');
274 int len = vstr_len(&line);
275 int ret = readline(&line, "... ");
276 if (ret == 0 || vstr_len(&line) == len) {
277 // done entering compound statement
Damien4b6e85c2013-10-21 09:56:56 +0100278 break;
279 }
Damien4b6e85c2013-10-21 09:56:56 +0100280 }
281 }
Damien4b6e85c2013-10-21 09:56:56 +0100282
283 py_lexer_str_buf_t sb;
Damiene9f1e502013-10-22 23:09:25 +0100284 py_lexer_t *lex = py_lexer_new_from_str_len("<stdin>", vstr_str(&line), vstr_len(&line), false, &sb);
Damien4b6e85c2013-10-21 09:56:56 +0100285 py_parse_node_t pn = py_parse(lex, PY_PARSE_SINGLE_INPUT);
286 py_lexer_free(lex);
287
288 if (pn != PY_PARSE_NODE_NULL) {
289 bool comp_ok = py_compile(pn, true);
290 if (comp_ok) {
291 py_obj_t module_fun = rt_make_function_from_id(1);
292 if (module_fun != py_const_none) {
293 nlr_buf_t nlr;
294 if (nlr_push(&nlr) == 0) {
295 rt_call_function_0(module_fun);
296 nlr_pop();
297 } else {
298 // uncaught exception
299 py_obj_print((py_obj_t)nlr.ret_val);
300 printf("\n");
301 }
302 }
303 }
304 }
305 }
Damiene9f1e502013-10-22 23:09:25 +0100306
Damien94186c82013-10-23 00:02:06 +0100307 usb_vcp_send_str("\r\n");
308}
309
310bool do_file(const char *filename) {
311 py_lexer_file_buf_t fb;
312 py_lexer_t *lex = py_lexer_new_from_file(filename, &fb);
313
314 if (lex == NULL) {
315 printf("could not open file '%s' for reading\n", filename);
316 return false;
317 }
318
319 py_parse_node_t pn = py_parse(lex, PY_PARSE_FILE_INPUT);
320 py_lexer_free(lex);
321
322 if (pn == PY_PARSE_NODE_NULL) {
323 return false;
324 }
325
326 bool comp_ok = py_compile(pn, false);
327 if (!comp_ok) {
328 return false;
329 }
330
331 py_obj_t module_fun = rt_make_function_from_id(1);
332 if (module_fun == py_const_none) {
333 return false;
334 }
335
336 nlr_buf_t nlr;
337 if (nlr_push(&nlr) == 0) {
338 rt_call_function_0(module_fun);
339 nlr_pop();
340 return true;
341 } else {
342 // uncaught exception
343 py_obj_print((py_obj_t)nlr.ret_val);
344 printf("\n");
345 return false;
346 }
Damien4b6e85c2013-10-21 09:56:56 +0100347}
348
Damien0c5827f2013-10-22 21:13:36 +0100349#define RAM_START (0x20000000) // fixed for chip
350#define HEAP_END (0x2001c000) // tunable
351#define RAM_END (0x20020000) // fixed for chip
352
353void gc_helper_get_regs_and_clean_stack(machine_uint_t *regs, machine_uint_t heap_end);
354
Damien3f69aca2013-10-21 23:46:04 +0100355void gc_collect() {
Damien0c5827f2013-10-22 21:13:36 +0100356 uint32_t start = sys_tick_counter;
Damien3f69aca2013-10-21 23:46:04 +0100357 gc_collect_start();
Damien0c5827f2013-10-22 21:13:36 +0100358 gc_collect_root((void**)RAM_START, (((uint32_t)&_heap_start) - RAM_START) / 4);
359 machine_uint_t regs[10];
360 gc_helper_get_regs_and_clean_stack(regs, HEAP_END);
361 gc_collect_root((void**)HEAP_END, (RAM_END - HEAP_END) / 4); // will trace regs since they now live in this function on the stack
Damien3f69aca2013-10-21 23:46:04 +0100362 gc_collect_end();
Damien0c5827f2013-10-22 21:13:36 +0100363 uint32_t ticks = sys_tick_counter - start; // TODO implement a function that does this properly
364 gc_info_t info;
365 gc_info(&info);
366 printf("GC@%lu %lums\n", start, ticks);
367 printf(" %lu total\n", info.total);
368 printf(" %lu : %lu\n", info.used, info.free);
369 printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block);
370}
371
Damiene9f1e502013-10-22 23:09:25 +0100372py_obj_t pyb_gc() {
Damien0c5827f2013-10-22 21:13:36 +0100373 gc_collect();
374 return py_const_none;
Damien3f69aca2013-10-21 23:46:04 +0100375}
376
Damien00ff04f2013-10-19 14:40:54 +0100377int main() {
378 // TODO disable JTAG
379
Damienafe12bc2013-10-19 18:13:48 +0100380 // set interrupt priority config to use all 4 bits for pre-empting
381 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
382
383 // enable the CCM RAM and the GPIO's
384 RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
385
Damien00ff04f2013-10-19 14:40:54 +0100386 // basic sub-system init
387 sys_tick_init();
Damien00ff04f2013-10-19 14:40:54 +0100388 led_init();
389
390 // turn on LED to indicate bootup
391 led_state(PYB_LED_G1, 1);
392
393 // more sub-system init
394 sw_init();
Damien00ff04f2013-10-19 14:40:54 +0100395 storage_init();
396
Damiene9f1e502013-10-22 23:09:25 +0100397soft_reset:
398
399 // LCD init
400 lcd_init();
401
Damien3f69aca2013-10-21 23:46:04 +0100402 // GC init
Damien0c5827f2013-10-22 21:13:36 +0100403 gc_init(&_heap_start, (void*)HEAP_END);
Damien3f69aca2013-10-21 23:46:04 +0100404
Damiene9f1e502013-10-22 23:09:25 +0100405 // Micro Python init
Damienafe12bc2013-10-19 18:13:48 +0100406 qstr_init();
407 rt_init();
Damien00ff04f2013-10-19 14:40:54 +0100408
Damienf48cf672013-10-21 10:42:06 +0100409 // add some functions to the python namespace
Damiene9f1e502013-10-22 23:09:25 +0100410 {
411 py_obj_t m = py_module_new();
412 rt_store_attr(m, qstr_from_str_static("info"), rt_make_function_0(pyb_info));
413 rt_store_attr(m, qstr_from_str_static("source_dir"), rt_make_function_1(pyb_source_dir));
414 rt_store_attr(m, qstr_from_str_static("main"), rt_make_function_1(pyb_main));
Damien94186c82013-10-23 00:02:06 +0100415 rt_store_attr(m, qstr_from_str_static("sync"), rt_make_function_0(pyb_sync));
Damiene9f1e502013-10-22 23:09:25 +0100416 rt_store_attr(m, qstr_from_str_static("gc"), rt_make_function_0(pyb_gc));
417 rt_store_attr(m, qstr_from_str_static("delay"), rt_make_function_1(pyb_delay));
418 rt_store_attr(m, qstr_from_str_static("led"), rt_make_function_1(pyb_led));
419 rt_store_attr(m, qstr_from_str_static("sw"), rt_make_function_0(pyb_sw));
420 rt_store_name(qstr_from_str_static("pyb"), m);
421 }
Damienf48cf672013-10-21 10:42:06 +0100422
Damiene9f1e502013-10-22 23:09:25 +0100423 // print a message to the LCD
424 lcd_print_str(" micro py board\n");
Damien00ff04f2013-10-19 14:40:54 +0100425
426 // local filesystem init
427 {
428 // try to mount the flash
429 FRESULT res = f_mount(&fatfs0, "0:", 1);
430 if (res == FR_OK) {
431 // mount sucessful
432 } else if (res == FR_NO_FILESYSTEM) {
433 // no filesystem, so create a fresh one
434
435 // LED on to indicate creation of LFS
436 led_state(PYB_LED_R2, 1);
437 uint32_t stc = sys_tick_counter;
438
439 res = f_mkfs("0:", 0, 0);
440 if (res == FR_OK) {
441 // success creating fresh LFS
442 } else {
443 __fatal_error("could not create LFS");
444 }
445
Damienafe12bc2013-10-19 18:13:48 +0100446 // keep LED on for at least 200ms
447 sys_tick_wait_at_least(stc, 200);
Damien00ff04f2013-10-19 14:40:54 +0100448 led_state(PYB_LED_R2, 0);
449 } else {
450 __fatal_error("could not access LFS");
Damien4a175e12013-10-17 22:50:21 +0100451 }
Damien00ff04f2013-10-19 14:40:54 +0100452 }
453
454 // make sure we have a /boot.py
455 {
456 FILINFO fno;
457 FRESULT res = f_stat("0:/boot.py", &fno);
458 if (res == FR_OK) {
459 if (fno.fattrib & AM_DIR) {
460 // exists as a directory
461 // TODO handle this case
462 // see http://elm-chan.org/fsw/ff/img/app2.c for a "rm -rf" implementation
463 } else {
464 // exists as a file, good!
465 }
466 } else {
467 // doesn't exist, create fresh file
468
469 // LED on to indicate creation of boot.py
470 led_state(PYB_LED_R2, 1);
471 uint32_t stc = sys_tick_counter;
472
473 FIL fp;
474 f_open(&fp, "0:/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
475 UINT n;
Damiene9f1e502013-10-22 23:09:25 +0100476 f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n);
Damien00ff04f2013-10-19 14:40:54 +0100477 // TODO check we could write n bytes
478 f_close(&fp);
479
Damienafe12bc2013-10-19 18:13:48 +0100480 // keep LED on for at least 200ms
481 sys_tick_wait_at_least(stc, 200);
Damien00ff04f2013-10-19 14:40:54 +0100482 led_state(PYB_LED_R2, 0);
483 }
484 }
485
Damien94186c82013-10-23 00:02:06 +0100486 // run /boot.py
487 if (!do_file("0:/boot.py")) {
488 flash_error(4);
489 }
490
Damiene9f1e502013-10-22 23:09:25 +0100491 // USB
492 usb_init();
493
Damien00ff04f2013-10-19 14:40:54 +0100494 // turn boot-up LED off
495 led_state(PYB_LED_G1, 0);
496
Damien94186c82013-10-23 00:02:06 +0100497 // run main script
498 {
499 vstr_t *vstr = vstr_new();
500 vstr_add_str(vstr, "0:/");
501 if (pyb_config_source_dir == 0) {
502 vstr_add_str(vstr, "src");
503 } else {
504 vstr_add_str(vstr, qstr_str(pyb_config_source_dir));
505 }
506 vstr_add_char(vstr, '/');
507 if (pyb_config_main == 0) {
508 vstr_add_str(vstr, "main.py");
509 } else {
510 vstr_add_str(vstr, qstr_str(pyb_config_main));
511 }
512 if (!do_file(vstr_str(vstr))) {
513 flash_error(3);
514 }
515 vstr_free(vstr);
516 }
517
Damien00ff04f2013-10-19 14:40:54 +0100518 //printf("init;al=%u\n", m_get_total_bytes_allocated()); // 1600, due to qstr_init
519 //sys_tick_delay_ms(1000);
520
Damiened656052013-10-13 00:42:20 +0100521 // Python!
Damien4b6e85c2013-10-21 09:56:56 +0100522 if (0) {
Damiened656052013-10-13 00:42:20 +0100523 //const char *pysrc = "def f():\n x=x+1\nprint(42)\n";
524 const char *pysrc =
525 // impl01.py
526 /*
527 "x = 0\n"
528 "while x < 400:\n"
529 " y = 0\n"
530 " while y < 400:\n"
531 " z = 0\n"
532 " while z < 400:\n"
533 " z = z + 1\n"
534 " y = y + 1\n"
535 " x = x + 1\n";
536 */
537 // impl02.py
Damien152568b2013-10-16 00:46:39 +0100538 /*
Damiened656052013-10-13 00:42:20 +0100539 "#@micropython.native\n"
540 "def f():\n"
541 " x = 0\n"
542 " while x < 400:\n"
543 " y = 0\n"
544 " while y < 400:\n"
545 " z = 0\n"
546 " while z < 400:\n"
547 " z = z + 1\n"
548 " y = y + 1\n"
549 " x = x + 1\n"
550 "f()\n";
Damien152568b2013-10-16 00:46:39 +0100551 */
Damien0c5827f2013-10-22 21:13:36 +0100552 /*
Damiened656052013-10-13 00:42:20 +0100553 "print('in python!')\n"
554 "x = 0\n"
555 "while x < 4:\n"
556 " pyb_led(True)\n"
557 " pyb_delay(201)\n"
558 " pyb_led(False)\n"
559 " pyb_delay(201)\n"
Damienfa2162b2013-10-20 17:42:00 +0100560 " x += 1\n"
Damiened656052013-10-13 00:42:20 +0100561 "print('press me!')\n"
562 "while True:\n"
563 " pyb_led(pyb_sw())\n";
Damien0c5827f2013-10-22 21:13:36 +0100564 */
Damiened656052013-10-13 00:42:20 +0100565 /*
566 // impl16.py
567 "@micropython.asm_thumb\n"
568 "def delay(r0):\n"
569 " b(loop_entry)\n"
570 " label(loop1)\n"
571 " movw(r1, 55999)\n"
572 " label(loop2)\n"
573 " subs(r1, r1, 1)\n"
574 " cmp(r1, 0)\n"
575 " bgt(loop2)\n"
576 " subs(r0, r0, 1)\n"
577 " label(loop_entry)\n"
578 " cmp(r0, 0)\n"
579 " bgt(loop1)\n"
580 "print('in python!')\n"
581 "@micropython.native\n"
582 "def flash(n):\n"
583 " x = 0\n"
584 " while x < n:\n"
585 " pyb_led(True)\n"
586 " delay(249)\n"
587 " pyb_led(False)\n"
588 " delay(249)\n"
589 " x = x + 1\n"
590 "flash(20)\n";
591 */
Damien152568b2013-10-16 00:46:39 +0100592 // impl18.py
593 /*
594 "# basic exceptions\n"
595 "x = 1\n"
596 "try:\n"
597 " x.a()\n"
598 "except:\n"
599 " print(x)\n";
600 */
601 // impl19.py
602 "# for loop\n"
603 "def f():\n"
604 " for x in range(400):\n"
605 " for y in range(400):\n"
606 " for z in range(400):\n"
607 " pass\n"
608 "f()\n";
Damiened656052013-10-13 00:42:20 +0100609
Damienfa2162b2013-10-20 17:42:00 +0100610 py_lexer_str_buf_t py_lexer_str_buf;
611 py_lexer_t *lex = py_lexer_new_from_str_len("<stdin>", pysrc, strlen(pysrc), false, &py_lexer_str_buf);
Damiened656052013-10-13 00:42:20 +0100612
Damienfa2162b2013-10-20 17:42:00 +0100613 // nalloc=1740;6340;6836 -> 140;4600;496 bytes for lexer, parser, compiler
614 printf("lex; al=%u\n", m_get_total_bytes_allocated());
615 sys_tick_delay_ms(1000);
616 py_parse_node_t pn = py_parse(lex, PY_PARSE_FILE_INPUT);
617 py_lexer_free(lex);
618 if (pn != PY_PARSE_NODE_NULL) {
Damiened656052013-10-13 00:42:20 +0100619 printf("pars;al=%u\n", m_get_total_bytes_allocated());
Damien00ff04f2013-10-19 14:40:54 +0100620 sys_tick_delay_ms(1000);
Damiened656052013-10-13 00:42:20 +0100621 //parse_node_show(pn, 0);
Damienfa2162b2013-10-20 17:42:00 +0100622 bool comp_ok = py_compile(pn, false);
Damiened656052013-10-13 00:42:20 +0100623 printf("comp;al=%u\n", m_get_total_bytes_allocated());
Damien00ff04f2013-10-19 14:40:54 +0100624 sys_tick_delay_ms(1000);
Damiened656052013-10-13 00:42:20 +0100625
Damienfa2162b2013-10-20 17:42:00 +0100626 if (!comp_ok) {
627 printf("compile error\n");
628 } else {
Damiened656052013-10-13 00:42:20 +0100629 // execute it!
630
Damiened656052013-10-13 00:42:20 +0100631 py_obj_t module_fun = rt_make_function_from_id(1);
632
Damien152568b2013-10-16 00:46:39 +0100633 // flash once
Damien995b8aa2013-10-18 23:44:05 +0100634 led_state(PYB_LED_G1, 1);
Damien00ff04f2013-10-19 14:40:54 +0100635 sys_tick_delay_ms(100);
Damien995b8aa2013-10-18 23:44:05 +0100636 led_state(PYB_LED_G1, 0);
Damiened656052013-10-13 00:42:20 +0100637
Damien152568b2013-10-16 00:46:39 +0100638 nlr_buf_t nlr;
639 if (nlr_push(&nlr) == 0) {
640 py_obj_t ret = rt_call_function_0(module_fun);
641 printf("done! got: ");
642 py_obj_print(ret);
643 printf("\n");
644 nlr_pop();
645 } else {
646 // uncaught exception
647 printf("exception: ");
648 py_obj_print((py_obj_t)nlr.ret_val);
649 printf("\n");
650 }
651
652 // flash once
Damien995b8aa2013-10-18 23:44:05 +0100653 led_state(PYB_LED_G1, 1);
Damien00ff04f2013-10-19 14:40:54 +0100654 sys_tick_delay_ms(100);
Damien995b8aa2013-10-18 23:44:05 +0100655 led_state(PYB_LED_G1, 0);
Damien152568b2013-10-16 00:46:39 +0100656
Damien00ff04f2013-10-19 14:40:54 +0100657 sys_tick_delay_ms(1000);
Damiened656052013-10-13 00:42:20 +0100658 printf("nalloc=%u\n", m_get_total_bytes_allocated());
Damien00ff04f2013-10-19 14:40:54 +0100659 sys_tick_delay_ms(1000);
Damiened656052013-10-13 00:42:20 +0100660 }
661 }
662 }
Damiened656052013-10-13 00:42:20 +0100663
Damien4b6e85c2013-10-21 09:56:56 +0100664 do_repl();
665
Damiened656052013-10-13 00:42:20 +0100666 // benchmark C version of impl02.py
667 if (0) {
Damien995b8aa2013-10-18 23:44:05 +0100668 led_state(PYB_LED_G1, 1);
Damien00ff04f2013-10-19 14:40:54 +0100669 sys_tick_delay_ms(100);
Damien995b8aa2013-10-18 23:44:05 +0100670 led_state(PYB_LED_G1, 0);
Damiened656052013-10-13 00:42:20 +0100671 impl02_c_version();
Damien995b8aa2013-10-18 23:44:05 +0100672 led_state(PYB_LED_G1, 1);
Damien00ff04f2013-10-19 14:40:54 +0100673 sys_tick_delay_ms(100);
Damien995b8aa2013-10-18 23:44:05 +0100674 led_state(PYB_LED_G1, 0);
Damiened656052013-10-13 00:42:20 +0100675 }
676
677 // MMA testing
678 if (0) {
679 printf("1");
680 mma_init();
681 printf("2");
682 mma_start(0x4c, 1);
683 printf("3");
684 mma_send_byte(0);
685 printf("4");
686 mma_stop();
687 printf("5");
688 mma_start(0x4c, 1);
689 printf("6");
690 mma_send_byte(0);
691 printf("7");
692 mma_restart(0x4c, 0);
693 for (int i = 0; i <= 0xa; i++) {
694 int data;
695 if (i == 0xa) {
696 data = mma_read_nack();
697 } else {
698 data = mma_read_ack();
699 }
700 printf(" %02x", data);
701 }
702 printf("\n");
703
704 mma_start(0x4c, 1);
705 mma_send_byte(7); // mode
706 mma_send_byte(1); // active mode
707 mma_stop();
708
709 for (;;) {
Damien00ff04f2013-10-19 14:40:54 +0100710 sys_tick_delay_ms(500);
Damiened656052013-10-13 00:42:20 +0100711
712 mma_start(0x4c, 1);
713 mma_send_byte(0);
714 mma_restart(0x4c, 0);
715 for (int i = 0; i <= 3; i++) {
716 int data;
717 if (i == 3) {
718 data = mma_read_nack();
719 printf(" %02x\n", data);
720 } else {
721 data = mma_read_ack() & 0x3f;
722 if (data & 0x20) {
723 data |= 0xc0;
724 }
725 printf(" % 2d", data);
726 }
727 }
728 }
729 }
730
Damiened656052013-10-13 00:42:20 +0100731 // SD card testing
732 if (0) {
733 //sdio_init();
734 }
735
Damien94186c82013-10-23 00:02:06 +0100736 printf("PYB: sync filesystems\n");
737 pyb_sync();
738
739 printf("PYB: soft reboot\n");
Damiene9f1e502013-10-22 23:09:25 +0100740 goto soft_reset;
Damiened656052013-10-13 00:42:20 +0100741}