diff options
Diffstat (limited to 'stm')
-rw-r--r-- | stm/Makefile | 22 | ||||
-rw-r--r-- | stm/audio.c | 23 | ||||
-rw-r--r-- | stm/lcd.c | 53 | ||||
-rw-r--r-- | stm/led.c | 62 | ||||
-rw-r--r-- | stm/led.h | 2 | ||||
-rw-r--r-- | stm/lexerstm.c | 22 | ||||
-rw-r--r-- | stm/lexerstm.h | 8 | ||||
-rw-r--r-- | stm/main.c | 451 | ||||
-rw-r--r-- | stm/malloc0.c | 2 | ||||
-rw-r--r-- | stm/mpconfig.h (renamed from stm/mpyconfig.h) | 1 | ||||
-rw-r--r-- | stm/pybwlan.c | 77 | ||||
-rw-r--r-- | stm/servo.c | 160 | ||||
-rw-r--r-- | stm/servo.h | 5 | ||||
-rw-r--r-- | stm/stm32fxxx_it.c | 3 | ||||
-rw-r--r-- | stm/storage.c | 2 | ||||
-rw-r--r-- | stm/timer.c | 33 |
16 files changed, 511 insertions, 415 deletions
diff --git a/stm/Makefile b/stm/Makefile index 8817717950..1e0831159e 100644 --- a/stm/Makefile +++ b/stm/Makefile @@ -23,6 +23,7 @@ SRC_C = \ lexerstm.c \ led.c \ lcd.c \ + servo.c \ flash.c \ storage.c \ mma.c \ @@ -57,6 +58,25 @@ PY_O = \ runtime.o \ map.o \ obj.o \ + objbool.o \ + objboundmeth.o \ + objcell.o \ + objclass.o \ + objclosure.o \ + objcomplex.o \ + objdict.o \ + objexcept.o \ + objfloat.o \ + objfun.o \ + objgenerator.o \ + objinstance.o \ + objlist.o \ + objnone.o \ + objrange.o \ + objset.o \ + objstr.o \ + objtuple.o \ + objtype.o \ builtin.o \ vm.o \ repl.o \ @@ -150,7 +170,7 @@ $(BUILD)/%.o: $(CC3KSRC)/%.c $(BUILD)/%.o: $(PYSRC)/%.s $(AS) -o $@ $< -$(BUILD)/%.o: $(PYSRC)/%.c mpyconfig.h +$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h $(CC) $(CFLAGS) -c -o $@ $< $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h diff --git a/stm/audio.c b/stm/audio.c index 41614416e2..62d2ff2f86 100644 --- a/stm/audio.c +++ b/stm/audio.c @@ -6,9 +6,10 @@ #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "parse.h" #include "compile.h" +#include "obj.h" #include "runtime.h" #include "audio.h" @@ -44,22 +45,22 @@ void audio_drain(void) { } // direct access to DAC -py_obj_t pyb_audio_dac(py_obj_t val) { - DAC_SetChannel2Data(DAC_Align_8b_R, py_obj_get_int(val)); - return py_const_none; +mp_obj_t pyb_audio_dac(mp_obj_t val) { + DAC_SetChannel2Data(DAC_Align_8b_R, mp_obj_get_int(val)); + return mp_const_none; } -py_obj_t pyb_audio_is_full(void) { +mp_obj_t pyb_audio_is_full(void) { if (audio_is_full()) { - return py_const_true; + return mp_const_true; } else { - return py_const_false; + return mp_const_false; } } -py_obj_t pyb_audio_fill(py_obj_t val) { - audio_fill(py_obj_get_int(val)); - return py_const_none; +mp_obj_t pyb_audio_fill(mp_obj_t val) { + audio_fill(mp_obj_get_int(val)); + return mp_const_none; } void audio_init(void) { @@ -90,7 +91,7 @@ void audio_init(void) { // enable interrupt // Python interface - py_obj_t m = py_module_new(); + mp_obj_t m = mp_module_new(); rt_store_attr(m, qstr_from_str_static("dac"), rt_make_function_1(pyb_audio_dac)); rt_store_attr(m, qstr_from_str_static("is_full"), rt_make_function_0(pyb_audio_is_full)); rt_store_attr(m, qstr_from_str_static("fill"), rt_make_function_1(pyb_audio_fill)); @@ -3,9 +3,10 @@ #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "parse.h" #include "compile.h" +#include "obj.h" #include "runtime.h" #include "systick.h" @@ -88,16 +89,16 @@ static void lcd_data_out(uint8_t i) { // writes 8 vertical pixels // pos 0 is upper left, pos 1 is 8 pixels to right of that, pos 128 is 8 pixels below that -py_obj_t lcd_draw_pixel_8(py_obj_t py_pos, py_obj_t py_val) { - int pos = py_obj_get_int(py_pos); - int val = py_obj_get_int(py_val); +mp_obj_t lcd_draw_pixel_8(mp_obj_t mp_pos, mp_obj_t mp_val) { + int pos = mp_obj_get_int(mp_pos); + int val = mp_obj_get_int(mp_val); int page = pos / 128; int offset = pos - (page * 128); lcd_out(LCD_INSTR, 0xb0 | page); // page address set lcd_out(LCD_INSTR, 0x10 | ((offset >> 4) & 0x0f)); // column address set upper lcd_out(LCD_INSTR, 0x00 | (offset & 0x0f)); // column address set lower lcd_out(LCD_DATA, val); // write data - return py_const_none; + return mp_const_none; } #define LCD_BUF_W (16) @@ -112,45 +113,45 @@ int lcd_next_line; byte lcd_pix_buf[LCD_PIX_BUF_SIZE]; byte lcd_pix_buf2[LCD_PIX_BUF_SIZE]; -py_obj_t lcd_pix_clear(void) { +mp_obj_t lcd_pix_clear(void) { memset(lcd_pix_buf, 0, LCD_PIX_BUF_SIZE); memset(lcd_pix_buf2, 0, LCD_PIX_BUF_SIZE); - return py_const_none; + return mp_const_none; } -py_obj_t lcd_pix_get(py_obj_t py_x, py_obj_t py_y) { - int x = py_obj_get_int(py_x); - int y = py_obj_get_int(py_y); +mp_obj_t lcd_pix_get(mp_obj_t mp_x, mp_obj_t mp_y) { + int x = mp_obj_get_int(mp_x); + int y = mp_obj_get_int(mp_y); if (0 <= x && x <= 127 && 0 <= y && y <= 31) { uint byte_pos = x + 128 * ((uint)y >> 3); if (lcd_pix_buf[byte_pos] & (1 << (y & 7))) { - return py_obj_new_int(1); + return mp_obj_new_int(1); } } - return py_obj_new_int(0); + return mp_obj_new_int(0); } -py_obj_t lcd_pix_set(py_obj_t py_x, py_obj_t py_y) { - int x = py_obj_get_int(py_x); - int y = py_obj_get_int(py_y); +mp_obj_t lcd_pix_set(mp_obj_t mp_x, mp_obj_t mp_y) { + int x = mp_obj_get_int(mp_x); + int y = mp_obj_get_int(mp_y); if (0 <= x && x <= 127 && 0 <= y && y <= 31) { uint byte_pos = x + 128 * ((uint)y >> 3); lcd_pix_buf2[byte_pos] |= 1 << (y & 7); } - return py_const_none; + return mp_const_none; } -py_obj_t lcd_pix_reset(py_obj_t py_x, py_obj_t py_y) { - int x = py_obj_get_int(py_x); - int y = py_obj_get_int(py_y); +mp_obj_t lcd_pix_reset(mp_obj_t mp_x, mp_obj_t mp_y) { + int x = mp_obj_get_int(mp_x); + int y = mp_obj_get_int(mp_y); if (0 <= x && x <= 127 && 0 <= y && y <= 31) { uint byte_pos = x + 128 * ((uint)y >> 3); lcd_pix_buf2[byte_pos] &= ~(1 << (y & 7)); } - return py_const_none; + return mp_const_none; } -py_obj_t lcd_pix_show(void) { +mp_obj_t lcd_pix_show(void) { memcpy(lcd_pix_buf, lcd_pix_buf2, LCD_PIX_BUF_SIZE); for (uint page = 0; page < 4; page++) { lcd_out(LCD_INSTR, 0xb0 | page); // page address set @@ -160,12 +161,12 @@ py_obj_t lcd_pix_show(void) { lcd_out(LCD_DATA, lcd_pix_buf[i + 128 * page]); } } - return py_const_none; + return mp_const_none; } -py_obj_t lcd_print(py_obj_t text) { - lcd_print_str(qstr_str(py_obj_get_qstr(text))); - return py_const_none; +mp_obj_t lcd_print(mp_obj_t text) { + lcd_print_str(qstr_str(mp_obj_get_qstr(text))); + return mp_const_none; } void lcd_init(void) { @@ -219,7 +220,7 @@ void lcd_init(void) { lcd_next_line = 0; // Python interface - py_obj_t m = py_module_new(); + mp_obj_t m = mp_module_new(); rt_store_attr(m, qstr_from_str_static("lcd8"), rt_make_function_2(lcd_draw_pixel_8)); rt_store_attr(m, qstr_from_str_static("clear"), rt_make_function_0(lcd_pix_clear)); rt_store_attr(m, qstr_from_str_static("get"), rt_make_function_2(lcd_pix_get)); @@ -1,5 +1,10 @@ +#include <stdio.h> #include <stm32f4xx.h> #include <stm32f4xx_gpio.h> + +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" #include "led.h" #define PYB_LED_R_PORT (GPIOA) @@ -64,3 +69,60 @@ void led_toggle(pyb_led_t led) { port->BSRRH = pin; } } + +/******************************************************************************/ +/* Micro Python bindings */ + +typedef struct _pyb_led_obj_t { + mp_obj_base_t base; + uint led_id; +} pyb_led_obj_t; + +void led_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + pyb_led_obj_t *self = self_in; + print(env, "<LED %lu>", self->led_id); +} + +mp_obj_t led_obj_on(mp_obj_t self_in) { + pyb_led_obj_t *self = self_in; + switch (self->led_id) { + case 1: led_state(PYB_LED_G1, 1); break; + case 2: led_state(PYB_LED_G2, 1); break; + } + return mp_const_none; +} + +mp_obj_t led_obj_off(mp_obj_t self_in) { + pyb_led_obj_t *self = self_in; + switch (self->led_id) { + case 1: led_state(PYB_LED_G1, 0); break; + case 2: led_state(PYB_LED_G2, 0); break; + } + return mp_const_none; +} + +static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on); +static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off); + +static const mp_obj_type_t led_obj_type = { + { &mp_const_type }, + "Led", + led_obj_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + { "on", &led_obj_on_obj }, + { "off", &led_obj_off_obj }, + { NULL, NULL }, + } +}; + +mp_obj_t pyb_Led(mp_obj_t led_id) { + pyb_led_obj_t *o = m_new_obj(pyb_led_obj_t); + o->base.type = &led_obj_type; + o->led_id = mp_obj_get_int(led_id); + return o; +} @@ -8,3 +8,5 @@ typedef enum { void led_init(void); void led_state(pyb_led_t led, int state); void led_toggle(pyb_led_t led); + +mp_obj_t pyb_Led(mp_obj_t led_id); diff --git a/stm/lexerstm.c b/stm/lexerstm.c index 06ea04d1b9..4e99052242 100644 --- a/stm/lexerstm.c +++ b/stm/lexerstm.c @@ -7,37 +7,37 @@ #include "lexer.h" #include "lexerstm.h" -unichar str_buf_next_char(py_lexer_str_buf_t *sb) { +unichar str_buf_next_char(mp_lexer_str_buf_t *sb) { if (sb->src_cur < sb->src_end) { return *sb->src_cur++; } else { - return PY_LEXER_CHAR_EOF; + return MP_LEXER_CHAR_EOF; } } -void str_buf_free(py_lexer_str_buf_t *sb) { +void str_buf_free(mp_lexer_str_buf_t *sb) { if (sb->free) { m_free((char*)sb->src_beg); } } -py_lexer_t *py_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str, py_lexer_str_buf_t *sb) { +mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str, mp_lexer_str_buf_t *sb) { sb->free = free_str; sb->src_beg = str; sb->src_cur = str; sb->src_end = str + len; - return py_lexer_new(src_name, sb, (py_lexer_stream_next_char_t)str_buf_next_char, (py_lexer_stream_close_t)str_buf_free); + return mp_lexer_new(src_name, sb, (mp_lexer_stream_next_char_t)str_buf_next_char, (mp_lexer_stream_close_t)str_buf_free); } -unichar file_buf_next_char(py_lexer_file_buf_t *fb) { +unichar file_buf_next_char(mp_lexer_file_buf_t *fb) { if (fb->pos >= fb->len) { if (fb->len < sizeof(fb->buf)) { - return PY_LEXER_CHAR_EOF; + return MP_LEXER_CHAR_EOF; } else { UINT n; f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n); if (n == 0) { - return PY_LEXER_CHAR_EOF; + return MP_LEXER_CHAR_EOF; } fb->len = n; fb->pos = 0; @@ -46,11 +46,11 @@ unichar file_buf_next_char(py_lexer_file_buf_t *fb) { return fb->buf[fb->pos++]; } -void file_buf_close(py_lexer_file_buf_t *fb) { +void file_buf_close(mp_lexer_file_buf_t *fb) { f_close(&fb->fp); } -py_lexer_t *py_lexer_new_from_file(const char *filename, py_lexer_file_buf_t *fb) { +mp_lexer_t *mp_lexer_new_from_file(const char *filename, mp_lexer_file_buf_t *fb) { FRESULT res = f_open(&fb->fp, filename, FA_READ); if (res != FR_OK) { return NULL; @@ -59,5 +59,5 @@ py_lexer_t *py_lexer_new_from_file(const char *filename, py_lexer_file_buf_t *fb f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n); fb->len = n; fb->pos = 0; - return py_lexer_new(filename, fb, (py_lexer_stream_next_char_t)file_buf_next_char, (py_lexer_stream_close_t)file_buf_close); + return mp_lexer_new(filename, fb, (mp_lexer_stream_next_char_t)file_buf_next_char, (mp_lexer_stream_close_t)file_buf_close); } diff --git a/stm/lexerstm.h b/stm/lexerstm.h index f57d1faa9d..7e090898a2 100644 --- a/stm/lexerstm.h +++ b/stm/lexerstm.h @@ -3,14 +3,14 @@ typedef struct _py_lexer_str_buf_t { const char *src_beg; // beginning of source const char *src_cur; // current location in source const char *src_end; // end (exclusive) of source -} py_lexer_str_buf_t; +} mp_lexer_str_buf_t; typedef struct _py_lexer_file_buf_t { FIL fp; char buf[20]; uint16_t len; uint16_t pos; -} py_lexer_file_buf_t; +} mp_lexer_file_buf_t; -py_lexer_t *py_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str, py_lexer_str_buf_t *sb); -py_lexer_t *py_lexer_new_from_file(const char *filename, py_lexer_file_buf_t *fb); +mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str, mp_lexer_str_buf_t *sb); +mp_lexer_t *mp_lexer_new_from_file(const char *filename, mp_lexer_file_buf_t *fb); diff --git a/stm/main.c b/stm/main.c index a262a917e7..f45e899854 100644 --- a/stm/main.c +++ b/stm/main.c @@ -13,16 +13,27 @@ #include "std.h" #include "misc.h" -#include "mpyconfig.h" +#include "ff.h" +#include "mpconfig.h" +#include "nlr.h" +#include "misc.h" +#include "lexer.h" +#include "lexerstm.h" +#include "parse.h" +#include "compile.h" +#include "obj.h" +#include "runtime0.h" +#include "runtime.h" +#include "repl.h" #include "gc.h" #include "systick.h" #include "led.h" +#include "servo.h" #include "lcd.h" #include "storage.h" #include "mma.h" #include "usart.h" #include "usb.h" -#include "ff.h" #include "timer.h" #include "audio.h" #include "pybwlan.h" @@ -114,128 +125,43 @@ void __fatal_error(const char *msg) { } } -#include "nlr.h" -#include "misc.h" -#include "lexer.h" -#include "lexerstm.h" -#include "mpyconfig.h" -#include "parse.h" -#include "compile.h" -#include "runtime.h" -#include "obj.h" -#include "repl.h" - static qstr pyb_config_source_dir = 0; static qstr pyb_config_main = 0; -py_obj_t pyb_source_dir(py_obj_t source_dir) { - pyb_config_source_dir = py_obj_get_qstr(source_dir); - return py_const_none; +mp_obj_t pyb_source_dir(mp_obj_t source_dir) { + pyb_config_source_dir = mp_obj_get_qstr(source_dir); + return mp_const_none; } -py_obj_t pyb_main(py_obj_t main) { - pyb_config_main = py_obj_get_qstr(main); - return py_const_none; +mp_obj_t pyb_main(mp_obj_t main) { + pyb_config_main = mp_obj_get_qstr(main); + return mp_const_none; } // sync all file systems -py_obj_t pyb_sync(void) { +mp_obj_t pyb_sync(void) { storage_flush(); - return py_const_none; + return mp_const_none; } -py_obj_t pyb_delay(py_obj_t count) { - sys_tick_delay_ms(py_obj_get_int(count)); - return py_const_none; +mp_obj_t pyb_delay(mp_obj_t count) { + sys_tick_delay_ms(mp_obj_get_int(count)); + return mp_const_none; } -py_obj_t pyb_led(py_obj_t state) { +mp_obj_t pyb_led(mp_obj_t state) { led_state(PYB_LED_G1, rt_is_true(state)); return state; } -void led_obj_print(py_obj_t self) { - machine_uint_t led_id; - py_user_get_data(self, &led_id, NULL); - printf("<LED %lu>", led_id); -} - -py_obj_t led_obj_on(py_obj_t self) { - machine_uint_t led_id; - py_user_get_data(self, &led_id, NULL); - switch (led_id) { - case 1: led_state(PYB_LED_G1, 1); break; - case 2: led_state(PYB_LED_G2, 1); break; - } - return py_const_none; -} - -py_obj_t led_obj_off(py_obj_t self) { - machine_uint_t led_id; - py_user_get_data(self, &led_id, NULL); - switch (led_id) { - case 1: led_state(PYB_LED_G1, 0); break; - case 2: led_state(PYB_LED_G2, 0); break; - } - return py_const_none; -} - -const py_user_info_t led_obj_info = { - "Led", - led_obj_print, - { - {"on", 0, led_obj_on}, - {"off", 0, led_obj_off}, - {NULL, 0, NULL}, - } -}; - -py_obj_t pyb_Led(py_obj_t led_id) { - return py_obj_new_user(&led_obj_info, (machine_uint_t)py_obj_get_int(led_id), 0); -} - -py_obj_t pyb_sw(void) { +mp_obj_t pyb_sw(void) { if (sw_get()) { - return py_const_true; + return mp_const_true; } else { - return py_const_false; + return mp_const_false; } } -void servo_obj_print(py_obj_t self) { - machine_uint_t servo_id; - py_user_get_data(self, &servo_id, NULL); - printf("<Servo %lu>", servo_id); -} - -py_obj_t servo_obj_angle(py_obj_t self, py_obj_t angle) { - machine_uint_t servo_id; - py_user_get_data(self, &servo_id, NULL); - machine_int_t v = 152 + 85.0 * py_obj_get_float(angle) / 90.0; - if (v < 65) { v = 65; } - if (v > 210) { v = 210; } - switch (servo_id) { - case 1: TIM2->CCR1 = v; break; - case 2: TIM2->CCR2 = v; break; - case 3: TIM2->CCR3 = v; break; - case 4: TIM2->CCR4 = v; break; - } - return py_const_none; -} - -const py_user_info_t servo_obj_info = { - "Servo", - servo_obj_print, - { - {"angle", 1, servo_obj_angle}, - {NULL, 0, NULL}, - } -}; - -py_obj_t pyb_Servo(py_obj_t servo_id) { - return py_obj_new_user(&servo_obj_info, (machine_uint_t)py_obj_get_int(servo_id), 0); -} - /* void g(uint i) { printf("g:%d\n", i); @@ -306,13 +232,13 @@ static const char *help_text = ; // get some help about available functions -static py_obj_t pyb_help(void) { +static mp_obj_t pyb_help(void) { printf("%s", help_text); - return py_const_none; + return mp_const_none; } // get lots of info about the board -static py_obj_t pyb_info(void) { +static mp_obj_t pyb_info(void) { // get and print unique id; 96 bits { byte *id = (byte*)0x1fff7a10; @@ -364,14 +290,14 @@ static py_obj_t pyb_info(void) { printf("LFS free: %u bytes\n", (uint)(nclst * fatfs->csize * 512)); } - return py_const_none; + return mp_const_none; } // SD card test -static py_obj_t pyb_sd_test(void) { +static mp_obj_t pyb_sd_test(void) { extern void sdio_init(void); sdio_init(); - return py_const_none; + return mp_const_none; } static void SYSCLKConfig_STOP(void) { @@ -398,7 +324,7 @@ static void SYSCLKConfig_STOP(void) { } } -static py_obj_t pyb_stop(void) { +static mp_obj_t pyb_stop(void) { PWR_EnterSTANDBYMode(); //PWR_FlashPowerDownCmd(ENABLE); don't know what the logic is with this @@ -411,28 +337,28 @@ static py_obj_t pyb_stop(void) { //PWR_FlashPowerDownCmd(DISABLE); - return py_const_none; + return mp_const_none; } -static py_obj_t pyb_standby(void) { +static mp_obj_t pyb_standby(void) { PWR_EnterSTANDBYMode(); - return py_const_none; + return mp_const_none; } -py_obj_t pyb_usart_send(py_obj_t data) { - usart_tx_char(py_obj_get_int(data)); - return py_const_none; +mp_obj_t pyb_usart_send(mp_obj_t data) { + usart_tx_char(mp_obj_get_int(data)); + return mp_const_none; } -py_obj_t pyb_usart_receive(void) { - return py_obj_new_int(usart_rx_char()); +mp_obj_t pyb_usart_receive(void) { + return mp_obj_new_int(usart_rx_char()); } -py_obj_t pyb_usart_status(void) { +mp_obj_t pyb_usart_status(void) { if (usart_rx_any()) { - return py_const_true; + return mp_const_true; } else { - return py_const_false; + return mp_const_false; } } @@ -544,7 +470,7 @@ void do_repl(void) { continue; } - if (py_repl_is_compound_stmt(vstr_str(&line))) { + if (mp_repl_is_compound_stmt(vstr_str(&line))) { for (;;) { vstr_add_char(&line, '\n'); int len = vstr_len(&line); @@ -556,16 +482,16 @@ void do_repl(void) { } } - py_lexer_str_buf_t sb; - py_lexer_t *lex = py_lexer_new_from_str_len("<stdin>", vstr_str(&line), vstr_len(&line), false, &sb); - py_parse_node_t pn = py_parse(lex, PY_PARSE_SINGLE_INPUT); - py_lexer_free(lex); + mp_lexer_str_buf_t sb; + mp_lexer_t *lex = mp_lexer_new_from_str_len("<stdin>", vstr_str(&line), vstr_len(&line), false, &sb); + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT); + mp_lexer_free(lex); - if (pn != PY_PARSE_NODE_NULL) { - bool comp_ok = py_compile(pn, true); + if (pn != MP_PARSE_NODE_NULL) { + bool comp_ok = mp_compile(pn, true); if (comp_ok) { - py_obj_t module_fun = rt_make_function_from_id(1); - if (module_fun != py_const_none) { + mp_obj_t module_fun = rt_make_function_from_id(1); + if (module_fun != mp_const_none) { nlr_buf_t nlr; uint32_t start = sys_tick_counter; if (nlr_push(&nlr) == 0) { @@ -578,7 +504,7 @@ void do_repl(void) { } } else { // uncaught exception - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); } } @@ -590,28 +516,28 @@ void do_repl(void) { } bool do_file(const char *filename) { - py_lexer_file_buf_t fb; - py_lexer_t *lex = py_lexer_new_from_file(filename, &fb); + mp_lexer_file_buf_t fb; + mp_lexer_t *lex = mp_lexer_new_from_file(filename, &fb); if (lex == NULL) { printf("could not open file '%s' for reading\n", filename); return false; } - py_parse_node_t pn = py_parse(lex, PY_PARSE_FILE_INPUT); - py_lexer_free(lex); + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT); + mp_lexer_free(lex); - if (pn == PY_PARSE_NODE_NULL) { + if (pn == MP_PARSE_NODE_NULL) { return false; } - bool comp_ok = py_compile(pn, false); + bool comp_ok = mp_compile(pn, false); if (!comp_ok) { return false; } - py_obj_t module_fun = rt_make_function_from_id(1); - if (module_fun == py_const_none) { + mp_obj_t module_fun = rt_make_function_from_id(1); + if (module_fun == mp_const_none) { return false; } @@ -622,7 +548,7 @@ bool do_file(const char *filename) { return true; } else { // uncaught exception - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); return false; } @@ -655,115 +581,16 @@ void gc_collect(void) { } } -py_obj_t pyb_gc(void) { +mp_obj_t pyb_gc(void) { gc_collect(); - return py_const_none; -} - -// PWM -// TIM2 and TIM5 have CH1, CH2, CH3, CH4 on PA0-PA3 respectively -// they are both 32-bit counters -// 16-bit prescaler -// TIM2_CH3 also on PB10 (used below) -void servo_init(void) { - // TIM2 clock enable - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); - - // for PB10 - /* - // GPIOB Configuration: TIM2_CH3 (PB10) - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - // Connect TIM2 pins to AF1 - GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_TIM2); - */ - - // for PA0, PA1, PA2, PA3 - { - // GPIOA Configuration: TIM2_CH0, TIM2_CH1 (PA0, PA1) - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - // Connect TIM2 pins to AF1 - GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2); - } - - // Compute the prescaler value so TIM2 runs at 100kHz - uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 100000) - 1; - - // Time base configuration - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - TIM_TimeBaseStructure.TIM_Period = 2000; // timer cycles at 50Hz - TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; - TIM_TimeBaseStructure.TIM_ClockDivision = 0; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); - - // PWM Mode configuration - TIM_OCInitTypeDef TIM_OCInitStructure; - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_Pulse = 150; // units of 10us - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; - TIM_OC1Init(TIM2, &TIM_OCInitStructure); // channel 1 - TIM_OC2Init(TIM2, &TIM_OCInitStructure); // channel 2 - TIM_OC3Init(TIM2, &TIM_OCInitStructure); // channel 3 - TIM_OC4Init(TIM2, &TIM_OCInitStructure); // channel 4 - - // ? - TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 1 - TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 2 - TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 3 - TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 4 - - // ? - TIM_ARRPreloadConfig(TIM2, ENABLE); - - // TIM2 enable counter - TIM_Cmd(TIM2, ENABLE); -} - -py_obj_t pyb_servo_set(py_obj_t port, py_obj_t value) { - int p = py_obj_get_int(port); - int v = py_obj_get_int(value); - if (v < 50) { v = 50; } - if (v > 250) { v = 250; } - switch (p) { - case 1: TIM2->CCR1 = v; break; - case 2: TIM2->CCR2 = v; break; - case 3: TIM2->CCR3 = v; break; - case 4: TIM2->CCR4 = v; break; - } - return py_const_none; -} - -py_obj_t pyb_pwm_set(py_obj_t period, py_obj_t pulse) { - int pe = py_obj_get_int(period); - int pu = py_obj_get_int(pulse); - TIM2->ARR = pe; - TIM2->CCR3 = pu; - return py_const_none; + return mp_const_none; } #define MMA_ADDR (0x4c) int mma_buf[12]; -py_obj_t pyb_mma_read(void) { +mp_obj_t pyb_mma_read(void) { for (int i = 0; i <= 6; i += 3) { mma_buf[0 + i] = mma_buf[0 + i + 3]; mma_buf[1 + i] = mma_buf[1 + i + 3]; @@ -782,24 +609,24 @@ py_obj_t pyb_mma_read(void) { } int jolt_info = mma_read_nack(); - py_obj_t data[4]; - data[0] = py_obj_new_int(jolt_info); - data[1] = py_obj_new_int(mma_buf[2] + mma_buf[5] + mma_buf[8] + mma_buf[11]); - data[2] = py_obj_new_int(mma_buf[1] + mma_buf[4] + mma_buf[7] + mma_buf[10]); - data[3] = py_obj_new_int(mma_buf[0] + mma_buf[3] + mma_buf[6] + mma_buf[9]); + mp_obj_t data[4]; + data[0] = mp_obj_new_int(jolt_info); + data[1] = mp_obj_new_int(mma_buf[2] + mma_buf[5] + mma_buf[8] + mma_buf[11]); + data[2] = mp_obj_new_int(mma_buf[1] + mma_buf[4] + mma_buf[7] + mma_buf[10]); + data[3] = mp_obj_new_int(mma_buf[0] + mma_buf[3] + mma_buf[6] + mma_buf[9]); return rt_build_tuple(4, data); // items in reverse order in data } -py_obj_t pyb_hid_send_report(py_obj_t arg) { - py_obj_t *items = py_obj_get_array_fixed_n(arg, 4); +mp_obj_t pyb_hid_send_report(mp_obj_t arg) { + mp_obj_t *items = mp_obj_get_array_fixed_n(arg, 4); uint8_t data[4]; - data[0] = py_obj_get_int(items[0]); - data[1] = py_obj_get_int(items[1]); - data[2] = py_obj_get_int(items[2]); - data[3] = py_obj_get_int(items[3]); + data[0] = mp_obj_get_int(items[0]); + data[1] = mp_obj_get_int(items[1]); + data[2] = mp_obj_get_int(items[2]); + data[3] = mp_obj_get_int(items[3]); usb_hid_send_report(data); - return py_const_none; + return mp_const_none; } static void rtc_init(void) { @@ -855,90 +682,102 @@ static void rtc_init(void) { //RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2); } -py_obj_t pyb_rtc_read(void) { +mp_obj_t pyb_rtc_read(void) { RTC_TimeTypeDef RTC_TimeStructure; RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure); printf("%02d:%02d:%02d\n", RTC_TimeStructure.RTC_Hours, RTC_TimeStructure.RTC_Minutes, RTC_TimeStructure.RTC_Seconds); - return py_const_none; + return mp_const_none; } -void file_obj_print(py_obj_t o) { - FIL *fp; - py_user_get_data(o, (machine_uint_t*)&fp, NULL); - printf("<file %p>", fp); +typedef struct _pyb_file_obj_t { + mp_obj_base_t base; + FIL fp; +} pyb_file_obj_t; + +void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + printf("<file %p>", self_in); } -py_obj_t file_obj_read(py_obj_t self, py_obj_t arg) { - FIL *fp; - py_user_get_data(self, (machine_uint_t*)&fp, NULL); - int n = py_obj_get_int(arg); +mp_obj_t file_obj_read(mp_obj_t self_in, mp_obj_t arg) { + pyb_file_obj_t *self = self_in; + int n = mp_obj_get_int(arg); char *buf = m_new(char, n + 1); UINT n_out; - f_read(fp, buf, n, &n_out); + f_read(&self->fp, buf, n, &n_out); buf[n_out] = 0; - return py_obj_new_str(qstr_from_str_take(buf)); + return mp_obj_new_str(qstr_from_str_take(buf)); } -py_obj_t file_obj_write(py_obj_t self, py_obj_t arg) { - FIL *fp; - py_user_get_data(self, (machine_uint_t*)&fp, NULL); - const char *s = qstr_str(py_obj_get_qstr(arg)); +mp_obj_t file_obj_write(mp_obj_t self_in, mp_obj_t arg) { + pyb_file_obj_t *self = self_in; + const char *s = qstr_str(mp_obj_get_qstr(arg)); UINT n_out; - FRESULT res = f_write(fp, s, strlen(s), &n_out); + FRESULT res = f_write(&self->fp, s, strlen(s), &n_out); if (res != FR_OK) { printf("File error: could not write to file; error code %d\n", res); } else if (n_out != strlen(s)) { printf("File error: could not write all data to file; wrote %d / %d bytes\n", n_out, strlen(s)); } - return py_const_none; + return mp_const_none; } -py_obj_t file_obj_close(py_obj_t self) { - FIL *fp; - py_user_get_data(self, (machine_uint_t*)&fp, NULL); - f_close(fp); - return py_const_none; +mp_obj_t file_obj_close(mp_obj_t self_in) { + pyb_file_obj_t *self = self_in; + f_close(&self->fp); + return mp_const_none; } +static MP_DEFINE_CONST_FUN_OBJ_2(file_obj_read_obj, file_obj_read); +static MP_DEFINE_CONST_FUN_OBJ_2(file_obj_write_obj, file_obj_write); +static MP_DEFINE_CONST_FUN_OBJ_1(file_obj_close_obj, file_obj_close); + // TODO gc hook to close the file if not already closed -const py_user_info_t file_obj_info = { + +static const mp_obj_type_t file_obj_type = { + { &mp_const_type }, "File", - file_obj_print, - { - {"read", 1, file_obj_read}, - {"write", 1, file_obj_write}, - {"close", 0, file_obj_close}, - {NULL, 0, NULL}, + file_obj_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + { "read", &file_obj_read_obj }, + { "write", &file_obj_write_obj }, + { "close", &file_obj_close_obj }, + {NULL, NULL}, } }; -py_obj_t pyb_io_open(py_obj_t o_filename, py_obj_t o_mode) { - const char *filename = qstr_str(py_obj_get_qstr(o_filename)); - const char *mode = qstr_str(py_obj_get_qstr(o_mode)); - FIL *fp = m_new(FIL, 1); +mp_obj_t pyb_io_open(mp_obj_t o_filename, mp_obj_t o_mode) { + const char *filename = qstr_str(mp_obj_get_qstr(o_filename)); + const char *mode = qstr_str(mp_obj_get_qstr(o_mode)); + pyb_file_obj_t *self = m_new_obj(pyb_file_obj_t); + self->base.type = &file_obj_type; if (mode[0] == 'r') { // open for reading - FRESULT res = f_open(fp, filename, FA_READ); + FRESULT res = f_open(&self->fp, filename, FA_READ); if (res != FR_OK) { printf("FileNotFoundError: [Errno 2] No such file or directory: '%s'\n", filename); - return py_const_none; + return mp_const_none; } } else if (mode[0] == 'w') { // open for writing, truncate the file first - FRESULT res = f_open(fp, filename, FA_WRITE | FA_CREATE_ALWAYS); + FRESULT res = f_open(&self->fp, filename, FA_WRITE | FA_CREATE_ALWAYS); if (res != FR_OK) { printf("?FileError: could not create file: '%s'\n", filename); - return py_const_none; + return mp_const_none; } } else { printf("ValueError: invalid mode: '%s'\n", mode); - return py_const_none; + return mp_const_none; } - return py_obj_new_user(&file_obj_info, (machine_uint_t)fp, 0); + return self; } -py_obj_t pyb_rng_get(void) { - return py_obj_new_int(RNG_GetRandomNumber() >> 16); +mp_obj_t pyb_rng_get(void) { + return mp_obj_new_int(RNG_GetRandomNumber() >> 16); } int main(void) { @@ -1015,7 +854,7 @@ soft_reset: { rt_store_name(qstr_from_str_static("help"), rt_make_function_0(pyb_help)); - py_obj_t m = py_module_new(); + mp_obj_t m = mp_module_new(); rt_store_attr(m, qstr_from_str_static("info"), rt_make_function_0(pyb_info)); rt_store_attr(m, qstr_from_str_static("sd_test"), rt_make_function_0(pyb_sd_test)); rt_store_attr(m, qstr_from_str_static("stop"), rt_make_function_0(pyb_stop)); @@ -1312,19 +1151,19 @@ soft_reset: " pass\n" "f()\n"; - py_lexer_str_buf_t py_lexer_str_buf; - py_lexer_t *lex = py_lexer_new_from_str_len("<stdin>", pysrc, strlen(pysrc), false, &py_lexer_str_buf); + mp_lexer_str_buf_t mp_lexer_str_buf; + mp_lexer_t *lex = mp_lexer_new_from_str_len("<stdin>", pysrc, strlen(pysrc), false, &mp_lexer_str_buf); // nalloc=1740;6340;6836 -> 140;4600;496 bytes for lexer, parser, compiler printf("lex; al=%u\n", m_get_total_bytes_allocated()); sys_tick_delay_ms(1000); - py_parse_node_t pn = py_parse(lex, PY_PARSE_FILE_INPUT); - py_lexer_free(lex); - if (pn != PY_PARSE_NODE_NULL) { + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT); + mp_lexer_free(lex); + if (pn != MP_PARSE_NODE_NULL) { printf("pars;al=%u\n", m_get_total_bytes_allocated()); sys_tick_delay_ms(1000); //parse_node_show(pn, 0); - bool comp_ok = py_compile(pn, false); + bool comp_ok = mp_compile(pn, false); printf("comp;al=%u\n", m_get_total_bytes_allocated()); sys_tick_delay_ms(1000); @@ -1333,7 +1172,7 @@ soft_reset: } else { // execute it! - py_obj_t module_fun = rt_make_function_from_id(1); + mp_obj_t module_fun = rt_make_function_from_id(1); // flash once led_state(PYB_LED_G1, 1); @@ -1342,15 +1181,15 @@ soft_reset: nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { - py_obj_t ret = rt_call_function_0(module_fun); + mp_obj_t ret = rt_call_function_0(module_fun); printf("done! got: "); - py_obj_print(ret); + mp_obj_print(ret); printf("\n"); nlr_pop(); } else { // uncaught exception printf("exception: "); - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); } diff --git a/stm/malloc0.c b/stm/malloc0.c index 7157252ed2..7e3f620db2 100644 --- a/stm/malloc0.c +++ b/stm/malloc0.c @@ -1,6 +1,6 @@ #include <stdint.h> #include "std.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "gc.h" #if 0 diff --git a/stm/mpyconfig.h b/stm/mpconfig.h index 3fa3ac6524..1f9529e11b 100644 --- a/stm/mpyconfig.h +++ b/stm/mpconfig.h @@ -13,6 +13,7 @@ typedef int32_t machine_int_t; // must be pointer size typedef uint32_t machine_uint_t; // must be pointer size typedef void *machine_ptr_t; // must be of pointer size +typedef const void *machine_const_ptr_t; // must be of pointer size typedef float machine_float_t; machine_float_t machine_sqrt(machine_float_t x); diff --git a/stm/pybwlan.c b/stm/pybwlan.c index 3d1f216f88..863c241b60 100644 --- a/stm/pybwlan.c +++ b/stm/pybwlan.c @@ -11,7 +11,7 @@ #include "std.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "systick.h" #include "nlr.h" @@ -19,6 +19,7 @@ #include "lexer.h" #include "parse.h" #include "compile.h" +#include "obj.h" #include "runtime.h" #include "cc3k/ccspi.h" @@ -28,27 +29,27 @@ #include "cc3k/wlan.h" #include "cc3k/nvmem.h" -py_obj_t pyb_wlan_connect(int n_args, const py_obj_t *args) { +mp_obj_t pyb_wlan_connect(int n_args, const mp_obj_t *args) { const char *ap; const char *key; if (n_args == 2) { - ap = qstr_str(py_obj_get_qstr(args[0])); - key = qstr_str(py_obj_get_qstr(args[1])); + ap = qstr_str(mp_obj_get_qstr(args[0])); + key = qstr_str(mp_obj_get_qstr(args[1])); } else { - ap = "Rama3"; - key = "underthechristmastree"; + ap = "your-ssid"; + key = "your-password"; } // might want to set wlan_ioctl_set_connection_policy int ret = wlan_connect(WLAN_SEC_WPA2, ap, strlen(ap), NULL, (byte*)key, strlen(key)); - return py_obj_new_int(ret); + return mp_obj_new_int(ret); } -py_obj_t pyb_wlan_disconnect(void) { +mp_obj_t pyb_wlan_disconnect(void) { int ret = wlan_disconnect(); - return py_obj_new_int(ret); + return mp_obj_new_int(ret); } -py_obj_t decode_addr(unsigned char *ip, int nBytes) { +mp_obj_t decode_addr(unsigned char *ip, int nBytes) { char data[64] = ""; if (nBytes == 4) { snprintf(data, 64, "%u.%u.%u.%u", ip[3], ip[2], ip[1], ip[0]); @@ -57,21 +58,21 @@ py_obj_t decode_addr(unsigned char *ip, int nBytes) { } else if (nBytes == 32) { snprintf(data, 64, "%s", ip); } - return py_obj_new_str(qstr_from_strn_copy(data, strlen(data))); + return mp_obj_new_str(qstr_from_strn_copy(data, strlen(data))); } -void _wlan_getIP_get_address(py_obj_t object, qstr q_attr, unsigned char *ip, int nBytes) { +void _wlan_getIP_get_address(mp_obj_t object, qstr q_attr, unsigned char *ip, int nBytes) { rt_store_attr(object, q_attr, decode_addr(ip, nBytes)); } -py_obj_t pyb_wlan_get_ip(void) { +mp_obj_t pyb_wlan_get_ip(void) { tNetappIpconfigRetArgs ipconfig; netapp_ipconfig(&ipconfig); /* If byte 1 is 0 we don't have a valid address */ - if (ipconfig.aucIP[3] == 0) return py_const_none; + if (ipconfig.aucIP[3] == 0) return mp_const_none; - py_obj_t data = py_module_new(); // TODO should really be a class + mp_obj_t data = mp_module_new(); // TODO should really be a class _wlan_getIP_get_address(data, qstr_from_str_static("ip"), &ipconfig.aucIP[0], 4); _wlan_getIP_get_address(data, qstr_from_str_static("subnet"), &ipconfig.aucSubnetMask[0], 4); _wlan_getIP_get_address(data, qstr_from_str_static("gateway"), &ipconfig.aucDefaultGateway[0], 4); @@ -84,16 +85,16 @@ py_obj_t pyb_wlan_get_ip(void) { } uint32_t last_ip = 0; // XXX such a hack! -py_obj_t pyb_wlan_get_host(py_obj_t host_name) { - const char *host = qstr_str(py_obj_get_qstr(host_name)); +mp_obj_t pyb_wlan_get_host(mp_obj_t host_name) { + const char *host = qstr_str(mp_obj_get_qstr(host_name)); uint32_t ip; if (gethostbyname(host, strlen(host), &ip) < 0) { printf("gethostbyname failed\n"); - return py_const_none; + return mp_const_none; } if (ip == 0) { // unknown host - return py_const_none; + return mp_const_none; } last_ip = ip; byte ip_data[4]; @@ -104,19 +105,17 @@ py_obj_t pyb_wlan_get_host(py_obj_t host_name) { return decode_addr(ip_data, 4); } -py_obj_t py_obj_new_exception_2(qstr, const char *, void*, void*); - -py_obj_t pyb_wlan_http_get(py_obj_t host_name, py_obj_t host_path) { - if (host_name == py_const_none) { +mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) { + if (host_name == mp_const_none) { last_ip = (192 << 24) | (168 << 16) | (0 << 8) | (3); } else { - if (pyb_wlan_get_host(host_name) == py_const_none) { - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "unknown host", NULL, NULL)); + if (pyb_wlan_get_host(host_name) == mp_const_none) { + nlr_jump(mp_obj_new_exception_msg(qstr_from_str_static("WlanError"), "unknown host")); } } int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sd < 0) { - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd, NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd)); } //printf("socket seemed to work\n"); //sys_tick_delay_ms(200); @@ -127,13 +126,13 @@ py_obj_t pyb_wlan_http_get(py_obj_t host_name, py_obj_t host_path) { remote.sin_addr.s_addr = htonl(last_ip); int ret = connect(sd, (sockaddr*)&remote, sizeof(sockaddr)); if (ret != 0) { - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "connect failed: %d", (void*)ret, NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "connect failed: %d", (void*)ret)); } //printf("connect seemed to work\n"); //sys_tick_delay_ms(200); vstr_t *vstr = vstr_new(); - vstr_printf(vstr, "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: PYBv2\r\n\r\n", qstr_str(py_obj_get_qstr(host_path)), qstr_str(py_obj_get_qstr(host_name))); + vstr_printf(vstr, "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: PYBv2\r\n\r\n", qstr_str(mp_obj_get_qstr(host_path)), qstr_str(mp_obj_get_qstr(host_name))); const char *query = vstr_str(vstr); // send query @@ -148,7 +147,7 @@ py_obj_t pyb_wlan_http_get(py_obj_t host_name, py_obj_t host_path) { ret = send(sd, query + sent, strlen(query + sent), 0); //printf("sent %d bytes\n", ret); if (ret < 0) { - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "send failed", NULL, NULL)); + nlr_jump(mp_obj_new_exception_msg(qstr_from_str_static("WlanError"), "send failed")); } sent += ret; //sys_tick_delay_ms(200); @@ -159,7 +158,7 @@ py_obj_t pyb_wlan_http_get(py_obj_t host_name, py_obj_t host_path) { //sys_tick_delay_ms(5000); // receive reply - py_obj_t py_ret = py_const_none; + mp_obj_t mp_ret = mp_const_none; { //printf("doing receive\n"); char buf[64]; @@ -185,33 +184,33 @@ py_obj_t pyb_wlan_http_get(py_obj_t host_name, py_obj_t host_path) { // read data ret = recv(sd, buf, 64, 0); if (ret < 0) { - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "recv failed %d", (void*)ret, NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "recv failed %d", (void*)ret)); } vstr_add_strn(vstr, buf, ret); } - py_ret = py_obj_new_str(qstr_from_str_take(vstr_str(vstr))); + mp_ret = mp_obj_new_str(qstr_from_str_take(vstr_str(vstr))); } closesocket(sd); - return py_ret; + return mp_ret; } -py_obj_t pyb_wlan_serve(void) { +mp_obj_t pyb_wlan_serve(void) { printf("serve socket\n"); int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); printf("serve socket got %d\n", sd); sys_tick_delay_ms(500); if (sd < 0) { printf("socket fail\n"); - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd, NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd)); } /* if (setsockopt(sd, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, SOCK_ON, sizeof(SOCK_ON)) < 0) { printf("couldn't set socket as non-blocking\n"); - return py_const_none; + return mp_const_none; } */ @@ -226,7 +225,7 @@ py_obj_t pyb_wlan_serve(void) { sys_tick_delay_ms(100); if (ret != 0) { printf("bind fail\n"); - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "bind failed: %d", (void*)ret, NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "bind failed: %d", (void*)ret)); } printf("bind seemed to work\n"); @@ -268,7 +267,7 @@ py_obj_t pyb_wlan_serve(void) { closesocket(fd); closesocket(sd); - return py_const_none; + return mp_const_none; } //***************************************************************************** @@ -344,7 +343,7 @@ void pyb_wlan_init(void) { SpiInit(); wlan_init(CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch, ReadWlanInterruptPin, WlanInterruptEnable, WlanInterruptDisable, WriteWlanPin); - py_obj_t m = py_module_new(); + mp_obj_t m = mp_module_new(); rt_store_attr(m, qstr_from_str_static("connect"), rt_make_function_var(0, pyb_wlan_connect)); rt_store_attr(m, qstr_from_str_static("disconnect"), rt_make_function_0(pyb_wlan_disconnect)); rt_store_attr(m, qstr_from_str_static("ip"), rt_make_function_0(pyb_wlan_get_ip)); diff --git a/stm/servo.c b/stm/servo.c new file mode 100644 index 0000000000..ae421048b9 --- /dev/null +++ b/stm/servo.c @@ -0,0 +1,160 @@ +#include <stdio.h> +#include <stm32f4xx.h> +#include <stm32f4xx_rcc.h> +#include <stm32f4xx_gpio.h> +#include <stm32f4xx_tim.h> + +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "servo.h" + +// PWM +// TIM2 and TIM5 have CH1, CH2, CH3, CH4 on PA0-PA3 respectively +// they are both 32-bit counters +// 16-bit prescaler +// TIM2_CH3 also on PB10 (used below) +void servo_init(void) { + // TIM2 clock enable + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); + + // for PB10 + /* + // GPIOB Configuration: TIM2_CH3 (PB10) + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + // Connect TIM2 pins to AF1 + GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_TIM2); + */ + + // for PA0, PA1, PA2, PA3 + { + // GPIOA Configuration: TIM2_CH0, TIM2_CH1 (PA0, PA1) + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + // Connect TIM2 pins to AF1 + GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2); + } + + // Compute the prescaler value so TIM2 runs at 100kHz + uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 100000) - 1; + + // Time base configuration + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_TimeBaseStructure.TIM_Period = 2000; // timer cycles at 50Hz + TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); + + // PWM Mode configuration + TIM_OCInitTypeDef TIM_OCInitStructure; + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = 150; // units of 10us + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OC1Init(TIM2, &TIM_OCInitStructure); // channel 1 + TIM_OC2Init(TIM2, &TIM_OCInitStructure); // channel 2 + TIM_OC3Init(TIM2, &TIM_OCInitStructure); // channel 3 + TIM_OC4Init(TIM2, &TIM_OCInitStructure); // channel 4 + + // ? + TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 1 + TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 2 + TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 3 + TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 4 + + // ? + TIM_ARRPreloadConfig(TIM2, ENABLE); + + // TIM2 enable counter + TIM_Cmd(TIM2, ENABLE); +} + +/******************************************************************************/ +/* Micro Python bindings */ + +mp_obj_t pyb_servo_set(mp_obj_t port, mp_obj_t value) { + int p = mp_obj_get_int(port); + int v = mp_obj_get_int(value); + if (v < 50) { v = 50; } + if (v > 250) { v = 250; } + switch (p) { + case 1: TIM2->CCR1 = v; break; + case 2: TIM2->CCR2 = v; break; + case 3: TIM2->CCR3 = v; break; + case 4: TIM2->CCR4 = v; break; + } + return mp_const_none; +} + +mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse) { + int pe = mp_obj_get_int(period); + int pu = mp_obj_get_int(pulse); + TIM2->ARR = pe; + TIM2->CCR3 = pu; + return mp_const_none; +} + +typedef struct _pyb_servo_obj_t { + mp_obj_base_t base; + uint servo_id; +} pyb_servo_obj_t; + +static void servo_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + pyb_servo_obj_t *self = self_in; + print(env, "<Servo %lu>", self->servo_id); +} + +static mp_obj_t servo_obj_angle(mp_obj_t self_in, mp_obj_t angle) { + pyb_servo_obj_t *self = self_in; + machine_int_t v = 152 + 85.0 * mp_obj_get_float(angle) / 90.0; + if (v < 65) { v = 65; } + if (v > 210) { v = 210; } + switch (self->servo_id) { + case 1: TIM2->CCR1 = v; break; + case 2: TIM2->CCR2 = v; break; + case 3: TIM2->CCR3 = v; break; + case 4: TIM2->CCR4 = v; break; + } + return mp_const_none; +} + +static MP_DEFINE_CONST_FUN_OBJ_2(servo_obj_angle_obj, servo_obj_angle); + +static const mp_obj_type_t servo_obj_type = { + { &mp_const_type }, + "Servo", + servo_obj_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + { "angle", &servo_obj_angle_obj }, + { NULL, NULL }, + } +}; + +mp_obj_t pyb_Servo(mp_obj_t servo_id) { + pyb_servo_obj_t *o = m_new_obj(pyb_servo_obj_t); + o->base.type = &servo_obj_type; + o->servo_id = mp_obj_get_int(servo_id); + return o; +} diff --git a/stm/servo.h b/stm/servo.h new file mode 100644 index 0000000000..02702e0672 --- /dev/null +++ b/stm/servo.h @@ -0,0 +1,5 @@ +void servo_init(void); + +mp_obj_t pyb_servo_set(mp_obj_t port, mp_obj_t value); +mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse); +mp_obj_t pyb_Servo(mp_obj_t servo_id); diff --git a/stm/stm32fxxx_it.c b/stm/stm32fxxx_it.c index 0f17681e5f..4c185d0341 100644 --- a/stm/stm32fxxx_it.c +++ b/stm/stm32fxxx_it.c @@ -267,6 +267,9 @@ void TIM6_DAC_IRQHandler(void) { } #include "std.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" #include "led.h" // EXTI // for USRSW on A13 diff --git a/stm/storage.c b/stm/storage.c index ac0458d136..6878de22e6 100644 --- a/stm/storage.c +++ b/stm/storage.c @@ -3,6 +3,8 @@ #include "misc.h" #include "systick.h" +#include "mpconfig.h" +#include "obj.h" #include "led.h" #include "flash.h" #include "storage.h" diff --git a/stm/timer.c b/stm/timer.c index ecfc2bb289..2236bbce47 100644 --- a/stm/timer.c +++ b/stm/timer.c @@ -7,37 +7,38 @@ #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "parse.h" #include "compile.h" +#include "obj.h" #include "runtime.h" #include "timer.h" // TIM6 is used as an internal interrup to schedule something at a specific rate -py_obj_t timer_py_callback; +mp_obj_t timer_py_callback; -py_obj_t timer_py_set_callback(py_obj_t f) { +mp_obj_t timer_py_set_callback(mp_obj_t f) { timer_py_callback = f; - return py_const_none; + return mp_const_none; } -py_obj_t timer_py_set_period(py_obj_t period) { - TIM6->ARR = py_obj_get_int(period) & 0xffff; - return py_const_none; +mp_obj_t timer_py_set_period(mp_obj_t period) { + TIM6->ARR = mp_obj_get_int(period) & 0xffff; + return mp_const_none; } -py_obj_t timer_py_set_prescaler(py_obj_t prescaler) { - TIM6->PSC = py_obj_get_int(prescaler) & 0xffff; - return py_const_none; +mp_obj_t timer_py_set_prescaler(mp_obj_t prescaler) { + TIM6->PSC = mp_obj_get_int(prescaler) & 0xffff; + return mp_const_none; } -py_obj_t timer_py_get_value(void) { - return py_obj_new_int(TIM6->CNT & 0xfffff); +mp_obj_t timer_py_get_value(void) { + return mp_obj_new_int(TIM6->CNT & 0xfffff); } void timer_init(void) { - timer_py_callback = py_const_none; + timer_py_callback = mp_const_none; // TIM6 clock enable RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); @@ -71,7 +72,7 @@ void timer_init(void) { TIM_Cmd(TIM6, ENABLE); // Python interface - py_obj_t m = py_module_new(); + mp_obj_t m = mp_module_new(); rt_store_attr(m, qstr_from_str_static("callback"), rt_make_function_1(timer_py_set_callback)); rt_store_attr(m, qstr_from_str_static("period"), rt_make_function_1(timer_py_set_period)); rt_store_attr(m, qstr_from_str_static("prescaler"), rt_make_function_1(timer_py_set_prescaler)); @@ -80,7 +81,7 @@ void timer_init(void) { } void timer_interrupt(void) { - if (timer_py_callback != py_const_none) { + if (timer_py_callback != mp_const_none) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { // XXX what to do if the GC is in the middle of running?? @@ -89,7 +90,7 @@ void timer_interrupt(void) { } else { // uncaught exception printf("exception in timer interrupt\n"); - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); } } |