blob: e1c8df0508026e60c0597bb715d00ebb432a502b [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>
Damien52851552013-12-11 00:40:15 +00004#include <stm32f4xx_syscfg.h>
Damien00ff04f2013-10-19 14:40:54 +01005#include <stm32f4xx_gpio.h>
Damien52851552013-12-11 00:40:15 +00006#include <stm32f4xx_exti.h>
Damien0f654512013-10-23 20:39:20 +01007#include <stm32f4xx_tim.h>
Damien9281cd62013-10-26 02:29:02 +01008#include <stm32f4xx_pwr.h>
Damien81289412013-10-26 02:06:37 +01009#include <stm32f4xx_rtc.h>
Damien8f7491a2013-10-26 18:01:48 +010010#include <stm32f4xx_usart.h>
Damien39c6c592013-11-09 20:15:48 +000011#include <stm32f4xx_rng.h>
Damien00ff04f2013-10-19 14:40:54 +010012#include <stm_misc.h>
Damiened656052013-10-13 00:42:20 +010013#include "std.h"
14
Damien995b8aa2013-10-18 23:44:05 +010015#include "misc.h"
Damien3f69aca2013-10-21 23:46:04 +010016#include "mpyconfig.h"
17#include "gc.h"
Damien00ff04f2013-10-19 14:40:54 +010018#include "systick.h"
Damien995b8aa2013-10-18 23:44:05 +010019#include "led.h"
Damien00ff04f2013-10-19 14:40:54 +010020#include "lcd.h"
Damien995b8aa2013-10-18 23:44:05 +010021#include "storage.h"
Damienafe12bc2013-10-19 18:13:48 +010022#include "mma.h"
Damien8f7491a2013-10-26 18:01:48 +010023#include "usart.h"
Damienfb42ec12013-10-19 15:37:09 +010024#include "usb.h"
Damienfa2162b2013-10-20 17:42:00 +010025#include "ff.h"
Damienbd8e1102013-11-06 23:04:33 +000026#include "timer.h"
Damien1c62d042013-11-04 23:05:48 +000027#include "audio.h"
Damien065f8a52013-12-05 20:38:23 +000028#include "pybwlan.h"
29
30int errno;
Damiened656052013-10-13 00:42:20 +010031
Damien3f69aca2013-10-21 23:46:04 +010032extern uint32_t _heap_start;
33
Damien8fe84132013-11-30 15:06:24 +000034static FATFS fatfs0;
35
Damien94186c82013-10-23 00:02:06 +010036void flash_error(int n) {
37 for (int i = 0; i < n; i++) {
38 led_state(PYB_LED_R1, 1);
39 led_state(PYB_LED_R2, 0);
40 sys_tick_delay_ms(250);
41 led_state(PYB_LED_R1, 0);
42 led_state(PYB_LED_R2, 1);
43 sys_tick_delay_ms(250);
44 }
45 led_state(PYB_LED_R2, 0);
46}
47
Damien0f654512013-10-23 20:39:20 +010048static void impl02_c_version(void) {
Damiened656052013-10-13 00:42:20 +010049 int x = 0;
50 while (x < 400) {
51 int y = 0;
52 while (y < 400) {
53 volatile int z = 0;
54 while (z < 400) {
55 z = z + 1;
56 }
57 y = y + 1;
58 }
59 x = x + 1;
60 }
61}
62
Damiened656052013-10-13 00:42:20 +010063#define PYB_USRSW_PORT (GPIOA)
Damien00ff04f2013-10-19 14:40:54 +010064#define PYB_USRSW_PIN (GPIO_Pin_13)
Damiened656052013-10-13 00:42:20 +010065
Damien0f654512013-10-23 20:39:20 +010066void sw_init(void) {
Damiened656052013-10-13 00:42:20 +010067 // make it an input with pull-up
Damien00ff04f2013-10-19 14:40:54 +010068 GPIO_InitTypeDef GPIO_InitStructure;
69 GPIO_InitStructure.GPIO_Pin = PYB_USRSW_PIN;
70 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
71 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
72 GPIO_Init(PYB_USRSW_PORT, &GPIO_InitStructure);
Damien52851552013-12-11 00:40:15 +000073
74 // the rest does the EXTI interrupt
75
76 /* Enable SYSCFG clock */
77 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
78
79 /* Connect EXTI Line13 to PA13 pin */
80 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource13);
81
82 /* Configure EXTI Line13, rising edge */
83 EXTI_InitTypeDef EXTI_InitStructure;
84 EXTI_InitStructure.EXTI_Line = EXTI_Line13;
85 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
86 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
87 EXTI_InitStructure.EXTI_LineCmd = ENABLE;
88 EXTI_Init(&EXTI_InitStructure);
89
90 /* Enable and set EXTI15_10 Interrupt to the lowest priority */
91 NVIC_InitTypeDef NVIC_InitStructure;
92 NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
93 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
94 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
95 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
96 NVIC_Init(&NVIC_InitStructure);
Damiened656052013-10-13 00:42:20 +010097}
98
Damien0f654512013-10-23 20:39:20 +010099int sw_get(void) {
Damien00ff04f2013-10-19 14:40:54 +0100100 if (PYB_USRSW_PORT->IDR & PYB_USRSW_PIN) {
Damiened656052013-10-13 00:42:20 +0100101 // pulled high, so switch is not pressed
102 return 0;
103 } else {
104 // pulled low, so switch is pressed
105 return 1;
106 }
107}
108
Damiened656052013-10-13 00:42:20 +0100109void __fatal_error(const char *msg) {
110 lcd_print_strn("\nFATAL ERROR:\n", 14);
111 lcd_print_strn(msg, strlen(msg));
Damiened656052013-10-13 00:42:20 +0100112 for (;;) {
Damien94186c82013-10-23 00:02:06 +0100113 flash_error(1);
Damiened656052013-10-13 00:42:20 +0100114 }
115}
116
Damienfa2162b2013-10-20 17:42:00 +0100117#include "nlr.h"
Damiened656052013-10-13 00:42:20 +0100118#include "misc.h"
119#include "lexer.h"
Damienfa2162b2013-10-20 17:42:00 +0100120#include "lexerstm.h"
Damiened656052013-10-13 00:42:20 +0100121#include "mpyconfig.h"
122#include "parse.h"
123#include "compile.h"
124#include "runtime.h"
Damiene9f1e502013-10-22 23:09:25 +0100125#include "repl.h"
126
Damien94186c82013-10-23 00:02:06 +0100127static qstr pyb_config_source_dir = 0;
128static qstr pyb_config_main = 0;
129
Damiene9f1e502013-10-22 23:09:25 +0100130py_obj_t pyb_source_dir(py_obj_t source_dir) {
Damien0e496732013-11-03 14:53:34 +0000131 pyb_config_source_dir = py_obj_get_qstr(source_dir);
Damiene9f1e502013-10-22 23:09:25 +0100132 return py_const_none;
133}
134
135py_obj_t pyb_main(py_obj_t main) {
Damien0e496732013-11-03 14:53:34 +0000136 pyb_config_main = py_obj_get_qstr(main);
Damien94186c82013-10-23 00:02:06 +0100137 return py_const_none;
138}
139
140// sync all file systems
Damien0f654512013-10-23 20:39:20 +0100141py_obj_t pyb_sync(void) {
Damien94186c82013-10-23 00:02:06 +0100142 storage_flush();
Damiene9f1e502013-10-22 23:09:25 +0100143 return py_const_none;
144}
Damiened656052013-10-13 00:42:20 +0100145
Damiened656052013-10-13 00:42:20 +0100146py_obj_t pyb_delay(py_obj_t count) {
Damien0e496732013-11-03 14:53:34 +0000147 sys_tick_delay_ms(py_obj_get_int(count));
Damiened656052013-10-13 00:42:20 +0100148 return py_const_none;
149}
150
151py_obj_t pyb_led(py_obj_t state) {
Damien995b8aa2013-10-18 23:44:05 +0100152 led_state(PYB_LED_G1, rt_is_true(state));
Damiened656052013-10-13 00:42:20 +0100153 return state;
154}
155
Damiend6b4c662013-12-06 00:41:33 +0000156py_obj_t py_obj_new_user(const py_user_info_t *info, machine_uint_t data1, machine_uint_t data2);
157void py_user_get_data(py_obj_t o, machine_uint_t *data1, machine_uint_t *data2);
158void py_user_set_data(py_obj_t o, machine_uint_t data1, machine_uint_t data2);
159
160py_obj_t led_obj_on(py_obj_t self) {
161 machine_uint_t led_id;
162 py_user_get_data(self, &led_id, NULL);
163 switch (led_id) {
164 case 1: led_state(PYB_LED_G1, 1); break;
165 case 2: led_state(PYB_LED_G2, 1); break;
166 }
167 return py_const_none;
168}
169
170py_obj_t led_obj_off(py_obj_t self) {
171 machine_uint_t led_id;
172 py_user_get_data(self, &led_id, NULL);
173 switch (led_id) {
174 case 1: led_state(PYB_LED_G1, 0); break;
175 case 2: led_state(PYB_LED_G2, 0); break;
176 }
177 return py_const_none;
178}
179
180const py_user_info_t led_obj_info = {
181 "Led",
182 NULL, // print
183 {
184 {"on", 0, led_obj_on},
185 {"off", 0, led_obj_off},
186 {NULL, 0, NULL},
187 }
188};
189
190py_obj_t pyb_Led(py_obj_t led_id) {
191 return py_obj_new_user(&led_obj_info, (machine_uint_t)py_obj_get_int(led_id), 0);
192}
193
Damien0f654512013-10-23 20:39:20 +0100194py_obj_t pyb_sw(void) {
Damiened656052013-10-13 00:42:20 +0100195 if (sw_get()) {
196 return py_const_true;
197 } else {
198 return py_const_false;
199 }
200}
Damiened656052013-10-13 00:42:20 +0100201
Damien52851552013-12-11 00:40:15 +0000202py_obj_t servo_obj_angle(py_obj_t self, py_obj_t angle) {
203 machine_uint_t servo_id;
204 py_user_get_data(self, &servo_id, NULL);
205 machine_int_t v = 152 + 85.0 * py_obj_get_float(angle) / 90.0;
206 if (v < 65) { v = 65; }
207 if (v > 210) { v = 210; }
208 switch (servo_id) {
209 case 1: TIM2->CCR1 = v; break;
210 case 2: TIM2->CCR2 = v; break;
211 case 3: TIM2->CCR3 = v; break;
212 case 4: TIM2->CCR4 = v; break;
213 }
214 return py_const_none;
215}
216
217const py_user_info_t servo_obj_info = {
218 "Servo",
219 NULL, // print
220 {
221 {"angle", 1, servo_obj_angle},
222 {NULL, 0, NULL},
223 }
224};
225
226py_obj_t pyb_Servo(py_obj_t servo_id) {
227 return py_obj_new_user(&servo_obj_info, (machine_uint_t)py_obj_get_int(servo_id), 0);
228}
229
Damien4a175e12013-10-17 22:50:21 +0100230/*
Damien152568b2013-10-16 00:46:39 +0100231void g(uint i) {
232 printf("g:%d\n", i);
233 if (i & 1) {
234 nlr_jump((void*)(42 + i));
235 }
236}
Damien0f654512013-10-23 20:39:20 +0100237void f(void) {
Damien152568b2013-10-16 00:46:39 +0100238 nlr_buf_t nlr;
239 int i;
240 for (i = 0; i < 4; i++) {
241 printf("f:loop:%d:%p\n", i, &nlr);
242 if (nlr_push(&nlr) == 0) {
243 // normal
244 //printf("a:%p:%p %p %p %u\n", &nlr, nlr.ip, nlr.sp, nlr.prev, nlr.ret_val);
245 g(i);
246 printf("f:lp:%d:nrm\n", i);
247 nlr_pop();
248 } else {
249 // nlr
250 //printf("b:%p:%p %p %p %u\n", &nlr, nlr.ip, nlr.sp, nlr.prev, nlr.ret_val);
251 printf("f:lp:%d:nlr:%d\n", i, (int)nlr.ret_val);
252 }
253 }
254}
Damien0f654512013-10-23 20:39:20 +0100255void nlr_test(void) {
Damien152568b2013-10-16 00:46:39 +0100256 f(1);
257}
Damien4a175e12013-10-17 22:50:21 +0100258*/
259
Damien0f654512013-10-23 20:39:20 +0100260void fatality(void) {
Damien00ff04f2013-10-19 14:40:54 +0100261 led_state(PYB_LED_R1, 1);
262 led_state(PYB_LED_G1, 1);
263 led_state(PYB_LED_R2, 1);
264 led_state(PYB_LED_G2, 1);
265}
Damiened656052013-10-13 00:42:20 +0100266
Damienafe12bc2013-10-19 18:13:48 +0100267static const char fresh_boot_py[] =
Damien00ff04f2013-10-19 14:40:54 +0100268"# boot.py -- run on boot-up\n"
269"# can run arbitrary Python, but best to keep it minimal\n"
270"\n"
271"pyb.source_dir('/src')\n"
272"pyb.main('main.py')\n"
273"#pyb.usb_usr('VCP')\n"
274"#pyb.usb_msd(True, 'dual partition')\n"
275"#pyb.flush_cache(False)\n"
276"#pyb.error_log('error.txt')\n"
277;
Damiened656052013-10-13 00:42:20 +0100278
Damien00ff04f2013-10-19 14:40:54 +0100279// get lots of info about the board
Damien0f654512013-10-23 20:39:20 +0100280static py_obj_t pyb_info(void) {
Damiened656052013-10-13 00:42:20 +0100281 // get and print clock speeds
282 // SYSCLK=168MHz, HCLK=168MHz, PCLK1=42MHz, PCLK2=84MHz
Damiened656052013-10-13 00:42:20 +0100283 {
284 RCC_ClocksTypeDef rcc_clocks;
285 RCC_GetClocksFreq(&rcc_clocks);
Damien00ff04f2013-10-19 14:40:54 +0100286 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 +0100287 }
288
Damien995b8aa2013-10-18 23:44:05 +0100289 // to print info about memory
Damien00ff04f2013-10-19 14:40:54 +0100290 {
Damien4a175e12013-10-17 22:50:21 +0100291 extern void *_sidata;
292 extern void *_sdata;
293 extern void *_edata;
294 extern void *_sbss;
295 extern void *_ebss;
296 extern void *_estack;
297 extern void *_etext;
Damien00ff04f2013-10-19 14:40:54 +0100298 printf("_sidata=%p\n", &_sidata);
299 printf("_sdata=%p\n", &_sdata);
300 printf("_edata=%p\n", &_edata);
301 printf("_sbss=%p\n", &_sbss);
302 printf("_ebss=%p\n", &_ebss);
303 printf("_estack=%p\n", &_estack);
304 printf("_etext=%p\n", &_etext);
305 printf("_heap_start=%p\n", &_heap_start);
306 }
307
Damien94186c82013-10-23 00:02:06 +0100308 // GC info
309 {
310 gc_info_t info;
311 gc_info(&info);
312 printf("GC:\n");
313 printf(" %lu total\n", info.total);
314 printf(" %lu : %lu\n", info.used, info.free);
315 printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block);
316 }
317
Damien00ff04f2013-10-19 14:40:54 +0100318 // free space on flash
319 {
320 DWORD nclst;
321 FATFS *fatfs;
322 f_getfree("0:", &nclst, &fatfs);
Damien94186c82013-10-23 00:02:06 +0100323 printf("LFS free: %u bytes\n", (uint)(nclst * fatfs->csize * 512));
Damien00ff04f2013-10-19 14:40:54 +0100324 }
Damien00ff04f2013-10-19 14:40:54 +0100325
Damiene9f1e502013-10-22 23:09:25 +0100326 return py_const_none;
Damien4b6e85c2013-10-21 09:56:56 +0100327}
328
Damien52851552013-12-11 00:40:15 +0000329static void SYSCLKConfig_STOP(void) {
330 /* After wake-up from STOP reconfigure the system clock */
331 /* Enable HSE */
332 RCC_HSEConfig(RCC_HSE_ON);
333
334 /* Wait till HSE is ready */
335 while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) {
336 }
337
338 /* Enable PLL */
339 RCC_PLLCmd(ENABLE);
340
341 /* Wait till PLL is ready */
342 while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {
343 }
344
345 /* Select PLL as system clock source */
346 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
347
348 /* Wait till PLL is used as system clock source */
349 while (RCC_GetSYSCLKSource() != 0x08) {
350 }
351}
352
353static py_obj_t pyb_stop(void) {
354 PWR_EnterSTANDBYMode();
355 //PWR_FlashPowerDownCmd(ENABLE); don't know what the logic is with this
356
357 /* Enter Stop Mode */
358 PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
359
360 /* Configures system clock after wake-up from STOP: enable HSE, PLL and select
361 * PLL as system clock source (HSE and PLL are disabled in STOP mode) */
362 SYSCLKConfig_STOP();
363
364 //PWR_FlashPowerDownCmd(DISABLE);
365
366 return py_const_none;
367}
368
369static py_obj_t pyb_standby(void) {
370 PWR_EnterSTANDBYMode();
371 return py_const_none;
372}
373
Damien8f7491a2013-10-26 18:01:48 +0100374py_obj_t pyb_usart_send(py_obj_t data) {
Damien0e496732013-11-03 14:53:34 +0000375 usart_tx_char(py_obj_get_int(data));
Damien8f7491a2013-10-26 18:01:48 +0100376 return py_const_none;
377}
378
379py_obj_t pyb_usart_receive(void) {
380 return py_obj_new_int(usart_rx_char());
381}
382
383py_obj_t pyb_usart_status(void) {
384 if (usart_rx_any()) {
385 return py_const_true;
386 } else {
387 return py_const_false;
388 }
389}
390
Damien9281cd62013-10-26 02:29:02 +0100391char *strdup(const char *str) {
392 uint32_t len = strlen(str);
393 char *s2 = m_new(char, len + 1);
394 memcpy(s2, str, len);
395 s2[len] = 0;
396 return s2;
397}
398
399#define READLINE_HIST_SIZE (8)
400
401static const char *readline_hist[READLINE_HIST_SIZE] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
402
Damien8f7491a2013-10-26 18:01:48 +0100403void stdout_tx_str(const char *str) {
404 usart_tx_str(str);
405 usb_vcp_send_str(str);
406}
407
Damiene9f1e502013-10-22 23:09:25 +0100408int readline(vstr_t *line, const char *prompt) {
Damien8f7491a2013-10-26 18:01:48 +0100409 stdout_tx_str(prompt);
Damiene9f1e502013-10-22 23:09:25 +0100410 int len = vstr_len(line);
Damien9281cd62013-10-26 02:29:02 +0100411 int escape = 0;
412 int hist_num = 0;
Damiene9f1e502013-10-22 23:09:25 +0100413 for (;;) {
Damien8f7491a2013-10-26 18:01:48 +0100414 char c;
415 for (;;) {
416 if (usb_vcp_rx_any() != 0) {
417 c = usb_vcp_rx_get();
418 break;
419 } else if (usart_rx_any()) {
420 c = usart_rx_char();
421 break;
422 }
Damien9281cd62013-10-26 02:29:02 +0100423 sys_tick_delay_ms(1);
Damien52851552013-12-11 00:40:15 +0000424 if (storage_needs_flush()) {
425 storage_flush();
426 }
Damiene9f1e502013-10-22 23:09:25 +0100427 }
Damien9281cd62013-10-26 02:29:02 +0100428 if (escape == 0) {
429 if (c == 4 && vstr_len(line) == len) {
430 return 0;
431 } else if (c == '\r') {
Damien8f7491a2013-10-26 18:01:48 +0100432 stdout_tx_str("\r\n");
Damien9281cd62013-10-26 02:29:02 +0100433 for (int i = READLINE_HIST_SIZE - 1; i > 0; i--) {
434 readline_hist[i] = readline_hist[i - 1];
435 }
436 readline_hist[0] = strdup(vstr_str(line));
437 return 1;
438 } else if (c == 27) {
439 escape = true;
440 } else if (c == 127) {
441 if (vstr_len(line) > len) {
442 vstr_cut_tail(line, 1);
Damien8f7491a2013-10-26 18:01:48 +0100443 stdout_tx_str("\b \b");
Damien9281cd62013-10-26 02:29:02 +0100444 }
445 } else if (32 <= c && c <= 126) {
446 vstr_add_char(line, c);
Damien8f7491a2013-10-26 18:01:48 +0100447 stdout_tx_str(line->buf + line->len - 1);
Damiene9f1e502013-10-22 23:09:25 +0100448 }
Damien9281cd62013-10-26 02:29:02 +0100449 } else if (escape == 1) {
450 if (c == '[') {
451 escape = 2;
452 } else {
453 escape = 0;
454 }
455 } else if (escape == 2) {
456 escape = 0;
457 if (c == 'A') {
458 // up arrow
459 if (hist_num < READLINE_HIST_SIZE && readline_hist[hist_num] != NULL) {
460 // erase line
461 for (int i = line->len - len; i > 0; i--) {
Damien8f7491a2013-10-26 18:01:48 +0100462 stdout_tx_str("\b \b");
Damien9281cd62013-10-26 02:29:02 +0100463 }
464 // set line to history
465 line->len = len;
466 vstr_add_str(line, readline_hist[hist_num]);
467 // draw line
Damien8f7491a2013-10-26 18:01:48 +0100468 stdout_tx_str(readline_hist[hist_num]);
Damien9281cd62013-10-26 02:29:02 +0100469 // increase hist num
470 hist_num += 1;
471 }
472 }
473 } else {
474 escape = 0;
Damiene9f1e502013-10-22 23:09:25 +0100475 }
Damien9281cd62013-10-26 02:29:02 +0100476 sys_tick_delay_ms(10);
Damiene9f1e502013-10-22 23:09:25 +0100477 }
478}
479
Damien0f654512013-10-23 20:39:20 +0100480void do_repl(void) {
Damien8f7491a2013-10-26 18:01:48 +0100481 stdout_tx_str("Micro Python 0.5; STM32F405RG; PYBv2\r\n");
482 stdout_tx_str("Type \"help\" for more information.\r\n");
Damiene9f1e502013-10-22 23:09:25 +0100483
484 vstr_t line;
485 vstr_init(&line);
Damien4b6e85c2013-10-21 09:56:56 +0100486
487 for (;;) {
Damiene9f1e502013-10-22 23:09:25 +0100488 vstr_reset(&line);
489 int ret = readline(&line, ">>> ");
490 if (ret == 0) {
Damien4b6e85c2013-10-21 09:56:56 +0100491 // EOF
Damiene9f1e502013-10-22 23:09:25 +0100492 break;
Damien4b6e85c2013-10-21 09:56:56 +0100493 }
Damiene9f1e502013-10-22 23:09:25 +0100494
495 if (vstr_len(&line) == 0) {
496 continue;
497 }
498
499 if (py_repl_is_compound_stmt(vstr_str(&line))) {
Damien4b6e85c2013-10-21 09:56:56 +0100500 for (;;) {
Damiene9f1e502013-10-22 23:09:25 +0100501 vstr_add_char(&line, '\n');
502 int len = vstr_len(&line);
503 int ret = readline(&line, "... ");
504 if (ret == 0 || vstr_len(&line) == len) {
505 // done entering compound statement
Damien4b6e85c2013-10-21 09:56:56 +0100506 break;
507 }
Damien4b6e85c2013-10-21 09:56:56 +0100508 }
509 }
Damien4b6e85c2013-10-21 09:56:56 +0100510
511 py_lexer_str_buf_t sb;
Damiene9f1e502013-10-22 23:09:25 +0100512 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 +0100513 py_parse_node_t pn = py_parse(lex, PY_PARSE_SINGLE_INPUT);
514 py_lexer_free(lex);
515
516 if (pn != PY_PARSE_NODE_NULL) {
517 bool comp_ok = py_compile(pn, true);
518 if (comp_ok) {
519 py_obj_t module_fun = rt_make_function_from_id(1);
520 if (module_fun != py_const_none) {
521 nlr_buf_t nlr;
Damien8fe84132013-11-30 15:06:24 +0000522 uint32_t start = sys_tick_counter;
Damien4b6e85c2013-10-21 09:56:56 +0100523 if (nlr_push(&nlr) == 0) {
524 rt_call_function_0(module_fun);
525 nlr_pop();
Damien8fe84132013-11-30 15:06:24 +0000526 uint32_t ticks = sys_tick_counter - start; // TODO implement a function that does this properly
Damien52851552013-12-11 00:40:15 +0000527 //printf("(took %lu ms)\n", ticks);
Damien4b6e85c2013-10-21 09:56:56 +0100528 } else {
529 // uncaught exception
530 py_obj_print((py_obj_t)nlr.ret_val);
531 printf("\n");
532 }
533 }
534 }
535 }
536 }
Damiene9f1e502013-10-22 23:09:25 +0100537
Damien8f7491a2013-10-26 18:01:48 +0100538 stdout_tx_str("\r\n");
Damien94186c82013-10-23 00:02:06 +0100539}
540
541bool do_file(const char *filename) {
542 py_lexer_file_buf_t fb;
543 py_lexer_t *lex = py_lexer_new_from_file(filename, &fb);
544
545 if (lex == NULL) {
546 printf("could not open file '%s' for reading\n", filename);
547 return false;
548 }
549
550 py_parse_node_t pn = py_parse(lex, PY_PARSE_FILE_INPUT);
551 py_lexer_free(lex);
552
553 if (pn == PY_PARSE_NODE_NULL) {
554 return false;
555 }
556
557 bool comp_ok = py_compile(pn, false);
558 if (!comp_ok) {
559 return false;
560 }
561
562 py_obj_t module_fun = rt_make_function_from_id(1);
563 if (module_fun == py_const_none) {
564 return false;
565 }
566
567 nlr_buf_t nlr;
568 if (nlr_push(&nlr) == 0) {
569 rt_call_function_0(module_fun);
570 nlr_pop();
571 return true;
572 } else {
573 // uncaught exception
574 py_obj_print((py_obj_t)nlr.ret_val);
575 printf("\n");
576 return false;
577 }
Damien4b6e85c2013-10-21 09:56:56 +0100578}
579
Damien0c5827f2013-10-22 21:13:36 +0100580#define RAM_START (0x20000000) // fixed for chip
581#define HEAP_END (0x2001c000) // tunable
582#define RAM_END (0x20020000) // fixed for chip
583
584void gc_helper_get_regs_and_clean_stack(machine_uint_t *regs, machine_uint_t heap_end);
585
Damien0f654512013-10-23 20:39:20 +0100586void gc_collect(void) {
Damien0c5827f2013-10-22 21:13:36 +0100587 uint32_t start = sys_tick_counter;
Damien3f69aca2013-10-21 23:46:04 +0100588 gc_collect_start();
Damien0c5827f2013-10-22 21:13:36 +0100589 gc_collect_root((void**)RAM_START, (((uint32_t)&_heap_start) - RAM_START) / 4);
590 machine_uint_t regs[10];
591 gc_helper_get_regs_and_clean_stack(regs, HEAP_END);
592 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 +0100593 gc_collect_end();
Damien0c5827f2013-10-22 21:13:36 +0100594 uint32_t ticks = sys_tick_counter - start; // TODO implement a function that does this properly
595 gc_info_t info;
596 gc_info(&info);
597 printf("GC@%lu %lums\n", start, ticks);
598 printf(" %lu total\n", info.total);
599 printf(" %lu : %lu\n", info.used, info.free);
600 printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block);
601}
602
Damien0f654512013-10-23 20:39:20 +0100603py_obj_t pyb_gc(void) {
Damien0c5827f2013-10-22 21:13:36 +0100604 gc_collect();
605 return py_const_none;
Damien3f69aca2013-10-21 23:46:04 +0100606}
607
Damien0f654512013-10-23 20:39:20 +0100608// PWM
609// TIM2 and TIM5 have CH1, CH2, CH3, CH4 on PA0-PA3 respectively
610// they are both 32-bit counters
611// 16-bit prescaler
612// TIM2_CH3 also on PB10 (used below)
613void servo_init(void) {
614 // TIM2 clock enable
615 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
616
Damien8fe84132013-11-30 15:06:24 +0000617 // for PB10
618 /*
619 // GPIOB Configuration: TIM2_CH3 (PB10)
Damien0f654512013-10-23 20:39:20 +0100620 GPIO_InitTypeDef GPIO_InitStructure;
621 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
622 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
623 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
624 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
625 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
626 GPIO_Init(GPIOB, &GPIO_InitStructure);
627
628 // Connect TIM2 pins to AF1
629 GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_TIM2);
Damien8fe84132013-11-30 15:06:24 +0000630 */
631
632 // for PA0, PA1, PA2, PA3
633 {
634 // GPIOA Configuration: TIM2_CH0, TIM2_CH1 (PA0, PA1)
635 GPIO_InitTypeDef GPIO_InitStructure;
636 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
637 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
638 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
639 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
640 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
641 GPIO_Init(GPIOA, &GPIO_InitStructure);
642
643 // Connect TIM2 pins to AF1
644 GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);
645 GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);
646 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2);
647 GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2);
648 }
Damien0f654512013-10-23 20:39:20 +0100649
650 // Compute the prescaler value so TIM2 runs at 100kHz
651 uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 100000) - 1;
652
653 // Time base configuration
654 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
655 TIM_TimeBaseStructure.TIM_Period = 2000; // timer cycles at 50Hz
656 TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
657 TIM_TimeBaseStructure.TIM_ClockDivision = 0;
658 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
659 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
660
Damien8fe84132013-11-30 15:06:24 +0000661 // PWM Mode configuration
Damien0f654512013-10-23 20:39:20 +0100662 TIM_OCInitTypeDef TIM_OCInitStructure;
663 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
664 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
665 TIM_OCInitStructure.TIM_Pulse = 150; // units of 10us
666 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
Damien8fe84132013-11-30 15:06:24 +0000667 TIM_OC1Init(TIM2, &TIM_OCInitStructure); // channel 1
668 TIM_OC2Init(TIM2, &TIM_OCInitStructure); // channel 2
669 TIM_OC3Init(TIM2, &TIM_OCInitStructure); // channel 3
670 TIM_OC4Init(TIM2, &TIM_OCInitStructure); // channel 4
Damien0f654512013-10-23 20:39:20 +0100671
672 // ?
Damien8fe84132013-11-30 15:06:24 +0000673 TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 1
674 TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 2
675 TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 3
676 TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 4
Damien0f654512013-10-23 20:39:20 +0100677
678 // ?
679 TIM_ARRPreloadConfig(TIM2, ENABLE);
680
681 // TIM2 enable counter
682 TIM_Cmd(TIM2, ENABLE);
683}
684
Damien8fe84132013-11-30 15:06:24 +0000685py_obj_t pyb_servo_set(py_obj_t port, py_obj_t value) {
686 int p = py_obj_get_int(port);
Damien0e496732013-11-03 14:53:34 +0000687 int v = py_obj_get_int(value);
Damien52851552013-12-11 00:40:15 +0000688 if (v < 50) { v = 50; }
689 if (v > 250) { v = 250; }
Damien8fe84132013-11-30 15:06:24 +0000690 switch (p) {
691 case 1: TIM2->CCR1 = v; break;
692 case 2: TIM2->CCR2 = v; break;
693 case 3: TIM2->CCR3 = v; break;
694 case 4: TIM2->CCR4 = v; break;
695 }
Damien0f654512013-10-23 20:39:20 +0100696 return py_const_none;
697}
698
Damien0c70f882013-11-03 18:30:57 +0000699py_obj_t pyb_pwm_set(py_obj_t period, py_obj_t pulse) {
700 int pe = py_obj_get_int(period);
701 int pu = py_obj_get_int(pulse);
702 TIM2->ARR = pe;
703 TIM2->CCR3 = pu;
704 return py_const_none;
705}
706
Damien6f08f8c2013-10-23 22:17:26 +0100707#define MMA_ADDR (0x4c)
708
Damien8fe84132013-11-30 15:06:24 +0000709int mma_buf[12];
710
Damienbd8e1102013-11-06 23:04:33 +0000711py_obj_t pyb_mma_read(void) {
Damien8fe84132013-11-30 15:06:24 +0000712 for (int i = 0; i <= 6; i += 3) {
713 mma_buf[0 + i] = mma_buf[0 + i + 3];
714 mma_buf[1 + i] = mma_buf[1 + i + 3];
715 mma_buf[2 + i] = mma_buf[2 + i + 3];
716 }
717
Damien6f08f8c2013-10-23 22:17:26 +0100718 mma_start(MMA_ADDR, 1);
719 mma_send_byte(0);
720 mma_restart(MMA_ADDR, 0);
Damien8fe84132013-11-30 15:06:24 +0000721 for (int i = 0; i <= 2; i++) {
Damien6f08f8c2013-10-23 22:17:26 +0100722 int v = mma_read_ack() & 0x3f;
723 if (v & 0x20) {
724 v |= ~0x1f;
725 }
Damien8fe84132013-11-30 15:06:24 +0000726 mma_buf[9 + i] = v;
Damien6f08f8c2013-10-23 22:17:26 +0100727 }
Damien8fe84132013-11-30 15:06:24 +0000728 int jolt_info = mma_read_nack();
729
730 py_obj_t data[4];
731 data[0] = py_obj_new_int(jolt_info);
732 data[1] = py_obj_new_int(mma_buf[2] + mma_buf[5] + mma_buf[8] + mma_buf[11]);
733 data[2] = py_obj_new_int(mma_buf[1] + mma_buf[4] + mma_buf[7] + mma_buf[10]);
734 data[3] = py_obj_new_int(mma_buf[0] + mma_buf[3] + mma_buf[6] + mma_buf[9]);
735
Damien6f08f8c2013-10-23 22:17:26 +0100736 return rt_build_tuple(4, data); // items in reverse order in data
737}
738
Damien58a1b4c2013-10-25 20:53:54 +0100739py_obj_t pyb_hid_send_report(py_obj_t arg) {
Damien0e496732013-11-03 14:53:34 +0000740 py_obj_t *items = py_obj_get_array_fixed_n(arg, 4);
Damien58a1b4c2013-10-25 20:53:54 +0100741 uint8_t data[4];
Damien0e496732013-11-03 14:53:34 +0000742 data[0] = py_obj_get_int(items[0]);
743 data[1] = py_obj_get_int(items[1]);
744 data[2] = py_obj_get_int(items[2]);
745 data[3] = py_obj_get_int(items[3]);
Damien58a1b4c2013-10-25 20:53:54 +0100746 usb_hid_send_report(data);
747 return py_const_none;
748}
749
Damien81289412013-10-26 02:06:37 +0100750static void rtc_init(void) {
751 /* Enable the PWR clock */
752 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
753
754 /* Allow access to RTC */
755 PWR_BackupAccessCmd(ENABLE);
756
757 /* Enable the LSE OSC */
758 RCC_LSEConfig(RCC_LSE_ON);
759
760 /* Wait till LSE is ready */
761 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {
762 }
763
764 /* Select the RTC Clock Source */
765 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
766 /* ck_spre(1Hz) = RTCCLK(LSE) /(uwAsynchPrediv + 1)*(uwSynchPrediv + 1)*/
767 uint32_t uwSynchPrediv = 0xFF;
768 uint32_t uwAsynchPrediv = 0x7F;
769
770 /* Enable the RTC Clock */
771 RCC_RTCCLKCmd(ENABLE);
772
773 /* Wait for RTC APB registers synchronisation */
774 RTC_WaitForSynchro();
775
776 /* Configure the RTC data register and RTC prescaler */
777 RTC_InitTypeDef RTC_InitStructure;
778 RTC_InitStructure.RTC_AsynchPrediv = uwAsynchPrediv;
779 RTC_InitStructure.RTC_SynchPrediv = uwSynchPrediv;
780 RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
781 RTC_Init(&RTC_InitStructure);
782
783 // Set the date (BCD)
784 RTC_DateTypeDef RTC_DateStructure;
785 RTC_DateStructure.RTC_Year = 0x13;
786 RTC_DateStructure.RTC_Month = RTC_Month_October;
787 RTC_DateStructure.RTC_Date = 0x26;
788 RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Saturday;
789 RTC_SetDate(RTC_Format_BCD, &RTC_DateStructure);
790
791 // Set the time (BCD)
792 RTC_TimeTypeDef RTC_TimeStructure;
793 RTC_TimeStructure.RTC_H12 = RTC_H12_AM;
794 RTC_TimeStructure.RTC_Hours = 0x01;
795 RTC_TimeStructure.RTC_Minutes = 0x53;
796 RTC_TimeStructure.RTC_Seconds = 0x00;
797 RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure);
798
799 // Indicator for the RTC configuration
800 //RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);
801}
802
803py_obj_t pyb_rtc_read(void) {
804 RTC_TimeTypeDef RTC_TimeStructure;
805 RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
806 printf("%02d:%02d:%02d\n", RTC_TimeStructure.RTC_Hours, RTC_TimeStructure.RTC_Minutes, RTC_TimeStructure.RTC_Seconds);
807 return py_const_none;
808}
809
Damien0e496732013-11-03 14:53:34 +0000810void file_obj_print(py_obj_t o) {
811 FIL *fp;
812 py_user_get_data(o, (machine_uint_t*)&fp, NULL);
813 printf("<file %p>", fp);
814}
815
816py_obj_t file_obj_read(py_obj_t self, py_obj_t arg) {
817 FIL *fp;
818 py_user_get_data(self, (machine_uint_t*)&fp, NULL);
819 int n = py_obj_get_int(arg);
820 char *buf = m_new(char, n + 1);
821 UINT n_out;
822 f_read(fp, buf, n, &n_out);
823 buf[n_out] = 0;
824 return py_obj_new_str(qstr_from_str_take(buf));
825}
826
827py_obj_t file_obj_write(py_obj_t self, py_obj_t arg) {
828 FIL *fp;
829 py_user_get_data(self, (machine_uint_t*)&fp, NULL);
830 const char *s = qstr_str(py_obj_get_qstr(arg));
831 UINT n_out;
832 FRESULT res = f_write(fp, s, strlen(s), &n_out);
833 if (res != FR_OK) {
834 printf("File error: could not write to file; error code %d\n", res);
835 } else if (n_out != strlen(s)) {
836 printf("File error: could not write all data to file; wrote %d / %d bytes\n", n_out, strlen(s));
837 }
838 return py_const_none;
839}
840
841py_obj_t file_obj_close(py_obj_t self) {
842 FIL *fp;
843 py_user_get_data(self, (machine_uint_t*)&fp, NULL);
844 f_close(fp);
845 return py_const_none;
846}
847
848// TODO gc hook to close the file if not already closed
849const py_user_info_t file_obj_info = {
850 "File",
851 file_obj_print,
852 {
853 {"read", 1, file_obj_read},
854 {"write", 1, file_obj_write},
855 {"close", 0, file_obj_close},
856 {NULL, 0, NULL},
857 }
858};
859
860py_obj_t pyb_io_open(py_obj_t o_filename, py_obj_t o_mode) {
861 const char *filename = qstr_str(py_obj_get_qstr(o_filename));
862 const char *mode = qstr_str(py_obj_get_qstr(o_mode));
863 FIL *fp = m_new(FIL, 1);
864 if (mode[0] == 'r') {
865 // open for reading
866 FRESULT res = f_open(fp, filename, FA_READ);
867 if (res != FR_OK) {
868 printf("FileNotFoundError: [Errno 2] No such file or directory: '%s'\n", filename);
869 return py_const_none;
870 }
871 } else if (mode[0] == 'w') {
872 // open for writing, truncate the file first
873 FRESULT res = f_open(fp, filename, FA_WRITE | FA_CREATE_ALWAYS);
874 if (res != FR_OK) {
875 printf("?FileError: could not create file: '%s'\n", filename);
876 return py_const_none;
877 }
878 } else {
879 printf("ValueError: invalid mode: '%s'\n", mode);
880 return py_const_none;
881 }
882 return py_obj_new_user(&file_obj_info, (machine_uint_t)fp, 0);
883}
884
Damien39c6c592013-11-09 20:15:48 +0000885py_obj_t pyb_rng_get(void) {
886 return py_obj_new_int(RNG_GetRandomNumber() >> 16);
887}
888
Damien0f654512013-10-23 20:39:20 +0100889int main(void) {
Damien00ff04f2013-10-19 14:40:54 +0100890 // TODO disable JTAG
891
Damiend6b4c662013-12-06 00:41:33 +0000892 // update the SystemCoreClock variable
893 SystemCoreClockUpdate();
894
Damienafe12bc2013-10-19 18:13:48 +0100895 // set interrupt priority config to use all 4 bits for pre-empting
896 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
897
898 // enable the CCM RAM and the GPIO's
899 RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
900
Damien5892f472013-10-26 18:02:46 +0100901 // configure SDIO pins to be high to start with (apparently makes it more robust)
Damien7ee80ba2013-10-24 00:22:27 +0100902 {
903 GPIO_InitTypeDef GPIO_InitStructure;
904 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
905 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
906 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
907 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
908 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
909 GPIO_Init(GPIOC, &GPIO_InitStructure);
910
911 // Configure PD.02 CMD line
912 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
913 GPIO_Init(GPIOD, &GPIO_InitStructure);
914 }
915
Damien00ff04f2013-10-19 14:40:54 +0100916 // basic sub-system init
917 sys_tick_init();
Damien00ff04f2013-10-19 14:40:54 +0100918 led_init();
Damien81289412013-10-26 02:06:37 +0100919 rtc_init();
Damien00ff04f2013-10-19 14:40:54 +0100920
921 // turn on LED to indicate bootup
922 led_state(PYB_LED_G1, 1);
923
924 // more sub-system init
925 sw_init();
Damien00ff04f2013-10-19 14:40:54 +0100926 storage_init();
Damien065f8a52013-12-05 20:38:23 +0000927
928 //usart_init(); disabled while wi-fi is enabled
Damien00ff04f2013-10-19 14:40:54 +0100929
Damienbd8e1102013-11-06 23:04:33 +0000930 int first_soft_reset = true;
931
Damiene9f1e502013-10-22 23:09:25 +0100932soft_reset:
933
Damien3f69aca2013-10-21 23:46:04 +0100934 // GC init
Damien0c5827f2013-10-22 21:13:36 +0100935 gc_init(&_heap_start, (void*)HEAP_END);
Damien3f69aca2013-10-21 23:46:04 +0100936
Damiene9f1e502013-10-22 23:09:25 +0100937 // Micro Python init
Damienafe12bc2013-10-19 18:13:48 +0100938 qstr_init();
939 rt_init();
Damien00ff04f2013-10-19 14:40:54 +0100940
Damien39c6c592013-11-09 20:15:48 +0000941 // LCD init
Damien8fe84132013-11-30 15:06:24 +0000942 //lcd_init(); disabled while servos on PA0 PA1
Damien39c6c592013-11-09 20:15:48 +0000943
Damien0f654512013-10-23 20:39:20 +0100944 // servo
945 servo_init();
946
Damien1c62d042013-11-04 23:05:48 +0000947 // audio
Damien52851552013-12-11 00:40:15 +0000948 //audio_init();
Damien1c62d042013-11-04 23:05:48 +0000949
Damienbd8e1102013-11-06 23:04:33 +0000950 // timer
951 timer_init();
952
Damien39c6c592013-11-09 20:15:48 +0000953 // RNG
Damien52851552013-12-11 00:40:15 +0000954 if (0) {
Damien39c6c592013-11-09 20:15:48 +0000955 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
956 RNG_Cmd(ENABLE);
957 }
958
Damienf48cf672013-10-21 10:42:06 +0100959 // add some functions to the python namespace
Damiene9f1e502013-10-22 23:09:25 +0100960 {
961 py_obj_t m = py_module_new();
962 rt_store_attr(m, qstr_from_str_static("info"), rt_make_function_0(pyb_info));
Damien52851552013-12-11 00:40:15 +0000963 rt_store_attr(m, qstr_from_str_static("stop"), rt_make_function_0(pyb_stop));
964 rt_store_attr(m, qstr_from_str_static("standby"), rt_make_function_0(pyb_standby));
Damiene9f1e502013-10-22 23:09:25 +0100965 rt_store_attr(m, qstr_from_str_static("source_dir"), rt_make_function_1(pyb_source_dir));
966 rt_store_attr(m, qstr_from_str_static("main"), rt_make_function_1(pyb_main));
Damien94186c82013-10-23 00:02:06 +0100967 rt_store_attr(m, qstr_from_str_static("sync"), rt_make_function_0(pyb_sync));
Damiene9f1e502013-10-22 23:09:25 +0100968 rt_store_attr(m, qstr_from_str_static("gc"), rt_make_function_0(pyb_gc));
969 rt_store_attr(m, qstr_from_str_static("delay"), rt_make_function_1(pyb_delay));
970 rt_store_attr(m, qstr_from_str_static("led"), rt_make_function_1(pyb_led));
971 rt_store_attr(m, qstr_from_str_static("sw"), rt_make_function_0(pyb_sw));
Damien8fe84132013-11-30 15:06:24 +0000972 rt_store_attr(m, qstr_from_str_static("servo"), rt_make_function_2(pyb_servo_set));
Damien0c70f882013-11-03 18:30:57 +0000973 rt_store_attr(m, qstr_from_str_static("pwm"), rt_make_function_2(pyb_pwm_set));
Damien6f08f8c2013-10-23 22:17:26 +0100974 rt_store_attr(m, qstr_from_str_static("mma"), rt_make_function_0(pyb_mma_read));
Damien58a1b4c2013-10-25 20:53:54 +0100975 rt_store_attr(m, qstr_from_str_static("hid"), rt_make_function_1(pyb_hid_send_report));
Damien81289412013-10-26 02:06:37 +0100976 rt_store_attr(m, qstr_from_str_static("time"), rt_make_function_0(pyb_rtc_read));
Damien8f7491a2013-10-26 18:01:48 +0100977 rt_store_attr(m, qstr_from_str_static("uout"), rt_make_function_1(pyb_usart_send));
978 rt_store_attr(m, qstr_from_str_static("uin"), rt_make_function_0(pyb_usart_receive));
979 rt_store_attr(m, qstr_from_str_static("ustat"), rt_make_function_0(pyb_usart_status));
Damien39c6c592013-11-09 20:15:48 +0000980 rt_store_attr(m, qstr_from_str_static("rng"), rt_make_function_0(pyb_rng_get));
Damiend6b4c662013-12-06 00:41:33 +0000981 rt_store_attr(m, qstr_from_str_static("Led"), rt_make_function_1(pyb_Led));
Damien52851552013-12-11 00:40:15 +0000982 rt_store_attr(m, qstr_from_str_static("Servo"), rt_make_function_1(pyb_Servo));
Damiene9f1e502013-10-22 23:09:25 +0100983 rt_store_name(qstr_from_str_static("pyb"), m);
Damien0e496732013-11-03 14:53:34 +0000984
985 rt_store_name(qstr_from_str_static("open"), rt_make_function_2(pyb_io_open));
Damiene9f1e502013-10-22 23:09:25 +0100986 }
Damienf48cf672013-10-21 10:42:06 +0100987
Damiene9f1e502013-10-22 23:09:25 +0100988 // print a message to the LCD
989 lcd_print_str(" micro py board\n");
Damien00ff04f2013-10-19 14:40:54 +0100990
Damiend6b4c662013-12-06 00:41:33 +0000991 // check if user switch held (initiates reset of filesystem)
992 bool reset_filesystem = false;
993 if (sw_get()) {
994 reset_filesystem = true;
995 for (int i = 0; i < 50; i++) {
996 if (!sw_get()) {
997 reset_filesystem = false;
998 break;
999 }
1000 sys_tick_delay_ms(10);
1001 }
1002 }
1003
Damien00ff04f2013-10-19 14:40:54 +01001004 // local filesystem init
1005 {
1006 // try to mount the flash
1007 FRESULT res = f_mount(&fatfs0, "0:", 1);
Damiend6b4c662013-12-06 00:41:33 +00001008 if (!reset_filesystem && res == FR_OK) {
Damien00ff04f2013-10-19 14:40:54 +01001009 // mount sucessful
Damiend6b4c662013-12-06 00:41:33 +00001010 } else if (reset_filesystem || res == FR_NO_FILESYSTEM) {
Damien00ff04f2013-10-19 14:40:54 +01001011 // no filesystem, so create a fresh one
Damiend6b4c662013-12-06 00:41:33 +00001012 // TODO doesn't seem to work correctly when reset_filesystem is true...
Damien00ff04f2013-10-19 14:40:54 +01001013
1014 // LED on to indicate creation of LFS
1015 led_state(PYB_LED_R2, 1);
1016 uint32_t stc = sys_tick_counter;
1017
1018 res = f_mkfs("0:", 0, 0);
1019 if (res == FR_OK) {
1020 // success creating fresh LFS
1021 } else {
1022 __fatal_error("could not create LFS");
1023 }
1024
Damienafe12bc2013-10-19 18:13:48 +01001025 // keep LED on for at least 200ms
1026 sys_tick_wait_at_least(stc, 200);
Damien00ff04f2013-10-19 14:40:54 +01001027 led_state(PYB_LED_R2, 0);
1028 } else {
1029 __fatal_error("could not access LFS");
Damien4a175e12013-10-17 22:50:21 +01001030 }
Damien00ff04f2013-10-19 14:40:54 +01001031 }
1032
1033 // make sure we have a /boot.py
1034 {
1035 FILINFO fno;
1036 FRESULT res = f_stat("0:/boot.py", &fno);
1037 if (res == FR_OK) {
1038 if (fno.fattrib & AM_DIR) {
1039 // exists as a directory
1040 // TODO handle this case
1041 // see http://elm-chan.org/fsw/ff/img/app2.c for a "rm -rf" implementation
1042 } else {
1043 // exists as a file, good!
1044 }
1045 } else {
1046 // doesn't exist, create fresh file
1047
1048 // LED on to indicate creation of boot.py
1049 led_state(PYB_LED_R2, 1);
1050 uint32_t stc = sys_tick_counter;
1051
1052 FIL fp;
1053 f_open(&fp, "0:/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
1054 UINT n;
Damiene9f1e502013-10-22 23:09:25 +01001055 f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n);
Damien00ff04f2013-10-19 14:40:54 +01001056 // TODO check we could write n bytes
1057 f_close(&fp);
1058
Damienafe12bc2013-10-19 18:13:48 +01001059 // keep LED on for at least 200ms
1060 sys_tick_wait_at_least(stc, 200);
Damien00ff04f2013-10-19 14:40:54 +01001061 led_state(PYB_LED_R2, 0);
1062 }
1063 }
1064
Damien94186c82013-10-23 00:02:06 +01001065 // run /boot.py
1066 if (!do_file("0:/boot.py")) {
1067 flash_error(4);
1068 }
1069
Damiene9f1e502013-10-22 23:09:25 +01001070 // USB
1071 usb_init();
1072
Damien6f08f8c2013-10-23 22:17:26 +01001073 // MMA
Damienbd8e1102013-11-06 23:04:33 +00001074 if (first_soft_reset) {
Damien6f08f8c2013-10-23 22:17:26 +01001075 // init and reset address to zero
1076 mma_init();
1077 mma_start(MMA_ADDR, 1);
1078 mma_send_byte(0);
1079 mma_stop();
1080
1081 /*
1082 // read and print all 11 registers
1083 mma_start(MMA_ADDR, 1);
1084 mma_send_byte(0);
1085 mma_restart(MMA_ADDR, 0);
1086 for (int i = 0; i <= 0xa; i++) {
1087 int data;
1088 if (i == 0xa) {
1089 data = mma_read_nack();
1090 } else {
1091 data = mma_read_ack();
1092 }
1093 printf(" %02x", data);
1094 }
1095 printf("\n");
1096 */
1097
1098 // put into active mode
1099 mma_start(MMA_ADDR, 1);
1100 mma_send_byte(7); // mode
1101 mma_send_byte(1); // active mode
1102 mma_stop();
1103
1104 /*
1105 // infinite loop to read values
1106 for (;;) {
1107 sys_tick_delay_ms(500);
1108
1109 mma_start(MMA_ADDR, 1);
1110 mma_send_byte(0);
1111 mma_restart(MMA_ADDR, 0);
1112 for (int i = 0; i <= 3; i++) {
1113 int data;
1114 if (i == 3) {
1115 data = mma_read_nack();
1116 printf(" %02x\n", data);
1117 } else {
1118 data = mma_read_ack() & 0x3f;
1119 if (data & 0x20) {
1120 data |= ~0x1f;
1121 }
1122 printf(" % 2d", data);
1123 }
1124 }
1125 }
1126 */
1127 }
1128
Damien00ff04f2013-10-19 14:40:54 +01001129 // turn boot-up LED off
1130 led_state(PYB_LED_G1, 0);
1131
Damien94186c82013-10-23 00:02:06 +01001132 // run main script
1133 {
1134 vstr_t *vstr = vstr_new();
1135 vstr_add_str(vstr, "0:/");
1136 if (pyb_config_source_dir == 0) {
1137 vstr_add_str(vstr, "src");
1138 } else {
1139 vstr_add_str(vstr, qstr_str(pyb_config_source_dir));
1140 }
1141 vstr_add_char(vstr, '/');
1142 if (pyb_config_main == 0) {
1143 vstr_add_str(vstr, "main.py");
1144 } else {
1145 vstr_add_str(vstr, qstr_str(pyb_config_main));
1146 }
1147 if (!do_file(vstr_str(vstr))) {
1148 flash_error(3);
1149 }
1150 vstr_free(vstr);
1151 }
1152
Damien00ff04f2013-10-19 14:40:54 +01001153 //printf("init;al=%u\n", m_get_total_bytes_allocated()); // 1600, due to qstr_init
1154 //sys_tick_delay_ms(1000);
1155
Damiened656052013-10-13 00:42:20 +01001156 // Python!
Damien4b6e85c2013-10-21 09:56:56 +01001157 if (0) {
Damiened656052013-10-13 00:42:20 +01001158 //const char *pysrc = "def f():\n x=x+1\nprint(42)\n";
1159 const char *pysrc =
1160 // impl01.py
1161 /*
1162 "x = 0\n"
1163 "while x < 400:\n"
1164 " y = 0\n"
1165 " while y < 400:\n"
1166 " z = 0\n"
1167 " while z < 400:\n"
1168 " z = z + 1\n"
1169 " y = y + 1\n"
1170 " x = x + 1\n";
1171 */
1172 // impl02.py
Damien152568b2013-10-16 00:46:39 +01001173 /*
Damiened656052013-10-13 00:42:20 +01001174 "#@micropython.native\n"
1175 "def f():\n"
1176 " x = 0\n"
1177 " while x < 400:\n"
1178 " y = 0\n"
1179 " while y < 400:\n"
1180 " z = 0\n"
1181 " while z < 400:\n"
1182 " z = z + 1\n"
1183 " y = y + 1\n"
1184 " x = x + 1\n"
1185 "f()\n";
Damien152568b2013-10-16 00:46:39 +01001186 */
Damien0c5827f2013-10-22 21:13:36 +01001187 /*
Damiened656052013-10-13 00:42:20 +01001188 "print('in python!')\n"
1189 "x = 0\n"
1190 "while x < 4:\n"
1191 " pyb_led(True)\n"
1192 " pyb_delay(201)\n"
1193 " pyb_led(False)\n"
1194 " pyb_delay(201)\n"
Damienfa2162b2013-10-20 17:42:00 +01001195 " x += 1\n"
Damiened656052013-10-13 00:42:20 +01001196 "print('press me!')\n"
1197 "while True:\n"
1198 " pyb_led(pyb_sw())\n";
Damien0c5827f2013-10-22 21:13:36 +01001199 */
Damiened656052013-10-13 00:42:20 +01001200 /*
1201 // impl16.py
1202 "@micropython.asm_thumb\n"
1203 "def delay(r0):\n"
1204 " b(loop_entry)\n"
1205 " label(loop1)\n"
1206 " movw(r1, 55999)\n"
1207 " label(loop2)\n"
1208 " subs(r1, r1, 1)\n"
1209 " cmp(r1, 0)\n"
1210 " bgt(loop2)\n"
1211 " subs(r0, r0, 1)\n"
1212 " label(loop_entry)\n"
1213 " cmp(r0, 0)\n"
1214 " bgt(loop1)\n"
1215 "print('in python!')\n"
1216 "@micropython.native\n"
1217 "def flash(n):\n"
1218 " x = 0\n"
1219 " while x < n:\n"
1220 " pyb_led(True)\n"
1221 " delay(249)\n"
1222 " pyb_led(False)\n"
1223 " delay(249)\n"
1224 " x = x + 1\n"
1225 "flash(20)\n";
1226 */
Damien152568b2013-10-16 00:46:39 +01001227 // impl18.py
1228 /*
1229 "# basic exceptions\n"
1230 "x = 1\n"
1231 "try:\n"
1232 " x.a()\n"
1233 "except:\n"
1234 " print(x)\n";
1235 */
1236 // impl19.py
1237 "# for loop\n"
1238 "def f():\n"
1239 " for x in range(400):\n"
1240 " for y in range(400):\n"
1241 " for z in range(400):\n"
1242 " pass\n"
1243 "f()\n";
Damiened656052013-10-13 00:42:20 +01001244
Damienfa2162b2013-10-20 17:42:00 +01001245 py_lexer_str_buf_t py_lexer_str_buf;
1246 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 +01001247
Damienfa2162b2013-10-20 17:42:00 +01001248 // nalloc=1740;6340;6836 -> 140;4600;496 bytes for lexer, parser, compiler
1249 printf("lex; al=%u\n", m_get_total_bytes_allocated());
1250 sys_tick_delay_ms(1000);
1251 py_parse_node_t pn = py_parse(lex, PY_PARSE_FILE_INPUT);
1252 py_lexer_free(lex);
1253 if (pn != PY_PARSE_NODE_NULL) {
Damiened656052013-10-13 00:42:20 +01001254 printf("pars;al=%u\n", m_get_total_bytes_allocated());
Damien00ff04f2013-10-19 14:40:54 +01001255 sys_tick_delay_ms(1000);
Damiened656052013-10-13 00:42:20 +01001256 //parse_node_show(pn, 0);
Damienfa2162b2013-10-20 17:42:00 +01001257 bool comp_ok = py_compile(pn, false);
Damiened656052013-10-13 00:42:20 +01001258 printf("comp;al=%u\n", m_get_total_bytes_allocated());
Damien00ff04f2013-10-19 14:40:54 +01001259 sys_tick_delay_ms(1000);
Damiened656052013-10-13 00:42:20 +01001260
Damienfa2162b2013-10-20 17:42:00 +01001261 if (!comp_ok) {
1262 printf("compile error\n");
1263 } else {
Damiened656052013-10-13 00:42:20 +01001264 // execute it!
1265
Damiened656052013-10-13 00:42:20 +01001266 py_obj_t module_fun = rt_make_function_from_id(1);
1267
Damien152568b2013-10-16 00:46:39 +01001268 // flash once
Damien995b8aa2013-10-18 23:44:05 +01001269 led_state(PYB_LED_G1, 1);
Damien00ff04f2013-10-19 14:40:54 +01001270 sys_tick_delay_ms(100);
Damien995b8aa2013-10-18 23:44:05 +01001271 led_state(PYB_LED_G1, 0);
Damiened656052013-10-13 00:42:20 +01001272
Damien152568b2013-10-16 00:46:39 +01001273 nlr_buf_t nlr;
1274 if (nlr_push(&nlr) == 0) {
1275 py_obj_t ret = rt_call_function_0(module_fun);
1276 printf("done! got: ");
1277 py_obj_print(ret);
1278 printf("\n");
1279 nlr_pop();
1280 } else {
1281 // uncaught exception
1282 printf("exception: ");
1283 py_obj_print((py_obj_t)nlr.ret_val);
1284 printf("\n");
1285 }
1286
1287 // flash once
Damien995b8aa2013-10-18 23:44:05 +01001288 led_state(PYB_LED_G1, 1);
Damien00ff04f2013-10-19 14:40:54 +01001289 sys_tick_delay_ms(100);
Damien995b8aa2013-10-18 23:44:05 +01001290 led_state(PYB_LED_G1, 0);
Damien152568b2013-10-16 00:46:39 +01001291
Damien00ff04f2013-10-19 14:40:54 +01001292 sys_tick_delay_ms(1000);
Damiened656052013-10-13 00:42:20 +01001293 printf("nalloc=%u\n", m_get_total_bytes_allocated());
Damien00ff04f2013-10-19 14:40:54 +01001294 sys_tick_delay_ms(1000);
Damiened656052013-10-13 00:42:20 +01001295 }
1296 }
1297 }
Damiened656052013-10-13 00:42:20 +01001298
Damien58a1b4c2013-10-25 20:53:54 +01001299 // HID example
1300 if (0) {
1301 uint8_t data[4];
1302 data[0] = 0;
1303 data[1] = 1;
1304 data[2] = -2;
1305 data[3] = 0;
1306 for (;;) {
1307 if (sw_get()) {
1308 data[0] = 0x01; // 0x04 is middle, 0x02 is right
1309 } else {
1310 data[0] = 0x00;
1311 }
1312 mma_start(MMA_ADDR, 1);
1313 mma_send_byte(0);
1314 mma_restart(MMA_ADDR, 0);
1315 for (int i = 0; i <= 1; i++) {
1316 int v = mma_read_ack() & 0x3f;
1317 if (v & 0x20) {
1318 v |= ~0x1f;
1319 }
1320 data[1 + i] = v;
1321 }
1322 mma_read_nack();
1323 usb_hid_send_report(data);
1324 sys_tick_delay_ms(15);
1325 }
1326 }
1327
Damien065f8a52013-12-05 20:38:23 +00001328 // wifi
Damiend6b4c662013-12-06 00:41:33 +00001329 //pyb_wlan_init();
1330 //pyb_wlan_start();
Damien065f8a52013-12-05 20:38:23 +00001331
Damien4b6e85c2013-10-21 09:56:56 +01001332 do_repl();
1333
Damiened656052013-10-13 00:42:20 +01001334 // benchmark C version of impl02.py
1335 if (0) {
Damien995b8aa2013-10-18 23:44:05 +01001336 led_state(PYB_LED_G1, 1);
Damien00ff04f2013-10-19 14:40:54 +01001337 sys_tick_delay_ms(100);
Damien995b8aa2013-10-18 23:44:05 +01001338 led_state(PYB_LED_G1, 0);
Damiened656052013-10-13 00:42:20 +01001339 impl02_c_version();
Damien995b8aa2013-10-18 23:44:05 +01001340 led_state(PYB_LED_G1, 1);
Damien00ff04f2013-10-19 14:40:54 +01001341 sys_tick_delay_ms(100);
Damien995b8aa2013-10-18 23:44:05 +01001342 led_state(PYB_LED_G1, 0);
Damiened656052013-10-13 00:42:20 +01001343 }
1344
Damiened656052013-10-13 00:42:20 +01001345 // SD card testing
Damien7ee80ba2013-10-24 00:22:27 +01001346 if (1) {
1347 extern void sdio_init(void);
Damien8fe84132013-11-30 15:06:24 +00001348 //sdio_init();
Damiened656052013-10-13 00:42:20 +01001349 }
1350
Damien94186c82013-10-23 00:02:06 +01001351 printf("PYB: sync filesystems\n");
1352 pyb_sync();
1353
1354 printf("PYB: soft reboot\n");
Damienbd8e1102013-11-06 23:04:33 +00001355
1356 first_soft_reset = false;
Damiene9f1e502013-10-22 23:09:25 +01001357 goto soft_reset;
Damiened656052013-10-13 00:42:20 +01001358}
Damienfecee2b2013-11-02 16:41:51 +00001359
1360double __aeabi_f2d(float x) {
1361 // TODO
1362 return 0.0;
1363}
Damien0e496732013-11-03 14:53:34 +00001364
1365float __aeabi_d2f(double x) {
1366 // TODO
1367 return 0.0;
1368}
1369
1370double sqrt(double x) {
1371 // TODO
1372 return 0.0;
1373}
Damien39c6c592013-11-09 20:15:48 +00001374
1375machine_float_t machine_sqrt(machine_float_t x) {
1376 // TODO
1377 return x;
1378}