Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
17f45d41fe
22
py/builtin.c
22
py/builtin.c
@ -375,28 +375,6 @@ STATIC mp_obj_t mp_builtin_sorted(uint n_args, const mp_obj_t *args, mp_map_t *k
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted);
|
||||
|
||||
STATIC mp_obj_t mp_builtin_str(mp_obj_t o_in) {
|
||||
vstr_t *vstr = vstr_new();
|
||||
mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, o_in, PRINT_STR);
|
||||
mp_obj_t s = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
|
||||
vstr_free(vstr);
|
||||
return s;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_str_obj, mp_builtin_str);
|
||||
|
||||
// TODO: This should be type, this is just quick CPython compat hack
|
||||
STATIC mp_obj_t mp_builtin_bytes(uint n_args, const mp_obj_t *args) {
|
||||
if (!MP_OBJ_IS_QSTR(args[0]) && !MP_OBJ_IS_TYPE(args[0], &str_type)) {
|
||||
assert(0);
|
||||
}
|
||||
// Currently, MicroPython strings are mix between CPython byte and unicode
|
||||
// strings. So, conversion is null so far.
|
||||
return args[0];
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_bytes_obj, 1, 3, mp_builtin_bytes);
|
||||
|
||||
STATIC mp_obj_t mp_builtin_id(mp_obj_t o_in) {
|
||||
return mp_obj_new_int((machine_int_t)o_in);
|
||||
}
|
||||
|
@ -46,9 +46,9 @@ MATH_FUN_1(fabs, fabs)
|
||||
MATH_FUN_1(floor, floor) //TODO: delegate to x.__floor__() if x is not a float
|
||||
MATH_FUN_2(fmod, fmod)
|
||||
//MATH_FUN_1(frexp, frexp)
|
||||
MATH_FUN_1(isfinite, isfinite)
|
||||
MATH_FUN_1(isinf, isinf)
|
||||
MATH_FUN_1(isnan, isnan)
|
||||
//MATH_FUN_1(isfinite, isfinite)
|
||||
//MATH_FUN_1(isinf, isinf)
|
||||
//MATH_FUN_1(isnan, isnan)
|
||||
MATH_FUN_1(trunc, trunc)
|
||||
|
||||
//TODO: factorial, fsum, frexp, ldexp, modf
|
||||
@ -83,9 +83,9 @@ STATIC const mp_map_elem_t mp_module_math_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_floor), (mp_obj_t)&mp_math_floor_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_fmod), (mp_obj_t)&mp_math_fmod_obj },
|
||||
//{ MP_OBJ_NEW_QSTR(MP_QSTR_frexp), (mp_obj_t)&mp_math_frexp_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_isfinite), (mp_obj_t)&mp_math_isfinite_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_isinf), (mp_obj_t)&mp_math_isinf_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_isnan), (mp_obj_t)&mp_math_isnan_obj },
|
||||
//{ MP_OBJ_NEW_QSTR(MP_QSTR_isfinite), (mp_obj_t)&mp_math_isfinite_obj },
|
||||
//{ MP_OBJ_NEW_QSTR(MP_QSTR_isinf), (mp_obj_t)&mp_math_isinf_obj },
|
||||
//{ MP_OBJ_NEW_QSTR(MP_QSTR_isnan), (mp_obj_t)&mp_math_isnan_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_trunc), (mp_obj_t)&mp_math_trunc_obj },
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "parsenum.h"
|
||||
#include "runtime0.h"
|
||||
#include "map.h"
|
||||
|
||||
@ -36,15 +37,20 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
|
||||
return mp_obj_new_complex(0, 0);
|
||||
|
||||
case 1:
|
||||
// TODO allow string as first arg and parse it
|
||||
if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
|
||||
if (MP_OBJ_IS_STR(args[0])) {
|
||||
// a string, parse it
|
||||
uint l;
|
||||
const char *s = mp_obj_str_get_data(args[0], &l);
|
||||
return mp_parse_num_decimal(s, l, true, true);
|
||||
} else if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
|
||||
// a complex, just return it
|
||||
return args[0];
|
||||
} else {
|
||||
// something else, try to cast it to a complex
|
||||
return mp_obj_new_complex(mp_obj_get_float(args[0]), 0);
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
case 2: {
|
||||
mp_float_t real, imag;
|
||||
if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
|
||||
mp_obj_complex_get(args[0], &real, &imag);
|
||||
|
@ -39,10 +39,12 @@ STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
|
||||
// a string, parse it
|
||||
uint l;
|
||||
const char *s = mp_obj_str_get_data(args[0], &l);
|
||||
return mp_parse_num_decimal(s, l);
|
||||
return mp_parse_num_decimal(s, l, false, false);
|
||||
} else if (MP_OBJ_IS_TYPE(args[0], &mp_type_float)) {
|
||||
// a float, just return it
|
||||
return args[0];
|
||||
} else {
|
||||
// something else, try to cast it to a float
|
||||
return mp_obj_new_float(mp_obj_get_float(args[0]));
|
||||
}
|
||||
|
||||
|
196
py/objstr.c
196
py/objstr.c
@ -14,9 +14,11 @@ typedef struct _mp_obj_str_t {
|
||||
mp_obj_base_t base;
|
||||
machine_uint_t hash : 16; // XXX here we assume the hash size is 16 bits (it is at the moment; see qstr.c)
|
||||
machine_uint_t len : 16; // len == number of bytes used in data, alloc = len + 1 because (at the moment) we also append a null byte
|
||||
byte data[];
|
||||
const byte *data;
|
||||
} mp_obj_str_t;
|
||||
|
||||
const mp_obj_t mp_const_empty_bytes;
|
||||
|
||||
// use this macro to extract the string hash
|
||||
#define GET_STR_HASH(str_obj_in, str_hash) uint str_hash; if (MP_OBJ_IS_QSTR(str_obj_in)) { str_hash = qstr_hash(MP_OBJ_QSTR_VALUE(str_obj_in)); } else { str_hash = ((mp_obj_str_t*)str_obj_in)->hash; }
|
||||
|
||||
@ -28,6 +30,7 @@ typedef struct _mp_obj_str_t {
|
||||
|
||||
STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str);
|
||||
STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str);
|
||||
STATIC mp_obj_t str_new(const mp_obj_type_t *type, const byte* data, uint len);
|
||||
|
||||
/******************************************************************************/
|
||||
/* str */
|
||||
@ -78,6 +81,109 @@ STATIC void str_print(void (*print)(void *env, const char *fmt, ...), void *env,
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
|
||||
switch (n_args) {
|
||||
case 0:
|
||||
return MP_OBJ_NEW_QSTR(MP_QSTR_);
|
||||
|
||||
case 1:
|
||||
{
|
||||
vstr_t *vstr = vstr_new();
|
||||
mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, args[0], PRINT_STR);
|
||||
mp_obj_t s = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
|
||||
vstr_free(vstr);
|
||||
return s;
|
||||
}
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
{
|
||||
// TODO: validate 2nd/3rd args
|
||||
if (!MP_OBJ_IS_TYPE(args[0], &bytes_type)) {
|
||||
nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "bytes expected"));
|
||||
}
|
||||
GET_STR_DATA_LEN(args[0], str_data, str_len);
|
||||
GET_STR_HASH(args[0], str_hash);
|
||||
mp_obj_str_t *o = str_new(&str_type, NULL, str_len);
|
||||
o->data = str_data;
|
||||
o->hash = str_hash;
|
||||
return o;
|
||||
}
|
||||
|
||||
default:
|
||||
nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "str takes at most 3 arguments"));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t bytes_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
return mp_const_empty_bytes;
|
||||
}
|
||||
|
||||
if (MP_OBJ_IS_STR(args[0])) {
|
||||
if (n_args < 2 || n_args > 3) {
|
||||
goto wrong_args;
|
||||
}
|
||||
GET_STR_DATA_LEN(args[0], str_data, str_len);
|
||||
GET_STR_HASH(args[0], str_hash);
|
||||
mp_obj_str_t *o = str_new(&bytes_type, NULL, str_len);
|
||||
o->data = str_data;
|
||||
o->hash = str_hash;
|
||||
return o;
|
||||
}
|
||||
|
||||
if (n_args > 1) {
|
||||
goto wrong_args;
|
||||
}
|
||||
|
||||
if (MP_OBJ_IS_SMALL_INT(args[0])) {
|
||||
uint len = MP_OBJ_SMALL_INT_VALUE(args[0]);
|
||||
byte *data;
|
||||
|
||||
mp_obj_t o = mp_obj_str_builder_start(&bytes_type, len, &data);
|
||||
memset(data, 0, len);
|
||||
return mp_obj_str_builder_end(o);
|
||||
}
|
||||
|
||||
int len;
|
||||
byte *data;
|
||||
vstr_t *vstr = NULL;
|
||||
mp_obj_t o = NULL;
|
||||
// Try to create array of exact len if initializer len is known
|
||||
mp_obj_t len_in = mp_obj_len_maybe(args[0]);
|
||||
if (len_in == MP_OBJ_NULL) {
|
||||
len = -1;
|
||||
vstr = vstr_new();
|
||||
} else {
|
||||
len = MP_OBJ_SMALL_INT_VALUE(len_in);
|
||||
o = mp_obj_str_builder_start(&bytes_type, len, &data);
|
||||
}
|
||||
|
||||
mp_obj_t iterable = rt_getiter(args[0]);
|
||||
mp_obj_t item;
|
||||
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
|
||||
if (len == -1) {
|
||||
vstr_add_char(vstr, MP_OBJ_SMALL_INT_VALUE(item));
|
||||
} else {
|
||||
*data++ = MP_OBJ_SMALL_INT_VALUE(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (len == -1) {
|
||||
vstr_shrink(vstr);
|
||||
// TODO: Optimize, borrow buffer from vstr
|
||||
len = vstr_len(vstr);
|
||||
o = mp_obj_str_builder_start(&bytes_type, len, &data);
|
||||
memcpy(data, vstr_str(vstr), len);
|
||||
vstr_free(vstr);
|
||||
}
|
||||
|
||||
return mp_obj_str_builder_end(o);
|
||||
|
||||
wrong_args:
|
||||
nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "wrong number of arguments"));
|
||||
}
|
||||
|
||||
// like strstr but with specified length and allows \0 bytes
|
||||
// TODO replace with something more efficient/standard
|
||||
STATIC const byte *find_subbytes(const byte *haystack, uint hlen, const byte *needle, uint nlen) {
|
||||
@ -520,6 +626,62 @@ STATIC mp_obj_t str_count(uint n_args, const mp_obj_t *args) {
|
||||
return MP_OBJ_NEW_SMALL_INT(num_occurrences);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, machine_int_t direction) {
|
||||
assert(MP_OBJ_IS_STR(self_in));
|
||||
if (!MP_OBJ_IS_STR(arg)) {
|
||||
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"Can't convert '%s' object to str implicitly", mp_obj_get_type_str(arg)));
|
||||
}
|
||||
|
||||
GET_STR_DATA_LEN(self_in, str, str_len);
|
||||
GET_STR_DATA_LEN(arg, sep, sep_len);
|
||||
|
||||
if (sep_len == 0) {
|
||||
nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "empty separator"));
|
||||
}
|
||||
|
||||
mp_obj_t result[] = {MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_)};
|
||||
|
||||
if (direction > 0) {
|
||||
result[0] = self_in;
|
||||
} else {
|
||||
result[2] = self_in;
|
||||
}
|
||||
|
||||
if (str_len >= sep_len) {
|
||||
machine_uint_t str_index, str_index_end;
|
||||
if (direction > 0) {
|
||||
str_index = 0;
|
||||
str_index_end = str_len - sep_len;
|
||||
} else {
|
||||
str_index = str_len - sep_len;
|
||||
str_index_end = 0;
|
||||
}
|
||||
for (;;) {
|
||||
if (memcmp(&str[str_index], sep, sep_len) == 0) {
|
||||
result[0] = mp_obj_new_str(str, str_index, false);
|
||||
result[1] = arg;
|
||||
result[2] = mp_obj_new_str(str + str_index + sep_len, str_len - str_index - sep_len, false);
|
||||
break;
|
||||
}
|
||||
if (str_index == str_index_end) {
|
||||
break;
|
||||
}
|
||||
str_index += direction;
|
||||
}
|
||||
}
|
||||
|
||||
return mp_obj_new_tuple(3, result);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_partition(mp_obj_t self_in, mp_obj_t arg) {
|
||||
return str_partitioner(self_in, arg, 1);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) {
|
||||
return str_partitioner(self_in, arg, -1);
|
||||
}
|
||||
|
||||
STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, int flags) {
|
||||
if (flags == BUFFER_READ) {
|
||||
GET_STR_DATA_LEN(self_in, str_data, str_len);
|
||||
@ -542,6 +704,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_partition_obj, str_partition);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_rpartition_obj, str_rpartition);
|
||||
|
||||
STATIC const mp_method_t str_type_methods[] = {
|
||||
{ "find", &str_find_obj },
|
||||
@ -552,6 +716,8 @@ STATIC const mp_method_t str_type_methods[] = {
|
||||
{ "format", &str_format_obj },
|
||||
{ "replace", &str_replace_obj },
|
||||
{ "count", &str_count_obj },
|
||||
{ "partition", &str_partition_obj },
|
||||
{ "rpartition", &str_rpartition_obj },
|
||||
{ NULL, NULL }, // end-of-list sentinel
|
||||
};
|
||||
|
||||
@ -559,6 +725,7 @@ const mp_obj_type_t str_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_str,
|
||||
.print = str_print,
|
||||
.make_new = str_make_new,
|
||||
.binary_op = str_binary_op,
|
||||
.getiter = mp_obj_new_str_iterator,
|
||||
.methods = str_type_methods,
|
||||
@ -570,34 +737,45 @@ const mp_obj_type_t bytes_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_bytes,
|
||||
.print = str_print,
|
||||
.make_new = bytes_make_new,
|
||||
.binary_op = str_binary_op,
|
||||
.getiter = mp_obj_new_bytes_iterator,
|
||||
.methods = str_type_methods,
|
||||
};
|
||||
|
||||
// the zero-length bytes
|
||||
STATIC const mp_obj_str_t empty_bytes_obj = {{&bytes_type}, 0, 0, NULL};
|
||||
const mp_obj_t mp_const_empty_bytes = (mp_obj_t)&empty_bytes_obj;
|
||||
|
||||
mp_obj_t mp_obj_str_builder_start(const mp_obj_type_t *type, uint len, byte **data) {
|
||||
mp_obj_str_t *o = m_new_obj_var(mp_obj_str_t, byte, len + 1);
|
||||
mp_obj_str_t *o = m_new_obj(mp_obj_str_t);
|
||||
o->base.type = type;
|
||||
o->len = len;
|
||||
*data = o->data;
|
||||
byte *p = m_new(byte, len + 1);
|
||||
o->data = p;
|
||||
*data = p;
|
||||
return o;
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_str_builder_end(mp_obj_t o_in) {
|
||||
assert(MP_OBJ_IS_STR(o_in));
|
||||
mp_obj_str_t *o = o_in;
|
||||
o->hash = qstr_compute_hash(o->data, o->len);
|
||||
o->data[o->len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
|
||||
byte *p = (byte*)o->data;
|
||||
p[o->len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
|
||||
return o;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_new(const mp_obj_type_t *type, const byte* data, uint len) {
|
||||
mp_obj_str_t *o = m_new_obj_var(mp_obj_str_t, byte, len + 1);
|
||||
mp_obj_str_t *o = m_new_obj(mp_obj_str_t);
|
||||
o->base.type = type;
|
||||
o->hash = qstr_compute_hash(data, len);
|
||||
o->len = len;
|
||||
memcpy(o->data, data, len * sizeof(byte));
|
||||
o->data[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
|
||||
if (data) {
|
||||
o->hash = qstr_compute_hash(data, len);
|
||||
byte *p = m_new(byte, len + 1);
|
||||
o->data = p;
|
||||
memcpy(p, data, len * sizeof(byte));
|
||||
p[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
|
278
py/parsenum.c
278
py/parsenum.c
@ -9,139 +9,217 @@
|
||||
#include "parsenumbase.h"
|
||||
#include "parsenum.h"
|
||||
|
||||
#if defined(UNIX)
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#if MICROPY_ENABLE_FLOAT
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) {
|
||||
// TODO at the moment we ignore len; we should honour it!
|
||||
// TODO detect integer overflow and return bignum
|
||||
|
||||
int c, neg = 0;
|
||||
const char *p = str;
|
||||
char *num;
|
||||
long found;
|
||||
const char *restrict top = str + len;
|
||||
bool neg = false;
|
||||
|
||||
// check radix base
|
||||
if ((base != 0 && base < 2) || base > 36) {
|
||||
nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "ValueError: int() arg 2 must be >=2 and <= 36"));
|
||||
}
|
||||
// skip surrounded whitespace
|
||||
while (isspace((c = *(p++))));
|
||||
if (c == 0) {
|
||||
goto value_error;
|
||||
}
|
||||
// preced sign
|
||||
if (c == '+' || c == '-') {
|
||||
neg = - (c == '-');
|
||||
} else {
|
||||
p--;
|
||||
|
||||
// skip leading space
|
||||
for (; str < top && unichar_isspace(*str); str++) {
|
||||
}
|
||||
|
||||
len -= p - str;
|
||||
int skip = mp_parse_num_base(p, len, &base);
|
||||
p += skip;
|
||||
len -= skip;
|
||||
|
||||
errno = 0;
|
||||
found = strtol(p, &num, base);
|
||||
if (errno) {
|
||||
goto value_error;
|
||||
} else if (found && *(num) == 0) {
|
||||
goto done;
|
||||
} else if (found || num != p) {
|
||||
goto check_tail_space;
|
||||
} else {
|
||||
goto value_error;
|
||||
}
|
||||
|
||||
check_tail_space:
|
||||
if (*(num) != 0) {
|
||||
while (isspace((c = *(num++))));
|
||||
if (c != 0) {
|
||||
goto value_error;
|
||||
// parse optional sign
|
||||
if (str < top) {
|
||||
if (*str == '+') {
|
||||
str++;
|
||||
} else if (*str == '-') {
|
||||
str++;
|
||||
neg = true;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return MP_OBJ_NEW_SMALL_INT((found ^ neg) - neg);
|
||||
// parse optional base prefix
|
||||
str += mp_parse_num_base(str, top - str, &base);
|
||||
|
||||
// string should be an integer number
|
||||
machine_int_t int_val = 0;
|
||||
const char *restrict str_val_start = str;
|
||||
for (; str < top; str++) {
|
||||
machine_int_t old_val = int_val;
|
||||
int dig = *str;
|
||||
if (unichar_isdigit(dig) && dig - '0' < base) {
|
||||
// 0-9 digit
|
||||
int_val = base * int_val + dig - '0';
|
||||
} else if (base == 16) {
|
||||
dig |= 0x20;
|
||||
if ('a' <= dig && dig <= 'f') {
|
||||
// a-f hex digit
|
||||
int_val = base * int_val + dig - 'a' + 10;
|
||||
} else {
|
||||
// unknown character
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// unknown character
|
||||
break;
|
||||
}
|
||||
if (int_val < old_val) {
|
||||
// If new value became less than previous, it's overflow
|
||||
goto overflow;
|
||||
} else if ((old_val ^ int_val) & WORD_MSBIT_HIGH) {
|
||||
// If signed number changed sign - it's overflow
|
||||
goto overflow;
|
||||
}
|
||||
}
|
||||
|
||||
// check we parsed something
|
||||
if (str == str_val_start) {
|
||||
goto value_error;
|
||||
}
|
||||
|
||||
// negate value if needed
|
||||
if (neg) {
|
||||
int_val = -int_val;
|
||||
}
|
||||
|
||||
// skip trailing space
|
||||
for (; str < top && unichar_isspace(*str); str++) {
|
||||
}
|
||||
|
||||
// check we reached the end of the string
|
||||
if (str != top) {
|
||||
goto value_error;
|
||||
}
|
||||
|
||||
// return the object
|
||||
return MP_OBJ_NEW_SMALL_INT(int_val);
|
||||
|
||||
value_error:
|
||||
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid literal for int() with base %d: '%s'", base, str));
|
||||
|
||||
overflow:
|
||||
// TODO reparse using bignum
|
||||
nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "overflow parsing integer"));
|
||||
}
|
||||
|
||||
#else /* defined(UNIX) */
|
||||
|
||||
mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) {
|
||||
// TODO port strtol to stm
|
||||
return MP_OBJ_NEW_SMALL_INT(0);
|
||||
}
|
||||
|
||||
#endif /* defined(UNIX) */
|
||||
|
||||
#define PARSE_DEC_IN_INTG (1)
|
||||
#define PARSE_DEC_IN_FRAC (2)
|
||||
#define PARSE_DEC_IN_EXP (3)
|
||||
|
||||
mp_obj_t mp_parse_num_decimal(const char *str, uint len) {
|
||||
mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag, bool force_complex) {
|
||||
#if MICROPY_ENABLE_FLOAT
|
||||
int in = PARSE_DEC_IN_INTG;
|
||||
mp_float_t dec_val = 0;
|
||||
bool exp_neg = false;
|
||||
int exp_val = 0;
|
||||
int exp_extra = 0;
|
||||
bool imag = false;
|
||||
const char *top = str + len;
|
||||
for (; str < top; str++) {
|
||||
int dig = *str;
|
||||
if ('0' <= dig && dig <= '9') {
|
||||
dig -= '0';
|
||||
if (in == PARSE_DEC_IN_EXP) {
|
||||
exp_val = 10 * exp_val + dig;
|
||||
} else {
|
||||
dec_val = 10 * dec_val + dig;
|
||||
if (in == PARSE_DEC_IN_FRAC) {
|
||||
exp_extra -= 1;
|
||||
}
|
||||
}
|
||||
} else if (in == PARSE_DEC_IN_INTG && dig == '.') {
|
||||
in = PARSE_DEC_IN_FRAC;
|
||||
} else if (in != PARSE_DEC_IN_EXP && (dig == 'E' || dig == 'e')) {
|
||||
in = PARSE_DEC_IN_EXP;
|
||||
if (str[1] == '+') {
|
||||
str++;
|
||||
} else if (str[1] == '-') {
|
||||
str++;
|
||||
exp_neg = true;
|
||||
}
|
||||
} else if (dig == 'J' || dig == 'j') {
|
||||
mp_float_t dec_val = 0;
|
||||
bool dec_neg = false;
|
||||
bool imag = false;
|
||||
|
||||
// skip leading space
|
||||
for (; str < top && unichar_isspace(*str); str++) {
|
||||
}
|
||||
|
||||
// parse optional sign
|
||||
if (str < top) {
|
||||
if (*str == '+') {
|
||||
str++;
|
||||
imag = true;
|
||||
break;
|
||||
} else {
|
||||
// unknown character
|
||||
break;
|
||||
} else if (*str == '-') {
|
||||
str++;
|
||||
dec_neg = true;
|
||||
}
|
||||
}
|
||||
if (*str != 0) {
|
||||
|
||||
// determine what the string is
|
||||
if (str < top && (str[0] | 0x20) == 'i') {
|
||||
// string starts with 'i', should be 'inf' or 'infinity' (case insensitive)
|
||||
if (str + 2 < top && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'f') {
|
||||
// inf
|
||||
str += 3;
|
||||
dec_val = INFINITY;
|
||||
if (str + 4 < top && (str[0] | 0x20) == 'i' && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'i' && (str[3] | 0x20) == 't' && (str[4] | 0x20) == 'y') {
|
||||
// infinity
|
||||
str += 5;
|
||||
}
|
||||
}
|
||||
} else if (str < top && (str[0] | 0x20) == 'n') {
|
||||
// string starts with 'n', should be 'nan' (case insensitive)
|
||||
if (str + 2 < top && (str[1] | 0x20) == 'a' && (str[2] | 0x20) == 'n') {
|
||||
// NaN
|
||||
str += 3;
|
||||
dec_val = MICROPY_FLOAT_C_FUN(nan)("");
|
||||
}
|
||||
} else {
|
||||
// string should be a decimal number
|
||||
int in = PARSE_DEC_IN_INTG;
|
||||
bool exp_neg = false;
|
||||
int exp_val = 0;
|
||||
int exp_extra = 0;
|
||||
for (; str < top; str++) {
|
||||
int dig = *str;
|
||||
if ('0' <= dig && dig <= '9') {
|
||||
dig -= '0';
|
||||
if (in == PARSE_DEC_IN_EXP) {
|
||||
exp_val = 10 * exp_val + dig;
|
||||
} else {
|
||||
dec_val = 10 * dec_val + dig;
|
||||
if (in == PARSE_DEC_IN_FRAC) {
|
||||
exp_extra -= 1;
|
||||
}
|
||||
}
|
||||
} else if (in == PARSE_DEC_IN_INTG && dig == '.') {
|
||||
in = PARSE_DEC_IN_FRAC;
|
||||
} else if (in != PARSE_DEC_IN_EXP && ((dig | 0x20) == 'e')) {
|
||||
in = PARSE_DEC_IN_EXP;
|
||||
if (str[1] == '+') {
|
||||
str++;
|
||||
} else if (str[1] == '-') {
|
||||
str++;
|
||||
exp_neg = true;
|
||||
}
|
||||
} else if (allow_imag && (dig | 0x20) == 'j') {
|
||||
str++;
|
||||
imag = true;
|
||||
break;
|
||||
} else {
|
||||
// unknown character
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// work out the exponent
|
||||
if (exp_neg) {
|
||||
exp_val = -exp_val;
|
||||
}
|
||||
exp_val += exp_extra;
|
||||
|
||||
// apply the exponent
|
||||
for (; exp_val > 0; exp_val--) {
|
||||
dec_val *= 10;
|
||||
}
|
||||
for (; exp_val < 0; exp_val++) {
|
||||
dec_val *= 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
// negate value if needed
|
||||
if (dec_neg) {
|
||||
dec_val = -dec_val;
|
||||
}
|
||||
|
||||
// skip trailing space
|
||||
for (; str < top && unichar_isspace(*str); str++) {
|
||||
}
|
||||
|
||||
// check we reached the end of the string
|
||||
if (str != top) {
|
||||
nlr_jump(mp_obj_new_exception_msg(&mp_type_SyntaxError, "invalid syntax for number"));
|
||||
}
|
||||
if (exp_neg) {
|
||||
exp_val = -exp_val;
|
||||
}
|
||||
exp_val += exp_extra;
|
||||
for (; exp_val > 0; exp_val--) {
|
||||
dec_val *= 10;
|
||||
}
|
||||
for (; exp_val < 0; exp_val++) {
|
||||
dec_val *= 0.1;
|
||||
}
|
||||
|
||||
// return the object
|
||||
if (imag) {
|
||||
return mp_obj_new_complex(0, dec_val);
|
||||
} else if (force_complex) {
|
||||
return mp_obj_new_complex(dec_val, 0);
|
||||
} else {
|
||||
return mp_obj_new_float(dec_val);
|
||||
}
|
||||
|
||||
#else
|
||||
nlr_jump(mp_obj_new_exception_msg(&mp_type_SyntaxError, "decimal numbers not supported"));
|
||||
#endif
|
||||
|
@ -1,2 +1,2 @@
|
||||
mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base);
|
||||
mp_obj_t mp_parse_num_decimal(const char *str, uint len);
|
||||
mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag, bool force_complex);
|
||||
|
@ -89,6 +89,7 @@ STATIC const mp_builtin_elem_t builtin_table[] = {
|
||||
|
||||
// built-in types
|
||||
{ MP_QSTR_bool, (mp_obj_t)&bool_type },
|
||||
{ MP_QSTR_bytes, (mp_obj_t)&bytes_type },
|
||||
#if MICROPY_ENABLE_FLOAT
|
||||
{ MP_QSTR_complex, (mp_obj_t)&mp_type_complex },
|
||||
#endif
|
||||
@ -102,6 +103,7 @@ STATIC const mp_builtin_elem_t builtin_table[] = {
|
||||
{ MP_QSTR_list, (mp_obj_t)&list_type },
|
||||
{ MP_QSTR_map, (mp_obj_t)&map_type },
|
||||
{ MP_QSTR_set, (mp_obj_t)&set_type },
|
||||
{ MP_QSTR_str, (mp_obj_t)&str_type },
|
||||
{ MP_QSTR_super, (mp_obj_t)&super_type },
|
||||
{ MP_QSTR_tuple, (mp_obj_t)&tuple_type },
|
||||
{ MP_QSTR_type, (mp_obj_t)&mp_type_type },
|
||||
@ -114,7 +116,6 @@ STATIC const mp_builtin_elem_t builtin_table[] = {
|
||||
{ MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj },
|
||||
{ MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj },
|
||||
{ MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj },
|
||||
{ MP_QSTR_bytes, (mp_obj_t)&mp_builtin_bytes_obj },
|
||||
{ MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj },
|
||||
{ MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj },
|
||||
{ MP_QSTR_dir, (mp_obj_t)&mp_builtin_dir_obj },
|
||||
@ -137,7 +138,6 @@ STATIC const mp_builtin_elem_t builtin_table[] = {
|
||||
{ MP_QSTR_repr, (mp_obj_t)&mp_builtin_repr_obj },
|
||||
{ MP_QSTR_sorted, (mp_obj_t)&mp_builtin_sorted_obj },
|
||||
{ MP_QSTR_sum, (mp_obj_t)&mp_builtin_sum_obj },
|
||||
{ MP_QSTR_str, (mp_obj_t)&mp_builtin_str_obj },
|
||||
{ MP_QSTR_bytearray, (mp_obj_t)&mp_builtin_bytearray_obj },
|
||||
|
||||
// built-in exceptions
|
||||
@ -376,7 +376,7 @@ mp_obj_t rt_load_const_dec(qstr qstr) {
|
||||
DEBUG_OP_printf("load '%s'\n", qstr_str(qstr));
|
||||
uint len;
|
||||
const byte* data = qstr_data(qstr, &len);
|
||||
return mp_parse_num_decimal((const char*)data, len);
|
||||
return mp_parse_num_decimal((const char*)data, len, true, false);
|
||||
}
|
||||
|
||||
mp_obj_t rt_load_const_str(qstr qstr) {
|
||||
|
@ -394,6 +394,10 @@ void mp_byte_code_print(const byte *ip, int len) {
|
||||
printf("YIELD_VALUE");
|
||||
break;
|
||||
|
||||
case MP_BC_YIELD_FROM:
|
||||
printf("YIELD_FROM");
|
||||
break;
|
||||
|
||||
case MP_BC_IMPORT_NAME:
|
||||
DECODE_QSTR;
|
||||
printf("IMPORT_NAME %s", qstr_str(qstr));
|
||||
|
@ -44,6 +44,10 @@ float acosf(float x) { return 0.0; }
|
||||
float asinf(float x) { return 0.0; }
|
||||
float atanf(float x) { return 0.0; }
|
||||
float atan2f(float x, float y) { return 0.0; }
|
||||
float ceilf(float x) { return 0.0; }
|
||||
float floorf(float x) { return 0.0; }
|
||||
float truncf(float x) { return 0.0; }
|
||||
float fmodf(float x, float y) { return 0.0; }
|
||||
|
||||
/*****************************************************************************/
|
||||
// from musl-0.9.15 libm.h
|
||||
|
@ -21,7 +21,7 @@ INC += -I$(PY_SRC)
|
||||
INC += -I$(CMSIS_DIR)/inc
|
||||
INC += -I$(CMSIS_DIR)/devinc
|
||||
INC += -I$(HAL_DIR)/inc
|
||||
INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/cdc/inc
|
||||
INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/cdc/inc -I$(USBDEV_DIR)/class/msc/inc
|
||||
#INC += -I$(USBHOST_DIR)
|
||||
INC += -I$(FATFS_DIR)/src
|
||||
#INC += -I$(CC3K_DIR)
|
||||
@ -56,8 +56,10 @@ SRC_C = \
|
||||
stm32f4xx_it.c \
|
||||
stm32f4xx_hal_msp.c \
|
||||
usbd_conf.c \
|
||||
usbd_desc.c \
|
||||
usbd_desc_vcp.c \
|
||||
usbd_cdc_interface.c \
|
||||
usbd_desc_msc.c \
|
||||
usbd_msc_storage.c \
|
||||
pendsv.c \
|
||||
systick.c \
|
||||
led.c \
|
||||
@ -84,9 +86,9 @@ SRC_C = \
|
||||
sdcard.c \
|
||||
diskio.c \
|
||||
lcd.c \
|
||||
accel.c \
|
||||
|
||||
# servo.c \
|
||||
# accel.c \
|
||||
# timer.c \
|
||||
# audio.c \
|
||||
# i2c.c \
|
||||
@ -104,6 +106,7 @@ SRC_HAL = $(addprefix $(HAL_DIR)/src/,\
|
||||
stm32f4xx_hal_flash.c \
|
||||
stm32f4xx_hal_flash_ex.c \
|
||||
stm32f4xx_hal_gpio.c \
|
||||
stm32f4xx_hal_i2c.c \
|
||||
stm32f4xx_hal_pcd.c \
|
||||
stm32f4xx_hal_rcc.c \
|
||||
stm32f4xx_hal_rcc_ex.c \
|
||||
@ -122,6 +125,10 @@ SRC_USBDEV = $(addprefix $(USBDEV_DIR)/,\
|
||||
core/src/usbd_ctlreq.c \
|
||||
core/src/usbd_ioreq.c \
|
||||
class/cdc/src/usbd_cdc.c \
|
||||
class/msc/src/usbd_msc.c \
|
||||
class/msc/src/usbd_msc_bot.c \
|
||||
class/msc/src/usbd_msc_scsi.c \
|
||||
class/msc/src/usbd_msc_data.c \
|
||||
)
|
||||
|
||||
# usbd_core.c \
|
||||
|
137
stmhal/accel.c
Normal file
137
stmhal/accel.c
Normal file
@ -0,0 +1,137 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stm32f4xx_hal.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "accel.h"
|
||||
|
||||
#define MMA_ADDR (0x98)
|
||||
#define MMA_REG_MODE (7)
|
||||
|
||||
STATIC I2C_HandleTypeDef I2cHandle;
|
||||
|
||||
void accel_init(void) {
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
// PB5 is connected to AVDD; pull high to enable MMA accel device
|
||||
GPIOB->BSRRH = GPIO_PIN_5; // turn off AVDD
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_5;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
// wait 20ms, then turn on AVDD, then wait 20ms again
|
||||
HAL_Delay(20);
|
||||
GPIOB->BSRRL = GPIO_PIN_5;
|
||||
HAL_Delay(20);
|
||||
|
||||
// PB6=SCL, PB7=SDA
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL; // have external pull-up resistors on both lines
|
||||
GPIO_InitStructure.Alternate = GPIO_AF4_I2C1;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
// enable the I2C1 clock
|
||||
__I2C1_CLK_ENABLE();
|
||||
|
||||
// set up the I2C1 device
|
||||
memset(&I2cHandle, 0, sizeof(I2C_HandleTypeDef));
|
||||
I2cHandle.Instance = I2C1;
|
||||
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||||
I2cHandle.Init.ClockSpeed = 400000;
|
||||
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
|
||||
I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_16_9;
|
||||
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
|
||||
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
|
||||
I2cHandle.Init.OwnAddress1 = 0xfe; // unused
|
||||
I2cHandle.Init.OwnAddress2 = 0xfe; // unused
|
||||
|
||||
if (HAL_I2C_Init(&I2cHandle) != HAL_OK) {
|
||||
// init error
|
||||
printf("accel_init: HAL_I2C_Init failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
//printf("IsDeviceReady\n");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
status = HAL_I2C_IsDeviceReady(&I2cHandle, MMA_ADDR, 10, 200);
|
||||
//printf(" got %d\n", status);
|
||||
if (status == HAL_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//printf("MemWrite\n");
|
||||
uint8_t data[1];
|
||||
data[0] = 1; // active mode
|
||||
status = HAL_I2C_Mem_Write(&I2cHandle, MMA_ADDR, MMA_REG_MODE, I2C_MEMADD_SIZE_8BIT, data, 1, 200);
|
||||
//printf(" got %d\n", status);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
int accel_buf[12];
|
||||
|
||||
mp_obj_t pyb_accel_read(void) {
|
||||
for (int i = 0; i <= 6; i += 3) {
|
||||
accel_buf[0 + i] = accel_buf[0 + i + 3];
|
||||
accel_buf[1 + i] = accel_buf[1 + i + 3];
|
||||
accel_buf[2 + i] = accel_buf[2 + i + 3];
|
||||
}
|
||||
|
||||
uint8_t data_[4];
|
||||
HAL_I2C_Mem_Read(&I2cHandle, MMA_ADDR, 0, I2C_MEMADD_SIZE_8BIT, data_, 4, 200);
|
||||
accel_buf[9] = data_[0] & 0x3f; if (accel_buf[9] & 0x20) accel_buf[9] |= ~0x1f;
|
||||
accel_buf[10] = data_[1] & 0x3f; if (accel_buf[10] & 0x20) accel_buf[10] |= ~0x1f;
|
||||
accel_buf[11] = data_[2] & 0x3f; if (accel_buf[11] & 0x20) accel_buf[11] |= ~0x1f;
|
||||
int jolt_info = data_[3];
|
||||
|
||||
mp_obj_t data[4];
|
||||
data[0] = mp_obj_new_int(accel_buf[0] + accel_buf[3] + accel_buf[6] + accel_buf[9]);
|
||||
data[1] = mp_obj_new_int(accel_buf[1] + accel_buf[4] + accel_buf[7] + accel_buf[10]);
|
||||
data[2] = mp_obj_new_int(accel_buf[2] + accel_buf[5] + accel_buf[8] + accel_buf[11]);
|
||||
data[3] = mp_obj_new_int(jolt_info);
|
||||
|
||||
return rt_build_tuple(4, data);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_accel_read_obj, pyb_accel_read);
|
||||
|
||||
/*
|
||||
mp_obj_t pyb_accel_read_all(void) {
|
||||
mp_obj_t data[11];
|
||||
accel_start(MMA_ADDR, 1);
|
||||
accel_send_byte(0);
|
||||
accel_restart(MMA_ADDR, 0);
|
||||
for (int i = 0; i <= 9; i++) {
|
||||
data[i] = mp_obj_new_int(accel_read_ack());
|
||||
}
|
||||
data[10] = mp_obj_new_int(accel_read_nack());
|
||||
|
||||
return rt_build_tuple(11, data);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_accel_read_all_obj, pyb_accel_read_all);
|
||||
|
||||
mp_obj_t pyb_accel_write_mode(mp_obj_t o_int, mp_obj_t o_mode) {
|
||||
accel_start(MMA_ADDR, 1);
|
||||
accel_send_byte(6); // start at int
|
||||
accel_send_byte(mp_obj_get_int(o_int));
|
||||
accel_send_byte(mp_obj_get_int(o_mode));
|
||||
accel_stop();
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(pyb_accel_write_mode_obj, pyb_accel_write_mode);
|
||||
*/
|
11
stmhal/accel.h
Normal file
11
stmhal/accel.h
Normal file
@ -0,0 +1,11 @@
|
||||
void accel_init(void);
|
||||
void accel_restart(uint8_t addr, int write);
|
||||
void accel_start(uint8_t addr, int write);
|
||||
void accel_send_byte(uint8_t data);
|
||||
uint8_t accel_read_ack(void);
|
||||
uint8_t accel_read_nack(void);
|
||||
void accel_stop(void);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_accel_read_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_accel_read_all_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_accel_write_mode_obj);
|
@ -1,16 +1,18 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#if 0
|
||||
#include "ff.h"
|
||||
#endif
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
#if 0
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
FRESULT res = f_stat(path, &fno);
|
||||
if (res == FR_OK) {
|
||||
if ((fno.fattrib & AM_DIR) != 0) {
|
||||
@ -19,6 +21,5 @@ mp_import_stat_t mp_import_stat(const char *path) {
|
||||
return MP_IMPORT_STAT_FILE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
@ -73,6 +73,14 @@ void led_toggle(pyb_led_t led) {
|
||||
}
|
||||
}
|
||||
|
||||
void led_debug(int n, int delay) {
|
||||
led_state(1, n & 1);
|
||||
led_state(2, n & 2);
|
||||
led_state(3, n & 4);
|
||||
led_state(4, n & 8);
|
||||
HAL_Delay(delay);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
|
@ -19,5 +19,6 @@ typedef enum {
|
||||
void led_init(void);
|
||||
void led_state(pyb_led_t led, int state);
|
||||
void led_toggle(pyb_led_t led);
|
||||
void led_debug(int value, int delay);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_Led_obj);
|
||||
|
@ -33,9 +33,9 @@
|
||||
#include "sdcard.h"
|
||||
#include "ff.h"
|
||||
#include "lcd.h"
|
||||
#include "accel.h"
|
||||
#if 0
|
||||
#include "servo.h"
|
||||
#include "accel.h"
|
||||
#include "timer.h"
|
||||
#include "pybwlan.h"
|
||||
#include "pin.h"
|
||||
@ -170,22 +170,6 @@ int main(void) {
|
||||
// enable the CCM RAM
|
||||
__CCMDATARAMEN_CLK_ENABLE();
|
||||
|
||||
// some test code to flash LEDs
|
||||
led_init();
|
||||
|
||||
led_state(0, 1);
|
||||
led_state(1, 0);
|
||||
led_state(2, 1);
|
||||
|
||||
#if 0
|
||||
for (;;) {
|
||||
HAL_Delay(500);
|
||||
led_state(1, 1);
|
||||
HAL_Delay(500);
|
||||
led_state(1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if defined(NETDUINO_PLUS_2)
|
||||
{
|
||||
@ -348,6 +332,11 @@ soft_reset:
|
||||
// make sure we have a /boot.py
|
||||
{
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
led_debug(0, 500);
|
||||
FRESULT res = f_stat("0:/boot.py", &fno);
|
||||
if (res == FR_OK) {
|
||||
if (fno.fattrib & AM_DIR) {
|
||||
@ -382,18 +371,13 @@ soft_reset:
|
||||
flash_error(4);
|
||||
}
|
||||
|
||||
if (first_soft_reset) {
|
||||
#if 0
|
||||
#if MICROPY_HW_HAS_MMA7660
|
||||
// MMA accel: init and reset address to zero
|
||||
accel_init();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// turn boot-up LED off
|
||||
led_state(PYB_LED_GREEN, 0);
|
||||
|
||||
#if defined(USE_DEVICE_MODE)
|
||||
usbd_storage_medium_kind_t usbd_medium_kind = USBD_STORAGE_MEDIUM_FLASH;
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
// if an SD card is present then mount it on 1:/
|
||||
if (sdcard_is_present()) {
|
||||
@ -403,8 +387,8 @@ soft_reset:
|
||||
} else {
|
||||
if (first_soft_reset) {
|
||||
// use SD card as medium for the USB MSD
|
||||
#if 0
|
||||
usbd_storage_select_medium(USBD_STORAGE_MEDIUM_SDCARD);
|
||||
#if defined(USE_DEVICE_MODE)
|
||||
usbd_medium_kind = USBD_STORAGE_MEDIUM_SDCARD;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -416,7 +400,12 @@ soft_reset:
|
||||
pyb_usb_host_init();
|
||||
#elif defined(USE_DEVICE_MODE)
|
||||
// USB device
|
||||
pyb_usb_dev_init(PYB_USB_DEV_VCP_MSC);
|
||||
pyb_usb_dev_init(USBD_DEVICE_MSC, usbd_medium_kind);
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_HAS_MMA7660
|
||||
// MMA accel: init and reset
|
||||
accel_init();
|
||||
#endif
|
||||
|
||||
// run main script
|
||||
|
@ -44,6 +44,10 @@ float acosf(float x) { return 0.0; }
|
||||
float asinf(float x) { return 0.0; }
|
||||
float atanf(float x) { return 0.0; }
|
||||
float atan2f(float x, float y) { return 0.0; }
|
||||
float ceilf(float x) { return 0.0; }
|
||||
float floorf(float x) { return 0.0; }
|
||||
float truncf(float x) { return 0.0; }
|
||||
float fmodf(float x, float y) { return 0.0; }
|
||||
|
||||
/*****************************************************************************/
|
||||
// from musl-0.9.15 libm.h
|
||||
|
@ -21,10 +21,10 @@
|
||||
#include "usart.h"
|
||||
#include "storage.h"
|
||||
#include "sdcard.h"
|
||||
#include "accel.h"
|
||||
#if 0
|
||||
#include "servo.h"
|
||||
#include "usb.h"
|
||||
#include "accel.h"
|
||||
#include "i2c.h"
|
||||
#include "adc.h"
|
||||
#include "audio.h"
|
||||
@ -256,13 +256,13 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sdcard_obj },
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if MICROPY_HW_HAS_MMA7660
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_accel), (mp_obj_t)&pyb_accel_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_accel_read), (mp_obj_t)&pyb_accel_read_all_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_accel_mode), (mp_obj_t)&pyb_accel_write_mode_obj },
|
||||
//{ MP_OBJ_NEW_QSTR(MP_QSTR_accel_read), (mp_obj_t)&pyb_accel_read_all_obj },
|
||||
//{ MP_OBJ_NEW_QSTR(MP_QSTR_accel_mode), (mp_obj_t)&pyb_accel_write_mode_obj },
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hid), (mp_obj_t)&pyb_hid_send_report_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Led), (mp_obj_t)&pyb_Led_obj },
|
||||
|
30
stmhal/usb.c
30
stmhal/usb.c
@ -1,21 +1,16 @@
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
#include "usb_core.h"
|
||||
#include "usbd_cdc_core.h"
|
||||
#include "usbd_pyb_core.h"
|
||||
#include "usbd_usr.h"
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_desc.h"
|
||||
#include "usbd_cdc.h"
|
||||
#include "usbd_cdc_interface.h"
|
||||
#include "usbd_msc.h"
|
||||
#include "usbd_msc_storage.h"
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
//#include "pendsv.h"
|
||||
#include "usb.h"
|
||||
|
||||
#ifdef USE_DEVICE_MODE
|
||||
@ -26,12 +21,12 @@ static int dev_is_enabled = 0;
|
||||
uint32_t APP_dev_is_connected = 0; /* used by usbd_cdc_vcp */
|
||||
mp_obj_t mp_const_vcp_interrupt = MP_OBJ_NULL;
|
||||
|
||||
void pyb_usb_dev_init(int usb_dev_type) {
|
||||
void pyb_usb_dev_init(usbd_device_kind_t device_kind, usbd_storage_medium_kind_t medium_kind) {
|
||||
#ifdef USE_DEVICE_MODE
|
||||
if (!dev_is_enabled) {
|
||||
// only init USB once in the device's power-lifetime
|
||||
switch (usb_dev_type) {
|
||||
case PYB_USB_DEV_VCP_MSC:
|
||||
switch (device_kind) {
|
||||
case USBD_DEVICE_CDC:
|
||||
// XXX USBD_CDC_Init (called by one of these functions below) uses malloc,
|
||||
// so the memory is invalid after a soft reset (which resets the GC).
|
||||
USBD_Init(&hUSBDDevice, &VCP_Desc, 0);
|
||||
@ -41,7 +36,20 @@ void pyb_usb_dev_init(int usb_dev_type) {
|
||||
//USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_cb, &USR_cb);
|
||||
break;
|
||||
|
||||
case PYB_USB_DEV_HID:
|
||||
case USBD_DEVICE_MSC:
|
||||
// XXX USBD_CDC_Init (called by one of these functions below) uses malloc,
|
||||
// so the memory is invalid after a soft reset (which resets the GC).
|
||||
USBD_Init(&hUSBDDevice, &MSC_Desc, 0);
|
||||
USBD_RegisterClass(&hUSBDDevice, &USBD_MSC);
|
||||
if (medium_kind == USBD_STORAGE_MEDIUM_FLASH) {
|
||||
USBD_MSC_RegisterStorage(&hUSBDDevice, (USBD_StorageTypeDef*)&USBD_FLASH_STORAGE_fops);
|
||||
} else {
|
||||
USBD_MSC_RegisterStorage(&hUSBDDevice, (USBD_StorageTypeDef*)&USBD_SDCARD_STORAGE_fops);
|
||||
}
|
||||
USBD_Start(&hUSBDDevice);
|
||||
break;
|
||||
|
||||
case USBD_DEVICE_HID:
|
||||
//USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_HID_cb, &USR_cb);
|
||||
// TODO
|
||||
break;
|
||||
|
14
stmhal/usb.h
14
stmhal/usb.h
@ -4,10 +4,18 @@
|
||||
#define VCP_CHAR_CTRL_C (3)
|
||||
#define VCP_CHAR_CTRL_D (4)
|
||||
|
||||
#define PYB_USB_DEV_VCP_MSC (0)
|
||||
#define PYB_USB_DEV_HID (1)
|
||||
typedef enum {
|
||||
USBD_DEVICE_CDC,
|
||||
USBD_DEVICE_MSC,
|
||||
USBD_DEVICE_HID,
|
||||
} usbd_device_kind_t;
|
||||
|
||||
void pyb_usb_dev_init(int usb_dev_type);
|
||||
typedef enum {
|
||||
USBD_STORAGE_MEDIUM_FLASH,
|
||||
USBD_STORAGE_MEDIUM_SDCARD,
|
||||
} usbd_storage_medium_kind_t;
|
||||
|
||||
void pyb_usb_dev_init(usbd_device_kind_t device_kind, usbd_storage_medium_kind_t medium_kind);
|
||||
bool usb_vcp_is_enabled(void);
|
||||
bool usb_vcp_is_connected(void);
|
||||
void usb_vcp_set_interrupt_char(int c);
|
||||
|
@ -48,6 +48,9 @@
|
||||
#define USBD_SELF_POWERED 0
|
||||
#define USBD_DEBUG_LEVEL 0
|
||||
|
||||
// for MSC device
|
||||
#define MSC_MEDIA_PACKET 8192
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Memory management macros */
|
||||
#define USBD_malloc gc_alloc
|
||||
|
@ -1,43 +1,2 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file USB_Device/CDC_Standalone/Inc/usbd_desc.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.1
|
||||
* @date 26-February-2014
|
||||
* @brief Header for usbd_desc.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_DESC_H
|
||||
#define __USBD_DESC_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
extern USBD_DescriptorsTypeDef VCP_Desc;
|
||||
|
||||
#endif /* __USBD_DESC_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
extern USBD_DescriptorsTypeDef VCP_Desc;
|
||||
extern USBD_DescriptorsTypeDef MSC_Desc;
|
||||
|
227
stmhal/usbd_desc_msc.c
Normal file
227
stmhal/usbd_desc_msc.c
Normal file
@ -0,0 +1,227 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file USB_Device/MSC_Standalone/Src/usbd_desc.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.1
|
||||
* @date 26-February-2014
|
||||
* @brief This file provides the USBD descriptors and string formating method.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_desc.h"
|
||||
#include "usbd_conf.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#define USBD_VID 0x0483
|
||||
#define USBD_PID 0x5720
|
||||
#define USBD_LANGID_STRING 0x409
|
||||
#define USBD_MANUFACTURER_STRING "STMicroelectronics"
|
||||
#define USBD_PRODUCT_HS_STRING "Mass Storage in HS Mode"
|
||||
#define USBD_SERIALNUMBER_HS_STRING "00000000001A"
|
||||
#define USBD_PRODUCT_FS_STRING "Mass Storage in FS Mode"
|
||||
#define USBD_SERIALNUMBER_FS_STRING "00000000001B"
|
||||
#define USBD_CONFIGURATION_HS_STRING "MSC Config"
|
||||
#define USBD_INTERFACE_HS_STRING "MSC Interface"
|
||||
#define USBD_CONFIGURATION_FS_STRING "MSC Config"
|
||||
#define USBD_INTERFACE_FS_STRING "MSC Interface"
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
uint8_t *USBD_MSC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_MSC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_MSC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_MSC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_MSC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_MSC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_MSC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
#ifdef USB_SUPPORT_USER_STRING_DESC
|
||||
uint8_t *USBD_MSC_USRStringDesc(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);
|
||||
#endif /* USB_SUPPORT_USER_STRING_DESC */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
USBD_DescriptorsTypeDef MSC_Desc = {
|
||||
USBD_MSC_DeviceDescriptor,
|
||||
USBD_MSC_LangIDStrDescriptor,
|
||||
USBD_MSC_ManufacturerStrDescriptor,
|
||||
USBD_MSC_ProductStrDescriptor,
|
||||
USBD_MSC_SerialStrDescriptor,
|
||||
USBD_MSC_ConfigStrDescriptor,
|
||||
USBD_MSC_InterfaceStrDescriptor,
|
||||
};
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||
#pragma data_alignment=4
|
||||
#endif
|
||||
__ALIGN_BEGIN static uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
|
||||
0x12, /* bLength */
|
||||
USB_DESC_TYPE_DEVICE, /* bDescriptorType */
|
||||
0x00, /* bcdUSB */
|
||||
0x02,
|
||||
0x00, /* bDeviceClass */
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x00, /* bDeviceProtocol */
|
||||
USB_MAX_EP0_SIZE, /* bMaxPacketSize */
|
||||
LOBYTE(USBD_VID), /* idVendor */
|
||||
HIBYTE(USBD_VID), /* idVendor */
|
||||
LOBYTE(USBD_PID), /* idVendor */
|
||||
HIBYTE(USBD_PID), /* idVendor */
|
||||
0x00, /* bcdDevice rel. 2.00 */
|
||||
0x02,
|
||||
USBD_IDX_MFC_STR, /* Index of manufacturer string */
|
||||
USBD_IDX_PRODUCT_STR, /* Index of product string */
|
||||
USBD_IDX_SERIAL_STR, /* Index of serial number string */
|
||||
USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */
|
||||
}; /* USB_DeviceDescriptor */
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||
#pragma data_alignment=4
|
||||
#endif
|
||||
__ALIGN_BEGIN static uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
|
||||
USB_LEN_LANGID_STR_DESC,
|
||||
USB_DESC_TYPE_STRING,
|
||||
LOBYTE(USBD_LANGID_STRING),
|
||||
HIBYTE(USBD_LANGID_STRING),
|
||||
};
|
||||
|
||||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||
#pragma data_alignment=4
|
||||
#endif
|
||||
__ALIGN_BEGIN static uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Returns the device descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_MSC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
*length = sizeof(USBD_DeviceDesc);
|
||||
return USBD_DeviceDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the LangID string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_MSC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
*length = sizeof(USBD_LangIDDesc);
|
||||
return USBD_LangIDDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the product string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_MSC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
if(speed == 0)
|
||||
{
|
||||
USBD_GetString((uint8_t *)(uint8_t *)USBD_PRODUCT_HS_STRING, USBD_StrDesc, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_GetString((uint8_t *)(uint8_t *)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the manufacturer string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_MSC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
USBD_GetString((uint8_t *)(uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the serial number string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_MSC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
if(speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
USBD_GetString((uint8_t *)(uint8_t *)USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_GetString((uint8_t *)(uint8_t *)USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the configuration string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_MSC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
if(speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
USBD_GetString((uint8_t *)(uint8_t *)USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_GetString((uint8_t *)(uint8_t *)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the interface string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_MSC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
if(speed == 0)
|
||||
{
|
||||
USBD_GetString((uint8_t *)(uint8_t *)USBD_INTERFACE_HS_STRING, USBD_StrDesc, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_GetString((uint8_t *)(uint8_t *)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -73,7 +73,7 @@ USBD_DescriptorsTypeDef VCP_Desc = {
|
||||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||
#pragma data_alignment=4
|
||||
#endif
|
||||
__ALIGN_BEGIN uint8_t hUSBDDeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
|
||||
__ALIGN_BEGIN static uint8_t hUSBDDeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
|
||||
0x12, /* bLength */
|
||||
USB_DESC_TYPE_DEVICE, /* bDescriptorType */
|
||||
0x00, /* bcdUSB */
|
||||
@ -98,7 +98,7 @@ __ALIGN_BEGIN uint8_t hUSBDDeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
|
||||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||
#pragma data_alignment=4
|
||||
#endif
|
||||
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
|
||||
__ALIGN_BEGIN static uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
|
||||
USB_LEN_LANGID_STR_DESC,
|
||||
USB_DESC_TYPE_STRING,
|
||||
LOBYTE(USBD_LANGID_STRING),
|
||||
@ -108,7 +108,7 @@ __ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
|
||||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||
#pragma data_alignment=4
|
||||
#endif
|
||||
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
|
||||
__ALIGN_BEGIN static uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
320
stmhal/usbd_msc_storage.c
Normal file
320
stmhal/usbd_msc_storage.c
Normal file
@ -0,0 +1,320 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_storage_msd.c
|
||||
* @author MCD application Team
|
||||
* @version V1.1.0
|
||||
* @date 19-March-2012
|
||||
* @brief This file provides the disk operations functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Heavily modified by dpgeorge for Micro Python.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "usbd_msc.h"
|
||||
#include "usbd_msc_storage.h"
|
||||
|
||||
#include "misc.h"
|
||||
#include "storage.h"
|
||||
#include "diskio.h"
|
||||
#include "sdcard.h"
|
||||
|
||||
/******************************************************************************/
|
||||
// Callback functions for when the internal flash is the mass storage device
|
||||
|
||||
static const int8_t FLASH_STORAGE_Inquirydata[] = { // 36 bytes
|
||||
// LUN 0
|
||||
0x00,
|
||||
0x00, // 0x00 for a fixed drive, 0x80 for a removable drive
|
||||
0x02,
|
||||
0x02,
|
||||
(STANDARD_INQUIRY_DATA_LEN - 5),
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
'u', 'P', 'y', ' ', ' ', ' ', ' ', ' ', // Manufacturer : 8 bytes
|
||||
'm', 'i', 'c', 'r', 'o', 'S', 'D', ' ', // Product : 16 Bytes
|
||||
'F', 'l', 'a', 's', 'h', ' ', ' ', ' ',
|
||||
'1', '.', '0' ,'0', // Version : 4 Bytes
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialize the storage medium
|
||||
* @param lun : logical unit number
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t FLASH_STORAGE_Init(uint8_t lun) {
|
||||
storage_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief return medium capacity and block size
|
||||
* @param lun : logical unit number
|
||||
* @param block_num : number of physical block
|
||||
* @param block_size : size of a physical block
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t FLASH_STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size) {
|
||||
*block_size = storage_get_block_size();
|
||||
*block_num = storage_get_block_count();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check whether the medium is ready
|
||||
* @param lun : logical unit number
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t FLASH_STORAGE_IsReady(uint8_t lun) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check whether the medium is write-protected
|
||||
* @param lun : logical unit number
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t FLASH_STORAGE_IsWriteProtected(uint8_t lun) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read data from the medium
|
||||
* @param lun : logical unit number
|
||||
* @param buf : Pointer to the buffer to save data
|
||||
* @param blk_addr : address of 1st block to be read
|
||||
* @param blk_len : nmber of blocks to be read
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t FLASH_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
|
||||
disk_read(0, buf, blk_addr, blk_len);
|
||||
/*
|
||||
for (int i = 0; i < blk_len; i++) {
|
||||
if (!storage_read_block(buf + i * FLASH_BLOCK_SIZE, blk_addr + i)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write data to the medium
|
||||
* @param lun : logical unit number
|
||||
* @param buf : Pointer to the buffer to write from
|
||||
* @param blk_addr : address of 1st block to be written
|
||||
* @param blk_len : nmber of blocks to be read
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t FLASH_STORAGE_Write (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
|
||||
disk_write(0, buf, blk_addr, blk_len);
|
||||
/*
|
||||
for (int i = 0; i < blk_len; i++) {
|
||||
if (!storage_write_block(buf + i * FLASH_BLOCK_SIZE, blk_addr + i)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
storage_flush(); // XXX hack for now so that the cache is always flushed
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return number of supported logical unit
|
||||
* @param None
|
||||
* @retval number of logical unit
|
||||
*/
|
||||
int8_t FLASH_STORAGE_GetMaxLun(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const USBD_StorageTypeDef USBD_FLASH_STORAGE_fops = {
|
||||
FLASH_STORAGE_Init,
|
||||
FLASH_STORAGE_GetCapacity,
|
||||
FLASH_STORAGE_IsReady,
|
||||
FLASH_STORAGE_IsWriteProtected,
|
||||
FLASH_STORAGE_Read,
|
||||
FLASH_STORAGE_Write,
|
||||
FLASH_STORAGE_GetMaxLun,
|
||||
(int8_t *)FLASH_STORAGE_Inquirydata,
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
// Callback functions for when the SD card is the mass storage device
|
||||
|
||||
static const int8_t SDCARD_STORAGE_Inquirydata[] = { // 36 bytes
|
||||
// LUN 0
|
||||
0x00,
|
||||
0x80, // 0x00 for a fixed drive, 0x80 for a removable drive
|
||||
0x02,
|
||||
0x02,
|
||||
(STANDARD_INQUIRY_DATA_LEN - 5),
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
'u', 'P', 'y', ' ', ' ', ' ', ' ', ' ', // Manufacturer : 8 bytes
|
||||
'm', 'i', 'c', 'r', 'o', 'S', 'D', ' ', // Product : 16 Bytes
|
||||
'S', 'D', ' ', 'c', 'a', 'r', 'd', ' ',
|
||||
'1', '.', '0' ,'0', // Version : 4 Bytes
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialize the storage medium
|
||||
* @param lun : logical unit number
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t SDCARD_STORAGE_Init(uint8_t lun) {
|
||||
/*
|
||||
#ifndef USE_STM3210C_EVAL
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
#endif
|
||||
if( SD_Init() != 0)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
*/
|
||||
if (!sdcard_power_on()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief return medium capacity and block size
|
||||
* @param lun : logical unit number
|
||||
* @param block_num : number of physical block
|
||||
* @param block_size : size of a physical block
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t SDCARD_STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size) {
|
||||
/*
|
||||
#ifdef USE_STM3210C_EVAL
|
||||
SD_CardInfo SDCardInfo;
|
||||
SD_GetCardInfo(&SDCardInfo);
|
||||
#else
|
||||
if(SD_GetStatus() != 0 ) {
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
*block_size = SDCARD_BLOCK_SIZE;
|
||||
*block_num = sdcard_get_capacity_in_bytes() / SDCARD_BLOCK_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check whether the medium is ready
|
||||
* @param lun : logical unit number
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t SDCARD_STORAGE_IsReady(uint8_t lun) {
|
||||
/*
|
||||
#ifndef USE_STM3210C_EVAL
|
||||
|
||||
static int8_t last_status = 0;
|
||||
|
||||
if(last_status < 0)
|
||||
{
|
||||
SD_Init();
|
||||
last_status = 0;
|
||||
}
|
||||
|
||||
if(SD_GetStatus() != 0)
|
||||
{
|
||||
last_status = -1;
|
||||
return (-1);
|
||||
}
|
||||
#else
|
||||
if( SD_Init() != 0)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check whether the medium is write-protected
|
||||
* @param lun : logical unit number
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t SDCARD_STORAGE_IsWriteProtected(uint8_t lun) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read data from the medium
|
||||
* @param lun : logical unit number
|
||||
* @param buf : Pointer to the buffer to save data
|
||||
* @param blk_addr : address of 1st block to be read
|
||||
* @param blk_len : nmber of blocks to be read
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t SDCARD_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
|
||||
if (!sdcard_read_blocks(buf, blk_addr, blk_len)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write data to the medium
|
||||
* @param lun : logical unit number
|
||||
* @param buf : Pointer to the buffer to write from
|
||||
* @param blk_addr : address of 1st block to be written
|
||||
* @param blk_len : nmber of blocks to be read
|
||||
* @retval Status
|
||||
*/
|
||||
int8_t SDCARD_STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
|
||||
if (!sdcard_write_blocks(buf, blk_addr, blk_len)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return number of supported logical unit
|
||||
* @param None
|
||||
* @retval number of logical unit
|
||||
*/
|
||||
int8_t SDCARD_STORAGE_GetMaxLun(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const USBD_StorageTypeDef USBD_SDCARD_STORAGE_fops = {
|
||||
SDCARD_STORAGE_Init,
|
||||
SDCARD_STORAGE_GetCapacity,
|
||||
SDCARD_STORAGE_IsReady,
|
||||
SDCARD_STORAGE_IsWriteProtected,
|
||||
SDCARD_STORAGE_Read,
|
||||
SDCARD_STORAGE_Write,
|
||||
SDCARD_STORAGE_GetMaxLun,
|
||||
(int8_t *)SDCARD_STORAGE_Inquirydata,
|
||||
};
|
2
stmhal/usbd_msc_storage.h
Normal file
2
stmhal/usbd_msc_storage.h
Normal file
@ -0,0 +1,2 @@
|
||||
extern const USBD_StorageTypeDef USBD_FLASH_STORAGE_fops;
|
||||
extern const USBD_StorageTypeDef USBD_SDCARD_STORAGE_fops;
|
@ -4,8 +4,36 @@ print(str(a))
|
||||
print(repr(a))
|
||||
print(a[0], a[2])
|
||||
print(a[-1])
|
||||
print(str(a, "utf-8"))
|
||||
print(str(a, "utf-8", "ignore"))
|
||||
try:
|
||||
str(a, "utf-8", "ignore", "toomuch")
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
s = 0
|
||||
for i in a:
|
||||
s += i
|
||||
print(s)
|
||||
|
||||
|
||||
print(bytes("abc", "utf-8"))
|
||||
print(bytes("abc", "utf-8", "replace"))
|
||||
try:
|
||||
bytes("abc")
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
try:
|
||||
bytes("abc", "utf-8", "replace", "toomuch")
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
print(bytes(3))
|
||||
|
||||
print(bytes([3, 2, 1]))
|
||||
print(bytes(range(5)))
|
||||
|
||||
def gen():
|
||||
for i in range(4):
|
||||
yield i
|
||||
print(bytes(gen()))
|
||||
|
@ -37,3 +37,10 @@ a <<= 5
|
||||
print(a)
|
||||
a >>= 1
|
||||
print(a)
|
||||
|
||||
# Test referential integrity of long ints
|
||||
a = 0x1ffffffff
|
||||
b = a
|
||||
a += 1
|
||||
print(a)
|
||||
print(b)
|
||||
|
29
tests/basics/string_partition.py
Normal file
29
tests/basics/string_partition.py
Normal file
@ -0,0 +1,29 @@
|
||||
print("asdf".partition('g'))
|
||||
print("asdf".partition('a'))
|
||||
print("asdf".partition('s'))
|
||||
print("asdf".partition('f'))
|
||||
print("asdf".partition('d'))
|
||||
print("asdf".partition('asd'))
|
||||
print("asdf".partition('sdf'))
|
||||
print("asdf".partition('as'))
|
||||
print("asdf".partition('df'))
|
||||
print("asdf".partition('asdf'))
|
||||
print("asdf".partition('asdfa'))
|
||||
print("asdf".partition('fasdf'))
|
||||
print("asdf".partition('fasdfa'))
|
||||
print("abba".partition('a'))
|
||||
print("abba".partition('b'))
|
||||
|
||||
try:
|
||||
print("asdf".partition(1))
|
||||
except TypeError:
|
||||
print("Raised TypeError")
|
||||
else:
|
||||
print("Did not raise TypeError")
|
||||
|
||||
try:
|
||||
print("asdf".partition(''))
|
||||
except ValueError:
|
||||
print("Raised ValueError")
|
||||
else:
|
||||
print("Did not raise ValueError")
|
29
tests/basics/string_rpartition.py
Normal file
29
tests/basics/string_rpartition.py
Normal file
@ -0,0 +1,29 @@
|
||||
print("asdf".rpartition('g'))
|
||||
print("asdf".rpartition('a'))
|
||||
print("asdf".rpartition('s'))
|
||||
print("asdf".rpartition('f'))
|
||||
print("asdf".rpartition('d'))
|
||||
print("asdf".rpartition('asd'))
|
||||
print("asdf".rpartition('sdf'))
|
||||
print("asdf".rpartition('as'))
|
||||
print("asdf".rpartition('df'))
|
||||
print("asdf".rpartition('asdf'))
|
||||
print("asdf".rpartition('asdfa'))
|
||||
print("asdf".rpartition('fasdf'))
|
||||
print("asdf".rpartition('fasdfa'))
|
||||
print("abba".rpartition('a'))
|
||||
print("abba".rpartition('b'))
|
||||
|
||||
try:
|
||||
print("asdf".rpartition(1))
|
||||
except TypeError:
|
||||
print("Raised TypeError")
|
||||
else:
|
||||
print("Did not raise TypeError")
|
||||
|
||||
try:
|
||||
print("asdf".rpartition(''))
|
||||
except ValueError:
|
||||
print("Raised ValueError")
|
||||
else:
|
||||
print("Did not raise ValueError")
|
Loading…
x
Reference in New Issue
Block a user