diff options
Diffstat (limited to 'extmod')
-rw-r--r-- | extmod/fsusermount.c | 2 | ||||
-rw-r--r-- | extmod/machine_i2c.c | 8 | ||||
-rw-r--r-- | extmod/machine_pulse.c | 67 | ||||
-rw-r--r-- | extmod/machine_pulse.h | 37 | ||||
-rw-r--r-- | extmod/misc.h | 1 | ||||
-rw-r--r-- | extmod/modlwip.c | 132 | ||||
-rw-r--r-- | extmod/modubinascii.c | 2 | ||||
-rw-r--r-- | extmod/moduos_dupterm.c | 15 | ||||
-rw-r--r-- | extmod/modussl.c | 36 | ||||
-rw-r--r-- | extmod/modwebrepl.c | 12 | ||||
-rw-r--r-- | extmod/modwebsocket.c | 18 | ||||
-rw-r--r-- | extmod/vfs_fat.c | 165 | ||||
-rw-r--r-- | extmod/vfs_fat_misc.c | 7 | ||||
-rw-r--r-- | extmod/virtpin.c | 39 | ||||
-rw-r--r-- | extmod/virtpin.h | 40 |
15 files changed, 469 insertions, 112 deletions
diff --git a/extmod/fsusermount.c b/extmod/fsusermount.c index 8f789ca033..9ddc98f3dd 100644 --- a/extmod/fsusermount.c +++ b/extmod/fsusermount.c @@ -32,7 +32,7 @@ #include "py/nlr.h" #include "py/runtime.h" #include "lib/fatfs/ff.h" -#include "fsusermount.h" +#include "extmod/fsusermount.h" fs_user_mount_t *fatfs_mount_mkfs(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, bool mkfs) { static const mp_arg_t allowed_args[] = { diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index e3bdb36925..ceddf0730e 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -48,7 +48,7 @@ STATIC void mp_hal_i2c_delay(machine_i2c_obj_t *self) { } STATIC void mp_hal_i2c_scl_low(machine_i2c_obj_t *self) { - mp_hal_pin_low(self->scl); + mp_hal_pin_od_low(self->scl); } STATIC void mp_hal_i2c_scl_release(machine_i2c_obj_t *self) { @@ -56,7 +56,7 @@ STATIC void mp_hal_i2c_scl_release(machine_i2c_obj_t *self) { } STATIC void mp_hal_i2c_sda_low(machine_i2c_obj_t *self) { - mp_hal_pin_low(self->sda); + mp_hal_pin_od_low(self->sda); } STATIC void mp_hal_i2c_sda_release(machine_i2c_obj_t *self) { @@ -91,8 +91,8 @@ STATIC void mp_hal_i2c_init(machine_i2c_obj_t *self, uint32_t freq) { if (self->us_delay == 0) { self->us_delay = 1; } - mp_hal_pin_config_od(self->scl); - mp_hal_pin_config_od(self->sda); + mp_hal_pin_open_drain(self->scl); + mp_hal_pin_open_drain(self->sda); mp_hal_i2c_stop(self); } diff --git a/extmod/machine_pulse.c b/extmod/machine_pulse.c new file mode 100644 index 0000000000..8c8bff510c --- /dev/null +++ b/extmod/machine_pulse.c @@ -0,0 +1,67 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "py/mperrno.h" +#include "extmod/machine_pulse.h" + +#if MICROPY_PY_MACHINE_PULSE + +mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us) { + mp_uint_t start = mp_hal_ticks_us(); + while (mp_hal_pin_read(pin) != pulse_level) { + if ((mp_uint_t)(mp_hal_ticks_us() - start) >= timeout_us) { + return (mp_uint_t)-1; + } + } + start = mp_hal_ticks_us(); + while (mp_hal_pin_read(pin) == pulse_level) { + if ((mp_uint_t)(mp_hal_ticks_us() - start) >= timeout_us) { + return (mp_uint_t)-1; + } + } + return mp_hal_ticks_us() - start; +} + +STATIC mp_obj_t machine_time_pulse_us_(size_t n_args, const mp_obj_t *args) { + mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(args[0]); + int level = 0; + if (mp_obj_is_true(args[1])) { + level = 1; + } + mp_uint_t timeout_us = 1000000; + if (n_args > 2) { + timeout_us = mp_obj_get_int(args[2]); + } + mp_uint_t us = machine_time_pulse_us(pin, level, timeout_us); + if (us == (mp_uint_t)-1) { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ETIMEDOUT))); + } + return mp_obj_new_int(us); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_time_pulse_us_obj, 2, 3, machine_time_pulse_us_); + +#endif diff --git a/extmod/machine_pulse.h b/extmod/machine_pulse.h new file mode 100644 index 0000000000..3d5d81c073 --- /dev/null +++ b/extmod/machine_pulse.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_EXTMOD_MACHINE_PULSE_H__ +#define __MICROPY_INCLUDED_EXTMOD_MACHINE_PULSE_H__ + +#include "py/obj.h" +#include "py/mphal.h" + +mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us); + +MP_DECLARE_CONST_FUN_OBJ(machine_time_pulse_us_obj); + +#endif // __MICROPY_INCLUDED_EXTMOD_MACHINE_PULSE_H__ diff --git a/extmod/misc.h b/extmod/misc.h index 39bfd5ecb5..634ea924d0 100644 --- a/extmod/misc.h +++ b/extmod/misc.h @@ -34,6 +34,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_uos_dupterm_obj); #if MICROPY_PY_OS_DUPTERM void mp_uos_dupterm_tx_strn(const char *str, size_t len); +void mp_uos_deactivate(const char *msg, mp_obj_t exc); #else #define mp_uos_dupterm_tx_strn(s, l) #endif diff --git a/extmod/modlwip.c b/extmod/modlwip.c index 090e1005a8..cb7cc6596f 100644 --- a/extmod/modlwip.c +++ b/extmod/modlwip.c @@ -26,13 +26,13 @@ */ #include <string.h> -#include <errno.h> #include <stdio.h> #include "py/nlr.h" #include "py/objlist.h" #include "py/runtime.h" #include "py/stream.h" +#include "py/mperrno.h" #include "py/mphal.h" #include "netutils.h" @@ -172,45 +172,45 @@ STATIC const mp_obj_type_t lwip_slip_type = { // investigate in more detail. #if LWIP_VERSION < 0x01040100 static const int error_lookup_table[] = { - 0, /* ERR_OK 0 No error, everything OK. */ - ENOMEM, /* ERR_MEM -1 Out of memory error. */ - ENOBUFS, /* ERR_BUF -2 Buffer error. */ - EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ - EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ - EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ - EINVAL, /* ERR_VAL -6 Illegal value. */ - EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ - - ECONNABORTED, /* ERR_ABRT -8 Connection aborted. */ - ECONNRESET, /* ERR_RST -9 Connection reset. */ - ENOTCONN, /* ERR_CLSD -10 Connection closed. */ - ENOTCONN, /* ERR_CONN -11 Not connected. */ - EIO, /* ERR_ARG -12 Illegal argument. */ - EADDRINUSE, /* ERR_USE -13 Address in use. */ - -1, /* ERR_IF -14 Low-level netif error */ - EALREADY, /* ERR_ISCONN -15 Already connected. */ - EBADF, /* _ERR_BADF -16 Closed socket (null pcb) */ + 0, /* ERR_OK 0 No error, everything OK. */ + MP_ENOMEM, /* ERR_MEM -1 Out of memory error. */ + MP_ENOBUFS, /* ERR_BUF -2 Buffer error. */ + MP_EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ + MP_EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ + MP_EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ + MP_EINVAL, /* ERR_VAL -6 Illegal value. */ + MP_EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ + + MP_ECONNABORTED, /* ERR_ABRT -8 Connection aborted. */ + MP_ECONNRESET, /* ERR_RST -9 Connection reset. */ + MP_ENOTCONN, /* ERR_CLSD -10 Connection closed. */ + MP_ENOTCONN, /* ERR_CONN -11 Not connected. */ + MP_EIO, /* ERR_ARG -12 Illegal argument. */ + MP_EADDRINUSE, /* ERR_USE -13 Address in use. */ + -1, /* ERR_IF -14 Low-level netif error */ + MP_EALREADY, /* ERR_ISCONN -15 Already connected. */ + MP_EBADF, /* _ERR_BADF -16 Closed socket (null pcb) */ }; #else static const int error_lookup_table[] = { - 0, /* ERR_OK 0 No error, everything OK. */ - ENOMEM, /* ERR_MEM -1 Out of memory error. */ - ENOBUFS, /* ERR_BUF -2 Buffer error. */ - EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ - EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ - EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ - EINVAL, /* ERR_VAL -6 Illegal value. */ - EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ - - EADDRINUSE, /* ERR_USE -8 Address in use. */ - EALREADY, /* ERR_ISCONN -9 Already connected. */ - ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */ - ECONNRESET, /* ERR_RST -11 Connection reset. */ - ENOTCONN, /* ERR_CLSD -12 Connection closed. */ - ENOTCONN, /* ERR_CONN -13 Not connected. */ - EIO, /* ERR_ARG -14 Illegal argument. */ - -1, /* ERR_IF -15 Low-level netif error */ - EBADF, /* _ERR_BADF -16 Closed socket (null pcb) */ + 0, /* ERR_OK 0 No error, everything OK. */ + MP_ENOMEM, /* ERR_MEM -1 Out of memory error. */ + MP_ENOBUFS, /* ERR_BUF -2 Buffer error. */ + MP_EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ + MP_EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ + MP_EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ + MP_EINVAL, /* ERR_VAL -6 Illegal value. */ + MP_EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ + + MP_EADDRINUSE, /* ERR_USE -8 Address in use. */ + MP_EALREADY, /* ERR_ISCONN -9 Already connected. */ + MP_ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */ + MP_ECONNRESET, /* ERR_RST -11 Connection reset. */ + MP_ENOTCONN, /* ERR_CLSD -12 Connection closed. */ + MP_ENOTCONN, /* ERR_CONN -13 Not connected. */ + MP_EIO, /* ERR_ARG -14 Illegal argument. */ + -1, /* ERR_IF -15 Low-level netif error */ + MP_EBADF, /* _ERR_BADF -16 Closed socket (null pcb) */ }; #endif @@ -311,6 +311,17 @@ STATIC err_t _lwip_tcp_recv_unaccepted(void *arg, struct tcp_pcb *pcb, struct pb return ERR_BUF; } +// "Poll" (idle) callback to be called ASAP after accept callback +// to execute Python callback function, as it can't be executed +// from accept callback itself. +STATIC err_t _lwip_tcp_accept_finished(void *arg, struct tcp_pcb *pcb) +{ + lwip_socket_obj_t *socket = (lwip_socket_obj_t*)arg; + tcp_poll(pcb, NULL, 0); + exec_user_callback(socket); + return ERR_OK; +} + // Callback for incoming tcp connections. STATIC err_t _lwip_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { lwip_socket_obj_t *socket = (lwip_socket_obj_t*)arg; @@ -323,7 +334,12 @@ STATIC err_t _lwip_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { return ERR_BUF; } else { socket->incoming.connection = newpcb; - exec_user_callback(socket); + if (socket->callback != MP_OBJ_NULL) { + // Schedule accept callback to be called when lwIP is done + // with processing this incoming connection on its side and + // is idle. + tcp_poll(newpcb, _lwip_tcp_accept_finished, 1); + } return ERR_OK; } } @@ -363,7 +379,7 @@ STATIC mp_uint_t lwip_udp_send(lwip_socket_obj_t *socket, const byte *buf, mp_ui // FIXME: maybe PBUF_ROM? struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); if (p == NULL) { - *_errno = ENOMEM; + *_errno = MP_ENOMEM; return -1; } @@ -401,7 +417,7 @@ STATIC mp_uint_t lwip_udp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_ if (socket->incoming.pbuf != NULL) break; } if (socket->incoming.pbuf == NULL) { - *_errno = ETIMEDOUT; + *_errno = MP_ETIMEDOUT; return -1; } } else { @@ -444,7 +460,7 @@ STATIC mp_uint_t lwip_tcp_send(lwip_socket_obj_t *socket, const byte *buf, mp_ui if (available == 0) { // Non-blocking socket if (socket->timeout == 0) { - *_errno = EAGAIN; + *_errno = MP_EAGAIN; return MP_STREAM_ERROR; } @@ -457,7 +473,7 @@ STATIC mp_uint_t lwip_tcp_send(lwip_socket_obj_t *socket, const byte *buf, mp_ui // Avoid sending too small packets, so wait until at least 16 bytes available while (socket->state >= STATE_CONNECTED && (available = tcp_sndbuf(socket->pcb.tcp)) < 16) { if (socket->timeout != -1 && mp_hal_ticks_ms() - start > socket->timeout) { - *_errno = ETIMEDOUT; + *_errno = MP_ETIMEDOUT; return MP_STREAM_ERROR; } poll_sockets(); @@ -491,14 +507,14 @@ STATIC mp_uint_t lwip_tcp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_ if (socket->state == STATE_PEER_CLOSED) { return 0; } - *_errno = EAGAIN; + *_errno = MP_EAGAIN; return -1; } mp_uint_t start = mp_hal_ticks_ms(); while (socket->state == STATE_CONNECTED && socket->incoming.pbuf == NULL) { if (socket->timeout != -1 && mp_hal_ticks_ms() - start > socket->timeout) { - *_errno = ETIMEDOUT; + *_errno = MP_ETIMEDOUT; return -1; } poll_sockets(); @@ -570,11 +586,11 @@ STATIC mp_obj_t lwip_socket_make_new(const mp_obj_type_t *type, mp_uint_t n_args case MOD_NETWORK_SOCK_STREAM: socket->pcb.tcp = tcp_new(); break; case MOD_NETWORK_SOCK_DGRAM: socket->pcb.udp = udp_new(); break; //case MOD_NETWORK_SOCK_RAW: socket->pcb.raw = raw_new(); break; - default: nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINVAL))); + default: nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EINVAL))); } if (socket->pcb.tcp == NULL) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOMEM))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ENOMEM))); } switch (socket->type) { @@ -670,15 +686,15 @@ STATIC mp_obj_t lwip_socket_listen(mp_obj_t self_in, mp_obj_t backlog_in) { mp_int_t backlog = mp_obj_get_int(backlog_in); if (socket->pcb.tcp == NULL) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EBADF))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EBADF))); } if (socket->type != MOD_NETWORK_SOCK_STREAM) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EOPNOTSUPP))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EOPNOTSUPP))); } struct tcp_pcb *new_pcb = tcp_listen_with_backlog(socket->pcb.tcp, (u8_t)backlog); if (new_pcb == NULL) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOMEM))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ENOMEM))); } socket->pcb.tcp = new_pcb; tcp_accept(new_pcb, _lwip_tcp_accept); @@ -691,15 +707,15 @@ STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) { lwip_socket_obj_t *socket = self_in; if (socket->pcb.tcp == NULL) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EBADF))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EBADF))); } if (socket->type != MOD_NETWORK_SOCK_STREAM) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EOPNOTSUPP))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EOPNOTSUPP))); } // I need to do this because "tcp_accepted", later, is a macro. struct tcp_pcb *listener = socket->pcb.tcp; if (listener->state != LISTEN) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINVAL))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EINVAL))); } // accept incoming connection @@ -710,7 +726,7 @@ STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) { if (socket->incoming.connection != NULL) break; } if (socket->incoming.connection == NULL) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ETIMEDOUT))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ETIMEDOUT))); } } else { while (socket->incoming.connection == NULL) { @@ -757,7 +773,7 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { lwip_socket_obj_t *socket = self_in; if (socket->pcb.tcp == NULL) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EBADF))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EBADF))); } // get address @@ -772,9 +788,9 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { case MOD_NETWORK_SOCK_STREAM: { if (socket->state != STATE_NEW) { if (socket->state == STATE_CONNECTED) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EALREADY))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EALREADY))); } else { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINPROGRESS))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EINPROGRESS))); } } // Register our recieve callback. @@ -794,7 +810,7 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { if (socket->state != STATE_CONNECTING) break; } if (socket->state == STATE_CONNECTING) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ETIMEDOUT))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ETIMEDOUT))); } } else { while (socket->state == STATE_CONNECTING) { @@ -982,7 +998,7 @@ STATIC mp_obj_t lwip_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) { // most useful behavior is: check whether we will be able to send all of input // data without EAGAIN, and if won't be, raise it without sending any. if (bufinfo.len > tcp_sndbuf(socket->pcb.tcp)) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EAGAIN))); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_EAGAIN))); } } // TODO: In CPython3.5, socket timeout should apply to the diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c index 82f910b0e7..3cceb991f1 100644 --- a/extmod/modubinascii.c +++ b/extmod/modubinascii.c @@ -31,7 +31,7 @@ #include "py/nlr.h" #include "py/runtime.h" #include "py/binary.h" -#include "modubinascii.h" +#include "extmod/modubinascii.h" mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) { diff --git a/extmod/moduos_dupterm.c b/extmod/moduos_dupterm.c index 41b8b3c81e..4c9f9e4940 100644 --- a/extmod/moduos_dupterm.c +++ b/extmod/moduos_dupterm.c @@ -31,9 +31,20 @@ #include "py/nlr.h" #include "py/runtime.h" #include "py/objtuple.h" +#include "py/stream.h" #if MICROPY_PY_OS_DUPTERM +void mp_uos_deactivate(const char *msg, mp_obj_t exc) { + mp_obj_t term = MP_STATE_PORT(term_obj); + MP_STATE_PORT(term_obj) = NULL; + mp_printf(&mp_plat_print, msg); + if (exc != MP_OBJ_NULL) { + mp_obj_print_exception(&mp_plat_print, exc); + } + mp_stream_close(term); +} + void mp_uos_dupterm_tx_strn(const char *str, size_t len) { if (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) { nlr_buf_t nlr; @@ -44,9 +55,7 @@ void mp_uos_dupterm_tx_strn(const char *str, size_t len) { mp_call_method_n_kw(1, 0, write_m); nlr_pop(); } else { - MP_STATE_PORT(term_obj) = NULL; - mp_printf(&mp_plat_print, "dupterm: Exception in write() method, deactivating: "); - mp_obj_print_exception(&mp_plat_print, nlr.ret_val); + mp_uos_deactivate("dupterm: Exception in write() method, deactivating: ", nlr.ret_val); } } } diff --git a/extmod/modussl.c b/extmod/modussl.c index 51f4fead81..567033cf48 100644 --- a/extmod/modussl.c +++ b/extmod/modussl.c @@ -78,12 +78,12 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, bool server_side) { STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; - mp_obj_ssl_socket_t *self = self_in; + mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "<_SSLSocket %p>", self->ssl_sock); } STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) { - mp_obj_ssl_socket_t *o = o_in; + mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in); while (o->bytes_left == 0) { mp_int_t r = ssl_read(o->ssl_sock, &o->buf); @@ -113,7 +113,7 @@ STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errc } STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) { - mp_obj_ssl_socket_t *o = o_in; + mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in); mp_int_t r = ssl_write(o->ssl_sock, buf, size); if (r < 0) { *errcode = r; @@ -123,7 +123,7 @@ STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, in } STATIC mp_obj_t socket_close(mp_obj_t self_in) { - mp_obj_ssl_socket_t *self = self_in; + mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in); ssl_free(self->ssl_sock); ssl_ctx_free(self->ssl_ctx); @@ -133,13 +133,13 @@ STATIC mp_obj_t socket_close(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_close_obj, socket_close); -STATIC const mp_map_elem_t ussl_socket_locals_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj}, - { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&socket_close_obj }, +STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readall), MP_ROM_PTR(&mp_stream_readall_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socket_close_obj) }, }; STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table); @@ -157,10 +157,10 @@ STATIC const mp_obj_type_t ussl_socket_type = { .getiter = NULL, .iternext = NULL, .stream_p = &ussl_socket_stream_p, - .locals_dict = (mp_obj_t)&ussl_socket_locals_dict, + .locals_dict = (void*)&ussl_socket_locals_dict, }; -STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // TODO: Implement more args static const mp_arg_t allowed_args[] = { { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, @@ -175,13 +175,13 @@ STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args, mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args); - return socket_new(sock, args.server_side.u_bool); + return MP_OBJ_FROM_PTR(socket_new(sock, args.server_side.u_bool)); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket); -STATIC const mp_map_elem_t mp_module_ssl_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ussl) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_wrap_socket), (mp_obj_t)&mod_ssl_wrap_socket_obj }, +STATIC const mp_rom_map_elem_t mp_module_ssl_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ussl) }, + { MP_ROM_QSTR(MP_QSTR_wrap_socket), MP_ROM_PTR(&mod_ssl_wrap_socket_obj) }, }; STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table); @@ -195,6 +195,8 @@ const mp_obj_module_t mp_module_ussl = { // These functions might be split to stream_posix.c. They are referenced by // axtls os_port.h . +ssize_t mp_stream_posix_write(void *sock_obj, const void *buf, size_t len); +ssize_t mp_stream_posix_read(void *sock_obj, void *buf, size_t len); int mp_stream_errno; diff --git a/extmod/modwebrepl.c b/extmod/modwebrepl.c index c160abea2f..8ecab922aa 100644 --- a/extmod/modwebrepl.c +++ b/extmod/modwebrepl.c @@ -250,8 +250,8 @@ STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int DEBUG_printf("webrepl: Writing %lu bytes to file\n", buf_sz); int err; - mp_uint_t res = mp_stream_writeall(self->cur_file, filebuf, buf_sz, &err); - if(res == MP_STREAM_ERROR) { + mp_uint_t res = mp_stream_write_exactly(self->cur_file, filebuf, buf_sz, &err); + if (err != 0 || res != buf_sz) { assert(0); } @@ -284,6 +284,13 @@ STATIC mp_uint_t webrepl_write(mp_obj_t self_in, const void *buf, mp_uint_t size return stream_p->write(self->sock, buf, size, errcode); } +STATIC mp_obj_t webrepl_close(mp_obj_t self_in) { + mp_obj_webrepl_t *self = MP_OBJ_TO_PTR(self_in); + // TODO: This is a place to do cleanup + return mp_stream_close(self->sock); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(webrepl_close_obj, webrepl_close); + STATIC mp_obj_t webrepl_set_password(mp_obj_t passwd_in) { mp_uint_t len; const char *passwd = mp_obj_str_get_data(passwd_in, &len); @@ -297,6 +304,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(webrepl_set_password_obj, webrepl_set_password) STATIC const mp_map_elem_t webrepl_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&webrepl_close_obj }, }; STATIC MP_DEFINE_CONST_DICT(webrepl_locals_dict, webrepl_locals_dict_table); diff --git a/extmod/modwebsocket.c b/extmod/modwebsocket.c index 344933ded3..fc5e29a05e 100644 --- a/extmod/modwebsocket.c +++ b/extmod/modwebsocket.c @@ -240,9 +240,9 @@ STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t si mp_call_method_n_kw(1, 0, dest); } - mp_uint_t out_sz = mp_stream_writeall(self->sock, header, hdr_sz, errcode); - if (out_sz != MP_STREAM_ERROR) { - out_sz = mp_stream_writeall(self->sock, buf, size, errcode); + mp_uint_t out_sz = mp_stream_write_exactly(self->sock, header, hdr_sz, errcode); + if (*errcode == 0) { + out_sz = mp_stream_write_exactly(self->sock, buf, size, errcode); } if (self->opts & BLOCKING_WRITE) { @@ -250,6 +250,9 @@ STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t si mp_call_method_n_kw(1, 0, dest); } + if (*errcode != 0) { + return MP_STREAM_ERROR; + } return out_sz; } @@ -269,10 +272,19 @@ STATIC mp_uint_t websocket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t } } +STATIC mp_obj_t websocket_close(mp_obj_t self_in) { + mp_obj_websocket_t *self = MP_OBJ_TO_PTR(self_in); + // TODO: Send close signaling to the other side, otherwise it's + // abrupt close (connection abort). + return mp_stream_close(self->sock); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(websocket_close_obj, websocket_close); + STATIC const mp_map_elem_t websocket_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&mp_stream_ioctl_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&websocket_close_obj }, }; STATIC MP_DEFINE_CONST_DICT(websocket_locals_dict, websocket_locals_dict_table); diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index c52adfbe08..a4a81370f9 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -28,12 +28,14 @@ #include "py/mpconfig.h" #if MICROPY_VFS_FAT +#include <string.h> #include "py/nlr.h" #include "py/runtime.h" #include "lib/fatfs/ff.h" #include "lib/fatfs/diskio.h" #include "extmod/vfs_fat_file.h" -#include "fsusermount.h" +#include "extmod/fsusermount.h" +#include "timeutils.h" #define mp_obj_fat_vfs_t fs_user_mount_t @@ -79,12 +81,11 @@ STATIC mp_obj_t fat_vfs_remove(mp_obj_t vfs_in, mp_obj_t path_in) { const char *path = mp_obj_str_get_str(path_in); // TODO check that path is actually a file before trying to unlink it FRESULT res = f_unlink(path); - switch (res) { - case FR_OK: - return mp_const_none; - default: - // TODO: standard errno's - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing file '%s'", path)); + if (res == FR_OK) { + return mp_const_none; + } else { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, + MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res]))); } } STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_remove_obj, fat_vfs_remove); @@ -94,11 +95,11 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_ const char *old_path = mp_obj_str_get_str(path_in); const char *new_path = mp_obj_str_get_str(path_out); FRESULT res = f_rename(old_path, new_path); - switch (res) { - case FR_OK: - return mp_const_none; - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error renaming file '%s' to '%s'", old_path, new_path)); + if (res == FR_OK) { + return mp_const_none; + } else { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, + MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res]))); } } @@ -108,25 +109,149 @@ STATIC mp_obj_t fat_vfs_mkdir(mp_obj_t vfs_in, mp_obj_t path_o) { (void)vfs_in; const char *path = mp_obj_str_get_str(path_o); FRESULT res = f_mkdir(path); - switch (res) { - case FR_OK: - return mp_const_none; - case FR_EXIST: - // TODO should be FileExistsError - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "File exists: '%s'", path)); - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path)); + if (res == FR_OK) { + return mp_const_none; + } else { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, + MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res]))); } } STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_mkdir_obj, fat_vfs_mkdir); +/// Change current directory. +STATIC mp_obj_t fat_vfs_chdir(mp_obj_t vfs_in, mp_obj_t path_in) { + (void)vfs_in; + const char *path; + path = mp_obj_str_get_str(path_in); + + FRESULT res = f_chdrive(path); + + if (res == FR_OK) { + res = f_chdir(path); + } + + if (res != FR_OK) { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, + MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res]))); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_chdir_obj, fat_vfs_chdir); + +/// Get the current directory. +STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) { + (void)vfs_in; + char buf[MICROPY_ALLOC_PATH_MAX + 1]; + FRESULT res = f_getcwd(buf, sizeof buf); + + if (res != FR_OK) { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res]))); + } + + return mp_obj_new_str(buf, strlen(buf), false); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getcwd_obj, fat_vfs_getcwd); + +// Checks for path equality, ignoring trailing slashes: +// path_equal(/, /) -> true +// second argument must be in canonical form (meaning no trailing slash, unless it's just /) +STATIC bool path_equal(const char *path, const char *path_canonical) { + while (*path_canonical != '\0' && *path == *path_canonical) { + ++path; + ++path_canonical; + } + if (*path_canonical != '\0') { + return false; + } + while (*path == '/') { + ++path; + } + return *path == '\0'; +} + +/// \function stat(path) +/// Get the status of a file or directory. +STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) { + (void)vfs_in; + const char *path = mp_obj_str_get_str(path_in); + + FILINFO fno; +#if _USE_LFN + fno.lfname = NULL; + fno.lfsize = 0; +#endif + FRESULT res; + + if (path_equal(path, "/")) { + // stat root directory + fno.fsize = 0; + fno.fdate = 0; + fno.ftime = 0; + fno.fattrib = AM_DIR; + } else { + res = FR_NO_PATH; + for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) { + fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i]; + if (vfs != NULL && path_equal(path, vfs->str)) { + // stat mounted device directory + fno.fsize = 0; + fno.fdate = 0; + fno.ftime = 0; + fno.fattrib = AM_DIR; + res = FR_OK; + } + } + if (res == FR_NO_PATH) { + // stat normal file + res = f_stat(path, &fno); + } + if (res != FR_OK) { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, + MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res]))); + } + } + + mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); + mp_int_t mode = 0; + if (fno.fattrib & AM_DIR) { + mode |= 0x4000; // stat.S_IFDIR + } else { + mode |= 0x8000; // stat.S_IFREG + } + mp_int_t seconds = timeutils_seconds_since_2000( + 1980 + ((fno.fdate >> 9) & 0x7f), + (fno.fdate >> 5) & 0x0f, + fno.fdate & 0x1f, + (fno.ftime >> 11) & 0x1f, + (fno.ftime >> 5) & 0x3f, + 2 * (fno.ftime & 0x1f) + ); + t->items[0] = MP_OBJ_NEW_SMALL_INT(mode); // st_mode + t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino + t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev + t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // st_nlink + t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid + t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid + t->items[6] = MP_OBJ_NEW_SMALL_INT(fno.fsize); // st_size + t->items[7] = MP_OBJ_NEW_SMALL_INT(seconds); // st_atime + t->items[8] = MP_OBJ_NEW_SMALL_INT(seconds); // st_mtime + t->items[9] = MP_OBJ_NEW_SMALL_INT(seconds); // st_ctime + + return MP_OBJ_FROM_PTR(t); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_stat_obj, fat_vfs_stat); + STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) }, { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&fat_vfs_open_obj) }, { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&fat_vfs_listdir_obj) }, { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&fat_vfs_mkdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&fat_vfs_chdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&fat_vfs_getcwd_obj) }, { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&fat_vfs_remove_obj) }, { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&fat_vfs_rename_obj) }, + { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&fat_vfs_stat_obj) }, }; STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table); diff --git a/extmod/vfs_fat_misc.c b/extmod/vfs_fat_misc.c index 145b624c2b..23fe4be88d 100644 --- a/extmod/vfs_fat_misc.c +++ b/extmod/vfs_fat_misc.c @@ -35,7 +35,7 @@ #include "lib/fatfs/ff.h" #include "lib/fatfs/diskio.h" #include "extmod/vfs_fat_file.h" -#include "fsusermount.h" +#include "extmod/fsusermount.h" #include "py/lexer.h" #if _USE_LFN @@ -54,8 +54,9 @@ mp_obj_t fat_vfs_listdir(const char *path, bool is_str_type) { res = f_opendir(&dir, path); /* Open the directory */ if (res != FR_OK) { - // TODO should be mp_type_FileNotFoundError - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path)); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, + MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res]))); + } mp_obj_t dir_list = mp_obj_new_list(0, NULL); diff --git a/extmod/virtpin.c b/extmod/virtpin.c new file mode 100644 index 0000000000..a5817ab4d0 --- /dev/null +++ b/extmod/virtpin.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "extmod/virtpin.h" + +int mp_virtual_pin_read(mp_obj_t pin) { + mp_obj_base_t* s = (mp_obj_base_t*)MP_OBJ_TO_PTR(pin); + mp_pin_p_t *pin_p = (mp_pin_p_t*)s->type->stream_p; + return pin_p->ioctl(pin, MP_PIN_READ, 0, NULL); +} + +void mp_virtual_pin_write(mp_obj_t pin, int value) { + mp_obj_base_t* s = (mp_obj_base_t*)MP_OBJ_TO_PTR(pin); + mp_pin_p_t *pin_p = (mp_pin_p_t*)s->type->stream_p; + pin_p->ioctl(pin, MP_PIN_WRITE, value, NULL); +} diff --git a/extmod/virtpin.h b/extmod/virtpin.h new file mode 100644 index 0000000000..3821f9dec5 --- /dev/null +++ b/extmod/virtpin.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" + +#define MP_PIN_READ (1) +#define MP_PIN_WRITE (2) +#define MP_PIN_INPUT (3) +#define MP_PIN_OUTPUT (4) + +// Pin protocol +typedef struct _mp_pin_p_t { + mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode); +} mp_pin_p_t; + +int mp_virtual_pin_read(mp_obj_t pin); +void mp_virtual_pin_write(mp_obj_t pin, int value); |