diff options
96 files changed, 2179 insertions, 1755 deletions
diff --git a/bare-arm/Makefile b/bare-arm/Makefile index f9c9fb9a31..745945deb6 100644 --- a/bare-arm/Makefile +++ b/bare-arm/Makefile @@ -38,9 +38,9 @@ SRC_S = \ OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o)) -all: $(BUILD)/flash.elf +all: $(BUILD)/firmware.elf -$(BUILD)/flash.elf: $(OBJ) +$(BUILD)/firmware.elf: $(OBJ) $(ECHO) "LINK $@" $(Q)$(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(Q)$(SIZE) $@ diff --git a/examples/micropython.py b/examples/micropython.py index 091c92deb3..f91da94f41 100644 --- a/examples/micropython.py +++ b/examples/micropython.py @@ -5,4 +5,4 @@ def nodecor(x): return x -byte_code = native = viper = nodecor +bytecode = native = viper = nodecor diff --git a/py/asmthumb.c b/py/asmthumb.c index 9e3a9abe25..891947567b 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -46,7 +46,7 @@ struct _asm_thumb_t { uint code_offset; uint code_size; byte *code_base; - byte dummy_data[8]; + byte dummy_data[4]; uint max_num_labels; int *label_offsets; @@ -113,6 +113,7 @@ void asm_thumb_end_pass(asm_thumb_t *as) { } // all functions must go through this one to emit bytes +// if as->pass < ASM_THUMB_PASS_EMIT, then this function only returns a buffer of 4 bytes length STATIC byte *asm_thumb_get_cur_to_write_bytes(asm_thumb_t *as, int num_bytes_to_write) { //printf("emit %d\n", num_bytes_to_write); if (as->pass < ASM_THUMB_PASS_EMIT) { @@ -251,10 +252,13 @@ void asm_thumb_align(asm_thumb_t* as, uint align) { void asm_thumb_data(asm_thumb_t* as, uint bytesize, uint val) { byte *c = asm_thumb_get_cur_to_write_bytes(as, bytesize); - // little endian - for (uint i = 0; i < bytesize; i++) { - *c++ = val; - val >>= 8; + // only write to the buffer in the emit pass (otherwise we overflow dummy_data) + if (as->pass == ASM_THUMB_PASS_EMIT) { + // little endian + for (uint i = 0; i < bytesize; i++) { + *c++ = val; + val >>= 8; + } } } @@ -36,10 +36,10 @@ typedef struct _mp_exc_stack { byte opcode; } mp_exc_stack_t; -mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret); -mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out, mp_exc_stack_t *exc_stack, mp_exc_stack_t **exc_sp_in_out, volatile mp_obj_t inject_exc); -void mp_byte_code_print(const byte *code, int len); -void mp_byte_code_print2(const byte *code, int len); +mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret); +mp_vm_return_kind_t mp_execute_bytecode2(const byte *code_info, const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out, mp_exc_stack_t *exc_stack, mp_exc_stack_t **exc_sp_in_out, volatile mp_obj_t inject_exc); +void mp_bytecode_print(const byte *code, int len); +void mp_bytecode_print2(const byte *code, int len); // Helper macros to access pointer with least significant bit holding a flag #define MP_TAGPTR_PTR(x) ((void*)((machine_uint_t)(x) & ~((machine_uint_t)1))) diff --git a/py/builtinimport.c b/py/builtinimport.c index 3d833eda79..e6bb7586c8 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -287,6 +287,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) { // create a qstr for the module name up to this depth qstr mod_name = qstr_from_strn(mod_str, i); DEBUG_printf("Processing module: %s\n", qstr_str(mod_name)); + DEBUG_printf("Previous path: %s\n", vstr_str(&path)); // find the file corresponding to the module name mp_import_stat_t stat; @@ -299,6 +300,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) { vstr_add_strn(&path, mod_str + last, i - last); stat = stat_dir_or_file(&path); } + DEBUG_printf("Current path: %s\n", vstr_str(&path)); // fail if we couldn't find the file if (stat == MP_IMPORT_STAT_NO_EXIST) { @@ -313,6 +315,8 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) { if (stat == MP_IMPORT_STAT_DIR) { DEBUG_printf("%s is dir\n", vstr_str(&path)); + // https://docs.python.org/3.3/reference/import.html + // "Specifically, any module that contains a __path__ attribute is considered a package." mp_store_attr(module_obj, MP_QSTR___path__, mp_obj_new_str((byte*)vstr_str(&path), vstr_len(&path), false)); vstr_add_char(&path, PATH_SEP_CHAR); vstr_add_str(&path, "__init__.py"); @@ -321,10 +325,8 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) { printf("Notice: %s is imported as namespace package\n", vstr_str(&path)); } else { do_load(module_obj, &path); + vstr_cut_tail_bytes(&path, sizeof("/__init__.py") - 1); // cut off /__init__.py } - vstr_cut_tail_bytes(&path, sizeof("/__init__.py") - 1); // cut off /__init__.py - // https://docs.python.org/3.3/reference/import.html - // "Specifically, any module that contains a __path__ attribute is considered a package." } else { // MP_IMPORT_STAT_FILE do_load(module_obj, &path); // TODO: We cannot just break here, at the very least, we must execute diff --git a/py/builtintables.c b/py/builtintables.c index c064bb439f..a1888a6e97 100644 --- a/py/builtintables.c +++ b/py/builtintables.c @@ -53,6 +53,9 @@ STATIC const mp_map_elem_t mp_builtin_object_table[] = { #if MICROPY_ENABLE_FLOAT { MP_OBJ_NEW_QSTR(MP_QSTR_float), (mp_obj_t)&mp_type_float }, #endif +#if MICROPY_ENABLE_FROZENSET + { MP_OBJ_NEW_QSTR(MP_QSTR_frozenset), (mp_obj_t)&mp_type_frozenset }, +#endif { MP_OBJ_NEW_QSTR(MP_QSTR_int), (mp_obj_t)&mp_type_int }, { MP_OBJ_NEW_QSTR(MP_QSTR_list), (mp_obj_t)&mp_type_list }, { MP_OBJ_NEW_QSTR(MP_QSTR_map), (mp_obj_t)&mp_type_map }, diff --git a/py/compile.c b/py/compile.c index 8a26f6dc35..36ffa928ee 100644 --- a/py/compile.c +++ b/py/compile.c @@ -1146,7 +1146,7 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_ } qstr attr = MP_PARSE_NODE_LEAF_ARG(name_nodes[1]); - if (attr == MP_QSTR_byte_code) { + if (attr == MP_QSTR_bytecode) { *emit_options = MP_EMIT_OPT_BYTE_CODE; #if MICROPY_EMIT_NATIVE } else if (attr == MP_QSTR_native) { diff --git a/py/emitbc.c b/py/emitbc.c index 6a8861eaef..06f63b6f6c 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -44,10 +44,15 @@ #if !MICROPY_EMIT_CPYTHON +#define BYTES_FOR_INT ((BYTES_PER_WORD * 8 + 6) / 7) +#define DUMMY_DATA_SIZE (BYTES_FOR_INT) + struct _emit_t { - pass_kind_t pass; + pass_kind_t pass : 8; + uint last_emit_was_return_value : 8; + byte dummy_data[DUMMY_DATA_SIZE]; + int stack_size; - bool last_emit_was_return_value; scope_t *scope; @@ -59,10 +64,9 @@ struct _emit_t { uint code_info_offset; uint code_info_size; - uint byte_code_offset; - uint byte_code_size; + uint bytecode_offset; + uint bytecode_size; byte *code_base; // stores both byte code and code info - byte dummy_data[8]; }; STATIC void emit_bc_rot_two(emit_t *emit); @@ -121,57 +125,57 @@ STATIC void emit_write_code_info_bytes_lines(emit_t* emit, uint bytes_to_skip, u #endif // all functions must go through this one to emit byte code -STATIC byte* emit_get_cur_to_write_byte_code(emit_t* emit, int num_bytes_to_write) { +STATIC byte* emit_get_cur_to_write_bytecode(emit_t* emit, int num_bytes_to_write) { //printf("emit %d\n", num_bytes_to_write); if (emit->pass < MP_PASS_EMIT) { - emit->byte_code_offset += num_bytes_to_write; + emit->bytecode_offset += num_bytes_to_write; return emit->dummy_data; } else { - assert(emit->byte_code_offset + num_bytes_to_write <= emit->byte_code_size); - byte *c = emit->code_base + emit->code_info_size + emit->byte_code_offset; - emit->byte_code_offset += num_bytes_to_write; + assert(emit->bytecode_offset + num_bytes_to_write <= emit->bytecode_size); + byte *c = emit->code_base + emit->code_info_size + emit->bytecode_offset; + emit->bytecode_offset += num_bytes_to_write; return c; } } -STATIC void emit_align_byte_code_to_machine_word(emit_t* emit) { - emit->byte_code_offset = (emit->byte_code_offset + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1)); +STATIC void emit_align_bytecode_to_machine_word(emit_t* emit) { + emit->bytecode_offset = (emit->bytecode_offset + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1)); } -STATIC void emit_write_byte_code_byte(emit_t* emit, byte b1) { - byte* c = emit_get_cur_to_write_byte_code(emit, 1); +STATIC void emit_write_bytecode_byte(emit_t* emit, byte b1) { + byte* c = emit_get_cur_to_write_bytecode(emit, 1); c[0] = b1; } -STATIC void emit_write_byte_code_byte_byte(emit_t* emit, byte b1, uint b2) { +STATIC void emit_write_bytecode_byte_byte(emit_t* emit, byte b1, uint b2) { assert((b2 & (~0xff)) == 0); - byte* c = emit_get_cur_to_write_byte_code(emit, 2); + byte* c = emit_get_cur_to_write_bytecode(emit, 2); c[0] = b1; c[1] = b2; } -STATIC void emit_write_byte_code_uint(emit_t* emit, uint num) { +STATIC void emit_write_bytecode_uint(emit_t* emit, uint num) { // We store each 7 bits in a separate byte, and that's how many bytes needed - byte buf[(BYTES_PER_WORD * 8 + 6) / 7]; + byte buf[BYTES_FOR_INT]; byte *p = buf + sizeof(buf); // We encode in little-ending order, but store in big-endian, to help decoding do { *--p = num & 0x7f; num >>= 7; } while (num != 0); - byte* c = emit_get_cur_to_write_byte_code(emit, buf + sizeof(buf) - p); + byte* c = emit_get_cur_to_write_bytecode(emit, buf + sizeof(buf) - p); while (p != buf + sizeof(buf) - 1) { *c++ = *p++ | 0x80; } *c = *p; } -// Similar to emit_write_byte_code_uint(), just some extra handling to encode sign -STATIC void emit_write_byte_code_byte_int(emit_t* emit, byte b1, machine_int_t num) { - emit_write_byte_code_byte(emit, b1); +// Similar to emit_write_bytecode_uint(), just some extra handling to encode sign +STATIC void emit_write_bytecode_byte_int(emit_t* emit, byte b1, machine_int_t num) { + emit_write_bytecode_byte(emit, b1); // We store each 7 bits in a separate byte, and that's how many bytes needed - byte buf[(BYTES_PER_WORD * 8 + 6) / 7]; + byte buf[BYTES_FOR_INT]; byte *p = buf + sizeof(buf); // We encode in little-ending order, but store in big-endian, to help decoding do { @@ -186,64 +190,64 @@ STATIC void emit_write_byte_code_byte_int(emit_t* emit, byte b1, machine_int_t n *--p = 0; } - byte* c = emit_get_cur_to_write_byte_code(emit, buf + sizeof(buf) - p); + byte* c = emit_get_cur_to_write_bytecode(emit, buf + sizeof(buf) - p); while (p != buf + sizeof(buf) - 1) { *c++ = *p++ | 0x80; } *c = *p; } -STATIC void emit_write_byte_code_byte_uint(emit_t* emit, byte b, uint num) { - emit_write_byte_code_byte(emit, b); - emit_write_byte_code_uint(emit, num); +STATIC void emit_write_bytecode_byte_uint(emit_t* emit, byte b, uint num) { + emit_write_bytecode_byte(emit, b); + emit_write_bytecode_uint(emit, num); } // aligns the pointer so it is friendly to GC -STATIC void emit_write_byte_code_byte_ptr(emit_t* emit, byte b, void *ptr) { - emit_write_byte_code_byte(emit, b); - emit_align_byte_code_to_machine_word(emit); - machine_uint_t *c = (machine_uint_t*)emit_get_cur_to_write_byte_code(emit, sizeof(machine_uint_t)); +STATIC void emit_write_bytecode_byte_ptr(emit_t* emit, byte b, void *ptr) { + emit_write_bytecode_byte(emit, b); + emit_align_bytecode_to_machine_word(emit); + machine_uint_t *c = (machine_uint_t*)emit_get_cur_to_write_bytecode(emit, sizeof(machine_uint_t)); *c = (machine_uint_t)ptr; } /* currently unused -STATIC void emit_write_byte_code_byte_uint_uint(emit_t* emit, byte b, uint num1, uint num2) { - emit_write_byte_code_byte(emit, b); - emit_write_byte_code_byte_uint(emit, num1); - emit_write_byte_code_byte_uint(emit, num2); +STATIC void emit_write_bytecode_byte_uint_uint(emit_t* emit, byte b, uint num1, uint num2) { + emit_write_bytecode_byte(emit, b); + emit_write_bytecode_byte_uint(emit, num1); + emit_write_bytecode_byte_uint(emit, num2); } */ -STATIC void emit_write_byte_code_byte_qstr(emit_t* emit, byte b, qstr qstr) { - emit_write_byte_code_byte_uint(emit, b, qstr); +STATIC void emit_write_bytecode_byte_qstr(emit_t* emit, byte b, qstr qstr) { + emit_write_bytecode_byte_uint(emit, b, qstr); } // unsigned labels are relative to ip following this instruction, stored as 16 bits -STATIC void emit_write_byte_code_byte_unsigned_label(emit_t* emit, byte b1, uint label) { - uint byte_code_offset; +STATIC void emit_write_bytecode_byte_unsigned_label(emit_t* emit, byte b1, uint label) { + uint bytecode_offset; if (emit->pass < MP_PASS_EMIT) { - byte_code_offset = 0; + bytecode_offset = 0; } else { - byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3; + bytecode_offset = emit->label_offsets[label] - emit->bytecode_offset - 3; } - byte *c = emit_get_cur_to_write_byte_code(emit, 3); + byte *c = emit_get_cur_to_write_bytecode(emit, 3); c[0] = b1; - c[1] = byte_code_offset; - c[2] = byte_code_offset >> 8; + c[1] = bytecode_offset; + c[2] = bytecode_offset >> 8; } // signed labels are relative to ip following this instruction, stored as 16 bits, in excess -STATIC void emit_write_byte_code_byte_signed_label(emit_t* emit, byte b1, uint label) { - int byte_code_offset; +STATIC void emit_write_bytecode_byte_signed_label(emit_t* emit, byte b1, uint label) { + int bytecode_offset; if (emit->pass < MP_PASS_EMIT) { - byte_code_offset = 0; + bytecode_offset = 0; } else { - byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3 + 0x8000; + bytecode_offset = emit->label_offsets[label] - emit->bytecode_offset - 3 + 0x8000; } - byte* c = emit_get_cur_to_write_byte_code(emit, 3); + byte* c = emit_get_cur_to_write_bytecode(emit, 3); c[0] = b1; - c[1] = byte_code_offset; - c[2] = byte_code_offset >> 8; + c[1] = bytecode_offset; + c[2] = bytecode_offset >> 8; } STATIC void emit_bc_set_native_types(emit_t *emit, bool do_native_types) { @@ -259,7 +263,7 @@ STATIC void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { if (pass < MP_PASS_EMIT) { memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(uint)); } - emit->byte_code_offset = 0; + emit->bytecode_offset = 0; emit->code_info_offset = 0; // write code info size; use maximum space (4 bytes) to write it; TODO possible optimise this @@ -278,7 +282,7 @@ STATIC void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { // bytecode prelude: local state size and exception stack size; 16 bit uints for now { - byte* c = emit_get_cur_to_write_byte_code(emit, 4); + byte* c = emit_get_cur_to_write_bytecode(emit, 4); uint n_state = scope->num_locals + scope->stack_size; if (n_state == 0) { // Need at least 1 entry in the state, in the case an exception is @@ -301,11 +305,11 @@ STATIC void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { } } assert(num_cell <= 255); - emit_write_byte_code_byte(emit, num_cell); // write number of locals that are cells + emit_write_bytecode_byte(emit, num_cell); // write number of locals that are cells for (int i = 0; i < scope->id_info_len; i++) { id_info_t *id = &scope->id_info[i]; if (id->kind == ID_INFO_KIND_CELL) { - emit_write_byte_code_byte(emit, id->local_num); // write the local which should be converted to a cell + emit_write_bytecode_byte(emit, id->local_num); // write the local which should be converted to a cell } } } @@ -317,21 +321,21 @@ STATIC void emit_bc_end_pass(emit_t *emit) { } *emit_get_cur_to_write_code_info(emit, 1) = 0; // end of line number info - emit_align_code_info_to_machine_word(emit); // align so that following byte_code is aligned + emit_align_code_info_to_machine_word(emit); // align so that following bytecode is aligned if (emit->pass == MP_PASS_CODE_SIZE) { // calculate size of code in bytes emit->code_info_size = emit->code_info_offset; - emit->byte_code_size = emit->byte_code_offset; - emit->code_base = m_new0(byte, emit->code_info_size + emit->byte_code_size); + emit->bytecode_size = emit->bytecode_offset; + emit->code_base = m_new0(byte, emit->code_info_size + emit->bytecode_size); } else if (emit->pass == MP_PASS_EMIT) { qstr *arg_names = m_new(qstr, emit->scope->num_pos_args + emit->scope->num_kwonly_args); for (int i = 0; i < emit->scope->num_pos_args + emit->scope->num_kwonly_args; i++) { arg_names[i] = emit->scope->id_info[i].qstr; } - mp_emit_glue_assign_byte_code(emit->scope->raw_code, emit->code_base, - emit->code_info_size + emit->byte_code_size, + mp_emit_glue_assign_bytecode(emit->scope->raw_code, emit->code_base, + emit->code_info_size + emit->bytecode_size, emit->scope->num_pos_args, emit->scope->num_kwonly_args, arg_names, emit->scope->scope_flags); } @@ -346,14 +350,14 @@ STATIC void emit_bc_adjust_stack_size(emit_t *emit, int delta) { } STATIC void emit_bc_set_source_line(emit_t *emit, int source_line) { - //printf("source: line %d -> %d offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->byte_code_offset); + //printf("source: line %d -> %d offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->bytecode_offset); #if MICROPY_ENABLE_SOURCE_LINE if (source_line > emit->last_source_line) { - uint bytes_to_skip = emit->byte_code_offset - emit->last_source_line_offset; + uint bytes_to_skip = emit->bytecode_offset - emit->last_source_line_offset; uint lines_to_skip = source_line - emit->last_source_line; emit_write_code_info_bytes_lines(emit, bytes_to_skip, lines_to_skip); //printf(" %d %d\n", bytes_to_skip, lines_to_skip); - emit->last_source_line_offset = emit->byte_code_offset; + emit->last_source_line_offset = emit->bytecode_offset; emit->last_source_line = source_line; } #endif @@ -386,167 +390,167 @@ STATIC void emit_bc_label_assign(emit_t *emit, uint l) { if (emit->pass < MP_PASS_EMIT) { // assign label offset assert(emit->label_offsets[l] == -1); - emit->label_offsets[l] = emit->byte_code_offset; + emit->label_offsets[l] = emit->bytecode_offset; } else { // ensure label offset has not changed from MP_PASS_CODE_SIZE to MP_PASS_EMIT - //printf("l%d: (at %d vs %d)\n", l, emit->byte_code_offset, emit->label_offsets[l]); - assert(emit->label_offsets[l] == emit->byte_code_offset); + //printf("l%d: (at %d vs %d)\n", l, emit->bytecode_offset, emit->label_offsets[l]); + assert(emit->label_offsets[l] == emit->bytecode_offset); } } STATIC void emit_bc_import_name(emit_t *emit, qstr qstr) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte_qstr(emit, MP_BC_IMPORT_NAME, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_IMPORT_NAME, qstr); } STATIC void emit_bc_import_from(emit_t *emit, qstr qstr) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte_qstr(emit, MP_BC_IMPORT_FROM, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_IMPORT_FROM, qstr); } STATIC void emit_bc_import_star(emit_t *emit) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte(emit, MP_BC_IMPORT_STAR); + emit_write_bytecode_byte(emit, MP_BC_IMPORT_STAR); } STATIC void emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) { emit_bc_pre(emit, 1); switch (tok) { - case MP_TOKEN_KW_FALSE: emit_write_byte_code_byte(emit, MP_BC_LOAD_CONST_FALSE); break; - case MP_TOKEN_KW_NONE: emit_write_byte_code_byte(emit, MP_BC_LOAD_CONST_NONE); break; - case MP_TOKEN_KW_TRUE: emit_write_byte_code_byte(emit, MP_BC_LOAD_CONST_TRUE); break; - case MP_TOKEN_ELLIPSIS: emit_write_byte_code_byte(emit, MP_BC_LOAD_CONST_ELLIPSIS); break; + case MP_TOKEN_KW_FALSE: emit_write_bytecode_byte(emit, MP_BC_LOAD_CONST_FALSE); break; + case MP_TOKEN_KW_NONE: emit_write_bytecode_byte(emit, MP_BC_LOAD_CONST_NONE); break; + case MP_TOKEN_KW_TRUE: emit_write_bytecode_byte(emit, MP_BC_LOAD_CONST_TRUE); break; + case MP_TOKEN_ELLIPSIS: emit_write_bytecode_byte(emit, MP_BC_LOAD_CONST_ELLIPSIS); break; default: assert(0); } } STATIC void emit_bc_load_const_small_int(emit_t *emit, machine_int_t arg) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte_int(emit, MP_BC_LOAD_CONST_SMALL_INT, arg); + emit_write_bytecode_byte_int(emit, MP_BC_LOAD_CONST_SMALL_INT, arg); } STATIC void emit_bc_load_const_int(emit_t *emit, qstr qstr) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_INT, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_CONST_INT, qstr); } STATIC void emit_bc_load_const_dec(emit_t *emit, qstr qstr) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_DEC, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_CONST_DEC, qstr); } STATIC void emit_bc_load_const_str(emit_t *emit, qstr qstr, bool bytes) { emit_bc_pre(emit, 1); if (bytes) { - emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_BYTES, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_CONST_BYTES, qstr); } else { - emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_CONST_STRING, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_CONST_STRING, qstr); } } STATIC void emit_bc_load_null(emit_t *emit) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte(emit, MP_BC_LOAD_NULL); + emit_write_bytecode_byte(emit, MP_BC_LOAD_NULL); }; STATIC void emit_bc_load_fast(emit_t *emit, qstr qstr, uint id_flags, int local_num) { assert(local_num >= 0); emit_bc_pre(emit, 1); switch (local_num) { - case 0: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_0); break; - case 1: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_1); break; - case 2: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_2); break; - default: emit_write_byte_code_byte_uint(emit, MP_BC_LOAD_FAST_N, local_num); break; + case 0: emit_write_bytecode_byte(emit, MP_BC_LOAD_FAST_0); break; + case 1: emit_write_bytecode_byte(emit, MP_BC_LOAD_FAST_1); break; + case 2: emit_write_bytecode_byte(emit, MP_BC_LOAD_FAST_2); break; + default: emit_write_bytecode_byte_uint(emit, MP_BC_LOAD_FAST_N, local_num); break; } } STATIC void emit_bc_load_deref(emit_t *emit, qstr qstr, int local_num) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte_uint(emit, MP_BC_LOAD_DEREF, local_num); + emit_write_bytecode_byte_uint(emit, MP_BC_LOAD_DEREF, local_num); } STATIC void emit_bc_load_name(emit_t *emit, qstr qstr) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_NAME, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_NAME, qstr); } STATIC void emit_bc_load_global(emit_t *emit, qstr qstr) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_GLOBAL, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_GLOBAL, qstr); } STATIC void emit_bc_load_attr(emit_t *emit, qstr qstr) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_ATTR, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_ATTR, qstr); } STATIC void emit_bc_load_method(emit_t *emit, qstr qstr) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte_qstr(emit, MP_BC_LOAD_METHOD, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_METHOD, qstr); } STATIC void emit_bc_load_build_class(emit_t *emit) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte(emit, MP_BC_LOAD_BUILD_CLASS); + emit_write_bytecode_byte(emit, MP_BC_LOAD_BUILD_CLASS); } STATIC void emit_bc_load_subscr(emit_t *emit) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte(emit, MP_BC_LOAD_SUBSCR); + emit_write_bytecode_byte(emit, MP_BC_LOAD_SUBSCR); } STATIC void emit_bc_store_fast(emit_t *emit, qstr qstr, int local_num) { assert(local_num >= 0); emit_bc_pre(emit, -1); switch (local_num) { - case 0: emit_write_byte_code_byte(emit, MP_BC_STORE_FAST_0); break; - case 1: emit_write_byte_code_byte(emit, MP_BC_STORE_FAST_1); break; - case 2: emit_write_byte_code_byte(emit, MP_BC_STORE_FAST_2); break; - default: emit_write_byte_code_byte_uint(emit, MP_BC_STORE_FAST_N, local_num); break; + case 0: emit_write_bytecode_byte(emit, MP_BC_STORE_FAST_0); break; + case 1: emit_write_bytecode_byte(emit, MP_BC_STORE_FAST_1); break; + case 2: emit_write_bytecode_byte(emit, MP_BC_STORE_FAST_2); break; + default: emit_write_bytecode_byte_uint(emit, MP_BC_STORE_FAST_N, local_num); break; } } STATIC void emit_bc_store_deref(emit_t *emit, qstr qstr, int local_num) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte_uint(emit, MP_BC_STORE_DEREF, local_num); + emit_write_bytecode_byte_uint(emit, MP_BC_STORE_DEREF, local_num); } STATIC void emit_bc_store_name(emit_t *emit, qstr qstr) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte_qstr(emit, MP_BC_STORE_NAME, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_STORE_NAME, qstr); } STATIC void emit_bc_store_global(emit_t *emit, qstr qstr) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte_qstr(emit, MP_BC_STORE_GLOBAL, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_STORE_GLOBAL, qstr); } STATIC void emit_bc_store_attr(emit_t *emit, qstr qstr) { emit_bc_pre(emit, -2); - emit_write_byte_code_byte_qstr(emit, MP_BC_STORE_ATTR, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_STORE_ATTR, qstr); } STATIC void emit_bc_store_subscr(emit_t *emit) { emit_bc_pre(emit, -3); - emit_write_byte_code_byte(emit, MP_BC_STORE_SUBSCR); + emit_write_bytecode_byte(emit, MP_BC_STORE_SUBSCR); } STATIC void emit_bc_delete_fast(emit_t *emit, qstr qstr, int local_num) { - emit_write_byte_code_byte_uint(emit, MP_BC_DELETE_FAST, local_num); + emit_write_bytecode_byte_uint(emit, MP_BC_DELETE_FAST, local_num); } STATIC void emit_bc_delete_deref(emit_t *emit, qstr qstr, int local_num) { - emit_write_byte_code_byte_uint(emit, MP_BC_DELETE_DEREF, local_num); + emit_write_bytecode_byte_uint(emit, MP_BC_DELETE_DEREF, local_num); } STATIC void emit_bc_delete_name(emit_t *emit, qstr qstr) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte_qstr(emit, MP_BC_DELETE_NAME, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_DELETE_NAME, qstr); } STATIC void emit_bc_delete_global(emit_t *emit, qstr qstr) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte_qstr(emit, MP_BC_DELETE_GLOBAL, qstr); + emit_write_bytecode_byte_qstr(emit, MP_BC_DELETE_GLOBAL, qstr); } STATIC void emit_bc_delete_attr(emit_t *emit, qstr qstr) { @@ -563,52 +567,52 @@ STATIC void emit_bc_delete_subscr(emit_t *emit) { STATIC void emit_bc_dup_top(emit_t *emit) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte(emit, MP_BC_DUP_TOP); + emit_write_bytecode_byte(emit, MP_BC_DUP_TOP); } STATIC void emit_bc_dup_top_two(emit_t *emit) { emit_bc_pre(emit, 2); - emit_write_byte_code_byte(emit, MP_BC_DUP_TOP_TWO); + emit_write_bytecode_byte(emit, MP_BC_DUP_TOP_TWO); } STATIC void emit_bc_pop_top(emit_t *emit) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte(emit, MP_BC_POP_TOP); + emit_write_bytecode_byte(emit, MP_BC_POP_TOP); } STATIC void emit_bc_rot_two(emit_t *emit) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte(emit, MP_BC_ROT_TWO); + emit_write_bytecode_byte(emit, MP_BC_ROT_TWO); } STATIC void emit_bc_rot_three(emit_t *emit) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte(emit, MP_BC_ROT_THREE); + emit_write_bytecode_byte(emit, MP_BC_ROT_THREE); } STATIC void emit_bc_jump(emit_t *emit, uint label) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte_signed_label(emit, MP_BC_JUMP, label); + emit_write_bytecode_byte_signed_label(emit, MP_BC_JUMP, label); } STATIC void emit_bc_pop_jump_if_true(emit_t *emit, uint label) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte_signed_label(emit, MP_BC_POP_JUMP_IF_TRUE, label); + emit_write_bytecode_byte_signed_label(emit, MP_BC_POP_JUMP_IF_TRUE, label); } STATIC void emit_bc_pop_jump_if_false(emit_t *emit, uint label) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte_signed_label(emit, MP_BC_POP_JUMP_IF_FALSE, label); + emit_write_bytecode_byte_signed_label(emit, MP_BC_POP_JUMP_IF_FALSE, label); } STATIC void emit_bc_jump_if_true_or_pop(emit_t *emit, uint label) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte_signed_label(emit, MP_BC_JUMP_IF_TRUE_OR_POP, label); + emit_write_bytecode_byte_signed_label(emit, MP_BC_JUMP_IF_TRUE_OR_POP, label); } STATIC void emit_bc_jump_if_false_or_pop(emit_t *emit, uint label) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte_signed_label(emit, MP_BC_JUMP_IF_FALSE_OR_POP, label); + emit_write_bytecode_byte_signed_label(emit, MP_BC_JUMP_IF_FALSE_OR_POP, label); } STATIC void emit_bc_unwind_jump(emit_t *emit, uint label, int except_depth) { @@ -616,44 +620,44 @@ STATIC void emit_bc_unwind_jump(emit_t *emit, uint label, int except_depth) { emit_bc_jump(emit, label); } else { emit_bc_pre(emit, 0); - emit_write_byte_code_byte_signed_label(emit, MP_BC_UNWIND_JUMP, label); - emit_write_byte_code_byte(emit, except_depth); + emit_write_bytecode_byte_signed_label(emit, MP_BC_UNWIND_JUMP, label); + emit_write_bytecode_byte(emit, except_depth); } } STATIC void emit_bc_setup_with(emit_t *emit, uint label) { emit_bc_pre(emit, 7); - emit_write_byte_code_byte_unsigned_label(emit, MP_BC_SETUP_WITH, label); + emit_write_bytecode_byte_unsigned_label(emit, MP_BC_SETUP_WITH, label); } STATIC void emit_bc_with_cleanup(emit_t *emit) { emit_bc_pre(emit, -7); - emit_write_byte_code_byte(emit, MP_BC_WITH_CLEANUP); + emit_write_bytecode_byte(emit, MP_BC_WITH_CLEANUP); } STATIC void emit_bc_setup_except(emit_t *emit, uint label) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte_unsigned_label(emit, MP_BC_SETUP_EXCEPT, label); + emit_write_bytecode_byte_unsigned_label(emit, MP_BC_SETUP_EXCEPT, label); } STATIC void emit_bc_setup_finally(emit_t *emit, uint label) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte_unsigned_label(emit, MP_BC_SETUP_FINALLY, label); + emit_write_bytecode_byte_unsigned_label(emit, MP_BC_SETUP_FINALLY, label); } STATIC void emit_bc_end_finally(emit_t *emit) { emit_bc_pre(emit, -1); - emit_write_byte_code_byte(emit, MP_BC_END_FINALLY); + emit_write_bytecode_byte(emit, MP_BC_END_FINALLY); } STATIC void emit_bc_get_iter(emit_t *emit) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte(emit, MP_BC_GET_ITER); + emit_write_bytecode_byte(emit, MP_BC_GET_ITER); } STATIC void emit_bc_for_iter(emit_t *emit, uint label) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte_unsigned_label(emit, MP_BC_FOR_ITER, label); + emit_write_bytecode_byte_unsigned_label(emit, MP_BC_FOR_ITER, label); } STATIC void emit_bc_for_iter_end(emit_t *emit) { @@ -662,23 +666,23 @@ STATIC void emit_bc_for_iter_end(emit_t *emit) { STATIC void emit_bc_pop_block(emit_t *emit) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte(emit, MP_BC_POP_BLOCK); + emit_write_bytecode_byte(emit, MP_BC_POP_BLOCK); } STATIC void emit_bc_pop_except(emit_t *emit) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte(emit, MP_BC_POP_EXCEPT); + emit_write_bytecode_byte(emit, MP_BC_POP_EXCEPT); } STATIC void emit_bc_unary_op(emit_t *emit, mp_unary_op_t op) { if (op == MP_UNARY_OP_NOT) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte_byte(emit, MP_BC_UNARY_OP, MP_UNARY_OP_BOOL); + emit_write_bytecode_byte_byte(emit, MP_BC_UNARY_OP, MP_UNARY_OP_BOOL); emit_bc_pre(emit, 0); - emit_write_byte_code_byte(emit, MP_BC_NOT); + emit_write_bytecode_byte(emit, MP_BC_NOT); } else { emit_bc_pre(emit, 0); - emit_write_byte_code_byte_byte(emit, MP_BC_UNARY_OP, op); + emit_write_bytecode_byte_byte(emit, MP_BC_UNARY_OP, op); } } @@ -692,98 +696,98 @@ STATIC void emit_bc_binary_op(emit_t *emit, mp_binary_op_t op) { op = MP_BINARY_OP_IS; } emit_bc_pre(emit, -1); - emit_write_byte_code_byte_byte(emit, MP_BC_BINARY_OP, op); + emit_write_bytecode_byte_byte(emit, MP_BC_BINARY_OP, op); if (invert) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte(emit, MP_BC_NOT); + emit_write_bytecode_byte(emit, MP_BC_NOT); } } STATIC void emit_bc_build_tuple(emit_t *emit, int n_args) { assert(n_args >= 0); emit_bc_pre(emit, 1 - n_args); - emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_TUPLE, n_args); + emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_TUPLE, n_args); } STATIC void emit_bc_build_list(emit_t *emit, int n_args) { assert(n_args >= 0); emit_bc_pre(emit, 1 - n_args); - emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_LIST, n_args); + emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_LIST, n_args); } STATIC void emit_bc_list_append(emit_t *emit, int list_stack_index) { assert(list_stack_index >= 0); emit_bc_pre(emit, -1); - emit_write_byte_code_byte_uint(emit, MP_BC_LIST_APPEND, list_stack_index); + emit_write_bytecode_byte_uint(emit, MP_BC_LIST_APPEND, list_stack_index); } STATIC void emit_bc_build_map(emit_t *emit, int n_args) { assert(n_args >= 0); emit_bc_pre(emit, 1); - emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_MAP, n_args); + emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_MAP, n_args); } STATIC void emit_bc_store_map(emit_t *emit) { emit_bc_pre(emit, -2); - emit_write_byte_code_byte(emit, MP_BC_STORE_MAP); + emit_write_bytecode_byte(emit, MP_BC_STORE_MAP); } STATIC void emit_bc_map_add(emit_t *emit, int map_stack_index) { assert(map_stack_index >= 0); emit_bc_pre(emit, -2); - emit_write_byte_code_byte_uint(emit, MP_BC_MAP_ADD, map_stack_index); + emit_write_bytecode_byte_uint(emit, MP_BC_MAP_ADD, map_stack_index); } STATIC void emit_bc_build_set(emit_t *emit, int n_args) { assert(n_args >= 0); emit_bc_pre(emit, 1 - n_args); - emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_SET, n_args); + emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_SET, n_args); } STATIC void emit_bc_set_add(emit_t *emit, int set_stack_index) { assert(set_stack_index >= 0); emit_bc_pre(emit, -1); - emit_write_byte_code_byte_uint(emit, MP_BC_SET_ADD, set_stack_index); + emit_write_bytecode_byte_uint(emit, MP_BC_SET_ADD, set_stack_index); } STATIC void emit_bc_build_slice(emit_t *emit, int n_args) { assert(n_args >= 0); emit_bc_pre(emit, 1 - n_args); - emit_write_byte_code_byte_uint(emit, MP_BC_BUILD_SLICE, n_args); + emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_SLICE, n_args); } STATIC void emit_bc_unpack_sequence(emit_t *emit, int n_args) { assert(n_args >= 0); emit_bc_pre(emit, -1 + n_args); - emit_write_byte_code_byte_uint(emit, MP_BC_UNPACK_SEQUENCE, n_args); + emit_write_bytecode_byte_uint(emit, MP_BC_UNPACK_SEQUENCE, n_args); } STATIC void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) { assert(n_left >=0 && n_right >= 0); emit_bc_pre(emit, -1 + n_left + n_right + 1); - emit_write_byte_code_byte_uint(emit, MP_BC_UNPACK_EX, n_left | (n_right << 8)); + emit_write_bytecode_byte_uint(emit, MP_BC_UNPACK_EX, n_left | (n_right << 8)); } STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) { if (n_pos_defaults == 0 && n_kw_defaults == 0) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_FUNCTION, scope->raw_code); + emit_write_bytecode_byte_ptr(emit, MP_BC_MAKE_FUNCTION, scope->raw_code); } else { emit_bc_pre(emit, -1); - emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code); + emit_write_bytecode_byte_ptr(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code); } } STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, uint n_closed_over, uint n_pos_defaults, uint n_kw_defaults) { if (n_pos_defaults == 0 && n_kw_defaults == 0) { emit_bc_pre(emit, -n_closed_over + 1); - emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_CLOSURE, scope->raw_code); - emit_write_byte_code_byte(emit, n_closed_over); + emit_write_bytecode_byte_ptr(emit, MP_BC_MAKE_CLOSURE, scope->raw_code); + emit_write_bytecode_byte(emit, n_closed_over); } else { assert(n_closed_over <= 255); emit_bc_pre(emit, -2 - n_closed_over + 1); - emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code); - emit_write_byte_code_byte(emit, n_closed_over); + emit_write_bytecode_byte_ptr(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code); + emit_write_bytecode_byte(emit, n_closed_over); } } @@ -798,10 +802,10 @@ STATIC void emit_bc_call_function_method_helper(emit_t *emit, int stack_adj, uin emit_bc_load_null(emit); } emit_bc_pre(emit, stack_adj - n_positional - 2 * n_keyword - 2); - emit_write_byte_code_byte_uint(emit, bytecode_base + 1, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints? + emit_write_bytecode_byte_uint(emit, bytecode_base + 1, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints? } else { emit_bc_pre(emit, stack_adj - n_positional - 2 * n_keyword); - emit_write_byte_code_byte_uint(emit, bytecode_base, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints? + emit_write_bytecode_byte_uint(emit, bytecode_base, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints? } } @@ -816,25 +820,25 @@ STATIC void emit_bc_call_method(emit_t *emit, int n_positional, int n_keyword, u STATIC void emit_bc_return_value(emit_t *emit) { emit_bc_pre(emit, -1); emit->last_emit_was_return_value = true; - emit_write_byte_code_byte(emit, MP_BC_RETURN_VALUE); + emit_write_bytecode_byte(emit, MP_BC_RETURN_VALUE); } STATIC void emit_bc_raise_varargs(emit_t *emit, int n_args) { assert(0 <= n_args && n_args <= 2); emit_bc_pre(emit, -n_args); - emit_write_byte_code_byte_byte(emit, MP_BC_RAISE_VARARGS, n_args); + emit_write_bytecode_byte_byte(emit, MP_BC_RAISE_VARARGS, n_args); } STATIC void emit_bc_yield_value(emit_t *emit) { emit_bc_pre(emit, 0); emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; - emit_write_byte_code_byte(emit, MP_BC_YIELD_VALUE); + emit_write_bytecode_byte(emit, MP_BC_YIELD_VALUE); } STATIC void emit_bc_yield_from(emit_t *emit) { emit_bc_pre(emit, -1); emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; - emit_write_byte_code_byte(emit, MP_BC_YIELD_FROM); + emit_write_bytecode_byte(emit, MP_BC_YIELD_FROM); } const emit_method_table_t emit_bc_method_table = { diff --git a/py/emitcpy.c b/py/emitcpy.c index 77967a2a95..a8a6265b8c 100644 --- a/py/emitcpy.c +++ b/py/emitcpy.c @@ -46,7 +46,7 @@ struct _emit_t { int pass; - int byte_code_offset; + int bytecode_offset; int stack_size; bool last_emit_was_return_value; @@ -68,7 +68,7 @@ STATIC void emit_cpy_set_native_types(emit_t *emit, bool do_native_types) { STATIC void emit_cpy_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { emit->pass = pass; - emit->byte_code_offset = 0; + emit->bytecode_offset = 0; emit->stack_size = 0; emit->last_emit_was_return_value = false; emit->scope = scope; @@ -108,20 +108,20 @@ STATIC void emit_cpy_delete_id(emit_t *emit, qstr qstr) { } // TODO: module-polymorphic function (read: name clash if made global) -static void emit_pre(emit_t *emit, int stack_size_delta, int byte_code_size) { +static void emit_pre(emit_t *emit, int stack_size_delta, int bytecode_size) { emit->stack_size += stack_size_delta; if (emit->stack_size > emit->scope->stack_size) { emit->scope->stack_size = emit->stack_size; } emit->last_emit_was_return_value = false; - if (emit->pass == MP_PASS_EMIT && byte_code_size > 0) { - if (emit->byte_code_offset >= 1000) { - printf("%d ", emit->byte_code_offset); + if (emit->pass == MP_PASS_EMIT && bytecode_size > 0) { + if (emit->bytecode_offset >= 1000) { + printf("%d ", emit->bytecode_offset); } else { - printf("% 4d ", emit->byte_code_offset); + printf("% 4d ", emit->bytecode_offset); } } - emit->byte_code_offset += byte_code_size; + emit->bytecode_offset += bytecode_size; } STATIC void emit_cpy_label_assign(emit_t *emit, uint l) { @@ -130,11 +130,11 @@ STATIC void emit_cpy_label_assign(emit_t *emit, uint l) { if (emit->pass < MP_PASS_EMIT) { // assign label offset assert(emit->label_offsets[l] == -1); - emit->label_offsets[l] = emit->byte_code_offset; + emit->label_offsets[l] = emit->bytecode_offset; } else { // ensure label offset has not changed from MP_PASS_CODE_SIZE to MP_PASS_EMIT - assert(emit->label_offsets[l] == emit->byte_code_offset); - //printf("l%d: (at %d)\n", l, emit->byte_code_offset); + assert(emit->label_offsets[l] == emit->bytecode_offset); + //printf("l%d: (at %d)\n", l, emit->bytecode_offset); } } @@ -421,7 +421,7 @@ STATIC void emit_cpy_jump(emit_t *emit, uint label) { emit_pre(emit, 0, 3); if (emit->pass == MP_PASS_EMIT) { int dest = emit->label_offsets[label]; - if (dest < emit->byte_code_offset) { + if (dest < emit->bytecode_offset) { printf("JUMP_ABSOLUTE %d\n", emit->label_offsets[label]); } else { printf("JUMP_FORWARD %d\n", emit->label_offsets[label]); diff --git a/py/emitglue.c b/py/emitglue.c index ed3b385d9f..7265a206a8 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -73,8 +73,8 @@ mp_raw_code_t *mp_emit_glue_new_raw_code(void) { return rc; } -void mp_emit_glue_assign_byte_code(mp_raw_code_t *rc, byte *code, uint len, uint n_pos_args, uint n_kwonly_args, qstr *arg_names, uint scope_flags) { - rc->kind = MP_CODE_BYTE; +void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint n_pos_args, uint n_kwonly_args, qstr *arg_names, uint scope_flags) { + rc->kind = MP_CODE_BYTECODE; rc->scope_flags = scope_flags; rc->n_pos_args = n_pos_args; rc->n_kwonly_args = n_kwonly_args; @@ -99,45 +99,20 @@ void mp_emit_glue_assign_byte_code(mp_raw_code_t *rc, byte *code, uint len, uint #endif #if MICROPY_DEBUG_PRINTERS if (mp_verbose_flag > 0) { - mp_byte_code_print(code, len); + mp_bytecode_print(code, len); } #endif } -void mp_emit_glue_assign_native_code(mp_raw_code_t *rc, void *fun, uint len, int n_args) { - rc->kind = MP_CODE_NATIVE; +void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun, uint len, int n_args) { + assert(kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER || kind == MP_CODE_NATIVE_ASM); + rc->kind = kind; rc->scope_flags = 0; rc->n_pos_args = n_args; rc->u_native.fun = fun; #ifdef DEBUG_PRINT - DEBUG_printf("assign native code: fun=%p len=%u n_args=%d\n", fun, len, n_args); - byte *fun_data = (byte*)(((machine_uint_t)fun) & (~1)); // need to clear lower bit in case it's thumb code - for (int i = 0; i < 128 && i < len; i++) { - if (i > 0 && i % 16 == 0) { - DEBUG_printf("\n"); - } - DEBUG_printf(" %02x", fun_data[i]); - } - DEBUG_printf("\n"); - -#ifdef WRITE_CODE - if (fp_write_code != NULL) { - fwrite(fun_data, len, 1, fp_write_code); - fflush(fp_write_code); - } -#endif -#endif -} - -void mp_emit_glue_assign_inline_asm_code(mp_raw_code_t *rc, void *fun, uint len, int n_args) { - rc->kind = MP_CODE_INLINE_ASM; - rc->scope_flags = 0; - rc->n_pos_args = n_args; - rc->u_inline_asm.fun = fun; - -#ifdef DEBUG_PRINT - DEBUG_printf("assign inline asm code: fun=%p len=%u n_args=%d\n", fun, len, n_args); + DEBUG_printf("assign native: kind=%d fun=%p len=%u n_args=%d\n", kind, fun, len, n_args); byte *fun_data = (byte*)(((machine_uint_t)fun) & (~1)); // need to clear lower bit in case it's thumb code for (int i = 0; i < 128 && i < len; i++) { if (i > 0 && i % 16 == 0) { @@ -169,14 +144,15 @@ mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp // make the function, depending on the raw code kind mp_obj_t fun; switch (rc->kind) { - case MP_CODE_BYTE: + case MP_CODE_BYTECODE: fun = mp_obj_new_fun_bc(rc->scope_flags, rc->arg_names, rc->n_pos_args, rc->n_kwonly_args, def_args, rc->u_byte.code); break; - case MP_CODE_NATIVE: + case MP_CODE_NATIVE_PY: fun = mp_make_function_n(rc->n_pos_args, rc->u_native.fun); break; - case MP_CODE_INLINE_ASM: - fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->u_inline_asm.fun); + case MP_CODE_NATIVE_VIPER: + case MP_CODE_NATIVE_ASM: + fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->u_native.fun); break; default: // raw code was never set (this should not happen) diff --git a/py/emitglue.h b/py/emitglue.h index 9d7d2993b2..43bfb5e08a 100644 --- a/py/emitglue.h +++ b/py/emitglue.h @@ -29,9 +29,10 @@ typedef enum { MP_CODE_UNUSED, MP_CODE_RESERVED, - MP_CODE_BYTE, - MP_CODE_NATIVE, - MP_CODE_INLINE_ASM, + MP_CODE_BYTECODE, + MP_CODE_NATIVE_PY, + MP_CODE_NATIVE_VIPER, + MP_CODE_NATIVE_ASM, } mp_raw_code_kind_t; typedef struct _mp_code_t { @@ -46,11 +47,8 @@ typedef struct _mp_code_t { uint len; } u_byte; struct { - mp_fun_t fun; - } u_native; - struct { void *fun; - } u_inline_asm; + } u_native; }; } mp_raw_code_t; @@ -59,9 +57,8 @@ void mp_emit_glue_deinit(void); mp_raw_code_t *mp_emit_glue_new_raw_code(void); -void mp_emit_glue_assign_byte_code(mp_raw_code_t *rc, byte *code, uint len, uint n_pos_args, uint n_kwonly_args, qstr *arg_names, uint scope_flags); -void mp_emit_glue_assign_native_code(mp_raw_code_t *rc, void *f, uint len, int n_args); -void mp_emit_glue_assign_inline_asm_code(mp_raw_code_t *rc, void *f, uint len, int n_args); +void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint n_pos_args, uint n_kwonly_args, qstr *arg_names, uint scope_flags); +void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *f, uint len, int n_args); mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args); mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, uint n_closed_over, const mp_obj_t *args); diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 83ee7f69bf..79ed1c4a02 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -99,7 +99,7 @@ STATIC bool emit_inline_thumb_end_pass(emit_inline_asm_t *emit) { if (emit->pass == MP_PASS_EMIT) { void *f = asm_thumb_get_code(emit->as); - mp_emit_glue_assign_inline_asm_code(emit->scope->raw_code, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args); + mp_emit_glue_assign_native(emit->scope->raw_code, MP_CODE_NATIVE_ASM, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args); } return emit->success; diff --git a/py/emitnative.c b/py/emitnative.c index 4ce21e9c0e..261b1a2a51 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -309,10 +309,10 @@ STATIC void emit_native_end_pass(emit_t *emit) { if (emit->pass == MP_PASS_EMIT) { #if N_X64 void *f = asm_x64_get_code(emit->as); - mp_emit_glue_assign_native_code(emit->scope->raw_code, f, asm_x64_get_code_size(emit->as), emit->scope->num_pos_args); + mp_emit_glue_assign_native(emit->scope->raw_code, emit->do_viper_types ? MP_CODE_NATIVE_VIPER : MP_CODE_NATIVE_PY, f, asm_x64_get_code_size(emit->as), emit->scope->num_pos_args); #elif N_THUMB void *f = asm_thumb_get_code(emit->as); - mp_emit_glue_assign_native_code(emit->scope->raw_code, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args); + mp_emit_glue_assign_native(emit->scope->raw_code, emit->do_viper_types ? MP_CODE_NATIVE_VIPER : MP_CODE_NATIVE_PY, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args); #endif } } @@ -438,6 +438,11 @@ STATIC void emit_access_stack(emit_t *emit, int pos, vtype_kind_t *vtype, int re } } +STATIC void emit_pre_pop_discard(emit_t *emit, vtype_kind_t *vtype) { + emit->last_emit_was_return_value = false; + adjust_stack(emit, -1); +} + STATIC void emit_pre_pop_reg(emit_t *emit, vtype_kind_t *vtype, int reg_dest) { emit->last_emit_was_return_value = false; emit_access_stack(emit, 1, vtype, reg_dest); @@ -938,7 +943,7 @@ STATIC void emit_native_dup_top_two(emit_t *emit) { STATIC void emit_native_pop_top(emit_t *emit) { vtype_kind_t vtype; - emit_pre_pop_reg(emit, &vtype, REG_TEMP0); + emit_pre_pop_discard(emit, &vtype); emit_post(emit); } @@ -113,7 +113,7 @@ STATIC machine_uint_t gc_lock_depth; void gc_init(void *start, void *end) { // align end pointer on block boundary end = (void*)((machine_uint_t)end & (~(BYTES_PER_BLOCK - 1))); - DEBUG_printf("Initializing GC heap: %p..%p = %ld bytes\n", start, end, end - start); + DEBUG_printf("Initializing GC heap: %p..%p = " UINT_FMT " bytes\n", start, end, end - start); // calculate parameters for GC (T=total, A=alloc table, F=finaliser table, P=pool; all in bytes): // T = A + F + P diff --git a/py/lexer.c b/py/lexer.c index 373a8d7231..f736ef3030 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -210,8 +210,9 @@ STATIC void next_char(mp_lexer_t *lex) { void indent_push(mp_lexer_t *lex, uint indent) { if (lex->num_indent_level >= lex->alloc_indent_level) { - lex->indent_level = m_renew(uint16_t, lex->indent_level, lex->alloc_indent_level, lex->alloc_indent_level * 2); - lex->alloc_indent_level *= 2; + // TODO use m_renew_maybe and somehow indicate an error if it fails... probably by using MP_TOKEN_MEMORY_ERROR + lex->indent_level = m_renew(uint16_t, lex->indent_level, lex->alloc_indent_level, lex->alloc_indent_level + MP_ALLOC_LEXEL_INDENT_INC); + lex->alloc_indent_level += MP_ALLOC_LEXEL_INDENT_INC; } lex->indent_level[lex->num_indent_level++] = indent; } @@ -696,7 +697,15 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs } mp_lexer_t *mp_lexer_new(qstr src_name, void *stream_data, mp_lexer_stream_next_char_t stream_next_char, mp_lexer_stream_close_t stream_close) { - mp_lexer_t *lex = m_new(mp_lexer_t, 1); + mp_lexer_t *lex = m_new_maybe(mp_lexer_t, 1); + + // check for memory allocation error + if (lex == NULL) { + if (stream_close) { + stream_close(stream_data); + } + return NULL; + } lex->source_name = src_name; lex->stream_data = stream_data; @@ -706,12 +715,20 @@ mp_lexer_t *mp_lexer_new(qstr src_name, void *stream_data, mp_lexer_stream_next_ lex->column = 1; lex->emit_dent = 0; lex->nested_bracket_level = 0; - lex->alloc_indent_level = 16; + lex->alloc_indent_level = MP_ALLOC_LEXER_INDENT_INIT; lex->num_indent_level = 1; - lex->indent_level = m_new(uint16_t, lex->alloc_indent_level); - lex->indent_level[0] = 0; + lex->indent_level = m_new_maybe(uint16_t, lex->alloc_indent_level); vstr_init(&lex->vstr, 32); + // check for memory allocation error + if (lex->indent_level == NULL || vstr_had_error(&lex->vstr)) { + mp_lexer_free(lex); + return NULL; + } + + // store sentinel for first indentation level + lex->indent_level[0] = 0; + // preload characters lex->chr0 = stream_next_char(stream_data); lex->chr1 = stream_next_char(stream_data); @@ -50,6 +50,7 @@ typedef unsigned int uint; // TODO make a lazy m_renew that can increase by a smaller amount than requested (but by at least 1 more element) #define m_new(type, num) ((type*)(m_malloc(sizeof(type) * (num)))) +#define m_new_maybe(type, num) ((type*)(m_malloc_maybe(sizeof(type) * (num)))) #define m_new0(type, num) ((type*)(m_malloc0(sizeof(type) * (num)))) #define m_new_obj(type) (m_new(type, 1)) #define m_new_obj_var(obj_type, var_type, var_num) ((obj_type*)m_malloc(sizeof(obj_type) + sizeof(var_type) * (var_num))) @@ -95,6 +96,8 @@ bool unichar_isalpha(unichar c); bool unichar_isprint(unichar c); bool unichar_isdigit(unichar c); bool unichar_isxdigit(unichar c); +unichar unichar_tolower(unichar c); +unichar unichar_toupper(unichar c); /** variable string *********************************************/ diff --git a/py/modsys.c b/py/modsys.c index 33bf04ba2c..d133d6b278 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -36,6 +36,8 @@ #if MICROPY_ENABLE_MOD_SYS +MP_DECLARE_CONST_FUN_OBJ(mp_sys_exit_obj); + // These should be implemented by ports, specific types don't matter, // only addresses. struct _dummy_t; @@ -53,6 +55,11 @@ STATIC const MP_DEFINE_STR_OBJ(version_obj, "3.4.0"); STATIC const mp_map_elem_t mp_module_sys_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sys) }, +#if MICROPY_SYS_EXIT + // Should be implemented by port + { MP_OBJ_NEW_QSTR(MP_QSTR_exit), (mp_obj_t)&mp_sys_exit_obj }, +#endif + { MP_OBJ_NEW_QSTR(MP_QSTR_path), (mp_obj_t)&mp_sys_path_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_argv), (mp_obj_t)&mp_sys_argv_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_version), (mp_obj_t)&version_obj }, diff --git a/py/mpconfig.h b/py/mpconfig.h index 119859a3a4..a7e1c4a40d 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -36,6 +36,16 @@ /*****************************************************************************/ /* Memory allocation policy */ +// Initial amount for lexer indentation level +#ifndef MP_ALLOC_LEXER_INDENT_INIT +#define MP_ALLOC_LEXER_INDENT_INIT (10) +#endif + +// Increment for lexer indentation level +#ifndef MP_ALLOC_LEXEL_INDENT_INC +#define MP_ALLOC_LEXEL_INDENT_INC (8) +#endif + // Initial amount for parse rule stack #ifndef MP_ALLOC_PARSE_RULE_INIT #define MP_ALLOC_PARSE_RULE_INIT (64) @@ -100,7 +110,7 @@ // Whether to build functions that print debugging info: // mp_token_show -// mp_byte_code_print +// mp_bytecode_print // mp_parse_node_print #ifndef MICROPY_DEBUG_PRINTERS #define MICROPY_DEBUG_PRINTERS (0) @@ -229,12 +239,22 @@ typedef double mp_float_t; #define MICROPY_MOD_SYS_STDFILES (0) #endif +// sys.exit() availability +#ifndef MICROPY_SYS_EXIT +#define MICROPY_SYS_EXIT (0) +#endif + // Whether to support slice object and correspondingly // slice subscript operators #ifndef MICROPY_ENABLE_SLICE #define MICROPY_ENABLE_SLICE (1) #endif +// Whether to support frozenset object +#ifndef MICROPY_ENABLE_FROZENSET +#define MICROPY_ENABLE_FROZENSET (0) +#endif + // Whether to support the property object #ifndef MICROPY_ENABLE_PROPERTY #define MICROPY_ENABLE_PROPERTY (1) @@ -36,18 +36,18 @@ #include "runtime0.h" #include "runtime.h" -mp_obj_type_t *mp_obj_get_type(mp_obj_t o_in) { +mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in) { if (MP_OBJ_IS_SMALL_INT(o_in)) { return (mp_obj_t)&mp_type_int; } else if (MP_OBJ_IS_QSTR(o_in)) { return (mp_obj_t)&mp_type_str; } else { - mp_obj_base_t *o = o_in; + const mp_obj_base_t *o = o_in; return (mp_obj_t)o->type; } } -const char *mp_obj_get_type_str(mp_obj_t o_in) { +const char *mp_obj_get_type_str(mp_const_obj_t o_in) { return qstr_str(mp_obj_get_type(o_in)->name); } @@ -59,6 +59,12 @@ void printf_wrapper(void *env, const char *fmt, ...) { } void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { +#if !NDEBUG + if (o_in == NULL) { + print(env, "(nil)"); + return; + } +#endif mp_obj_type_t *type = mp_obj_get_type(o_in); if (type->print != NULL) { type->print(print, env, o_in, kind); @@ -255,8 +255,8 @@ struct _mp_obj_type_t { mp_make_new_fun_t make_new; // to make an instance of the type mp_call_fun_t call; - mp_unary_op_fun_t unary_op; // can return NULL if op not supported - mp_binary_op_fun_t binary_op; // can return NULL if op not supported + mp_unary_op_fun_t unary_op; // can return MP_OBJ_NOT_SUPPORTED if op not supported + mp_binary_op_fun_t binary_op; // can return MP_OBJ_NOT_SUPPORTED if op not supported mp_load_attr_fun_t load_attr; mp_store_attr_fun_t store_attr; // if value is MP_OBJ_NULL, then delete that attribute @@ -266,7 +266,7 @@ struct _mp_obj_type_t { // can return MP_OBJ_NOT_SUPPORTED mp_fun_1_t getiter; - mp_fun_1_t iternext; // may return MP_OBJ_NULL as an optimisation instead of raising StopIteration() (with no args) + mp_fun_1_t iternext; // may return MP_OBJ_STOP_ITERATION as an optimisation instead of raising StopIteration() (with no args) mp_buffer_p_t buffer_p; const mp_stream_p_t *stream_p; @@ -308,6 +308,7 @@ extern const mp_obj_type_t mp_type_filter; extern const mp_obj_type_t mp_type_dict; extern const mp_obj_type_t mp_type_range; extern const mp_obj_type_t mp_type_set; +extern const mp_obj_type_t mp_type_frozenset; extern const mp_obj_type_t mp_type_slice; extern const mp_obj_type_t mp_type_zip; extern const mp_obj_type_t mp_type_array; @@ -397,9 +398,10 @@ mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self); mp_obj_t mp_obj_new_getitem_iter(mp_obj_t *args); mp_obj_t mp_obj_new_module(qstr module_name); -mp_obj_type_t *mp_obj_get_type(mp_obj_t o_in); -const char *mp_obj_get_type_str(mp_obj_t o_in); +mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in); +const char *mp_obj_get_type_str(mp_const_obj_t o_in); bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo); // arguments should be type objects +mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t native_type); void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind); void mp_obj_print(mp_obj_t o, mp_print_kind_t kind); @@ -479,11 +481,11 @@ typedef struct _mp_obj_float_t { mp_float_t value; } mp_obj_float_t; mp_float_t mp_obj_float_get(mp_obj_t self_in); -mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs); // can return MP_OBJ_NULL +mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs); // can return MP_OBJ_NOT_SUPPORTED // complex void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag); -mp_obj_t mp_obj_complex_binary_op(int op, mp_float_t lhs_real, mp_float_t lhs_imag, mp_obj_t rhs_in); // can return MP_OBJ_NULL +mp_obj_t mp_obj_complex_binary_op(int op, mp_float_t lhs_real, mp_float_t lhs_imag, mp_obj_t rhs_in); // can return MP_OBJ_NOT_SUPPORTED #endif // tuple @@ -563,12 +565,17 @@ const mp_obj_t *mp_obj_property_get(mp_obj_t self_in); // sequence helpers void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest); -bool m_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, machine_uint_t *begin, machine_uint_t *end); -#define m_seq_copy(dest, src, len, item_t) memcpy(dest, src, len * sizeof(item_t)) -#define m_seq_cat(dest, src1, len1, src2, len2, item_t) { memcpy(dest, src1, (len1) * sizeof(item_t)); memcpy(dest + (len1), src2, (len2) * sizeof(item_t)); } +bool mp_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, machine_uint_t *begin, machine_uint_t *end); +#define mp_seq_copy(dest, src, len, item_t) memcpy(dest, src, len * sizeof(item_t)) +#define mp_seq_cat(dest, src1, len1, src2, len2, item_t) { memcpy(dest, src1, (len1) * sizeof(item_t)); memcpy(dest + (len1), src2, (len2) * sizeof(item_t)); } bool mp_seq_cmp_bytes(int op, const byte *data1, uint len1, const byte *data2, uint len2); bool mp_seq_cmp_objs(int op, const mp_obj_t *items1, uint len1, const mp_obj_t *items2, uint len2); mp_obj_t mp_seq_index_obj(const mp_obj_t *items, uint len, uint n_args, const mp_obj_t *args); mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value); // Helper to clear stale pointers from allocated, but unused memory, to preclude GC problems #define mp_seq_clear(start, len, alloc_len, item_sz) memset((byte*)(start) + (len) * (item_sz), 0, ((alloc_len) - (len)) * (item_sz)) +#define mp_seq_replace_slice_no_grow(dest, dest_len, beg, end, slice, slice_len, item_t) \ + /*printf("memcpy(%p, %p, %d)\n", dest + beg, slice, slice_len * sizeof(item_t));*/ \ + memcpy(dest + beg, slice, slice_len * sizeof(item_t)); \ + /*printf("memcpy(%p, %p, %d)\n", dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t));*/ \ + memcpy(dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t)); diff --git a/py/objarray.c b/py/objarray.c index 6fca4a4317..b394d77461 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -176,7 +176,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value return MP_OBJ_NOT_SUPPORTED; } machine_uint_t start, stop; - if (!m_seq_get_fast_slice_indexes(o->len, index_in, &start, &stop)) { + if (!mp_seq_get_fast_slice_indexes(o->len, index_in, &start, &stop)) { assert(0); } mp_obj_array_t *res = array_new(o->typecode, stop - start); diff --git a/py/objboundmeth.c b/py/objboundmeth.c index 85094add6a..9bbd34e9dd 100644 --- a/py/objboundmeth.c +++ b/py/objboundmeth.c @@ -39,6 +39,17 @@ typedef struct _mp_obj_bound_meth_t { mp_obj_t self; } mp_obj_bound_meth_t; +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED +STATIC void bound_meth_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { + mp_obj_bound_meth_t *o = o_in; + print(env, "<bound_method %p ", o); + mp_obj_print_helper(print, env, o->self, PRINT_REPR); + print(env, "."); + mp_obj_print_helper(print, env, o->meth, PRINT_REPR); + print(env, ">"); +} +#endif + mp_obj_t bound_meth_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) { mp_obj_bound_meth_t *self = self_in; @@ -65,6 +76,9 @@ mp_obj_t bound_meth_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_ const mp_obj_type_t bound_meth_type = { { &mp_type_type }, .name = MP_QSTR_bound_method, +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED + .print = bound_meth_print, +#endif .call = bound_meth_call, }; diff --git a/py/objdict.c b/py/objdict.c index 6a6fff2a9f..9d4ebb6279 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -465,12 +465,15 @@ STATIC void dict_view_print(void (*print)(void *env, const char *fmt, ...), void STATIC mp_obj_t dict_view_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { /* only supported for the 'keys' kind until sets and dicts are refactored */ mp_obj_dict_view_t *o = lhs_in; - if (o->kind != MP_DICT_VIEW_KEYS) return NULL; - if (op != MP_BINARY_OP_IN) return NULL; + if (o->kind != MP_DICT_VIEW_KEYS) { + return MP_OBJ_NOT_SUPPORTED; + } + if (op != MP_BINARY_OP_IN) { + return MP_OBJ_NOT_SUPPORTED; + } return dict_binary_op(op, o->dict, rhs_in); } - STATIC const mp_obj_type_t dict_view_type = { { &mp_type_type }, .name = MP_QSTR_dict_view, diff --git a/py/objfloat.c b/py/objfloat.c index d5cbe18fb0..5260fadc1c 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -97,7 +97,7 @@ STATIC mp_obj_t float_unary_op(int op, mp_obj_t o_in) { case MP_UNARY_OP_BOOL: return MP_BOOL(o->value != 0); case MP_UNARY_OP_POSITIVE: return o_in; case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-o->value); - default: return NULL; // op not supported + default: return MP_OBJ_NOT_SUPPORTED; } } diff --git a/py/objfun.c b/py/objfun.c index b4cd796c7c..732009376d 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -58,7 +58,7 @@ STATIC mp_obj_t fun_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { // we don't even need to check for 2nd arg type. return MP_BOOL(lhs_in == rhs_in); } - return NULL; + return MP_OBJ_NOT_SUPPORTED; } STATIC mp_obj_t fun_native_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) { @@ -378,7 +378,7 @@ continue2:; DEBUG_printf("Calling: args=%p, n_args=%d, extra_args=%p, n_extra_args=%d\n", args, n_args, extra_args, n_extra_args); dump_args(args, n_args); dump_args(extra_args, n_extra_args); - mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code(self->bytecode, args, n_args, extra_args, n_extra_args, &result); + mp_vm_return_kind_t vm_return_kind = mp_execute_bytecode(self->bytecode, args, n_args, extra_args, n_extra_args, &result); mp_globals_set(old_globals); if (vm_return_kind == MP_VM_RETURN_NORMAL) { @@ -506,12 +506,7 @@ STATIC mp_obj_t convert_val_from_inline_asm(machine_uint_t val) { STATIC mp_obj_t fun_asm_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) { mp_obj_fun_asm_t *self = self_in; - if (n_args != self->n_args) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes %d positional arguments but %d were given", self->n_args, n_args)); - } - if (n_kw != 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments")); - } + mp_arg_check_num(n_args, n_kw, self->n_args, self->n_args, false); machine_uint_t ret; if (n_args == 0) { diff --git a/py/objgenerator.c b/py/objgenerator.c index 9c19149164..fb8366bae5 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -118,7 +118,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ } mp_obj_dict_t *old_globals = mp_globals_get(); mp_globals_set(self->globals); - mp_vm_return_kind_t ret_kind = mp_execute_byte_code_2(self->code_info, &self->ip, + mp_vm_return_kind_t ret_kind = mp_execute_bytecode2(self->code_info, &self->ip, &self->state[self->n_state - 1], &self->sp, (mp_exc_stack_t*)(self->state + self->n_state), &self->exc_sp, throw_value); mp_globals_set(old_globals); @@ -276,7 +276,7 @@ mp_obj_t mp_obj_new_gen_instance(mp_obj_dict_t *globals, const byte *bytecode, u o->exc_sp = (mp_exc_stack_t*)(o->state + n_state) - 1; o->n_state = n_state; - // copy args to end of state array, in reverse (that's how mp_execute_byte_code_2 needs it) + // copy args to end of state array, in reverse (that's how mp_execute_bytecode2 needs it) for (uint i = 0; i < n_args; i++) { o->state[n_state - 1 - i] = args[i]; } diff --git a/py/objint_mpz.c b/py/objint_mpz.c index a7fcac9f28..8e72782d66 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -90,7 +90,7 @@ mp_obj_t mp_obj_int_unary_op(int op, mp_obj_t o_in) { case MP_UNARY_OP_POSITIVE: return o_in; case MP_UNARY_OP_NEGATIVE: { mp_obj_int_t *o2 = mp_obj_int_new_mpz(); mpz_neg_inpl(&o2->mpz, &o->mpz); return o2; } case MP_UNARY_OP_INVERT: { mp_obj_int_t *o2 = mp_obj_int_new_mpz(); mpz_not_inpl(&o2->mpz, &o->mpz); return o2; } - default: return NULL; // op not supported + default: return MP_OBJ_NOT_SUPPORTED; } } diff --git a/py/objlist.c b/py/objlist.c index d2d6f068d8..9e30ebb4aa 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -87,7 +87,6 @@ STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp default: nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "list takes at most 1 argument, %d given", n_args)); } - return NULL; } // Don't pass MP_BINARY_OP_NOT_EQUAL here @@ -116,16 +115,16 @@ STATIC mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { switch (op) { case MP_BINARY_OP_ADD: { if (!MP_OBJ_IS_TYPE(rhs, &mp_type_list)) { - return NULL; + return MP_OBJ_NOT_SUPPORTED; } mp_obj_list_t *p = rhs; mp_obj_list_t *s = list_new(o->len + p->len); - m_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); + mp_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); return s; } case MP_BINARY_OP_INPLACE_ADD: { if (!MP_OBJ_IS_TYPE(rhs, &mp_type_list)) { - return NULL; + return MP_OBJ_NOT_SUPPORTED; } list_extend(lhs, rhs); return o; @@ -133,7 +132,7 @@ STATIC mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { case MP_BINARY_OP_MULTIPLY: { machine_int_t n; if (!mp_obj_get_int_maybe(rhs, &n)) { - return NULL; + return MP_OBJ_NOT_SUPPORTED; } mp_obj_list_t *s = list_new(o->len * n); mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); @@ -154,6 +153,24 @@ STATIC mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete +#if MICROPY_ENABLE_SLICE + if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { + mp_obj_list_t *self = self_in; + machine_uint_t start, stop; + if (!mp_seq_get_fast_slice_indexes(self->len, index, &start, &stop)) { + assert(0); + } + + int len_adj = start - stop; + //printf("Len adj: %d\n", len_adj); + assert(len_adj <= 0); + mp_seq_replace_slice_no_grow(self->items, self->len, start, stop, self->items/*NULL*/, 0, mp_obj_t); + // Clear "freed" elements at the end of list + mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items)); + self->len += len_adj; + return mp_const_none; + } +#endif mp_obj_t args[2] = {self_in, index}; list_pop(2, args); return mp_const_none; @@ -163,17 +180,37 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { #if MICROPY_ENABLE_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { machine_uint_t start, stop; - if (!m_seq_get_fast_slice_indexes(self->len, index, &start, &stop)) { + if (!mp_seq_get_fast_slice_indexes(self->len, index, &start, &stop)) { assert(0); } mp_obj_list_t *res = list_new(stop - start); - m_seq_copy(res->items, self->items + start, res->len, mp_obj_t); + mp_seq_copy(res->items, self->items + start, res->len, mp_obj_t); return res; } #endif uint index_val = mp_get_index(self->base.type, self->len, index, false); return self->items[index_val]; } else { +#if MICROPY_ENABLE_SLICE + if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { + mp_obj_list_t *self = self_in; + assert(MP_OBJ_IS_TYPE(value, &mp_type_list)); + mp_obj_list_t *slice = value; + machine_uint_t start, stop; + if (!mp_seq_get_fast_slice_indexes(self->len, index, &start, &stop)) { + assert(0); + } + int len_adj = slice->len - (stop - start); + //printf("Len adj: %d\n", len_adj); + assert(len_adj <= 0); + mp_seq_replace_slice_no_grow(self->items, self->len, start, stop, slice->items, slice->len, mp_obj_t); + // Clear "freed" elements at the end of list + mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items)); + self->len += len_adj; + // TODO: apply allocation policy re: alloc_size + return mp_const_none; + } +#endif mp_obj_list_store(self_in, index, value); return mp_const_none; } diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index 70180b2db2..0874eea85f 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -160,6 +160,7 @@ mp_obj_t mp_obj_new_namedtuple_type(qstr name, const char *fields) { o->base.load_attr = namedtuple_load_attr; o->base.store_attr = namedtuple_store_attr; o->base.subscr = tuple_subscr; + o->base.getiter = tuple_getiter; o->base.bases_tuple = (mp_obj_t)&namedtuple_base_tuple; o->fields = fields; return o; diff --git a/py/objset.c b/py/objset.c index 8b1be26857..4198dac18f 100644 --- a/py/objset.c +++ b/py/objset.c @@ -50,13 +50,57 @@ typedef struct _mp_obj_set_it_t { STATIC mp_obj_t set_it_iternext(mp_obj_t self_in); +STATIC bool is_set_or_frozenset(mp_obj_t o) { + return MP_OBJ_IS_TYPE(o, &mp_type_set) +#if MICROPY_ENABLE_FROZENSET + || MP_OBJ_IS_TYPE(o, &mp_type_frozenset) +#endif + ; +} + +#if MICROPY_ENABLE_FROZENSET +STATIC void check_set_or_frozenset(mp_obj_t o) { + if (!is_set_or_frozenset(o)) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'set' object required")); + } +} +#else +#define check_set_or_frozenset(o) check_set(o) +#endif + +STATIC void check_set(mp_obj_t o) { + if (!MP_OBJ_IS_TYPE(o, &mp_type_set)) { + // Emulate CPython behavior + // AttributeError: 'frozenset' object has no attribute 'add' + #if MICROPY_ENABLE_FROZENSET + if (MP_OBJ_IS_TYPE(o, &mp_type_frozenset)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError, "'frozenset' has no such attribute")); + } + #endif + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'set' object required")); + } +} + STATIC void set_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { mp_obj_set_t *self = self_in; + #if MICROPY_ENABLE_FROZENSET + bool is_frozen = MP_OBJ_IS_TYPE(self_in, &mp_type_frozenset); + #endif if (self->set.used == 0) { + #if MICROPY_ENABLE_FROZENSET + if (is_frozen) { + print(env, "frozen"); + } + #endif print(env, "set()"); return; } bool first = true; + #if MICROPY_ENABLE_FROZENSET + if (is_frozen) { + print(env, "frozenset("); + } + #endif print(env, "{"); for (int i = 0; i < self->set.alloc; i++) { if (MP_SET_SLOT_IS_FILLED(&self->set, i)) { @@ -68,6 +112,11 @@ STATIC void set_print(void (*print)(void *env, const char *fmt, ...), void *env, } } print(env, "}"); + #if MICROPY_ENABLE_FROZENSET + if (is_frozen) { + print(env, ")"); + } + #endif } @@ -82,12 +131,14 @@ STATIC mp_obj_t set_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_ case 1: { // 1 argument, an iterable from which we make a new set - mp_obj_t set = mp_obj_new_set(0, NULL); + mp_obj_set_t *set = mp_obj_new_set(0, NULL); mp_obj_t iterable = mp_getiter(args[0]); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { mp_obj_set_store(set, item); } + // Set actual set/frozenset type + set->base.type = type_in; return set; } @@ -132,7 +183,7 @@ STATIC mp_obj_t set_getiter(mp_obj_t set_in) { /* set methods */ STATIC mp_obj_t set_add(mp_obj_t self_in, mp_obj_t item) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); + check_set(self_in); mp_obj_set_t *self = self_in; mp_set_lookup(&self->set, item, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); return mp_const_none; @@ -140,7 +191,7 @@ STATIC mp_obj_t set_add(mp_obj_t self_in, mp_obj_t item) { STATIC MP_DEFINE_CONST_FUN_OBJ_2(set_add_obj, set_add); STATIC mp_obj_t set_clear(mp_obj_t self_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); + check_set(self_in); mp_obj_set_t *self = self_in; mp_set_clear(&self->set); @@ -149,8 +200,7 @@ STATIC mp_obj_t set_clear(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(set_clear_obj, set_clear); -STATIC mp_obj_t set_copy(mp_obj_t self_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); +STATIC mp_obj_t set_copy_as_mutable(mp_obj_t self_in) { mp_obj_set_t *self = self_in; mp_obj_set_t *other = m_new_obj(mp_obj_set_t); @@ -161,10 +211,20 @@ STATIC mp_obj_t set_copy(mp_obj_t self_in) { return other; } + +STATIC mp_obj_t set_copy(mp_obj_t self_in) { + check_set_or_frozenset(self_in); + mp_obj_set_t *self = self_in; + + mp_obj_set_t *other = set_copy_as_mutable(self); + other->base.type = self->base.type; + + return other; +} STATIC MP_DEFINE_CONST_FUN_OBJ_1(set_copy_obj, set_copy); STATIC mp_obj_t set_discard(mp_obj_t self_in, mp_obj_t item) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); + check_set(self_in); mp_obj_set_t *self = self_in; mp_set_lookup(&self->set, item, MP_MAP_LOOKUP_REMOVE_IF_FOUND); return mp_const_none; @@ -173,12 +233,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(set_discard_obj, set_discard); STATIC mp_obj_t set_diff_int(int n_args, const mp_obj_t *args, bool update) { assert(n_args > 0); - assert(MP_OBJ_IS_TYPE(args[0], &mp_type_set)); + mp_obj_set_t *self; if (update) { + check_set(args[0]); self = args[0]; } else { - self = set_copy(args[0]); + check_set_or_frozenset(args[0]); + self = set_copy_as_mutable(args[0]); } @@ -195,6 +257,7 @@ STATIC mp_obj_t set_diff_int(int n_args, const mp_obj_t *args, bool update) { } } + self->base.type = ((mp_obj_set_t*)args[0])->base.type; return self; } @@ -210,7 +273,12 @@ STATIC mp_obj_t set_diff_update(uint n_args, const mp_obj_t *args) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(set_diff_update_obj, 1, set_diff_update); STATIC mp_obj_t set_intersect_int(mp_obj_t self_in, mp_obj_t other, bool update) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); + if (update) { + check_set(self_in); + } else { + check_set_or_frozenset(self_in); + } + if (self_in == other) { return update ? mp_const_none : set_copy(self_in); } @@ -247,7 +315,7 @@ STATIC mp_obj_t set_intersect_update(mp_obj_t self_in, mp_obj_t other) { STATIC MP_DEFINE_CONST_FUN_OBJ_2(set_intersect_update_obj, set_intersect_update); STATIC mp_obj_t set_isdisjoint(mp_obj_t self_in, mp_obj_t other) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); + check_set_or_frozenset(self_in); mp_obj_set_t *self = self_in; mp_obj_t iter = mp_getiter(other); @@ -264,7 +332,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(set_isdisjoint_obj, set_isdisjoint); STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool proper) { mp_obj_set_t *self; bool cleanup_self = false; - if (MP_OBJ_IS_TYPE(self_in, &mp_type_set)) { + if (is_set_or_frozenset(self_in)) { self = self_in; } else { self = set_make_new((mp_obj_t)&mp_type_set, 1, 0, &self_in); @@ -273,7 +341,7 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool mp_obj_set_t *other; bool cleanup_other = false; - if (MP_OBJ_IS_TYPE(other_in, &mp_type_set)) { + if (is_set_or_frozenset(other_in)) { other = other_in; } else { other = set_make_new((mp_obj_t)&mp_type_set, 1, 0, &other_in); @@ -292,6 +360,7 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool } } } + // TODO: Should free objects altogether if (cleanup_self) { set_clear(self); } @@ -319,9 +388,9 @@ STATIC mp_obj_t set_issuperset_proper(mp_obj_t self_in, mp_obj_t other_in) { } STATIC mp_obj_t set_equal(mp_obj_t self_in, mp_obj_t other_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); + check_set_or_frozenset(self_in); mp_obj_set_t *self = self_in; - if (!MP_OBJ_IS_TYPE(other_in, &mp_type_set)) { + if (!is_set_or_frozenset(other_in)) { return mp_const_false; } mp_obj_set_t *other = other_in; @@ -332,7 +401,7 @@ STATIC mp_obj_t set_equal(mp_obj_t self_in, mp_obj_t other_in) { } STATIC mp_obj_t set_pop(mp_obj_t self_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); + check_set(self_in); mp_obj_set_t *self = self_in; mp_obj_t obj = mp_set_remove_first(&self->set); if (obj == MP_OBJ_NULL) { @@ -343,7 +412,7 @@ STATIC mp_obj_t set_pop(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(set_pop_obj, set_pop); STATIC mp_obj_t set_remove(mp_obj_t self_in, mp_obj_t item) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); + check_set(self_in); mp_obj_set_t *self = self_in; if (mp_set_lookup(&self->set, item, MP_MAP_LOOKUP_REMOVE_IF_FOUND) == MP_OBJ_NULL) { nlr_raise(mp_obj_new_exception(&mp_type_KeyError)); @@ -353,7 +422,7 @@ STATIC mp_obj_t set_remove(mp_obj_t self_in, mp_obj_t item) { STATIC MP_DEFINE_CONST_FUN_OBJ_2(set_remove_obj, set_remove); STATIC mp_obj_t set_symmetric_difference_update(mp_obj_t self_in, mp_obj_t other_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); + check_set(self_in); mp_obj_set_t *self = self_in; mp_obj_t iter = mp_getiter(other_in); mp_obj_t next; @@ -365,10 +434,11 @@ STATIC mp_obj_t set_symmetric_difference_update(mp_obj_t self_in, mp_obj_t other STATIC MP_DEFINE_CONST_FUN_OBJ_2(set_symmetric_difference_update_obj, set_symmetric_difference_update); STATIC mp_obj_t set_symmetric_difference(mp_obj_t self_in, mp_obj_t other_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); - self_in = set_copy(self_in); - set_symmetric_difference_update(self_in, other_in); - return self_in; + check_set_or_frozenset(self_in); + mp_obj_set_t *self_out = set_copy_as_mutable(self_in); + set_symmetric_difference_update(self_out, other_in); + self_out->base.type = ((mp_obj_set_t*)self_in)->base.type; + return self_out; } STATIC MP_DEFINE_CONST_FUN_OBJ_2(set_symmetric_difference_obj, set_symmetric_difference); @@ -382,7 +452,6 @@ STATIC void set_update_int(mp_obj_set_t *self, mp_obj_t other_in) { STATIC mp_obj_t set_update(uint n_args, const mp_obj_t *args) { assert(n_args > 0); - assert(MP_OBJ_IS_TYPE(args[0], &mp_type_set)); for (int i = 1; i < n_args; i++) { set_update_int(args[0], args[i]); @@ -393,7 +462,7 @@ STATIC mp_obj_t set_update(uint n_args, const mp_obj_t *args) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(set_update_obj, 1, set_update); STATIC mp_obj_t set_union(mp_obj_t self_in, mp_obj_t other_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); + check_set_or_frozenset(self_in); mp_obj_set_t *self = set_copy(self_in); set_update_int(self, other_in); return self; @@ -412,41 +481,39 @@ STATIC mp_obj_t set_unary_op(int op, mp_obj_t self_in) { STATIC mp_obj_t set_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_t args[] = {lhs, rhs}; switch (op) { - case MP_BINARY_OP_OR: - return set_union(lhs, rhs); - case MP_BINARY_OP_XOR: - return set_symmetric_difference(lhs, rhs); - case MP_BINARY_OP_AND: - return set_intersect(lhs, rhs); - case MP_BINARY_OP_SUBTRACT: - return set_diff(2, args); - case MP_BINARY_OP_INPLACE_OR: - return set_union(lhs, rhs); - case MP_BINARY_OP_INPLACE_XOR: - return set_symmetric_difference(lhs, rhs); - case MP_BINARY_OP_INPLACE_AND: - return set_intersect(lhs, rhs); - case MP_BINARY_OP_INPLACE_SUBTRACT: - return set_diff(2, args); - case MP_BINARY_OP_LESS: - return set_issubset_proper(lhs, rhs); - case MP_BINARY_OP_MORE: - return set_issuperset_proper(lhs, rhs); - case MP_BINARY_OP_EQUAL: - return set_equal(lhs, rhs); - case MP_BINARY_OP_LESS_EQUAL: - return set_issubset(lhs, rhs); - case MP_BINARY_OP_MORE_EQUAL: - return set_issuperset(lhs, rhs); - case MP_BINARY_OP_IN: - { - mp_obj_set_t *o = lhs; - mp_obj_t elem = mp_set_lookup(&o->set, rhs, MP_MAP_LOOKUP); - return MP_BOOL(elem != NULL); - } - default: - // op not supported - return NULL; + case MP_BINARY_OP_OR: + return set_union(lhs, rhs); + case MP_BINARY_OP_XOR: + return set_symmetric_difference(lhs, rhs); + case MP_BINARY_OP_AND: + return set_intersect(lhs, rhs); + case MP_BINARY_OP_SUBTRACT: + return set_diff(2, args); + case MP_BINARY_OP_INPLACE_OR: + return set_union(lhs, rhs); + case MP_BINARY_OP_INPLACE_XOR: + return set_symmetric_difference(lhs, rhs); + case MP_BINARY_OP_INPLACE_AND: + return set_intersect(lhs, rhs); + case MP_BINARY_OP_INPLACE_SUBTRACT: + return set_diff(2, args); + case MP_BINARY_OP_LESS: + return set_issubset_proper(lhs, rhs); + case MP_BINARY_OP_MORE: + return set_issuperset_proper(lhs, rhs); + case MP_BINARY_OP_EQUAL: + return set_equal(lhs, rhs); + case MP_BINARY_OP_LESS_EQUAL: + return set_issubset(lhs, rhs); + case MP_BINARY_OP_MORE_EQUAL: + return set_issuperset(lhs, rhs); + case MP_BINARY_OP_IN: { + mp_obj_set_t *o = lhs; + mp_obj_t elem = mp_set_lookup(&o->set, rhs, MP_MAP_LOOKUP); + return MP_BOOL(elem != NULL); + } + default: + return MP_OBJ_NOT_SUPPORTED; } } @@ -488,6 +555,19 @@ const mp_obj_type_t mp_type_set = { .locals_dict = (mp_obj_t)&set_locals_dict, }; +#if MICROPY_ENABLE_FROZENSET +const mp_obj_type_t mp_type_frozenset = { + { &mp_type_type }, + .name = MP_QSTR_frozenset, + .print = set_print, + .make_new = set_make_new, + .unary_op = set_unary_op, + .binary_op = set_binary_op, + .getiter = set_getiter, + .locals_dict = (mp_obj_t)&set_locals_dict, +}; +#endif + mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items) { mp_obj_set_t *o = m_new_obj(mp_obj_set_t); o->base.type = &mp_type_set; diff --git a/py/objstr.c b/py/objstr.c index 7ca8afc6ba..33bfcc3756 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -54,6 +54,11 @@ 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); STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in); +STATIC NORETURN void arg_type_mixup(); + +STATIC bool is_str_or_bytes(mp_obj_t o) { + return MP_OBJ_IS_STR(o) || MP_OBJ_IS_TYPE(o, &mp_type_bytes); +} /******************************************************************************/ /* str */ @@ -287,10 +292,9 @@ STATIC mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { } break; - case MP_BINARY_OP_MULTIPLY: - { + case MP_BINARY_OP_MULTIPLY: { if (!MP_OBJ_IS_SMALL_INT(rhs_in)) { - return NULL; + return MP_OBJ_NOT_SUPPORTED; } int n = MP_OBJ_SMALL_INT_VALUE(rhs_in); byte *data; @@ -334,7 +338,7 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { #if MICROPY_ENABLE_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { machine_uint_t start, stop; - if (!m_seq_get_fast_slice_indexes(self_len, index, &start, &stop)) { + if (!mp_seq_get_fast_slice_indexes(self_len, index, &start, &stop)) { assert(0); } return mp_obj_new_str(self_data + start, stop - start, false); @@ -536,7 +540,8 @@ enum { LSTRIP, RSTRIP, STRIP }; STATIC mp_obj_t str_uni_strip(int type, uint n_args, const mp_obj_t *args) { assert(1 <= n_args && n_args <= 2); - assert(MP_OBJ_IS_STR(args[0])); + assert(is_str_or_bytes(args[0])); + const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); const byte *chars_to_del; uint chars_to_del_len; @@ -546,7 +551,9 @@ STATIC mp_obj_t str_uni_strip(int type, uint n_args, const mp_obj_t *args) { chars_to_del = whitespace; chars_to_del_len = sizeof(whitespace); } else { - assert(MP_OBJ_IS_STR(args[1])); + if (mp_obj_get_type(args[1]) != self_type) { + arg_type_mixup(); + } GET_STR_DATA_LEN(args[1], s, l); chars_to_del = s; chars_to_del_len = l; @@ -590,7 +597,7 @@ STATIC mp_obj_t str_uni_strip(int type, uint n_args, const mp_obj_t *args) { assert(last_good_char_pos >= first_good_char_pos); //+1 to accomodate the last character machine_uint_t stripped_len = last_good_char_pos - first_good_char_pos + 1; - return mp_obj_new_str(orig_str + first_good_char_pos, stripped_len, false); + return str_new(self_type, orig_str + first_good_char_pos, stripped_len); } STATIC mp_obj_t str_strip(uint n_args, const mp_obj_t *args) { @@ -1327,9 +1334,12 @@ STATIC mp_obj_t str_count(uint n_args, const mp_obj_t *args) { } 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)) { - bad_implicit_conversion(arg); + if (!is_str_or_bytes(self_in)) { + assert(0); + } + mp_obj_type_t *self_type = mp_obj_get_type(self_in); + if (self_type != mp_obj_get_type(arg)) { + arg_type_mixup(); } GET_STR_DATA_LEN(self_in, str, str_len); @@ -1350,9 +1360,9 @@ STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, machine_int_t di const byte *position_ptr = find_subbytes(str, str_len, sep, sep_len, direction); if (position_ptr != NULL) { machine_uint_t position = position_ptr - str; - result[0] = mp_obj_new_str(str, position, false); + result[0] = str_new(self_type, str, position); result[1] = arg; - result[2] = mp_obj_new_str(str + position + sep_len, str_len - position - sep_len, false); + result[2] = str_new(self_type, str + position + sep_len, str_len - position - sep_len); } return mp_obj_new_tuple(3, result); @@ -1366,6 +1376,32 @@ STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) { return str_partitioner(self_in, arg, -1); } +enum { CASE_UPPER, CASE_LOWER }; + +// Supposedly not too critical operations, so optimize for code size +STATIC mp_obj_t str_caseconv(int op, mp_obj_t self_in) { + GET_STR_DATA_LEN(self_in, self_data, self_len); + byte *data; + mp_obj_t s = mp_obj_str_builder_start(mp_obj_get_type(self_in), self_len, &data); + for (int i = 0; i < self_len; i++) { + if (op == CASE_UPPER) { + *data++ = unichar_toupper(*self_data++); + } else { + *data++ = unichar_tolower(*self_data++); + } + } + *data = 0; + return mp_obj_str_builder_end(s); +} + +STATIC mp_obj_t str_lower(mp_obj_t self_in) { + return str_caseconv(CASE_LOWER, self_in); +} + +STATIC mp_obj_t str_upper(mp_obj_t self_in) { + return str_caseconv(CASE_UPPER, self_in); +} + #if MICROPY_CPYTHON_COMPAT // These methods are superfluous in the presense of str() and bytes() // constructors. @@ -1429,6 +1465,8 @@ 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 MP_DEFINE_CONST_FUN_OBJ_1(str_lower_obj, str_lower); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(str_upper_obj, str_upper); STATIC const mp_map_elem_t str_locals_dict_table[] = { #if MICROPY_CPYTHON_COMPAT @@ -1450,6 +1488,8 @@ STATIC const mp_map_elem_t str_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_count), (mp_obj_t)&str_count_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_partition), (mp_obj_t)&str_partition_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_rpartition), (mp_obj_t)&str_rpartition_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_lower), (mp_obj_t)&str_lower_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_upper), (mp_obj_t)&str_upper_obj }, }; STATIC MP_DEFINE_CONST_DICT(str_locals_dict, str_locals_dict_table); @@ -1557,6 +1597,10 @@ STATIC void bad_implicit_conversion(mp_obj_t self_in) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(self_in))); } +STATIC void arg_type_mixup() { + nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "Can't mix str and bytes arguments")); +} + uint mp_obj_str_get_hash(mp_obj_t self_in) { // TODO: This has too big overhead for hash accessor if (MP_OBJ_IS_STR(self_in) || MP_OBJ_IS_TYPE(self_in, &mp_type_bytes)) { @@ -1603,7 +1647,7 @@ const char *mp_obj_str_get_str(mp_obj_t self_in) { } const char *mp_obj_str_get_data(mp_obj_t self_in, uint *len) { - if (MP_OBJ_IS_STR(self_in)) { + if (is_str_or_bytes(self_in)) { GET_STR_DATA_LEN(self_in, s, l); *len = l; return (const char*)s; diff --git a/py/objtuple.c b/py/objtuple.c index 9434b418cd..ca65b28e31 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -99,12 +99,20 @@ mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m // Don't pass MP_BINARY_OP_NOT_EQUAL here STATIC bool tuple_cmp_helper(int op, mp_obj_t self_in, mp_obj_t another_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_tuple)); - if (!MP_OBJ_IS_TYPE(another_in, &mp_type_tuple)) { - return false; + mp_obj_type_t *self_type = mp_obj_get_type(self_in); + if (self_type->getiter != tuple_getiter) { + assert(0); } + mp_obj_type_t *another_type = mp_obj_get_type(another_in); mp_obj_tuple_t *self = self_in; mp_obj_tuple_t *another = another_in; + if (another_type->getiter != tuple_getiter) { + // Slow path for user subclasses + another = mp_instance_cast_to_native_base(another, &mp_type_tuple); + if (another == MP_OBJ_NULL) { + return false; + } + } return mp_seq_cmp_objs(op, self->items, self->len, another->items, another->len); } @@ -121,20 +129,18 @@ mp_obj_t tuple_unary_op(int op, mp_obj_t self_in) { mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_tuple_t *o = lhs; switch (op) { - case MP_BINARY_OP_ADD: - { + case MP_BINARY_OP_ADD: { if (!mp_obj_is_subclass_fast(mp_obj_get_type(rhs), (mp_obj_t)&mp_type_tuple)) { - return NULL; + return MP_OBJ_NOT_SUPPORTED; } mp_obj_tuple_t *p = rhs; mp_obj_tuple_t *s = mp_obj_new_tuple(o->len + p->len, NULL); - m_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); + mp_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); return s; } - case MP_BINARY_OP_MULTIPLY: - { + case MP_BINARY_OP_MULTIPLY: { if (!MP_OBJ_IS_SMALL_INT(rhs)) { - return NULL; + return MP_OBJ_NOT_SUPPORTED; } int n = MP_OBJ_SMALL_INT_VALUE(rhs); mp_obj_tuple_t *s = mp_obj_new_tuple(o->len * n, NULL); @@ -150,7 +156,7 @@ mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { default: // op not supported - return NULL; + return MP_OBJ_NOT_SUPPORTED; } } @@ -161,11 +167,11 @@ mp_obj_t tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { #if MICROPY_ENABLE_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { machine_uint_t start, stop; - if (!m_seq_get_fast_slice_indexes(self->len, index, &start, &stop)) { + if (!mp_seq_get_fast_slice_indexes(self->len, index, &start, &stop)) { assert(0); } mp_obj_tuple_t *res = mp_obj_new_tuple(stop - start, NULL); - m_seq_copy(res->items, self->items + start, res->len, mp_obj_t); + mp_seq_copy(res->items, self->items + start, res->len, mp_obj_t); return res; } #endif @@ -176,7 +182,7 @@ mp_obj_t tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } } -STATIC mp_obj_t tuple_getiter(mp_obj_t o_in) { +mp_obj_t tuple_getiter(mp_obj_t o_in) { return mp_obj_new_tuple_iterator(o_in, 0); } diff --git a/py/objtuple.h b/py/objtuple.h index 0e48c3c843..9c33ed09f5 100644 --- a/py/objtuple.h +++ b/py/objtuple.h @@ -34,3 +34,4 @@ void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_o mp_obj_t tuple_unary_op(int op, mp_obj_t self_in); mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs); mp_obj_t tuple_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value); +mp_obj_t tuple_getiter(mp_obj_t o_in); diff --git a/py/objtype.c b/py/objtype.c index 7a7d758429..c579477db7 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -67,7 +67,12 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t int count = 0; for (uint i = 0; i < len; i++) { assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type)); - if (is_native_type((const mp_obj_type_t *)items[i])) { + const mp_obj_type_t *bt = (const mp_obj_type_t *)items[i]; + if (bt == &mp_type_object) { + // Not a "real" type + continue; + } + if (is_native_type(bt)) { *last_native_base = items[i]; count++; } else { @@ -116,11 +121,13 @@ STATIC void mp_obj_class_lookup(mp_obj_instance_t *o, const mp_obj_type_t *type, if (o != MP_OBJ_NULL && is_native_type(type)) { dest[1] = o->subobj[0]; } + // TODO: Sensibly, we should call instance_convert_return_attr() here, + // instead of multiple places later. Also, this code duplicates runtime.c much. return; } } - // Try this for completeness, by all native methods should be statically defined + // Try this for completeness, but all native methods should be statically defined // in locals_dict, and would be handled by above. if (o != MP_OBJ_NULL && is_native_type(type)) { mp_load_method_maybe(o->subobj[0], attr, dest); @@ -144,7 +151,12 @@ STATIC void mp_obj_class_lookup(mp_obj_instance_t *o, const mp_obj_type_t *type, } for (uint i = 0; i < len - 1; i++) { assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type)); - mp_obj_class_lookup(o, (mp_obj_type_t*)items[i], attr, meth_offset, dest); + mp_obj_type_t *bt = (mp_obj_type_t*)items[i]; + if (bt == &mp_type_object) { + // Not a "real" type + continue; + } + mp_obj_class_lookup(o, bt, attr, meth_offset, dest); if (dest[0] != MP_OBJ_NULL) { return; } @@ -153,6 +165,10 @@ STATIC void mp_obj_class_lookup(mp_obj_instance_t *o, const mp_obj_type_t *type, // search last base (simple tail recursion elimination) assert(MP_OBJ_IS_TYPE(items[len - 1], &mp_type_type)); type = (mp_obj_type_t*)items[len - 1]; + if (type == &mp_type_object) { + // Not a "real" type + return; + } } } @@ -317,6 +333,9 @@ STATIC void instance_convert_return_attr(mp_obj_t self, mp_obj_t member, mp_obj_ // return a bound method, with self being the type of this object dest[0] = ((mp_obj_static_class_method_t*)member)->fun; dest[1] = mp_obj_get_type(self); + } else if (MP_OBJ_IS_TYPE(member, &mp_type_type)) { + // Don't try to bind types + dest[0] = member; } else if (mp_obj_is_callable(member)) { // return a bound method, with self being this object dest[0] = member; @@ -487,6 +506,28 @@ STATIC mp_obj_t instance_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp return mp_call_function_n_kw(meth, n_args, n_kw, args); } +STATIC mp_obj_t instance_getiter(mp_obj_t self_in) { + mp_obj_instance_t *self = self_in; + mp_obj_t member[2] = {MP_OBJ_NULL}; + mp_obj_class_lookup(self, self->base.type, MP_QSTR___iter__, offsetof(mp_obj_type_t, getiter), member); + if (member[0] == MP_OBJ_NULL) { + // This kinda duplicates code in mp_getiter() + mp_obj_class_lookup(self, self->base.type, MP_QSTR___getitem__, 0, member); + if (member[0] != MP_OBJ_NULL) { + // __getitem__ exists, create an iterator + instance_convert_return_attr(self_in, member[0], member); + return mp_obj_new_getitem_iter(member); + } + return MP_OBJ_NULL; + } + if (member[0] == MP_OBJ_SENTINEL) { + mp_obj_type_t *type = mp_obj_get_type(self->subobj[0]); + return type->getiter(self->subobj[0]); + } + mp_obj_t meth = mp_obj_new_bound_meth(member[0], self); + return mp_call_function_n_kw(meth, 0, 0, NULL); +} + /******************************************************************************/ // type object // - the struct is mp_obj_type_t and is defined in obj.h so const types can be made @@ -596,8 +637,10 @@ STATIC mp_obj_t type_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { // Types can be equal only if it's the same type structure, // we don't even need to check for 2nd arg type. return MP_BOOL(lhs_in == rhs_in); + + default: + return MP_OBJ_NOT_SUPPORTED; } - return NULL; } const mp_obj_type_t mp_type_type = { @@ -639,6 +682,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) o->store_attr = instance_store_attr; o->subscr = instance_subscr; o->call = instance_call; + o->getiter = instance_getiter; o->bases_tuple = bases_tuple; o->locals_dict = locals_dict; @@ -801,6 +845,15 @@ STATIC mp_obj_t mp_builtin_isinstance(mp_obj_t object, mp_obj_t classinfo) { MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_isinstance_obj, mp_builtin_isinstance); +mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t native_type) { + mp_obj_type_t *self_type = mp_obj_get_type(self_in); + if (!mp_obj_is_subclass_fast(self_type, native_type)) { + return MP_OBJ_NULL; + } + mp_obj_instance_t *self = (mp_obj_instance_t*)self_in; + return self->subobj[0]; +} + /******************************************************************************/ // staticmethod and classmethod types (probably should go in a different file) diff --git a/py/parse.c b/py/parse.c index 0ec336cd1a..f5efd7a4f4 100644 --- a/py/parse.c +++ b/py/parse.c @@ -344,21 +344,26 @@ STATIC void push_result_rule(parser_t *parser, int src_line, const rule_t *rule, mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_parse_error_kind_t *parse_error_kind_out) { - // allocate memory for the parser and its stacks + // initialise parser and allocate memory for its stacks - parser_t *parser = m_new_obj(parser_t); + parser_t parser; - parser->had_memory_error = false; + parser.had_memory_error = false; - parser->rule_stack_alloc = MP_ALLOC_PARSE_RULE_INIT; - parser->rule_stack_top = 0; - parser->rule_stack = m_new(rule_stack_t, parser->rule_stack_alloc); + parser.rule_stack_alloc = MP_ALLOC_PARSE_RULE_INIT; + parser.rule_stack_top = 0; + parser.rule_stack = m_new_maybe(rule_stack_t, parser.rule_stack_alloc); - parser->result_stack_alloc = MP_ALLOC_PARSE_RESULT_INIT; - parser->result_stack_top = 0; - parser->result_stack = m_new(mp_parse_node_t, parser->result_stack_alloc); + parser.result_stack_alloc = MP_ALLOC_PARSE_RESULT_INIT; + parser.result_stack_top = 0; + parser.result_stack = m_new_maybe(mp_parse_node_t, parser.result_stack_alloc); - parser->lexer = lex; + parser.lexer = lex; + + // check if we could allocate the stacks + if (parser.rule_stack == NULL || parser.result_stack == NULL) { + goto memory_error; + } // work out the top-level rule to use, and push it on the stack int top_level_rule; @@ -367,7 +372,7 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p case MP_PARSE_EVAL_INPUT: top_level_rule = RULE_eval_input; break; default: top_level_rule = RULE_file_input; } - push_rule(parser, mp_lexer_cur(lex)->src_line, rules[top_level_rule], 0); + push_rule(&parser, mp_lexer_cur(lex)->src_line, rules[top_level_rule], 0); // parse! @@ -381,17 +386,17 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p for (;;) { next_rule: - if (parser->rule_stack_top == 0 || parser->had_memory_error) { + if (parser.rule_stack_top == 0 || parser.had_memory_error) { break; } - pop_rule(parser, &rule, &i, &rule_src_line); + pop_rule(&parser, &rule, &i, &rule_src_line); n = rule->act & RULE_ACT_ARG_MASK; /* // debugging - printf("depth=%d ", parser->rule_stack_top); - for (int j = 0; j < parser->rule_stack_top; ++j) { + printf("depth=%d ", parser.rule_stack_top); + for (int j = 0; j < parser.rule_stack_top; ++j) { printf(" "); } printf("%s n=%d i=%d bt=%d\n", rule->rule_name, n, i, backtrack); @@ -408,14 +413,14 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p switch (rule->arg[i] & RULE_ARG_KIND_MASK) { case RULE_ARG_TOK: if (mp_lexer_is_kind(lex, rule->arg[i] & RULE_ARG_ARG_MASK)) { - push_result_token(parser, lex); + push_result_token(&parser, lex); mp_lexer_to_next(lex); goto next_rule; } break; case RULE_ARG_RULE: - push_rule(parser, rule_src_line, rule, i + 1); // save this or-rule - push_rule_from_arg(parser, rule->arg[i]); // push child of or-rule + push_rule(&parser, rule_src_line, rule, i + 1); // save this or-rule + push_rule_from_arg(&parser, rule->arg[i]); // push child of or-rule goto next_rule; default: assert(0); @@ -423,14 +428,14 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p } if ((rule->arg[i] & RULE_ARG_KIND_MASK) == RULE_ARG_TOK) { if (mp_lexer_is_kind(lex, rule->arg[i] & RULE_ARG_ARG_MASK)) { - push_result_token(parser, lex); + push_result_token(&parser, lex); mp_lexer_to_next(lex); } else { backtrack = true; goto next_rule; } } else { - push_rule_from_arg(parser, rule->arg[i]); + push_rule_from_arg(&parser, rule->arg[i]); } break; @@ -441,7 +446,7 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p assert(i > 0); if ((rule->arg[i - 1] & RULE_ARG_KIND_MASK) == RULE_ARG_OPT_RULE) { // an optional rule that failed, so continue with next arg - push_result_node(parser, MP_PARSE_NODE_NULL); + push_result_node(&parser, MP_PARSE_NODE_NULL); backtrack = false; } else { // a mandatory rule that failed, so propagate backtrack @@ -463,7 +468,7 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p if (mp_lexer_is_kind(lex, tok_kind)) { // matched token if (tok_kind == MP_TOKEN_NAME) { - push_result_token(parser, lex); + push_result_token(&parser, lex); } mp_lexer_to_next(lex); } else { @@ -480,8 +485,8 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p break; case RULE_ARG_RULE: case RULE_ARG_OPT_RULE: - push_rule(parser, rule_src_line, rule, i + 1); // save this and-rule - push_rule_from_arg(parser, rule->arg[i]); // push child of and-rule + push_rule(&parser, rule_src_line, rule, i + 1); // save this and-rule + push_rule_from_arg(&parser, rule->arg[i]); // push child of and-rule goto next_rule; default: assert(0); @@ -514,12 +519,12 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p #if 0 && !MICROPY_ENABLE_DOC_STRING // this code discards lonely statement, such as doc strings // problem is that doc strings have already been interned, so this doesn't really help reduce RAM usage - if (input_kind != MP_PARSE_SINGLE_INPUT && rule->rule_id == RULE_expr_stmt && peek_result(parser, 0) == MP_PARSE_NODE_NULL) { - mp_parse_node_t p = peek_result(parser, 1); + if (input_kind != MP_PARSE_SINGLE_INPUT && rule->rule_id == RULE_expr_stmt && peek_result(&parser, 0) == MP_PARSE_NODE_NULL) { + mp_parse_node_t p = peek_result(&parser, 1); if (MP_PARSE_NODE_IS_LEAF(p) && !MP_PARSE_NODE_IS_ID(p)) { pop_result(parser); pop_result(parser); - push_result_rule(parser, rule_src_line, rules[RULE_pass_stmt], 0); + push_result_rule(&parser, rule_src_line, rules[RULE_pass_stmt], 0); break; } } @@ -540,35 +545,35 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p // always emit these rules, and add an extra blank node at the end (to be used by the compiler to store data) if (ADD_BLANK_NODE(rule->rule_id)) { emit_rule = true; - push_result_node(parser, MP_PARSE_NODE_NULL); + push_result_node(&parser, MP_PARSE_NODE_NULL); i += 1; } int num_not_nil = 0; for (int x = 0; x < i; ++x) { - if (peek_result(parser, x) != MP_PARSE_NODE_NULL) { + if (peek_result(&parser, x) != MP_PARSE_NODE_NULL) { num_not_nil += 1; } } //printf("done and %s n=%d i=%d notnil=%d\n", rule->rule_name, n, i, num_not_nil); if (emit_rule) { - push_result_rule(parser, rule_src_line, rule, i); + push_result_rule(&parser, rule_src_line, rule, i); } else if (num_not_nil == 0) { - push_result_rule(parser, rule_src_line, rule, i); // needed for, eg, atom_paren, testlist_comp_3b + push_result_rule(&parser, rule_src_line, rule, i); // needed for, eg, atom_paren, testlist_comp_3b //result_stack_show(parser); //assert(0); } else if (num_not_nil == 1) { // single result, leave it on stack mp_parse_node_t pn = MP_PARSE_NODE_NULL; for (int x = 0; x < i; ++x) { - mp_parse_node_t pn2 = pop_result(parser); + mp_parse_node_t pn2 = pop_result(&parser); if (pn2 != MP_PARSE_NODE_NULL) { pn = pn2; } } - push_result_node(parser, pn); + push_result_node(&parser, pn); } else { - push_result_rule(parser, rule_src_line, rule, i); + push_result_rule(&parser, rule_src_line, rule, i); } break; @@ -615,7 +620,7 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p if (i & 1 & n) { // separators which are tokens are not pushed to result stack } else { - push_result_token(parser, lex); + push_result_token(&parser, lex); } mp_lexer_to_next(lex); // got element of list, so continue parsing list @@ -628,8 +633,8 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p } break; case RULE_ARG_RULE: - push_rule(parser, rule_src_line, rule, i + 1); // save this list-rule - push_rule_from_arg(parser, arg); // push child of list-rule + push_rule(&parser, rule_src_line, rule, i + 1); // save this list-rule + push_rule_from_arg(&parser, arg); // push child of list-rule goto next_rule; default: assert(0); @@ -649,13 +654,13 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p // list matched single item if (had_trailing_sep) { // if there was a trailing separator, make a list of a single item - push_result_rule(parser, rule_src_line, rule, i); + push_result_rule(&parser, rule_src_line, rule, i); } else { // just leave single item on stack (ie don't wrap in a list) } } else { //printf("done list %s %d %d\n", rule->rule_name, n, i); - push_result_rule(parser, rule_src_line, rule, i); + push_result_rule(&parser, rule_src_line, rule, i); } break; @@ -667,7 +672,8 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p mp_parse_node_t result; // check if we had a memory error - if (parser->had_memory_error) { + if (parser.had_memory_error) { +memory_error: *parse_error_kind_out = MP_PARSE_ERROR_MEMORY; result = MP_PARSE_NODE_NULL; goto finished; @@ -681,19 +687,18 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p //printf("--------------\n"); //result_stack_show(parser); - //printf("rule stack alloc: %d\n", parser->rule_stack_alloc); - //printf("result stack alloc: %d\n", parser->result_stack_alloc); + //printf("rule stack alloc: %d\n", parser.rule_stack_alloc); + //printf("result stack alloc: %d\n", parser.result_stack_alloc); //printf("number of parse nodes allocated: %d\n", num_parse_nodes_allocated); // get the root parse node that we created - assert(parser->result_stack_top == 1); - result = parser->result_stack[0]; + assert(parser.result_stack_top == 1); + result = parser.result_stack[0]; finished: // free the memory that we don't need anymore - m_del(rule_stack_t, parser->rule_stack, parser->rule_stack_alloc); - m_del(mp_parse_node_t, parser->result_stack, parser->result_stack_alloc); - m_del_obj(parser_t, parser); + m_del(rule_stack_t, parser.rule_stack, parser.rule_stack_alloc); + m_del(mp_parse_node_t, parser.result_stack, parser.result_stack_alloc); // return the result return result; diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 30fad4413d..13476b3be8 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -61,7 +61,7 @@ Q(__del__) Q(__call__) Q(micropython) -Q(byte_code) +Q(bytecode) Q(native) Q(viper) Q(const) @@ -239,6 +239,8 @@ Q(startswith) Q(replace) Q(partition) Q(rpartition) +Q(lower) +Q(upper) Q(iterable) Q(start) @@ -251,6 +253,10 @@ Q(iterator) Q(module) Q(slice) +#if MICROPY_ENABLE_FROZENSET +Q(frozenset) +#endif + #if MICROPY_ENABLE_MOD_MATH || MICROPY_ENABLE_MOD_CMATH Q(math) Q(e) @@ -325,6 +331,7 @@ Q(utf-8) Q(argv) Q(byteorder) Q(big) +Q(exit) Q(little) Q(stdin) Q(stdout) diff --git a/py/runtime.c b/py/runtime.c index f8eac40609..a2de2d75b1 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -578,7 +578,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, uint n_args_n_kw, const mp_obj_ } // copy the fixed pos args - m_seq_copy(args2 + args2_len, args, n_args, mp_obj_t); + mp_seq_copy(args2 + args2_len, args, n_args, mp_obj_t); args2_len += n_args; } else if (MP_OBJ_IS_TYPE(pos_seq, &mp_type_tuple) || MP_OBJ_IS_TYPE(pos_seq, &mp_type_list)) { @@ -599,7 +599,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, uint n_args_n_kw, const mp_obj_ } // copy the fixed and variable position args - m_seq_cat(args2 + args2_len, args, n_args, items, len, mp_obj_t); + mp_seq_cat(args2 + args2_len, args, n_args, items, len, mp_obj_t); args2_len += n_args + len; } else { @@ -615,7 +615,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, uint n_args_n_kw, const mp_obj_ } // copy the fixed position args - m_seq_copy(args2 + args2_len, args, n_args, mp_obj_t); + mp_seq_copy(args2 + args2_len, args, n_args, mp_obj_t); // extract the variable position args from the iterator mp_obj_t iterable = mp_getiter(pos_seq); @@ -633,7 +633,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, uint n_args_n_kw, const mp_obj_ uint pos_args_len = args2_len; // Copy the fixed kw args. - m_seq_copy(args2 + args2_len, args + n_args, 2 * n_kw, mp_obj_t); + mp_seq_copy(args2 + args2_len, args + n_args, 2 * n_kw, mp_obj_t); args2_len += 2 * n_kw; // Extract (key,value) pairs from kw_dict dictionary and append to args2. @@ -840,6 +840,9 @@ void mp_load_method_maybe(mp_obj_t base, qstr attr, mp_obj_t *dest) { // return a bound method, with self being the type of this object dest[0] = ((mp_obj_static_class_method_t*)elem->value)->fun; dest[1] = mp_obj_get_type(base); + } else if (MP_OBJ_IS_TYPE(elem->value, &mp_type_type)) { + // Don't try to bind types + dest[0] = elem->value; } else if (mp_obj_is_callable(elem->value)) { // return a bound method, with self being this object dest[0] = elem->value; diff --git a/py/sequence.c b/py/sequence.c index 3d2bbba4df..91162fc099 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -50,7 +50,7 @@ void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void } } -bool m_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, machine_uint_t *begin, machine_uint_t *end) { +bool mp_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, machine_uint_t *begin, machine_uint_t *end) { machine_int_t start, stop, step; mp_obj_slice_get(slice, &start, &stop, &step); if (step != 1) { diff --git a/py/showbc.c b/py/showbc.c index d8ab4be074..48d5328c20 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -54,9 +54,9 @@ ip += sizeof(machine_uint_t); \ } while (0) -void mp_byte_code_print2(const byte *ip, int len); +void mp_bytecode_print2(const byte *ip, int len); -void mp_byte_code_print(const byte *ip, int len) { +void mp_bytecode_print(const byte *ip, int len) { const byte *ip_start = ip; // get code info size @@ -99,10 +99,10 @@ void mp_byte_code_print(const byte *ip, int len) { printf(" bc=" INT_FMT " line=" UINT_FMT "\n", bc, source_line); } } - mp_byte_code_print2(ip, len - 0); + mp_bytecode_print2(ip, len - 0); } -void mp_byte_code_print2(const byte *ip, int len) { +void mp_bytecode_print2(const byte *ip, int len) { const byte *ip_start = ip; machine_uint_t unum; qstr qstr; diff --git a/py/unicode.c b/py/unicode.c index fff6030fc0..1cd82f3be8 100644 --- a/py/unicode.c +++ b/py/unicode.c @@ -97,6 +97,7 @@ bool unichar_isxdigit(unichar c) { bool char_is_alpha_or_digit(unichar c) { return c < 128 && (attr[c] & (FL_ALPHA | FL_DIGIT)) != 0; } +*/ bool char_is_upper(unichar c) { return c < 128 && (attr[c] & FL_UPPER) != 0; @@ -105,4 +106,17 @@ bool char_is_upper(unichar c) { bool char_is_lower(unichar c) { return c < 128 && (attr[c] & FL_LOWER) != 0; } -*/ + +unichar unichar_tolower(unichar c) { + if (char_is_upper(c)) { + return c + 0x20; + } + return c; +} + +unichar unichar_toupper(unichar c) { + if (char_is_lower(c)) { + return c - 0x20; + } + return c; +} @@ -47,7 +47,7 @@ #define DETECT_VM_STACK_OVERFLOW (0) #if 0 -#define TRACE(ip) mp_byte_code_print2(ip, 1); +#define TRACE(ip) mp_bytecode_print2(ip, 1); #else #define TRACE(ip) #endif @@ -104,7 +104,7 @@ typedef enum { currently_in_except_block = MP_TAGPTR_TAG(exc_sp->val_sp); /* restore previous state */ \ exc_sp--; /* pop back to previous exception handler */ -mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret) { +mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret) { const byte *ip = code; // get code info size, and skip line number table @@ -155,7 +155,7 @@ mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, } // execute the byte code - mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code_2(code, &ip, &state[n_state - 1], &sp, exc_stack, &exc_sp, MP_OBJ_NULL); + mp_vm_return_kind_t vm_return_kind = mp_execute_bytecode2(code, &ip, &state[n_state - 1], &sp, exc_stack, &exc_sp, MP_OBJ_NULL); #if DETECT_VM_STACK_OVERFLOW // We can't check the case when an exception is returned in state[n_state - 1] @@ -217,10 +217,10 @@ mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, // MP_VM_RETURN_NORMAL, sp valid, return value in *sp // MP_VM_RETURN_YIELD, ip, sp valid, yielded value in *sp // MP_VM_RETURN_EXCEPTION, exception in fastn[0] -mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, - mp_obj_t *fastn, mp_obj_t **sp_in_out, - mp_exc_stack_t *exc_stack, mp_exc_stack_t **exc_sp_in_out, - volatile mp_obj_t inject_exc) { +mp_vm_return_kind_t mp_execute_bytecode2(const byte *code_info, const byte **ip_in_out, + mp_obj_t *fastn, mp_obj_t **sp_in_out, + mp_exc_stack_t *exc_stack, mp_exc_stack_t **exc_sp_in_out, + volatile mp_obj_t inject_exc) { #if MICROPY_USE_COMPUTED_GOTO #include "vmentrytable.h" #define DISPATCH() do { \ @@ -1,9 +1,9 @@ #include <stdio.h> #include <stm32f4xx.h> +#include "mpconfig.h" #include "misc.h" #include "nlr.h" -#include "mpconfig.h" #include "qstr.h" #include "obj.h" #include "adc.h" diff --git a/stm/audio.c b/stm/audio.c index 36fa77c428..9fa9938000 100644 --- a/stm/audio.c +++ b/stm/audio.c @@ -3,9 +3,9 @@ #include "stm32f4xx_dac.h" +#include "mpconfig.h" #include "nlr.h" #include "misc.h" -#include "mpconfig.h" #include "qstr.h" #include "parse.h" #include "obj.h" diff --git a/stm/gpio.c b/stm/gpio.c index 9f9e8e0792..9366208931 100644 --- a/stm/gpio.c +++ b/stm/gpio.c @@ -16,9 +16,9 @@ #include <usbd_storage_msd.h> #include <stm_misc.h> +#include "mpconfig.h" #include "nlr.h" #include "misc.h" -#include "mpconfig.h" #include "qstr.h" #include "misc.h" #include "parse.h" @@ -1,9 +1,9 @@ #include <string.h> #include <stm32f4xx_gpio.h> +#include "mpconfig.h" #include "nlr.h" #include "misc.h" -#include "mpconfig.h" #if MICROPY_HW_HAS_LCD diff --git a/stm/pyexec.c b/stm/pyexec.c index 52a436218e..00d5f0bdad 100644 --- a/stm/pyexec.c +++ b/stm/pyexec.c @@ -2,9 +2,9 @@ #include <string.h> #include <stdio.h> +#include "mpconfig.h" #include "nlr.h" #include "misc.h" -#include "mpconfig.h" #include "qstr.h" #include "misc.h" #include "lexer.h" diff --git a/stm/timer.c b/stm/timer.c index 0a19fa5a81..8d51de2cc1 100644 --- a/stm/timer.c +++ b/stm/timer.c @@ -6,9 +6,9 @@ #include "stm32f4xx_rcc.h" #include "stm32f4xx_tim.h" +#include "mpconfig.h" #include "nlr.h" #include "misc.h" -#include "mpconfig.h" #include "qstr.h" #include "parse.h" #include "obj.h" diff --git a/stmhal/cc3k/cc3000_common.c b/stmhal/cc3k/cc3000_common.c index 8d9bd7d03a..51c299c446 100644 --- a/stmhal/cc3k/cc3000_common.c +++ b/stmhal/cc3k/cc3000_common.c @@ -3,14 +3,6 @@ * cc3000_common.c.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ @@ -60,7 +52,6 @@ #include "socket.h" #include "wlan.h" #include "evnt_handler.h" -#include "ccdebug.h" //***************************************************************************** // @@ -96,12 +87,12 @@ __error__(char *pcFilename, unsigned long ulLine) // //***************************************************************************** -uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32) +unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32) { - *(p)++ = (uint8_t)(u32); - *(p)++ = (uint8_t)((u32) >> 8); - *(p)++ = (uint8_t)((u32) >> 16); - *(p)++ = (uint8_t)((u32) >> 24); + *(p)++ = (unsigned char)(u32); + *(p)++ = (unsigned char)((u32) >> 8); + *(p)++ = (unsigned char)((u32) >> 16); + *(p)++ = (unsigned char)((u32) >> 24); return p; } @@ -119,10 +110,10 @@ uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32) // //***************************************************************************** -uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16) +unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16) { - *(p)++ = (uint8_t)(u16); - *(p)++ = (uint8_t)((u16) >> 8); + *(p)++ = (unsigned char)(u16); + *(p)++ = (unsigned char)((u16) >> 8); return p; } @@ -140,20 +131,10 @@ uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16) // //***************************************************************************** -uint16_t STREAM_TO_UINT16_f(char* cp, uint16_t offset) +unsigned short STREAM_TO_UINT16_f(char* p, unsigned short offset) { - uint8_t *p = (uint8_t *)cp; - /* - DEBUGPRINT_F("Stream2u16: "); - DEBUGPRINT_HEX(cp[offset+1]); - DEBUGPRINT_F(" + "); - DEBUGPRINT_HEX(cp[offset]); - DEBUGPRINT_F("\n\r"); - */ - - return (uint16_t)((uint16_t) - ((uint16_t)(*(p + offset + 1)) << 8) + - (uint16_t)(*(p + offset))); + return (unsigned short)((unsigned short)((unsigned short) + (*(p + offset + 1)) << 8) + (unsigned short)(*(p + offset))); } //***************************************************************************** @@ -170,23 +151,12 @@ uint16_t STREAM_TO_UINT16_f(char* cp, uint16_t offset) // //***************************************************************************** -uint32_t STREAM_TO_UINT32_f(char * cp, uint16_t offset) +unsigned long STREAM_TO_UINT32_f(char* p, unsigned short offset) { - uint8_t *p = (uint8_t *)cp; - - /* - DEBUGPRINT_F("\tStream2u32: "); - DEBUGPRINT_HEX(cp[offset+3]); DEBUGPRINT_F(" + "); - DEBUGPRINT_HEX(cp[offset+2]); DEBUGPRINT_F(" + "); - DEBUGPRINT_HEX(cp[offset+1]); DEBUGPRINT_F(" + "); - DEBUGPRINT_HEX(cp[offset]); - DEBUGPRINT_F("\n\r"); - */ - - return (uint32_t)((uint32_t)((uint32_t) - (*(p + offset + 3)) << 24) + (uint32_t)((uint32_t) - (*(p + offset + 2)) << 16) + (uint32_t)((uint32_t) - (*(p + offset + 1)) << 8) + (uint32_t)(*(p + offset))); + return (unsigned long)((unsigned long)((unsigned long) + (*(p + offset + 3)) << 24) + (unsigned long)((unsigned long) + (*(p + offset + 2)) << 16) + (unsigned long)((unsigned long) + (*(p + offset + 1)) << 8) + (unsigned long)(*(p + offset))); } diff --git a/stmhal/cc3k/cc3000_common.h b/stmhal/cc3k/cc3000_common.h index 4297d249bf..a4322f5051 100644 --- a/stmhal/cc3k/cc3000_common.h +++ b/stmhal/cc3k/cc3000_common.h @@ -3,14 +3,6 @@ * cc3000_common.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ @@ -46,9 +38,6 @@ //****************************************************************************** // Include files //****************************************************************************** -//#include <stdlib.h> -//#include <errno.h> -//#include <stdint.h> //***************************************************************************** // @@ -70,9 +59,9 @@ extern "C" { //***************************************************************************** // COMMON DEFINES //***************************************************************************** -#define ERROR_SOCKET_INACTIVE -57 +#define ERROR_SOCKET_INACTIVE -57 -#define WLAN_ENABLE (1) +#define WLAN_ENABLE (1) #define WLAN_DISABLE (0) #define MAC_ADDR_LEN (6) @@ -80,8 +69,8 @@ extern "C" { #define SP_PORTION_SIZE (32) // #define CC3000_TINY_DRIVER - -/*Defines for minimal and maximal RX buffer size. This size includes the spi + +/*Defines for minimal and maximal RX buffer size. This size includes the spi header and hci header. The maximal buffer size derives from: MTU + HCI header + SPI header + sendto() agrs size @@ -89,26 +78,26 @@ extern "C" { HCI header + SPI header + max args size This buffer is used for receiving events and data. - The packet can not be longer than MTU size and CC3000 does not support - fragmentation. Note that the same buffer is used for reception of the data - and events from CC3000. That is why the minimum is defined. + The packet can not be longer than MTU size and CC3000 does not support + fragmentation. Note that the same buffer is used for reception of the data + and events from CC3000. That is why the minimum is defined. The calculation for the actual size of buffer for reception is: Given the maximal data size MAX_DATA that is expected to be received by application, the required buffer is: Using recv() or recvfrom(): - + max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen + ucArgsize + 1) - + Using gethostbyname() with minimal buffer size will limit the host name returned to 99 bytes only. - The 1 is used for the overrun detection + The 1 is used for the overrun detection Buffer size increased to 130 following the add_profile() with WEP security - which requires TX buffer size of 130 bytes: + which requires TX buffer size of 130 bytes: HEADERS_SIZE_EVNT + WLAN_ADD_PROFILE_WEP_PARAM_LEN + MAX SSID LEN + 4 * MAX KEY LEN = 130 - MAX SSID LEN = 32 - MAX SSID LEN = 13 (with add_profile only ascii key setting is supported, + MAX SSID LEN = 32 + MAX SSID LEN = 13 (with add_profile only ascii key setting is supported, therfore maximum key size is 13) */ @@ -117,24 +106,24 @@ extern "C" { /*Defines for minimal and maximal TX buffer size. This buffer is used for sending events and data. - The packet can not be longer than MTU size and CC3000 does not support + The packet can not be longer than MTU size and CC3000 does not support fragmentation. Note that the same buffer is used for transmission of the data and commands. That is why the minimum is defined. The calculation for the actual size of buffer for transmission is: Given the maximal data size MAX_DATA, the required buffer is: Using Sendto(): - + max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE + SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) - + Using Send(): - + max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE + HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) - - The 1 is used for the overrun detection */ -#define CC3000_MINIMAL_TX_SIZE (130 + 1) + The 1 is used for the overrun detection */ + +#define CC3000_MINIMAL_TX_SIZE (130 + 1) #define CC3000_MAXIMAL_TX_SIZE (1519 + 1) //TX and RX buffer sizes, allow to receive and transmit maximum data at length 8. @@ -143,41 +132,37 @@ extern "C" { #define TINY_CC3000_MAXIMAL_TX_SIZE 59 #endif -/*In order to determine your preferred buffer size, +/*In order to determine your preferred buffer size, change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between - the minimal and maximal specified above. + the minimal and maximal specified above. Note that the buffers are allocated by SPI. In case you change the size of those buffers, you might need also to change the linker file, since for example on MSP430 FRAM devices the buffers are allocated in the FRAM section that is allocated manually and not by IDE. */ - + #ifndef CC3000_TINY_DRIVER - + #define CC3000_RX_BUFFER_SIZE (CC3000_MINIMAL_RX_SIZE) #define CC3000_TX_BUFFER_SIZE (CC3000_MINIMAL_TX_SIZE) - + //if defined TINY DRIVER we use smaller RX and TX buffer in order to minimize RAM consumption #else #define CC3000_RX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_RX_SIZE) #define CC3000_TX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_TX_SIZE) -#endif +#endif //***************************************************************************** // Compound Types //***************************************************************************** -#ifdef __AVR__ -typedef unsigned long time_t; /* KTown: Updated to be compatible with Arduino Time.h */ -#else typedef long time_t; -#endif typedef unsigned long clock_t; typedef long suseconds_t; typedef struct timeval timeval; -struct timeval +struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ @@ -263,12 +248,12 @@ extern void SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams); //! @return none //! //! @brief Wait for data, pass it to the hci_event_handler -//! and update in a global variable that there is +//! and update in a global variable that there is //! data to read. // //***************************************************************************** -extern void SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen); +extern void SimpleLinkWaitData(unsigned char *pBuf, unsigned char *from, unsigned char *fromlen); //***************************************************************************** // @@ -284,7 +269,7 @@ extern void SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen); // //***************************************************************************** -extern uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32); +extern unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32); //***************************************************************************** // @@ -295,12 +280,12 @@ extern uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32); //! //! \return pointer to the new stream //! -//! \brief This function is used for copying 16 bit to stream +//! \brief This function is used for copying 16 bit to stream //! while converting to little endian format. // //***************************************************************************** -extern uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16); +extern unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16); //***************************************************************************** // @@ -311,12 +296,12 @@ extern uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16); //! //! \return pointer to the new 16 bit //! -//! \brief This function is used for copying received stream to +//! \brief This function is used for copying received stream to //! 16 bit in little endian format. // //***************************************************************************** -extern uint16_t STREAM_TO_UINT16_f(char* p, uint16_t offset); +extern unsigned short STREAM_TO_UINT16_f(char* p, unsigned short offset); //***************************************************************************** // @@ -332,7 +317,7 @@ extern uint16_t STREAM_TO_UINT16_f(char* p, uint16_t offset); // //***************************************************************************** -extern uint32_t STREAM_TO_UINT32_f(char* p, uint16_t offset); +extern unsigned long STREAM_TO_UINT32_f(char* p, unsigned short offset); //***************************************************************************** @@ -361,14 +346,14 @@ extern void cc3k_int_poll(); //This macro is used for copying 32 bit to stream while converting to little endian format. #define UINT32_TO_STREAM(_p, _u32) (UINT32_TO_STREAM_f(_p, _u32)) //This macro is used for copying a specified value length bits (l) to stream while converting to little endian format. -#define ARRAY_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(p)++ = ((uint8_t *) a)[_i];} +#define ARRAY_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(p)++ = ((unsigned char *) a)[_i];} //This macro is used for copying received stream to 8 bit in little endian format. -#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (uint8_t)(*(_p + _offset));} +#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (unsigned char)(*(_p + _offset));} //This macro is used for copying received stream to 16 bit in little endian format. #define STREAM_TO_UINT16(_p, _offset, _u16) {_u16 = STREAM_TO_UINT16_f(_p, _offset);} //This macro is used for copying received stream to 32 bit in little endian format. #define STREAM_TO_UINT32(_p, _offset, _u32) {_u32 = STREAM_TO_UINT32_f(_p, _offset);} -#define STREAM_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(a)++= ((uint8_t *) p)[_i];} +#define STREAM_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(a)++= ((unsigned char *) p)[_i];} diff --git a/stmhal/cc3k/ccdebug.h b/stmhal/cc3k/ccdebug.h deleted file mode 100644 index 307f027d4c..0000000000 --- a/stmhal/cc3k/ccdebug.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************/ -/*! - @file Adafruit_CC3000.cpp - @author KTOWN (Kevin Townsend for Adafruit Industries) - @license BSD (see license.txt) - - This is a library for the Adafruit CC3000 WiFi breakout board - This library works with the Adafruit CC3000 breakout - ----> https://www.adafruit.com/products/1469 - - Check out the links above for our tutorials and wiring diagrams - These chips use SPI to communicate. - - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - @section HISTORY - - v1.0 - Initial release -*/ -/**************************************************************************/ - -//#include <Arduino.h> - -#ifndef _CC3000_DEBUG -#define _CC3000_DEBUG - -#define DEBUG_MODE (0) - -#define PRINT_F(__s) DEBUGPRINT(FLASHIFY(__s)) - -#if (DEBUG_MODE != 0) -#define DEBUGPRINT_F(__s) DEBUGPRINT(FLASHIFY(__s)) -#define DEBUGPRINT_DEC(x) printDec(x) -#define DEBUGPRINT_DEC16(x) printDec16(x) -#define DEBUGPRINT_HEX(x) printHex(x) -#define DEBUGPRINT_HEX16(x) printHex16(x) -#else -#define DEBUGPRINT_F(__s) /* do nothing! */ -#define DEBUGPRINT_DEC(x) -#define DEBUGPRINT_DEC16(x) -#define DEBUGPRINT_HEX(x) -#define DEBUGPRINT_HEX16(x) -#endif - -#if 1 // print debugging info -#define DEBUG_PRINT (1) -#define DEBUG_printf(args...) printf(args) -#else // don't print debugging info -#define DEBUG_printf(args...) (void)0 -#endif - -int printf(const char *fmt, ...); - -#endif diff --git a/stmhal/cc3k/ccspi.c b/stmhal/cc3k/ccspi.c index 133b17d030..8029956a64 100644 --- a/stmhal/cc3k/ccspi.c +++ b/stmhal/cc3k/ccspi.c @@ -3,9 +3,9 @@ * spi.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) +* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) * & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout +* This library works with the Adafruit CC3000 breakout * ----> https://www.adafruit.com/products/1469 * Adafruit invests time and resources providing this open source code, * please support Adafruit and open-source hardware by purchasing @@ -51,9 +51,14 @@ #include "netapp.h" #include "evnt_handler.h" #include "cc3000_common.h" -#include "ccdebug.h" #include "pybcc3k.h" +#if 0 // print debugging info +#define DEBUG_printf(args...) printf(args) +#else // don't print debugging info +#define DEBUG_printf(args...) (void)0 +#endif + #define READ (3) #define WRITE (1) #define HI(value) (((value) & 0xFF00) >> 8) @@ -140,8 +145,8 @@ void SpiInit(void) /**************************************************************************/ void SpiClose(void) { - DEBUGPRINT_F("\tCC3000: SpiClose"); - + DEBUG_printf("\tCC3000: SpiClose"); + if (sSpiInformation.pRxPacket) { sSpiInformation.pRxPacket = 0; @@ -158,8 +163,8 @@ void SpiClose(void) /**************************************************************************/ void SpiOpen(gcSpiHandleRx pfRxHandler) { - DEBUGPRINT_F("\tCC3000: SpiOpen"); - + DEBUG_printf("\tCC3000: SpiOpen"); + sSpiInformation.ulSpiState = eSPI_STATE_POWERUP; memset(spi_buffer, 0, sizeof(spi_buffer)); @@ -170,14 +175,14 @@ void SpiOpen(gcSpiHandleRx pfRxHandler) sSpiInformation.pTxPacket = NULL; sSpiInformation.pRxPacket = (unsigned char *)spi_buffer; sSpiInformation.usRxPacketLength = 0; - + spi_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; /* Enable interrupt on the GPIO pin of WLAN IRQ */ tSLInformation.WlanInterruptEnable(); - DEBUGPRINT_F("\tCC3000: Finished SpiOpen\n\r"); + DEBUG_printf("\tCC3000: Finished SpiOpen\n\r"); } /**************************************************************************/ @@ -191,8 +196,8 @@ extern uint8_t g_csPin, g_irqPin, g_vbatPin, g_IRQnum, g_SPIspeed; int init_spi(void) { - DEBUGPRINT_F("\tCC3000: init_spi\n\r"); - + DEBUG_printf("\tCC3000: init_spi\n\r"); + /* Set POWER_EN pin to output and disable the CC3000 by default */ pinMode(g_vbatPin, OUTPUT); digitalWrite(g_vbatPin, 0); @@ -214,7 +219,7 @@ int init_spi(void) SPI.setDataMode(SPI_MODE1); SPI.setBitOrder(MSBFIRST); SPI.setClockDivider(g_SPIspeed); - + // Newly-initialized SPI is in the same state that ASSERT_CS will set it // to. Invoke DEASSERT (which also restores SPI registers) so the next // ASSERT call won't clobber the ccspi_old* values -- we need those! @@ -222,8 +227,8 @@ int init_spi(void) /* ToDo: Configure IRQ interrupt! */ - DEBUGPRINT_F("\tCC3000: Finished init_spi\n\r"); - + DEBUG_printf("\tCC3000: Finished init_spi\n\r"); + return(ESUCCESS); } #endif @@ -235,8 +240,8 @@ int init_spi(void) /**************************************************************************/ long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength) { - DEBUGPRINT_F("\tCC3000: SpiWriteFirst\n\r"); - + DEBUG_printf("\tCC3000: SpiWriteFirst\n\r"); + /* Workaround for the first transaction */ CC3000_ASSERT_CS(); @@ -267,8 +272,8 @@ long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength) { unsigned char ucPad = 0; - DEBUGPRINT_F("\tCC3000: SpiWrite\n\r"); - + DEBUG_printf("\tCC3000: SpiWrite\n\r"); + /* Figure out the total length of the packet in order to figure out if there is padding or not */ if(!(usLength & 0x0001)) { @@ -288,7 +293,7 @@ long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength) * occurred - and we will be stuck here forever! */ if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) { - DEBUGPRINT_F("\tCC3000: Error - No magic number found in SpiWrite\n\r"); + DEBUG_printf("\tCC3000: Error - No magic number found in SpiWrite\n\r"); while (1); } @@ -383,7 +388,7 @@ void SpiReadDataSynchronous(unsigned char *data, unsigned short size) /**************************************************************************/ void SpiReadHeader(void) { - DEBUGPRINT_F("\tCC3000: SpiReadHeader\n\r"); + DEBUG_printf("\tCC3000: SpiReadHeader\n\r"); SpiReadDataSynchronous(sSpiInformation.pRxPacket, HEADERS_SIZE_EVNT); } @@ -398,7 +403,7 @@ long SpiReadDataCont(void) long data_to_recv; unsigned char *evnt_buff, type; - DEBUGPRINT_F("\tCC3000: SpiReadDataCont\n\r"); + DEBUG_printf("\tCC3000: SpiReadDataCont\n\r"); /* Determine what type of packet we have */ evnt_buff = sSpiInformation.pRxPacket; @@ -454,7 +459,7 @@ long SpiReadDataCont(void) /**************************************************************************/ void SpiPauseSpi(void) { - DEBUGPRINT_F("\tCC3000: SpiPauseSpi\n\r"); + DEBUG_printf("\tCC3000: SpiPauseSpi\n\r"); ccspi_int_enabled = 0; pyb_cc3000_pause_spi(); @@ -467,7 +472,7 @@ void SpiPauseSpi(void) /**************************************************************************/ void SpiResumeSpi(void) { - DEBUGPRINT_F("\tCC3000: SpiResumeSpi\n\r"); + DEBUG_printf("\tCC3000: SpiResumeSpi\n\r"); ccspi_int_enabled = 1; pyb_cc3000_resume_spi(); @@ -480,24 +485,24 @@ void SpiResumeSpi(void) /**************************************************************************/ void SpiTriggerRxProcessing(void) { - DEBUGPRINT_F("\tCC3000: SpiTriggerRxProcessing\n\r"); + DEBUG_printf("\tCC3000: SpiTriggerRxProcessing\n\r"); /* Trigger Rx processing */ SpiPauseSpi(); CC3000_DEASSERT_CS(); - //DEBUGPRINT_F("Magic?\n\r"); + //DEBUG_printf("Magic?\n\r"); /* The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) * for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun * occurred - and we will stuck here forever! */ if (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) { /* You've got problems if you're here! */ - DEBUGPRINT_F("\tCC3000: ERROR - magic number missing!\n\r"); + DEBUG_printf("\tCC3000: ERROR - magic number missing!\n\r"); while (1); } - //DEBUGPRINT_F("OK!\n\r"); + //DEBUG_printf("OK!\n\r"); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE); } @@ -509,14 +514,14 @@ void SpiTriggerRxProcessing(void) /**************************************************************************/ void SSIContReadOperation(void) { - DEBUGPRINT_F("\tCC3000: SpiContReadOperation\n\r"); - + DEBUG_printf("\tCC3000: SpiContReadOperation\n\r"); + /* The header was read - continue with the payload read */ if (!SpiReadDataCont()) { /* All the data was read - finalize handling by switching to teh task * and calling from task Event Handler */ - //DEBUGPRINT_F("SPItrig\n\r"); + //DEBUG_printf("SPItrig\n\r"); SpiTriggerRxProcessing(); } } @@ -527,24 +532,7 @@ void SSIContReadOperation(void) */ /**************************************************************************/ void WriteWlanPin( unsigned char val ) -{ -#if 0 - if (DEBUG_MODE) - { - DEBUGPRINT_F("\tCC3000: WriteWlanPin - "); - DEBUGPRINT_DEC(val); - DEBUGPRINT_F("\n\r"); - delay(1); - } - if (val) - { - digitalWrite(g_vbatPin, HIGH); - } - else - { - digitalWrite(g_vbatPin, LOW); - } -#endif +{ pyb_cc3000_set_en(val == WLAN_ENABLE); } @@ -555,9 +543,7 @@ void WriteWlanPin( unsigned char val ) /**************************************************************************/ long ReadWlanInterruptPin(void) { - DEBUGPRINT_F("\tCC3000: ReadWlanInterruptPin - "); - DEBUGPRINT_DEC(digitalRead(g_irqPin)); - DEBUGPRINT_F("\n\r"); + DEBUG_printf("CC3000: ReadWlanInterruptPin\n"); return pyb_cc3000_get_irq(); } @@ -569,9 +555,9 @@ long ReadWlanInterruptPin(void) /**************************************************************************/ void WlanInterruptEnable() { - DEBUGPRINT_F("\tCC3000: WlanInterruptEnable.\n\r"); - // delay(100); - ccspi_int_enabled = 1; + DEBUG_printf("\tCC3000: WlanInterruptEnable.\n\r"); + // delay(100); + ccspi_int_enabled = 1; pyb_cc3000_enable_irq(); } @@ -582,7 +568,7 @@ void WlanInterruptEnable() /**************************************************************************/ void WlanInterruptDisable() { - DEBUGPRINT_F("\tCC3000: WlanInterruptDisable\n\r"); + DEBUG_printf("\tCC3000: WlanInterruptDisable\n\r"); ccspi_int_enabled = 0; pyb_cc3000_disable_irq(); } @@ -687,8 +673,8 @@ void SPI_IRQ(void) { ccspi_is_in_irq = 1; - DEBUGPRINT_F("\tCC3000: Entering SPI_IRQ\n\r"); - + DEBUG_printf("\tCC3000: Entering SPI_IRQ\n\r"); + if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) { /* IRQ line was low ... perform a callback on the HCI Layer */ @@ -696,8 +682,8 @@ void SPI_IRQ(void) } else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE) { - //DEBUGPRINT_F("IDLE\n\r"); - sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; + //DEBUG_printf("IDLE\n\r"); + sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; /* IRQ line goes down - start reception */ CC3000_ASSERT_CS(); @@ -705,7 +691,7 @@ void SPI_IRQ(void) // Wait for TX/RX Compete which will come as DMA interrupt SpiReadHeader(); sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; - //DEBUGPRINT_F("SSICont\n\r"); + //DEBUG_printf("SSICont\n\r"); SSIContReadOperation(); } else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ) @@ -715,7 +701,7 @@ void SPI_IRQ(void) CC3000_DEASSERT_CS(); } - DEBUGPRINT_F("\tCC3000: Leaving SPI_IRQ\n\r"); + DEBUG_printf("\tCC3000: Leaving SPI_IRQ\n\r"); ccspi_is_in_irq = 0; return; diff --git a/stmhal/cc3k/ccspi.h b/stmhal/cc3k/ccspi.h index 70805ec38e..66408a9db5 100644 --- a/stmhal/cc3k/ccspi.h +++ b/stmhal/cc3k/ccspi.h @@ -3,9 +3,9 @@ * spi.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) +* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) * & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout +* This library works with the Adafruit CC3000 breakout * ----> https://www.adafruit.com/products/1469 * Adafruit invests time and resources providing this open source code, * please support Adafruit and open-source hardware by purchasing diff --git a/stmhal/cc3k/evnt_handler.c b/stmhal/cc3k/evnt_handler.c index cca2e796d7..280e06f059 100644 --- a/stmhal/cc3k/evnt_handler.c +++ b/stmhal/cc3k/evnt_handler.c @@ -3,14 +3,6 @@ * evnt_handler.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -64,7 +56,6 @@ #include "socket.h" #include "netapp.h" #include "ccspi.h" -#include "ccdebug.h" @@ -251,22 +242,17 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen) while (1) { - cc3k_int_poll(); - if (tSLInformation.usEventOrDataReceived != 0) { - pucReceivedData = (tSLInformation.pucReceivedData); if (*pucReceivedData == HCI_TYPE_EVNT) { // Event Received - STREAM_TO_UINT16((char *)pucReceivedData, - HCI_EVENT_OPCODE_OFFSET, - usReceivedEventOpcode); + STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode); pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; RecvParams = pucReceivedParams; - RetParams = (unsigned char *)pRetParams; + RetParams = pRetParams; // In case unsolicited event received - here the handling finished if (hci_unsol_event_handler((char *)pucReceivedData) == 0) @@ -277,10 +263,8 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen) { case HCI_CMND_READ_BUFFER_SIZE: { - STREAM_TO_UINT8((char *)pucReceivedParams, 0, - tSLInformation.usNumberOfFreeBuffers); - STREAM_TO_UINT16((char *)pucReceivedParams, 1, - tSLInformation.usSlBufferLength); + STREAM_TO_UINT8((char *)pucReceivedParams, 0, tSLInformation.usNumberOfFreeBuffers); + STREAM_TO_UINT16((char *)pucReceivedParams, 1, tSLInformation.usSlBufferLength); } break; @@ -297,8 +281,7 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen) case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: - STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET - ,*(unsigned char *)pRetParams); + STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET ,*(unsigned char *)pRetParams); break; case HCI_CMND_SETSOCKOPT: @@ -320,14 +303,12 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen) case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: - STREAM_TO_UINT32((char *)pucReceivedParams,0 - ,*(unsigned long *)pRetParams); + STREAM_TO_UINT32((char *)pucReceivedParams,0 ,*(unsigned long *)pRetParams); break; case HCI_EVNT_READ_SP_VERSION: - STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET - ,*(unsigned char *)pRetParams); + STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET ,*(unsigned char *)pRetParams); pRetParams = ((char *)pRetParams) + 1; STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32); UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32); @@ -360,17 +341,17 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen) case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { - STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams); - //tBsdReadReturnParams *tread = (tBsdReadReturnParams *)pRetParams; // unused - if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) - { - set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); - } - break; + STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams); + + if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) + { + set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); + } + break; } case HCI_EVNT_SEND: @@ -447,7 +428,7 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen) //Read SSID STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); - + break; } } @@ -520,9 +501,6 @@ hci_unsol_event_handler(char *event_hdr) STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type); - DEBUGPRINT_F("\tHCI_UNSOL_EVT: "); - DEBUGPRINT_HEX16(event_type); - if (event_type & HCI_EVNT_UNSOL_BASE) { switch(event_type) @@ -614,23 +592,14 @@ hci_unsol_event_handler(char *event_hdr) break; case HCI_EVNT_BSD_TCP_CLOSE_WAIT: { - DEBUGPRINT_F("\tTCP Close Wait\n\r"); - uint8_t socketnum; - data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE; - /* - printHex(data[0]); PRINT_F("\t"); - printHex(data[1]); PRINT_F("\t"); - printHex(data[2]); PRINT_F("\t"); - printHex(data[3]); PRINT_F("\t"); - printHex(data[4]); PRINT_F("\t"); - printHex(data[5]); PRINT_F("\t"); - */ - socketnum = data[0]; - //STREAM_TO_UINT16(data, 0, socketnum); - if( tSLInformation.sWlanCB ) - { - tSLInformation.sWlanCB(event_type, (char *)&socketnum, 1); - } + data = (char *)(event_hdr) + HCI_EVENT_HEADER_SIZE; + if( tSLInformation.sWlanCB ) + { + //data[0] represents the socket id, for which FIN was received by remote. + //Upon receiving this event, the user can close the socket, or else the + //socket will be closded after inacvitity timeout (by default 60 seconds) + tSLInformation.sWlanCB(event_type, data, 1); + } } break; @@ -647,8 +616,6 @@ hci_unsol_event_handler(char *event_hdr) char *pArg; long status; - DEBUGPRINT_F("\tSEND event response\n\r"); - pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr); STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status); @@ -666,6 +633,12 @@ hci_unsol_event_handler(char *event_hdr) return (0); } + //handle a case where unsolicited event arrived, but was not handled by any of the cases above + if ((event_type != tSLInformation.usRxEventOpcode) && (event_type != HCI_EVNT_PATCHES_REQ)) + { + return(1); + } + return(0); } diff --git a/stmhal/cc3k/evnt_handler.h b/stmhal/cc3k/evnt_handler.h index 1391752bd8..908c7079c0 100644 --- a/stmhal/cc3k/evnt_handler.h +++ b/stmhal/cc3k/evnt_handler.h @@ -3,14 +3,6 @@ * evnt_handler.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,29 +12,28 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ #ifndef __EVENT_HANDLER_H__ #define __EVENT_HANDLER_H__ - #include "hci.h" #include "socket.h" @@ -100,7 +91,7 @@ extern long hci_unsol_event_handler(char *event_hdr); //! //! @return ESUCCESS if successful, EFAIL if an error occurred //! -//! @brief Parse the incoming unsolicited event packets and issues +//! @brief Parse the incoming unsolicited event packets and issues //! corresponding event handler. // //***************************************************************************** @@ -126,7 +117,7 @@ typedef struct _bsd_accept_return_t long iSocketDescriptor; long iStatus; sockaddr tSocketAddress; - + } tBsdReturnParams; diff --git a/stmhal/cc3k/hci.c b/stmhal/cc3k/hci.c index 533311f175..fe72af5d36 100644 --- a/stmhal/cc3k/hci.c +++ b/stmhal/cc3k/hci.c @@ -3,14 +3,6 @@ * hci.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ @@ -76,21 +68,21 @@ //! @brief Initiate an HCI command. // //***************************************************************************** -unsigned short +unsigned short hci_command_send(unsigned short usOpcode, unsigned char *pucBuff, unsigned char ucArgsLength) -{ +{ unsigned char *stream; - + stream = (pucBuff + SPI_HEADER_SIZE); - + UINT8_TO_STREAM(stream, HCI_TYPE_CMND); stream = UINT16_TO_STREAM(stream, usOpcode); UINT8_TO_STREAM(stream, ucArgsLength); - + //Update the opcode of the event we will be waiting for SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE); - + return(0); } @@ -110,25 +102,25 @@ hci_command_send(unsigned short usOpcode, unsigned char *pucBuff, // //***************************************************************************** long -hci_data_send(unsigned char ucOpcode, +hci_data_send(unsigned char ucOpcode, unsigned char *ucArgs, - unsigned short usArgsLength, + unsigned short usArgsLength, unsigned short usDataLength, const unsigned char *ucTail, unsigned short usTailLength) { unsigned char *stream; - + stream = ((ucArgs) + SPI_HEADER_SIZE); - + UINT8_TO_STREAM(stream, HCI_TYPE_DATA); UINT8_TO_STREAM(stream, ucOpcode); UINT8_TO_STREAM(stream, usArgsLength); stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength); - + // Send the packet over the SPI SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength); - + return(ESUCCESS); } @@ -149,17 +141,17 @@ hci_data_send(unsigned char ucOpcode, //***************************************************************************** void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff, unsigned char ucArgsLength,unsigned short ucDataLength) -{ +{ unsigned char *stream = (pucBuff + SPI_HEADER_SIZE); - + UINT8_TO_STREAM(stream, HCI_TYPE_DATA); UINT8_TO_STREAM(stream, usOpcode); UINT8_TO_STREAM(stream, ucArgsLength); stream = UINT16_TO_STREAM(stream, ucArgsLength + ucDataLength); - + // Send the command over SPI on data channel SpiWrite(pucBuff, ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE); - + return; } @@ -169,7 +161,7 @@ void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff, //! //! @param usOpcode command operation code //! @param pucBuff pointer to the command's arguments buffer -//! @param patch pointer to patch content buffer +//! @param patch pointer to patch content buffer //! @param usDataLength data length //! //! @return none @@ -179,57 +171,55 @@ void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff, //***************************************************************************** void hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength) -{ +{ unsigned char *data_ptr = (pucBuff + SPI_HEADER_SIZE); unsigned short usTransLength; unsigned char *stream = (pucBuff + SPI_HEADER_SIZE); - + UINT8_TO_STREAM(stream, HCI_TYPE_PATCH); UINT8_TO_STREAM(stream, ucOpcode); stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); - + if (usDataLength <= SL_PATCH_PORTION_SIZE) { UINT16_TO_STREAM(stream, usDataLength); stream = UINT16_TO_STREAM(stream, usDataLength); memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength); - + // Update the opcode of the event we will be waiting for SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE); } else { - + usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE); UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE); memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE); usDataLength -= SL_PATCH_PORTION_SIZE; patch += SL_PATCH_PORTION_SIZE; - + // Update the opcode of the event we will be waiting for SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE); - + while (usDataLength) { - cc3k_int_poll(); - if (usDataLength <= SL_PATCH_PORTION_SIZE) { usTransLength = usDataLength; usDataLength = 0; - + } else { usTransLength = SL_PATCH_PORTION_SIZE; usDataLength -= usTransLength; } - + *(unsigned short *)data_ptr = usTransLength; memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength); patch += usTransLength; - + // Update the opcode of the event we will be waiting for SpiWrite((unsigned char *)data_ptr, usTransLength + sizeof(usTransLength)); } diff --git a/stmhal/cc3k/hci.h b/stmhal/cc3k/hci.h index 3466a9cfe6..890ec5f745 100644 --- a/stmhal/cc3k/hci.h +++ b/stmhal/cc3k/hci.h @@ -3,14 +3,6 @@ * hci.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ @@ -175,7 +167,7 @@ extern "C" { #define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT #define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME #define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE - + #define HCI_EVNT_SEND 0x1003 #define HCI_EVNT_WRITE 0x100E #define HCI_EVNT_SENDTO 0x100F @@ -238,8 +230,8 @@ extern "C" { #define HCI_EVENT_LENGTH_OFFSET (3) #define HCI_EVENT_STATUS_OFFSET (4) #define HCI_DATA_LENGTH_OFFSET (3) - - + + //***************************************************************************** @@ -261,10 +253,10 @@ extern "C" { //! @brief Initiate an HCI command. // //***************************************************************************** -extern unsigned short hci_command_send(unsigned short usOpcode, +extern unsigned short hci_command_send(unsigned short usOpcode, unsigned char *ucArgs, unsigned char ucArgsLength); - + //***************************************************************************** // @@ -312,7 +304,7 @@ extern void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuf //! //! @param usOpcode command operation code //! @param pucBuff pointer to the command's arguments buffer -//! @param patch pointer to patch content buffer +//! @param patch pointer to patch content buffer //! @param usDataLength data length //! //! @return none diff --git a/stmhal/cc3k/host_driver_version.h b/stmhal/cc3k/host_driver_version.h index c218704a2e..b99c75e679 100644 --- a/stmhal/cc3k/host_driver_version.h +++ b/stmhal/cc3k/host_driver_version.h @@ -12,30 +12,30 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ #ifndef __HOST_DRIVER_VERSION_H__ #define __HOST_DRIVER_VERSION_H__ -#define DRIVER_VERSION_NUMBER 13 +#define DRIVER_VERSION_NUMBER 14 diff --git a/stmhal/cc3k/netapp.c b/stmhal/cc3k/netapp.c index cdeccefc46..66cc441f57 100644 --- a/stmhal/cc3k/netapp.c +++ b/stmhal/cc3k/netapp.c @@ -3,14 +3,6 @@ * netapp.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ @@ -68,13 +60,13 @@ // //! netapp_config_mac_adrress //! -//! @param mac device mac address, 6 bytes. Saved: yes +//! @param mac device mac address, 6 bytes. Saved: yes //! //! @return return on success 0, otherwise error. //! -//! @brief Configure device MAC address and store it in NVMEM. +//! @brief Configure device MAC address and store it in NVMEM. //! The value of the MAC address configured through the API will -//! be stored in CC3000 non volatile memory, thus preserved +//! be stored in CC3000 non volatile memory, thus preserved //! over resets. // //***************************************************************************** @@ -87,26 +79,26 @@ long netapp_config_mac_adrress(unsigned char * mac) // //! netapp_dhcp //! -//! @param aucIP device mac address, 6 bytes. Saved: yes -//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes -//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes -//! @param aucDNSServer device mac address, 6 bytes. Saved: yes +//! @param aucIP device mac address, 6 bytes. Saved: yes +//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes +//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes +//! @param aucDNSServer device mac address, 6 bytes. Saved: yes //! //! @return return on success 0, otherwise error. //! -//! @brief netapp_dhcp is used to configure the network interface, -//! static or dynamic (DHCP).\n In order to activate DHCP mode, +//! @brief netapp_dhcp is used to configure the network interface, +//! static or dynamic (DHCP).\n In order to activate DHCP mode, //! aucIP, aucSubnetMask, aucDefaultGateway must be 0. //! The default mode of CC3000 is DHCP mode. //! Note that the configuration is saved in non volatile memory //! and thus preserved over resets. -//! -//! @note If the mode is altered a reset of CC3000 device is required -//! in order to apply changes.\nAlso note that asynchronous event -//! of DHCP_EVENT, which is generated when an IP address is -//! allocated either by the DHCP server or due to static -//! allocation is generated only upon a connection to the -//! AP was established. +//! +//! @note If the mode is altered a reset of CC3000 device is required +//! in order to apply changes.\nAlso note that asynchronous event +//! of DHCP_EVENT, which is generated when an IP address is +//! allocated either by the DHCP server or due to static +//! allocation is generated only upon a connection to the +//! AP was established. //! //***************************************************************************** long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer) @@ -114,24 +106,24 @@ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned lon signed char scRet; unsigned char *ptr; unsigned char *args; - + scRet = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in temporary command buffer ARRAY_TO_STREAM(args,aucIP,4); ARRAY_TO_STREAM(args,aucSubnetMask,4); ARRAY_TO_STREAM(args,aucDefaultGateway,4); args = UINT32_TO_STREAM(args, 0); ARRAY_TO_STREAM(args,aucDNSServer,4); - + // Initiate a HCI command hci_command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN); - + // Wait for command complete event SimpleLinkWaitEvent(HCI_NETAPP_DHCP, &scRet); - + return(scRet); } @@ -140,22 +132,22 @@ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned lon // //! netapp_timeout_values //! -//! @param aucDHCP DHCP lease time request, also impact +//! @param aucDHCP DHCP lease time request, also impact //! the DHCP renew timeout. Range: [0-0xffffffff] seconds, //! 0 or 0xffffffff == infinity lease timeout. -//! Resolution:10 seconds. Influence: only after -//! reconnecting to the AP. +//! Resolution:10 seconds. Influence: only after +//! reconnecting to the AP. //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds. -//! The parameter is saved into the CC3000 NVMEM. +//! The parameter is saved into the CC3000 NVMEM. //! The default value on CC3000 is 14400 seconds. -//! +//! //! @param aucARP ARP refresh timeout, if ARP entry is not updated by //! incoming packet, the ARP entry will be deleted by -//! the end of the timeout. +//! the end of the timeout. //! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout //! Resolution: 10 seconds. Influence: on runtime. //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds -//! The parameter is saved into the CC3000 NVMEM. +//! The parameter is saved into the CC3000 NVMEM. //! The default value on CC3000 is 3600 seconds. //! //! @param aucKeepalive Keepalive event sent by the end of keepalive timeout @@ -163,7 +155,7 @@ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned lon //! Resolution: 10 seconds. //! Influence: on runtime. //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec -//! The parameter is saved into the CC3000 NVMEM. +//! The parameter is saved into the CC3000 NVMEM. //! The default value on CC3000 is 10 seconds. //! //! @param aucInactivity Socket inactivity timeout, socket timeout is @@ -172,50 +164,50 @@ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned lon //! Range: [0-0xffffffff] sec, 0 == infinity timeout. //! Resolution: 10 seconds. Influence: on runtime. //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec -//! The parameter is saved into the CC3000 NVMEM. +//! The parameter is saved into the CC3000 NVMEM. //! The default value on CC3000 is 60 seconds. //! //! @return return on success 0, otherwise error. //! -//! @brief Set new timeout values. Function set new timeout values for: -//! DHCP lease timeout, ARP refresh timeout, keepalive event -//! timeout and socket inactivity timeout -//! +//! @brief Set new timeout values. Function set new timeout values for: +//! DHCP lease timeout, ARP refresh timeout, keepalive event +//! timeout and socket inactivity timeout +//! //! @note If a parameter set to non zero value which is less than 20s, //! it will be set automatically to 20s. //! //***************************************************************************** #ifndef CC3000_TINY_DRIVER -long +long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity) { signed char scRet; unsigned char *ptr; unsigned char *args; - + scRet = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - - // Set minimal values of timers + + // Set minimal values of timers MIN_TIMER_SET(*aucDHCP) MIN_TIMER_SET(*aucARP) MIN_TIMER_SET(*aucKeepalive) MIN_TIMER_SET(*aucInactivity) - + // Fill in temporary command buffer args = UINT32_TO_STREAM(args, *aucDHCP); args = UINT32_TO_STREAM(args, *aucARP); args = UINT32_TO_STREAM(args, *aucKeepalive); args = UINT32_TO_STREAM(args, *aucInactivity); - + // Initiate a HCI command hci_command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN); - + // Wait for command complete event SimpleLinkWaitEvent(HCI_NETAPP_SET_TIMERS, &scRet); - + return(scRet); } #endif @@ -227,53 +219,44 @@ netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned lon //! //! @param ip destination IP address //! @param pingAttempts number of echo requests to send -//! @param pingSize send buffer size which may be up to 1400 bytes +//! @param pingSize send buffer size which may be up to 1400 bytes //! @param pingTimeout Time to wait for a response,in milliseconds. //! //! @return return on success 0, otherwise error. //! -//! @brief send ICMP ECHO_REQUEST to network hosts -//! -//! @note If an operation finished successfully asynchronous ping report +//! @brief send ICMP ECHO_REQUEST to network hosts +//! +//! @note If an operation finished successfully asynchronous ping report //! event will be generated. The report structure is as defined //! by structure netapp_pingreport_args_t. //! -//! @warning Calling this function while a previous Ping Requests are in +//! @warning Calling this function while a previous Ping Requests are in //! progress will stop the previous ping request. //***************************************************************************** #ifndef CC3000_TINY_DRIVER long -netapp_ping_send(uint32_t *ip, uint32_t ulPingAttempts, uint32_t ulPingSize, uint32_t ulPingTimeout) +netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout) { signed char scRet; unsigned char *ptr, *args; - + scRet = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in temporary command buffer args = UINT32_TO_STREAM(args, *ip); args = UINT32_TO_STREAM(args, ulPingAttempts); args = UINT32_TO_STREAM(args, ulPingSize); args = UINT32_TO_STREAM(args, ulPingTimeout); - /* - if (CC3KPrinter != 0) - { - for(uint8_t i=0; i<4+4+4+4; i++) { - CC3KPrinter->print(" 0x"); CC3KPrinter->( (ptr + HEADERS_SIZE_CMD)[i], HEX); - } - } - */ - // Initiate a HCI command hci_command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN); - + // Wait for command complete event SimpleLinkWaitEvent(HCI_NETAPP_PING_SEND, &scRet); - + return(scRet); } #endif @@ -286,7 +269,7 @@ netapp_ping_send(uint32_t *ip, uint32_t ulPingAttempts, uint32_t ulPingSize, uin //! //! @return none //! -//! @brief Request for ping status. This API triggers the CC3000 to send +//! @brief Request for ping status. This API triggers the CC3000 to send //! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT. //! This event will carry the report structure: //! netapp_pingreport_args_t. This structure is filled in with ping @@ -295,8 +278,8 @@ netapp_ping_send(uint32_t *ip, uint32_t ulPingAttempts, uint32_t ulPingSize, uin //! packets_received - echo reply, min_round_time - minimum //! round time, max_round_time - max round time, //! avg_round_time - average round time -//! -//! @note When a ping operation is not active, the returned structure +//! +//! @note When a ping operation is not active, the returned structure //! fields are 0. //! //***************************************************************************** @@ -308,14 +291,14 @@ void netapp_ping_report() unsigned char *ptr; ptr = tSLInformation.pucTxCommandBuffer; signed char scRet; - + scRet = EFAIL; - + // Initiate a HCI command hci_command_send(HCI_NETAPP_PING_REPORT, ptr, 0); - + // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet); + SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet); } #endif @@ -325,10 +308,10 @@ void netapp_ping_report() //! //! @param none //! -//! @return On success, zero is returned. On error, -1 is returned. +//! @return On success, zero is returned. On error, -1 is returned. //! //! @brief Stop any ping request. -//! +//! //! //***************************************************************************** @@ -337,16 +320,16 @@ long netapp_ping_stop() { signed char scRet; unsigned char *ptr; - + scRet = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; - + // Initiate a HCI command hci_command_send(HCI_NETAPP_PING_STOP, ptr, 0); - + // Wait for command complete event SimpleLinkWaitEvent(HCI_NETAPP_PING_STOP, &scRet); - + return(scRet); } #endif @@ -355,7 +338,7 @@ long netapp_ping_stop() // //! netapp_ipconfig //! -//! @param[out] ipconfig This argument is a pointer to a +//! @param[out] ipconfig This argument is a pointer to a //! tNetappIpconfigRetArgs structure. This structure is //! filled in with the network interface configuration. //! tNetappIpconfigRetArgs:\n aucIP - ip address, @@ -370,7 +353,7 @@ long netapp_ping_stop() //! Note that the information is available only after the WLAN //! connection was established. Calling this function before //! associated, will cause non-defined values to be returned. -//! +//! //! @note The function is useful for figuring out the IP Configuration of //! the device when DHCP is used and for figuring out the SSID of //! the Wireless network the device is associated with. @@ -381,15 +364,15 @@ long netapp_ping_stop() void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ) { unsigned char *ptr; - + ptr = tSLInformation.pucTxCommandBuffer; - + // Initiate a HCI command hci_command_send(HCI_NETAPP_IPCONFIG, ptr, 0); - + // Wait for command complete event SimpleLinkWaitEvent(HCI_NETAPP_IPCONFIG, ipconfig ); - + } #else void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ) @@ -415,16 +398,16 @@ long netapp_arp_flush(void) { signed char scRet; unsigned char *ptr; - + scRet = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; - + // Initiate a HCI command hci_command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0); - + // Wait for command complete event SimpleLinkWaitEvent(HCI_NETAPP_ARP_FLUSH, &scRet); - + return(scRet); } #endif diff --git a/stmhal/cc3k/netapp.h b/stmhal/cc3k/netapp.h index 747ae64ede..933269098d 100644 --- a/stmhal/cc3k/netapp.h +++ b/stmhal/cc3k/netapp.h @@ -3,14 +3,6 @@ * netapp.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,29 +12,30 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ #ifndef __NETAPP_H__ #define __NETAPP_H__ + //***************************************************************************** // // If building with a C++ compiler, make all of the definitions in this header @@ -96,13 +89,13 @@ typedef struct _netapp_pingreport_args // //! netapp_config_mac_adrress //! -//! @param mac device mac address, 6 bytes. Saved: yes +//! @param mac device mac address, 6 bytes. Saved: yes //! //! @return return on success 0, otherwise error. //! -//! @brief Configure device MAC address and store it in NVMEM. +//! @brief Configure device MAC address and store it in NVMEM. //! The value of the MAC address configured through the API will -//! be stored in CC3000 non volatile memory, thus preserved +//! be stored in CC3000 non volatile memory, thus preserved //! over resets. // //***************************************************************************** @@ -112,26 +105,26 @@ extern long netapp_config_mac_adrress( unsigned char *mac ); // //! netapp_dhcp //! -//! @param aucIP device mac address, 6 bytes. Saved: yes -//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes -//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes -//! @param aucDNSServer device mac address, 6 bytes. Saved: yes +//! @param aucIP device mac address, 6 bytes. Saved: yes +//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes +//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes +//! @param aucDNSServer device mac address, 6 bytes. Saved: yes //! //! @return return on success 0, otherwise error. //! -//! @brief netapp_dhcp is used to configure the network interface, -//! static or dynamic (DHCP).\n In order to activate DHCP mode, +//! @brief netapp_dhcp is used to configure the network interface, +//! static or dynamic (DHCP).\n In order to activate DHCP mode, //! aucIP, aucSubnetMask, aucDefaultGateway must be 0. //! The default mode of CC3000 is DHCP mode. //! Note that the configuration is saved in non volatile memory //! and thus preserved over resets. -//! -//! @note If the mode is altered a reset of CC3000 device is required -//! in order to apply changes.\nAlso note that asynchronous event -//! of DHCP_EVENT, which is generated when an IP address is -//! allocated either by the DHCP server or due to static -//! allocation is generated only upon a connection to the -//! AP was established. +//! +//! @note If the mode is altered a reset of CC3000 device is required +//! in order to apply changes.\nAlso note that asynchronous event +//! of DHCP_EVENT, which is generated when an IP address is +//! allocated either by the DHCP server or due to static +//! allocation is generated only upon a connection to the +//! AP was established. //! //***************************************************************************** extern long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer); @@ -142,22 +135,22 @@ extern long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsi // //! netapp_timeout_values //! -//! @param aucDHCP DHCP lease time request, also impact +//! @param aucDHCP DHCP lease time request, also impact //! the DHCP renew timeout. Range: [0-0xffffffff] seconds, //! 0 or 0xffffffff == infinity lease timeout. -//! Resolution:10 seconds. Influence: only after -//! reconnecting to the AP. +//! Resolution:10 seconds. Influence: only after +//! reconnecting to the AP. //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds. -//! The parameter is saved into the CC3000 NVMEM. +//! The parameter is saved into the CC3000 NVMEM. //! The default value on CC3000 is 14400 seconds. -//! +//! //! @param aucARP ARP refresh timeout, if ARP entry is not updated by //! incoming packet, the ARP entry will be deleted by -//! the end of the timeout. +//! the end of the timeout. //! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout //! Resolution: 10 seconds. Influence: on runtime. //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds -//! The parameter is saved into the CC3000 NVMEM. +//! The parameter is saved into the CC3000 NVMEM. //! The default value on CC3000 is 3600 seconds. //! //! @param aucKeepalive Keepalive event sent by the end of keepalive timeout @@ -165,7 +158,7 @@ extern long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsi //! Resolution: 10 seconds. //! Influence: on runtime. //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec -//! The parameter is saved into the CC3000 NVMEM. +//! The parameter is saved into the CC3000 NVMEM. //! The default value on CC3000 is 10 seconds. //! //! @param aucInactivity Socket inactivity timeout, socket timeout is @@ -174,15 +167,15 @@ extern long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsi //! Range: [0-0xffffffff] sec, 0 == infinity timeout. //! Resolution: 10 seconds. Influence: on runtime. //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec -//! The parameter is saved into the CC3000 NVMEM. +//! The parameter is saved into the CC3000 NVMEM. //! The default value on CC3000 is 60 seconds. //! //! @return return on success 0, otherwise error. //! -//! @brief Set new timeout values. Function set new timeout values for: -//! DHCP lease timeout, ARP refresh timeout, keepalive event -//! timeout and socket inactivity timeout -//! +//! @brief Set new timeout values. Function set new timeout values for: +//! DHCP lease timeout, ARP refresh timeout, keepalive event +//! timeout and socket inactivity timeout +//! //! @note If a parameter set to non zero value which is less than 20s, //! it will be set automatically to 20s. //! @@ -197,23 +190,23 @@ extern long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP, //! //! @param ip destination IP address //! @param pingAttempts number of echo requests to send -//! @param pingSize send buffer size which may be up to 1400 bytes +//! @param pingSize send buffer size which may be up to 1400 bytes //! @param pingTimeout Time to wait for a response,in milliseconds. //! //! @return return on success 0, otherwise error. //! -//! @brief send ICMP ECHO_REQUEST to network hosts -//! -//! @note If an operation finished successfully asynchronous ping report +//! @brief send ICMP ECHO_REQUEST to network hosts +//! +//! @note If an operation finished successfully asynchronous ping report //! event will be generated. The report structure is as defined //! by structure netapp_pingreport_args_t. //! -//! @warning Calling this function while a previous Ping Requests are in +//! @warning Calling this function while a previous Ping Requests are in //! progress will stop the previous ping request. //***************************************************************************** #ifndef CC3000_TINY_DRIVER -extern long netapp_ping_send(uint32_t *ip, uint32_t ulPingAttempts, uint32_t ulPingSize, uint32_t ulPingTimeout); +extern long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout); #endif //***************************************************************************** @@ -222,10 +215,10 @@ extern long netapp_ping_send(uint32_t *ip, uint32_t ulPingAttempts, uint32_t ulP //! //! @param none //! -//! @return On success, zero is returned. On error, -1 is returned. +//! @return On success, zero is returned. On error, -1 is returned. //! //! @brief Stop any ping request. -//! +//! //! //***************************************************************************** @@ -240,7 +233,7 @@ extern long netapp_ping_stop(); //! //! @return none //! -//! @brief Request for ping status. This API triggers the CC3000 to send +//! @brief Request for ping status. This API triggers the CC3000 to send //! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT. //! This event will carry the report structure: //! netapp_pingreport_args_t. This structure is filled in with ping @@ -249,8 +242,8 @@ extern long netapp_ping_stop(); //! packets_received - echo reply, min_round_time - minimum //! round time, max_round_time - max round time, //! avg_round_time - average round time -//! -//! @note When a ping operation is not active, the returned structure +//! +//! @note When a ping operation is not active, the returned structure //! fields are 0. //! //***************************************************************************** @@ -263,7 +256,7 @@ extern void netapp_ping_report(); // //! netapp_ipconfig //! -//! @param[out] ipconfig This argument is a pointer to a +//! @param[out] ipconfig This argument is a pointer to a //! tNetappIpconfigRetArgs structure. This structure is //! filled in with the network interface configuration. //! tNetappIpconfigRetArgs:\n aucIP - ip address, @@ -278,7 +271,7 @@ extern void netapp_ping_report(); //! Note that the information is available only after the WLAN //! connection was established. Calling this function before //! associated, will cause non-defined values to be returned. -//! +//! //! @note The function is useful for figuring out the IP Configuration of //! the device when DHCP is used and for figuring out the SSID of //! the Wireless network the device is associated with. diff --git a/stmhal/cc3k/nvmem.c b/stmhal/cc3k/nvmem.c index 774759c41f..81abf55dd0 100644 --- a/stmhal/cc3k/nvmem.c +++ b/stmhal/cc3k/nvmem.c @@ -3,14 +3,6 @@ * nvmem.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ @@ -58,7 +50,6 @@ #include "hci.h" #include "socket.h" #include "evnt_handler.h" -#include "ccdebug.h" //***************************************************************************** // @@ -82,45 +73,45 @@ //! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID, //! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID, //! and user files 12-15. -//! @param ulLength number of bytes to read -//! @param ulOffset ulOffset in file from where to read +//! @param ulLength number of bytes to read +//! @param ulOffset ulOffset in file from where to read //! @param buff output buffer pointer //! //! @return number of bytes read, otherwise error. //! -//! @brief Reads data from the file referred by the ulFileId parameter. +//! @brief Reads data from the file referred by the ulFileId parameter. //! Reads data from file ulOffset till length. Err if the file can't -//! be used, is invalid, or if the read is out of bounds. -//! +//! be used, is invalid, or if the read is out of bounds. +//! //***************************************************************************** -signed long +signed long nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffset, unsigned char *buff) { unsigned char ucStatus = 0xFF; unsigned char *ptr; unsigned char *args; - + ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in HCI packet structure args = UINT32_TO_STREAM(args, ulFileId); args = UINT32_TO_STREAM(args, ulLength); args = UINT32_TO_STREAM(args, ulOffset); - + // Initiate a HCI command hci_command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN); SimpleLinkWaitEvent(HCI_CMND_NVMEM_READ, &ucStatus); - + // In case there is data - read it - even if an error code is returned // Note: It is the user responsibility to ignore the data in case of an error code - - // Wait for the data in a synchronous way. Here we assume that the buffer is + + // Wait for the data in a synchronous way. Here we assume that the buffer is // big enough to store also parameters of nvmem - + SimpleLinkWaitData(buff, 0, 0); - + return(ucStatus); } @@ -132,56 +123,48 @@ nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffse //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, //! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID, //! and user files 12-15. -//! @param ulLength number of bytes to write -//! @param ulEntryOffset offset in file to start write operation from +//! @param ulLength number of bytes to write +//! @param ulEntryOffset offset in file to start write operation from //! @param buff data to write //! //! @return on success 0, error otherwise. //! //! @brief Write data to nvmem. -//! writes data to file referred by the ulFileId parameter. -//! Writes data to file ulOffset till ulLength.The file id will be +//! writes data to file referred by the ulFileId parameter. +//! Writes data to file ulOffset till ulLength.The file id will be //! marked invalid till the write is done. The file entry doesn't //! need to be valid - only allocated. -//! +//! //***************************************************************************** -signed long -nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long +signed long +nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long ulEntryOffset, unsigned char *buff) { long iRes; unsigned char *ptr; unsigned char *args; - + iRes = EFAIL; - + ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE); - + // Fill in HCI packet structure args = UINT32_TO_STREAM(args, ulFileId); args = UINT32_TO_STREAM(args, 12); args = UINT32_TO_STREAM(args, ulLength); args = UINT32_TO_STREAM(args, ulEntryOffset); - - memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE + + + memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE + NVMEM_WRITE_PARAMS_LEN),buff,ulLength); -#if (DEBUG_MODE == 1) - PRINT_F("Writing:\t"); - for (uint8_t i=0; i<ulLength; i++) { - PRINT_F("0x"); - printHex(buff[i]); - PRINT_F(", "); - } - PRINT_F("\n\r"); -#endif + // Initiate a HCI command but it will come on data channel hci_data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN, ulLength); - + SimpleLinkWaitEvent(HCI_EVNT_NVMEM_WRITE, &iRes); - + return(iRes); } @@ -194,9 +177,9 @@ nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long //! //! @return on success 0, error otherwise. //! -//! @brief Write MAC address to EEPROM. +//! @brief Write MAC address to EEPROM. //! mac address as appears over the air (OUI first) -//! +//! //***************************************************************************** unsigned char nvmem_set_mac_address(unsigned char *mac) @@ -208,13 +191,13 @@ unsigned char nvmem_set_mac_address(unsigned char *mac) // //! nvmem_get_mac_address //! -//! @param[out] mac mac address +//! @param[out] mac mac address //! //! @return on success 0, error otherwise. //! -//! @brief Read MAC address from EEPROM. +//! @brief Read MAC address from EEPROM. //! mac address as appears over the air (OUI first) -//! +//! //***************************************************************************** unsigned char nvmem_get_mac_address(unsigned char *mac) @@ -228,19 +211,19 @@ unsigned char nvmem_get_mac_address(unsigned char *mac) //! //! @param ulFileId nvmem file id:\n //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! @param spLength number of bytes to write +//! @param spLength number of bytes to write //! @param spData SP data to write //! //! @return on success 0, error otherwise. //! -//! @brief program a patch to a specific file ID. +//! @brief program a patch to a specific file ID. //! The SP data is assumed to be organized in 2-dimensional. -//! Each line is SP_PORTION_SIZE bytes long. Actual programming is +//! Each line is SP_PORTION_SIZE bytes long. Actual programming is //! applied in SP_PORTION_SIZE bytes portions. -//! +//! //***************************************************************************** -unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const uint8_t *spData) +unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData) { unsigned char status = 0; unsigned short offset = 0; @@ -248,33 +231,24 @@ unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, while ((status == 0) && (spLength >= SP_PORTION_SIZE)) { -#if (DEBUG_MODE == 1) - PRINT_F("Writing: "); printDec16(offset); PRINT_F("\t"); - for (uint8_t i=0; i<SP_PORTION_SIZE; i++) { - PRINT_F("0x"); - printHex(spDataPtr[i]); - PRINT_F(", "); - } - PRINT_F("\n\r"); -#endif - status = nvmem_write(ulFileId, SP_PORTION_SIZE, offset, spDataPtr); - offset += SP_PORTION_SIZE; - spLength -= SP_PORTION_SIZE; - spDataPtr += SP_PORTION_SIZE; + status = nvmem_write(ulFileId, SP_PORTION_SIZE, offset, spDataPtr); + offset += SP_PORTION_SIZE; + spLength -= SP_PORTION_SIZE; + spDataPtr += SP_PORTION_SIZE; } - + if (status !=0) { // NVMEM error occurred return status; } - + if (spLength != 0) { - // if reached here, a reminder is left - status = nvmem_write(ulFileId, spLength, offset, spDataPtr); + // if reached here, a reminder is left + status = nvmem_write(ulFileId, spLength, offset, spDataPtr); } - + return status; } @@ -282,34 +256,34 @@ unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, // //! nvmem_read_sp_version //! -//! @param[out] patchVer first number indicates package ID and the second -//! number indicates package build number +//! @param[out] patchVer first number indicates package ID and the second +//! number indicates package build number //! //! @return on success 0, error otherwise. //! -//! @brief Read patch version. read package version (WiFi FW patch, +//! @brief Read patch version. read package version (WiFi FW patch, //! driver-supplicant-NS patch, bootloader patch) -//! +//! //***************************************************************************** #ifndef CC3000_TINY_DRIVER -uint8_t nvmem_read_sp_version(uint8_t* patchVer) +unsigned char nvmem_read_sp_version(unsigned char* patchVer) { - uint8_t *ptr; + unsigned char *ptr; // 1st byte is the status and the rest is the SP version - uint8_t retBuf[5]; - + unsigned char retBuf[5]; + ptr = tSLInformation.pucTxCommandBuffer; - + // Initiate a HCI command, no args are required - hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0); + hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0); SimpleLinkWaitEvent(HCI_CMND_READ_SP_VERSION, retBuf); - + // package ID - *patchVer = retBuf[3]; + *patchVer = retBuf[3]; // package build number - *(patchVer+1) = retBuf[4]; - + *(patchVer+1) = retBuf[4]; + return(retBuf[0]); } #endif @@ -322,39 +296,40 @@ uint8_t nvmem_read_sp_version(uint8_t* patchVer) //! * NVMEM_AES128_KEY_FILEID: 12 //! * NVMEM_SHARED_MEM_FILEID: 13 //! * and fileIDs 14 and 15 -//! @param ulNewLen entry ulLength +//! @param ulNewLen entry ulLength //! //! @return on success 0, error otherwise. //! -//! @brief Create new file entry and allocate space on the NVMEM. +//! @brief Create new file entry and allocate space on the NVMEM. //! Applies only to user files. //! Modify the size of file. -//! If the entry is unallocated - allocate it to size +//! If the entry is unallocated - allocate it to size //! ulNewLen (marked invalid). //! If it is allocated then deallocate it first. -//! To just mark the file as invalid without resizing - +//! To just mark the file as invalid without resizing - //! set ulNewLen=0. -//! +//! //***************************************************************************** -int8_t +signed long nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen) { - unsigned char *ptr; + unsigned char *ptr; unsigned char *args; - int8_t retval; - + unsigned short retval; + ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in HCI packet structure args = UINT32_TO_STREAM(args, ulFileId); args = UINT32_TO_STREAM(args, ulNewLen); - + // Initiate a HCI command hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN); - + SimpleLinkWaitEvent(HCI_CMND_NVMEM_CREATE_ENTRY, &retval); + return(retval); } diff --git a/stmhal/cc3k/nvmem.h b/stmhal/cc3k/nvmem.h index 8a035f5608..247b546eec 100644 --- a/stmhal/cc3k/nvmem.h +++ b/stmhal/cc3k/nvmem.h @@ -3,14 +3,6 @@ * nvmem.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ @@ -67,7 +59,7 @@ extern "C" { /**************************************************************************** ** ** Definitions for File IDs -** +** ****************************************************************************/ /* NVMEM file ID - system files*/ #define NVMEM_NVS_FILEID (0) @@ -103,16 +95,16 @@ extern "C" { //! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID, //! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID, //! and user files 12-15. -//! @param ulLength number of bytes to read -//! @param ulOffset ulOffset in file from where to read +//! @param ulLength number of bytes to read +//! @param ulOffset ulOffset in file from where to read //! @param buff output buffer pointer //! //! @return number of bytes read, otherwise error. //! -//! @brief Reads data from the file referred by the ulFileId parameter. +//! @brief Reads data from the file referred by the ulFileId parameter. //! Reads data from file ulOffset till length. Err if the file can't -//! be used, is invalid, or if the read is out of bounds. -//! +//! be used, is invalid, or if the read is out of bounds. +//! //***************************************************************************** extern signed long nvmem_read(unsigned long file_id, unsigned long length, unsigned long offset, unsigned char *buff); @@ -125,18 +117,18 @@ extern signed long nvmem_read(unsigned long file_id, unsigned long length, unsig //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, //! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID, //! and user files 12-15. -//! @param ulLength number of bytes to write -//! @param ulEntryOffset offset in file to start write operation from +//! @param ulLength number of bytes to write +//! @param ulEntryOffset offset in file to start write operation from //! @param buff data to write //! //! @return on success 0, error otherwise. //! //! @brief Write data to nvmem. -//! writes data to file referred by the ulFileId parameter. -//! Writes data to file ulOffset till ulLength.The file id will be +//! writes data to file referred by the ulFileId parameter. +//! Writes data to file ulOffset till ulLength.The file id will be //! marked invalid till the write is done. The file entry doesn't //! need to be valid - only allocated. -//! +//! //***************************************************************************** extern signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long ulEntryOffset, unsigned char *buff); @@ -150,9 +142,9 @@ extern signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, u //! //! @return on success 0, error otherwise. //! -//! @brief Write MAC address to EEPROM. +//! @brief Write MAC address to EEPROM. //! mac address as appears over the air (OUI first) -//! +//! //***************************************************************************** extern unsigned char nvmem_set_mac_address(unsigned char *mac); @@ -161,13 +153,13 @@ extern unsigned char nvmem_set_mac_address(unsigned char *mac); // //! nvmem_get_mac_address //! -//! @param[out] mac mac address +//! @param[out] mac mac address //! //! @return on success 0, error otherwise. //! -//! @brief Read MAC address from EEPROM. +//! @brief Read MAC address from EEPROM. //! mac address as appears over the air (OUI first) -//! +//! //***************************************************************************** extern unsigned char nvmem_get_mac_address(unsigned char *mac); @@ -178,16 +170,16 @@ extern unsigned char nvmem_get_mac_address(unsigned char *mac); //! //! @param ulFileId nvmem file id:\n //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! @param spLength number of bytes to write +//! @param spLength number of bytes to write //! @param spData SP data to write //! //! @return on success 0, error otherwise. //! -//! @brief program a patch to a specific file ID. +//! @brief program a patch to a specific file ID. //! The SP data is assumed to be organized in 2-dimensional. -//! Each line is SP_PORTION_SIZE bytes long. Actual programming is +//! Each line is SP_PORTION_SIZE bytes long. Actual programming is //! applied in SP_PORTION_SIZE bytes portions. -//! +//! //***************************************************************************** extern unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData); @@ -196,16 +188,16 @@ extern unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spL // //! nvmem_read_sp_version //! -//! @param[out] patchVer first number indicates package ID and the second -//! number indicates package build number +//! @param[out] patchVer first number indicates package ID and the second +//! number indicates package build number //! //! @return on success 0, error otherwise. //! -//! @brief Read patch version. read package version (WiFi FW patch, +//! @brief Read patch version. read package version (WiFi FW patch, //! driver-supplicant-NS patch, bootloader patch) -//! +//! //***************************************************************************** -#ifndef CC3000_TINY_DRIVER +#ifndef CC3000_TINY_DRIVER extern unsigned char nvmem_read_sp_version(unsigned char* patchVer); #endif @@ -217,21 +209,21 @@ extern unsigned char nvmem_read_sp_version(unsigned char* patchVer); //! * NVMEM_AES128_KEY_FILEID: 12 //! * NVMEM_SHARED_MEM_FILEID: 13 //! * and fileIDs 14 and 15 -//! @param ulNewLen entry ulLength +//! @param ulNewLen entry ulLength //! //! @return on success 0, error otherwise. //! -//! @brief Create new file entry and allocate space on the NVMEM. +//! @brief Create new file entry and allocate space on the NVMEM. //! Applies only to user files. //! Modify the size of file. -//! If the entry is unallocated - allocate it to size +//! If the entry is unallocated - allocate it to size //! ulNewLen (marked invalid). //! If it is allocated then deallocate it first. -//! To just mark the file as invalid without resizing - +//! To just mark the file as invalid without resizing - //! set ulNewLen=0. -//! +//! //***************************************************************************** -extern int8_t nvmem_create_entry(unsigned long file_id, unsigned long newlen); +extern signed long nvmem_create_entry(unsigned long file_id, unsigned long newlen); //***************************************************************************** diff --git a/stmhal/cc3k/pybcc3k.c b/stmhal/cc3k/pybcc3k.c index d43f42f0ba..a8bcc44288 100644 --- a/stmhal/cc3k/pybcc3k.c +++ b/stmhal/cc3k/pybcc3k.c @@ -1,3 +1,4 @@ +#include <stdio.h> #include <stdint.h> #include "stm32f4xx_hal.h" @@ -14,11 +15,16 @@ #include "extint.h" #include "spi.h" #include "ccspi.h" -#include "ccdebug.h" #include "pybcc3k.h" #if MICROPY_HW_ENABLE_CC3K +#if 1 // print debugging info +#define DEBUG_printf(args...) printf(args) +#else // don't print debugging info +#define DEBUG_printf(args...) (void)0 +#endif + // IRQ on PA14, input, pulled up, active low // EN on PC7, output, active high // CS on PC6, output, active low @@ -73,12 +79,13 @@ uint32_t exti14_missed = 0; // TODO hack; do it properly! void pyb_cc3000_enable_irq(void) { DEBUG_printf("pyb_cc3000_enable_irq: en=%lu miss=%lu\n", exti14_enabled, exti14_missed); if (exti14_missed) { - /* doesn't look like this is needed + // doesn't look like this is needed DEBUG_printf("pyb_cc3000_enable_irq: handling missed IRQ\n"); + /* // TODO hack if we have a pending IRQ extern void SpiIntGPIOHandler(void); - SpiIntGPIOHandler(); */ + SpiIntGPIOHandler(); exti14_missed = 0; } exti14_enabled = 1; diff --git a/stmhal/cc3k/security.c b/stmhal/cc3k/security.c index c52d7f67e6..dfd8d94322 100644 --- a/stmhal/cc3k/security.c +++ b/stmhal/cc3k/security.c @@ -12,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ @@ -49,7 +49,7 @@ #ifndef CC3000_UNENCRYPTED_SMART_CONFIG // foreward sbox -const unsigned char sbox[256] = { +const unsigned char sbox[256] = { //0 1 2 3 4 5 6 7 8 9 A B C D E F 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1 @@ -66,7 +66,7 @@ const unsigned char sbox[256] = { 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E -0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F +0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F // inverse sbox const unsigned char rsbox[256] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb @@ -130,7 +130,7 @@ void expandKey(unsigned char *expandedKey, expandedKey[ii*16 +14] = expandedKey[(ii-1)*16 +14]^expandedKey[ii*16 +10]; expandedKey[ii*16 +15] = expandedKey[(ii-1)*16 +15]^expandedKey[ii*16 +11]; } - + } //***************************************************************************** @@ -171,18 +171,18 @@ unsigned char galois_mul2(unsigned char value) //! - subbytes //! - shiftrows //! - mixcolums -//! is executed 9 times, after this addroundkey to finish the 9th +//! is executed 9 times, after this addroundkey to finish the 9th //! round, after that the 10th round without mixcolums //! no further subfunctions to save cycles for function calls //! no structuring with "for (....)" to save cycles. -//! +//! //! //***************************************************************************** void aes_encr(unsigned char *state, unsigned char *expandedKey) { unsigned char buf1, buf2, buf3, round; - + for (round = 0; round < 9; round ++){ // addroundkey, sbox and shiftrows // row 0 @@ -209,7 +209,7 @@ void aes_encr(unsigned char *state, unsigned char *expandedKey) state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])]; state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])]; state[ 3] = sbox[buf1]; - + // mixcolums ////////// // col1 buf1 = state[0] ^ state[1] ^ state[2] ^ state[3]; @@ -238,8 +238,8 @@ void aes_encr(unsigned char *state, unsigned char *expandedKey) buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1; buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1; buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1; - buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; - + buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; + } // 10th round without mixcols state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])]; @@ -280,9 +280,9 @@ void aes_encr(unsigned char *state, unsigned char *expandedKey) state[11]^=expandedKey[171]; state[12]^=expandedKey[172]; state[13]^=expandedKey[173]; - state[14]^=expandedKey[174]; + state[14]^=expandedKey[174]; state[15]^=expandedKey[175]; -} +} //***************************************************************************** // @@ -311,7 +311,7 @@ void aes_decr(unsigned char *state, unsigned char *expandedKey) unsigned char buf1, buf2, buf3; signed char round; round = 9; - + // initial addroundkey state[ 0]^=expandedKey[160]; state[ 1]^=expandedKey[161]; @@ -327,9 +327,9 @@ void aes_decr(unsigned char *state, unsigned char *expandedKey) state[11]^=expandedKey[171]; state[12]^=expandedKey[172]; state[13]^=expandedKey[173]; - state[14]^=expandedKey[174]; + state[14]^=expandedKey[174]; state[15]^=expandedKey[175]; - + // 10th round without mixcols state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ]; state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4]; @@ -354,7 +354,7 @@ void aes_decr(unsigned char *state, unsigned char *expandedKey) state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7]; state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11]; state[15] = buf1; - + for (round = 8; round >= 0; round--){ // barreto //col1 @@ -401,8 +401,8 @@ void aes_decr(unsigned char *state, unsigned char *expandedKey) buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1; buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1; buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1; - buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; - + buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; + // addroundkey, rsbox and shiftrows // row 0 state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ]; @@ -429,8 +429,8 @@ void aes_decr(unsigned char *state, unsigned char *expandedKey) state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11]; state[15] = buf1; } - -} + +} //***************************************************************************** // @@ -443,9 +443,9 @@ void aes_decr(unsigned char *state, unsigned char *expandedKey) //! //! @brief AES128 encryption: //! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes -//! is computed. The AES implementation is in mode ECB (Electronic -//! Code Book). -//! +//! is computed. The AES implementation is in mode ECB (Electronic +//! Code Book). +//! //! //***************************************************************************** @@ -453,7 +453,7 @@ void aes_encrypt(unsigned char *state, unsigned char *key) { // expand the key into 176 bytes - expandKey(expandedKey, key); + expandKey(expandedKey, key); aes_encr(state, expandedKey); } @@ -468,9 +468,9 @@ void aes_encrypt(unsigned char *state, //! //! @brief AES128 decryption: //! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes -//! is computed The AES implementation is in mode ECB +//! is computed The AES implementation is in mode ECB //! (Electronic Code Book). -//! +//! //! //***************************************************************************** @@ -491,15 +491,15 @@ void aes_decrypt(unsigned char *state, //! //! @brief Reads AES128 key from EEPROM //! Reads the AES128 key from fileID #12 in EEPROM -//! returns an error if the key does not exist. -//! +//! returns an error if the key does not exist. +//! //! //***************************************************************************** signed long aes_read_key(unsigned char *key) { signed long returnValue; - + returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key); return returnValue; @@ -515,7 +515,7 @@ signed long aes_read_key(unsigned char *key) //! //! @brief writes AES128 key from EEPROM //! Writes the AES128 key to fileID #12 in EEPROM -//! +//! //! //***************************************************************************** diff --git a/stmhal/cc3k/security.h b/stmhal/cc3k/security.h index 02214272e7..35f27763aa 100644 --- a/stmhal/cc3k/security.h +++ b/stmhal/cc3k/security.h @@ -12,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ @@ -64,9 +64,9 @@ extern "C" { //! //! @brief AES128 encryption: //! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes -//! is computed. The AES implementation is in mode ECB (Electronic -//! Code Book). -//! +//! is computed. The AES implementation is in mode ECB (Electronic +//! Code Book). +//! //! //***************************************************************************** extern void aes_encrypt(unsigned char *state, unsigned char *key); @@ -82,9 +82,9 @@ extern void aes_encrypt(unsigned char *state, unsigned char *key); //! //! @brief AES128 decryption: //! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes -//! is computed The AES implementation is in mode ECB +//! is computed The AES implementation is in mode ECB //! (Electronic Code Book). -//! +//! //! //***************************************************************************** extern void aes_decrypt(unsigned char *state, unsigned char *key); @@ -100,8 +100,8 @@ extern void aes_decrypt(unsigned char *state, unsigned char *key); //! //! @brief Reads AES128 key from EEPROM //! Reads the AES128 key from fileID #12 in EEPROM -//! returns an error if the key does not exist. -//! +//! returns an error if the key does not exist. +//! //! //***************************************************************************** extern signed long aes_read_key(unsigned char *key); @@ -116,7 +116,7 @@ extern signed long aes_read_key(unsigned char *key); //! //! @brief writes AES128 key from EEPROM //! Writes the AES128 key to fileID #12 in EEPROM -//! +//! //! //***************************************************************************** extern signed long aes_write_key(unsigned char *key); diff --git a/stmhal/cc3k/socket.c b/stmhal/cc3k/socket.c index 86a4549ecf..bfad60247a 100644 --- a/stmhal/cc3k/socket.c +++ b/stmhal/cc3k/socket.c @@ -3,14 +3,6 @@ * socket.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ @@ -58,17 +50,16 @@ #include "socket.h" #include "evnt_handler.h" #include "netapp.h" -#include "ccdebug.h" extern int errno; -//Enable this flag if and only if you must comply with BSD socket +//Enable this flag if and only if you must comply with BSD socket //close() function #ifdef _API_USE_BSD_CLOSE #define close(sd) closesocket(sd) #endif -//Enable this flag if and only if you must comply with BSD socket read() and +//Enable this flag if and only if you must comply with BSD socket read() and //write() functions #ifdef _API_USE_BSD_READ_WRITE #define read(sd, buf, len, flags) recv(sd, buf, len, flags) @@ -90,7 +81,7 @@ extern int errno; #define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12) -// The legnth of arguments for the SEND command: sd + buff_offset + len + flags, +// The legnth of arguments for the SEND command: sd + buff_offset + len + flags, // while size of each parameter is 32 bit - so the total length is 16 bytes; #define HCI_CMND_SEND_ARG_LENGTH (16) @@ -111,13 +102,13 @@ extern int errno; //! //! @param sd socket descriptor //! -//! @return 0 in case there are buffers available, +//! @return 0 in case there are buffers available, //! -1 in case of bad socket -//! -2 if there are no free buffers present (only when +//! -2 if there are no free buffers present (only when //! SEND_NON_BLOCKING is enabled) //! -//! @brief if SEND_NON_BLOCKING not define - block until have free buffer -//! becomes available, else return immediately with correct status +//! @brief if SEND_NON_BLOCKING not define - block until have free buffer +//! becomes available, else return immediately with correct status //! regarding the buffers available. // //***************************************************************************** @@ -128,7 +119,7 @@ HostFlowControlConsumeBuff(int sd) /* wait in busy loop */ do { - // In case last transmission failed then we will return the last failure + // In case last transmission failed then we will return the last failure // reason here. // Note that the buffer will not be allocated in this case if (tSLInformation.slTransmitDataError != 0) @@ -137,17 +128,17 @@ HostFlowControlConsumeBuff(int sd) tSLInformation.slTransmitDataError = 0; return errno; } - + if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) return -1; } while(0 == tSLInformation.usNumberOfFreeBuffers); - + tSLInformation.usNumberOfFreeBuffers--; - + return 0; #else - - // In case last transmission failed then we will return the last failure + + // In case last transmission failed then we will return the last failure // reason here. // Note that the buffer will not be allocated in this case if (tSLInformation.slTransmitDataError != 0) @@ -158,8 +149,8 @@ HostFlowControlConsumeBuff(int sd) } if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) return -1; - - //If there are no available buffers, return -2. It is recommended to use + + //If there are no available buffers, return -2. It is recommended to use // select or receive to see if there is any buffer occupied with received data // If so, call receive() to release the buffer. if(0 == tSLInformation.usNumberOfFreeBuffers) @@ -178,20 +169,20 @@ HostFlowControlConsumeBuff(int sd) // //! socket //! -//! @param domain selects the protocol family which will be used for +//! @param domain selects the protocol family which will be used for //! communication. On this version only AF_INET is supported -//! @param type specifies the communication semantics. On this version +//! @param type specifies the communication semantics. On this version //! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported -//! @param protocol specifies a particular protocol to be used with the -//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are +//! @param protocol specifies a particular protocol to be used with the +//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are //! supported. //! -//! @return On success, socket handle that is used for consequent socket +//! @return On success, socket handle that is used for consequent socket //! operations. On error, -1 is returned. //! //! @brief create an endpoint for communication -//! The socket function creates a socket that is bound to a specific -//! transport service provider. This function is called by the +//! The socket function creates a socket that is bound to a specific +//! transport service provider. This function is called by the //! application layer to obtain a socket handle. // //***************************************************************************** @@ -201,27 +192,27 @@ socket(long domain, long type, long protocol) { long ret; unsigned char *ptr, *args; - + ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in HCI packet structure args = UINT32_TO_STREAM(args, domain); args = UINT32_TO_STREAM(args, type); args = UINT32_TO_STREAM(args, protocol); - + // Initiate a HCI command hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret); - - // Process the event + + // Process the event errno = ret; - + set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); - + return(ret); } @@ -242,25 +233,25 @@ closesocket(long sd) { long ret; unsigned char *ptr, *args; - + ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in HCI packet structure args = UINT32_TO_STREAM(args, sd); - + // Initiate a HCI command hci_command_send(HCI_CMND_CLOSE_SOCKET, ptr, SOCKET_CLOSE_PARAMS_LEN); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret); errno = ret; - - // since 'close' call may result in either OK (and then it closed) or error - // mark this socket as invalid + + // since 'close' call may result in either OK (and then it closed) or error + // mark this socket as invalid set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - + return(ret); } @@ -268,15 +259,15 @@ closesocket(long sd) // //! accept //! -//! @param[in] sd socket descriptor (handle) +//! @param[in] sd socket descriptor (handle) //! @param[out] addr the argument addr is a pointer to a sockaddr structure -//! This structure is filled in with the address of the -//! peer socket, as known to the communications layer. -//! determined. The exact format of the address returned -//! addr is by the socket's address sockaddr. +//! This structure is filled in with the address of the +//! peer socket, as known to the communications layer. +//! determined. The exact format of the address returned +//! addr is by the socket's address sockaddr. //! On this version only AF_INET is supported. //! This argument returns in network order. -//! @param[out] addrlen the addrlen argument is a value-result argument: +//! @param[out] addrlen the addrlen argument is a value-result argument: //! it should initially contain the size of the structure //! pointed to by addr. //! @@ -288,21 +279,21 @@ closesocket(long sd) //! - On failure, SOC_ERROR (-1) //! //! @brief accept a connection on a socket: -//! This function is used with connection-based socket types -//! (SOCK_STREAM). It extracts the first connection request on the +//! This function is used with connection-based socket types +//! (SOCK_STREAM). It extracts the first connection request on the //! queue of pending connections, creates a new connected socket, and //! returns a new file descriptor referring to that socket. -//! The newly created socket is not in the listening state. -//! The original socket sd is unaffected by this call. +//! The newly created socket is not in the listening state. +//! The original socket sd is unaffected by this call. //! The argument sd is a socket that has been created with socket(), -//! bound to a local address with bind(), and is listening for -//! connections after a listen(). The argument addr is a pointer -//! to a sockaddr structure. This structure is filled in with the +//! bound to a local address with bind(), and is listening for +//! connections after a listen(). The argument addr is a pointer +//! to a sockaddr structure. This structure is filled in with the //! address of the peer socket, as known to the communications layer. -//! The exact format of the address returned addr is determined by the +//! The exact format of the address returned addr is determined by the //! socket's address family. The addrlen argument is a value-result //! argument: it should initially contain the size of the structure -//! pointed to by addr, on return it will contain the actual +//! pointed to by addr, on return it will contain the actual //! length (in bytes) of the address returned. //! //! @sa socket ; bind ; listen @@ -315,29 +306,30 @@ accept(long sd, sockaddr *addr, socklen_t *addrlen) long ret; unsigned char *ptr, *args; tBsdReturnParams tAcceptReturnArguments; - + ret = EFAIL; + tAcceptReturnArguments.iStatus = EFAIL; // in case of timeout ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); - + // Initiate a HCI command hci_command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments); - - + + // need specify return parameters!!! memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); *addrlen = ASIC_ADDR_LEN; - errno = tAcceptReturnArguments.iStatus; + errno = tAcceptReturnArguments.iStatus; ret = errno; - - // if succeeded, iStatus = new socket descriptor. otherwise - error number + + // if succeeded, iStatus = new socket descriptor. otherwise - error number if(M_IS_VALID_SD(ret)) { set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); @@ -346,7 +338,7 @@ accept(long sd, sockaddr *addr, socklen_t *addrlen) { set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); } - + return(ret); } @@ -354,8 +346,8 @@ accept(long sd, sockaddr *addr, socklen_t *addrlen) // //! bind //! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr specifies the destination address. On this version +//! @param[in] sd socket descriptor (handle) +//! @param[out] addr specifies the destination address. On this version //! only AF_INET is supported. //! @param[out] addrlen contains the size of the structure pointed to by addr. //! @@ -363,8 +355,8 @@ accept(long sd, sockaddr *addr, socklen_t *addrlen) //! //! @brief assign a name to a socket //! This function gives the socket the local address addr. -//! addr is addrlen bytes long. Traditionally, this is called when a -//! socket is created with socket, it exists in a name space (address +//! addr is addrlen bytes long. Traditionally, this is called when a +//! socket is created with socket, it exists in a name space (address //! family) but has no name assigned. //! It is necessary to assign a local address before a SOCK_STREAM //! socket may receive connections. @@ -378,28 +370,28 @@ bind(long sd, const sockaddr *addr, long addrlen) { long ret; unsigned char *ptr, *args; - + ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + addrlen = ASIC_ADDR_LEN; - + // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, 0x00000008); args = UINT32_TO_STREAM(args, addrlen); ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen); - + // Initiate a HCI command hci_command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_BIND, &ret); - + errno = ret; - + return(ret); } @@ -407,7 +399,7 @@ bind(long sd, const sockaddr *addr, long addrlen) // //! listen //! -//! @param[in] sd socket descriptor (handle) +//! @param[in] sd socket descriptor (handle) //! @param[in] backlog specifies the listen queue depth. On this version //! backlog is not supported. //! @return On success, zero is returned. On error, -1 is returned. @@ -418,7 +410,7 @@ bind(long sd, const sockaddr *addr, long addrlen) //! and then the connections are accepted with accept. //! The listen() call applies only to sockets of type SOCK_STREAM //! The backlog parameter defines the maximum length the queue of -//! pending connections may grow to. +//! pending connections may grow to. //! //! @sa socket ; accept ; bind //! @@ -431,23 +423,23 @@ listen(long sd, long backlog) { long ret; unsigned char *ptr, *args; - + ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, backlog); - + // Initiate a HCI command hci_command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret); errno = ret; - + return(ret); } @@ -455,14 +447,14 @@ listen(long sd, long backlog) // //! gethostbyname //! -//! @param[in] hostname host name -//! @param[in] usNameLen name length -//! @param[out] out_ip_addr This parameter is filled in with host IP address. -//! In case that host name is not resolved, -//! out_ip_addr is zero. +//! @param[in] hostname host name +//! @param[in] usNameLen name length +//! @param[out] out_ip_addr This parameter is filled in with host IP address. +//! In case that host name is not resolved, +//! out_ip_addr is zero. //! @return On success, positive is returned. On error, negative is returned //! -//! @brief Get host IP by name. Obtain the IP Address of machine on network, +//! @brief Get host IP by name. Obtain the IP Address of machine on network, //! by its name. //! //! @note On this version, only blocking mode is supported. Also note that @@ -471,40 +463,40 @@ listen(long sd, long backlog) //***************************************************************************** #ifndef CC3000_TINY_DRIVER -int -gethostbyname(const char * hostname, uint8_t usNameLen, uint32_t * out_ip_addr) +int +gethostbyname(const char* hostname, unsigned short usNameLen, unsigned long* out_ip_addr) { tBsdGethostbynameParams ret; unsigned char *ptr, *args; - + errno = EFAIL; - + if (usNameLen > HOSTNAME_MAX_LENGTH) { return errno; } - + ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - + // Fill in HCI packet structure args = UINT32_TO_STREAM(args, 8); args = UINT32_TO_STREAM(args, usNameLen); ARRAY_TO_STREAM(args, hostname, usNameLen); - + // Initiate a HCI command hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + usNameLen - 1); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret); - + errno = ret.retVal; - //Dprinter->print("errno: "); Dprinter->println(errno); - (*((uint32_t *)out_ip_addr)) = ret.outputAddress; - + + (*((long*)out_ip_addr)) = ret.outputAddress; + return (errno); - + } #endif @@ -512,25 +504,25 @@ gethostbyname(const char * hostname, uint8_t usNameLen, uint32_t * out_ip_addr) // //! connect //! -//! @param[in] sd socket descriptor (handle) +//! @param[in] sd socket descriptor (handle) //! @param[in] addr specifies the destination addr. On this version //! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr +//! @param[out] addrlen contains the size of the structure pointed to by addr //! @return On success, zero is returned. On error, -1 is returned //! -//! @brief initiate a connection on a socket -//! Function connects the socket referred to by the socket descriptor -//! sd, to the address specified by addr. The addrlen argument -//! specifies the size of addr. The format of the address in addr is -//! determined by the address space of the socket. If it is of type -//! SOCK_DGRAM, this call specifies the peer with which the socket is +//! @brief initiate a connection on a socket +//! Function connects the socket referred to by the socket descriptor +//! sd, to the address specified by addr. The addrlen argument +//! specifies the size of addr. The format of the address in addr is +//! determined by the address space of the socket. If it is of type +//! SOCK_DGRAM, this call specifies the peer with which the socket is //! to be associated; this address is that to which datagrams are to be -//! sent, and the only address from which datagrams are to be received. -//! If the socket is of type SOCK_STREAM, this call attempts to make a -//! connection to another socket. The other socket is specified by +//! sent, and the only address from which datagrams are to be received. +//! If the socket is of type SOCK_STREAM, this call attempts to make a +//! connection to another socket. The other socket is specified by //! address, which is an address in the communications space of the -//! socket. Note that the function implements only blocking behavior -//! thus the caller will be waiting either for the connection +//! socket. Note that the function implements only blocking behavior +//! thus the caller will be waiting either for the connection //! establishment or for the connection establishment failure. //! //! @sa socket @@ -542,27 +534,27 @@ connect(long sd, const sockaddr *addr, long addrlen) { long int ret; unsigned char *ptr, *args; - + ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); addrlen = 8; - + // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, 0x00000008); args = UINT32_TO_STREAM(args, addrlen); ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen); - + // Initiate a HCI command hci_command_send(HCI_CMND_CONNECT, ptr, SOCKET_CONNECT_PARAMS_LEN); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret); - + errno = ret; - + return((long)ret); } @@ -572,12 +564,12 @@ connect(long sd, const sockaddr *addr, long addrlen) //! select //! //! @param[in] nfds the highest-numbered file descriptor in any of the -//! three sets, plus 1. +//! three sets, plus 1. //! @param[out] writesds socket descriptors list for write monitoring -//! @param[out] readsds socket descriptors list for read monitoring +//! @param[out] readsds socket descriptors list for read monitoring //! @param[out] exceptsds socket descriptors list for exception monitoring //! @param[in] timeout is an upper bound on the amount of time elapsed -//! before select() returns. Null means infinity +//! before select() returns. Null means infinity //! timeout. The minimum timeout is 5 milliseconds, //! less than 5 milliseconds will be set //! automatically to 5 milliseconds. @@ -589,14 +581,14 @@ connect(long sd, const sockaddr *addr, long addrlen) //! On error, -1 is returned. //! *readsds - return the sockets on which Read request will //! return without delay with valid data. -//! *writesds - return the sockets on which Write request +//! *writesds - return the sockets on which Write request //! will return without delay. //! *exceptsds - return the sockets which closed recently. //! -//! @brief Monitor socket activity +//! @brief Monitor socket activity //! Select allow a program to monitor multiple file descriptors, -//! waiting until one or more of the file descriptors become -//! "ready" for some class of I/O operation +//! waiting until one or more of the file descriptors become +//! "ready" for some class of I/O operation //! //! @Note If the timeout value set to less than 5ms it will automatically set //! to 5ms to prevent overload of the system @@ -606,13 +598,13 @@ connect(long sd, const sockaddr *addr, long addrlen) //***************************************************************************** int -select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, +select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout) { unsigned char *ptr, *args; tBsdSelectRecvParams tParams; unsigned long is_blocking; - + if( timeout == NULL) { is_blocking = 1; /* blocking , infinity timeout */ @@ -621,11 +613,11 @@ select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, { is_blocking = 0; /* no blocking, timeout */ } - + // Fill in HCI packet structure ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in temporary command buffer args = UINT32_TO_STREAM(args, nfds); args = UINT32_TO_STREAM(args, 0x00000014); @@ -636,10 +628,10 @@ select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0)); args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0)); args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0)); - + if (timeout) { - if ( 0 == timeout->tv_sec && timeout->tv_usec < + if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS) { timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; @@ -647,13 +639,13 @@ select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, args = UINT32_TO_STREAM(args, timeout->tv_sec); args = UINT32_TO_STREAM(args, timeout->tv_usec); } - + // Initiate a HCI command hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams); - + // Update actually read FD if (tParams.iStatus >= 0) { @@ -661,19 +653,19 @@ select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, { memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); } - + if (writesds) { - memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); + memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); } - + if (exceptsds) { - memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); + memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); } - + return(tParams.iStatus); - + } else { @@ -697,31 +689,31 @@ select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, //! This function manipulate the options associated with a socket. //! Options may exist at multiple protocol levels; they are always //! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - +//! When manipulating socket options the level at which the option +//! resides and the name of the option must be specified. +//! To manipulate options at the socket level, level is specified as +//! SOL_SOCKET. To manipulate options at any other level the protocol +//! number of the appropriate protocol controlling the option is +//! supplied. For example, to indicate that an option is to be +//! interpreted by the TCP protocol, level should be set to the +//! protocol number of TCP; +//! The parameters optval and optlen are used to access optval - //! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option +//! in which the value for the requested option(s) are to +//! be returned. For getsockopt(), optlen is a value-result +//! parameter, initially containing the size of the buffer +//! pointed to by option_value, and modified on return to +//! indicate the actual size of the value returned. If no option //! value is to be supplied or returned, option_value may be NULL. //! //! @Note On this version the following two socket options are enabled: //! The only protocol level supported in this version //! is SOL_SOCKET (level). //! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout +//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout //! in milliseconds. //! In that case optval should be pointer to unsigned long. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on +//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on //! or off. //! In that case optval should be SOCK_ON or SOCK_OFF (optval). //! @@ -734,12 +726,12 @@ int setsockopt(long sd, long level, long optname, const void *optval, socklen_t optlen) { - long ret; + int ret; unsigned char *ptr, *args; - + ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, level); @@ -747,14 +739,14 @@ setsockopt(long sd, long level, long optname, const void *optval, args = UINT32_TO_STREAM(args, 0x00000008); args = UINT32_TO_STREAM(args, optlen); ARRAY_TO_STREAM(args, ((unsigned char *)optval), optlen); - + // Initiate a HCI command hci_command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret); - + if (ret >= 0) { return (0); @@ -762,7 +754,7 @@ setsockopt(long sd, long level, long optname, const void *optval, else { errno = ret; - return (-1); + return ret; } } #endif @@ -782,31 +774,31 @@ setsockopt(long sd, long level, long optname, const void *optval, //! This function manipulate the options associated with a socket. //! Options may exist at multiple protocol levels; they are always //! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - +//! When manipulating socket options the level at which the option +//! resides and the name of the option must be specified. +//! To manipulate options at the socket level, level is specified as +//! SOL_SOCKET. To manipulate options at any other level the protocol +//! number of the appropriate protocol controlling the option is +//! supplied. For example, to indicate that an option is to be +//! interpreted by the TCP protocol, level should be set to the +//! protocol number of TCP; +//! The parameters optval and optlen are used to access optval - //! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option +//! in which the value for the requested option(s) are to +//! be returned. For getsockopt(), optlen is a value-result +//! parameter, initially containing the size of the buffer +//! pointed to by option_value, and modified on return to +//! indicate the actual size of the value returned. If no option //! value is to be supplied or returned, option_value may be NULL. //! //! @Note On this version the following two socket options are enabled: //! The only protocol level supported in this version //! is SOL_SOCKET (level). //! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout +//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout //! in milliseconds. //! In that case optval should be pointer to unsigned long. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on +//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on //! or off. //! In that case optval should be SOCK_ON or SOCK_OFF (optval). //! @@ -819,22 +811,22 @@ getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen) { unsigned char *ptr, *args; tBsdGetSockOptReturnParams tRetParams; - + ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, level); args = UINT32_TO_STREAM(args, optname); - + // Initiate a HCI command hci_command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams); - + if (((signed char)tRetParams.iStatus) >= 0) { *optlen = 4; @@ -844,7 +836,7 @@ getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen) else { errno = tRetParams.iStatus; - return (-1); + return errno; } } @@ -875,45 +867,33 @@ simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from, { unsigned char *ptr, *args; tBsdReadReturnParams tSocketReadEvent; - + ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - + // Fill in HCI packet structure args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, len); args = UINT32_TO_STREAM(args, flags); - // Generate the read command, and wait for the + // Generate the read command, and wait for the hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(opcode, &tSocketReadEvent); - DEBUGPRINT_F("\n\r\tRecv'd data... Socket #"); - DEBUGPRINT_DEC(tSocketReadEvent.iSocketDescriptor); - DEBUGPRINT_F(" Bytes: 0x"); - DEBUGPRINT_HEX(tSocketReadEvent.iNumberOfBytes); - DEBUGPRINT_F(" Flags: 0x"); - DEBUGPRINT_HEX(tSocketReadEvent.uiFlags); - DEBUGPRINT_F("\n\r"); - // In case the number of bytes is more then zero - read data if (tSocketReadEvent.iNumberOfBytes > 0) { - // Wait for the data in a synchronous way. Here we assume that the bug is + // Wait for the data in a synchronous way. Here we assume that the bug is // big enough to store also parameters of receive from too.... - SimpleLinkWaitData((unsigned char *)buf, (unsigned char *)from, (unsigned char *)fromlen); + SimpleLinkWaitData(buf, (unsigned char *)from, (unsigned char *)fromlen); } - + + + errno = tSocketReadEvent.iNumberOfBytes; -#if (DEBUG_MODE == 1) - for (uint8_t i=0; i<errno; i++) { - putchar(((unsigned char *)buf)[i]); - } -#endif - return(tSocketReadEvent.iNumberOfBytes); } @@ -923,9 +903,9 @@ simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from, //! //! @param[in] sd socket handle //! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to +//! @param[in] len Specifies the length in bytes of the buffer pointed to //! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. +//! @param[in] flags Specifies the type of message reception. //! On this version, this parameter is not supported. //! //! @return Return the number of bytes received, or -1 if an error @@ -951,9 +931,9 @@ recv(long sd, void *buf, long len, long flags) //! //! @param[in] sd socket handle //! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to +//! @param[in] len Specifies the length in bytes of the buffer pointed to //! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. +//! @param[in] flags Specifies the type of message reception. //! On this version, this parameter is not supported. //! @param[in] from pointer to an address structure indicating the source //! address: sockaddr. On this version only AF_INET is @@ -1004,29 +984,29 @@ recvfrom(long sd, void *buf, long len, long flags, sockaddr *from, int simple_link_send(long sd, const void *buf, long len, long flags, const sockaddr *to, long tolen, long opcode) -{ +{ unsigned char uArgSize = 0, addrlen; unsigned char *ptr, *pDataPtr = NULL, *args; unsigned long addr_offset = 0; int res; tBsdReadReturnParams tSocketSendEvent; - + // Check the bsd_arguments if (0 != (res = HostFlowControlConsumeBuff(sd))) { return res; } - + //Update the number of sent packets tSLInformation.NumberOfSentPackets++; - + // Allocate a buffer and construct a packet and send it over spi ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_DATA); - + // Update the offset of data and parameters according to the command switch(opcode) - { + { case HCI_CMND_SENDTO: { addr_offset = len + sizeof(len) + sizeof(len); @@ -1035,7 +1015,7 @@ simple_link_send(long sd, const void *buf, long len, long flags, pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; break; } - + case HCI_CMND_SEND: { tolen = 0; @@ -1044,42 +1024,42 @@ simple_link_send(long sd, const void *buf, long len, long flags, pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; break; } - + default: { break; } } - + // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); args = UINT32_TO_STREAM(args, len); args = UINT32_TO_STREAM(args, flags); - + if (opcode == HCI_CMND_SENDTO) { args = UINT32_TO_STREAM(args, addr_offset); args = UINT32_TO_STREAM(args, addrlen); } - + // Copy the data received from user into the TX Buffer ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len); - + // In case we are using SendTo, copy the to parameters if (opcode == HCI_CMND_SENDTO) - { + { ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen); } - + // Initiate a HCI command hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen); - + if (opcode == HCI_CMND_SENDTO) SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent); else SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent); - + return (len); } @@ -1097,7 +1077,7 @@ simple_link_send(long sd, const void *buf, long len, long flags, //! error occurred //! //! @brief Write data to TCP socket -//! This function is used to transmit a message to another +//! This function is used to transmit a message to another //! socket. //! //! @Note On this version, only blocking mode is supported. @@ -1129,7 +1109,7 @@ send(long sd, const void *buf, long len, long flags) //! error occurred //! //! @brief Write data to TCP socket -//! This function is used to transmit a message to another +//! This function is used to transmit a message to another //! socket. //! //! @Note On this version, only blocking mode is supported. @@ -1153,9 +1133,9 @@ sendto(long sd, const void *buf, long len, long flags, const sockaddr *to, //! @param[in] deviceServiceName Service name as part of the published //! canonical domain name //! @param[in] deviceServiceNameLength Length of the service name -//! //! -//! @return On success, zero is returned, return SOC_ERROR if socket was not +//! +//! @return On success, zero is returned, return SOC_ERROR if socket was not //! opened successfully, or if an error occurred. //! //! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself. @@ -1165,31 +1145,31 @@ sendto(long sd, const void *buf, long len, long flags, const sockaddr *to, int mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength) { - char ret; + int ret; unsigned char *pTxBuffer, *pArgs; - + if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH) { return EFAIL; } - + pTxBuffer = tSLInformation.pucTxCommandBuffer; pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - + // Fill in HCI packet structure pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled); pArgs = UINT32_TO_STREAM(pArgs, 8); pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength); ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength); - + // Initiate a HCI command hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength); - + // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret); - + return ret; - + } #endif // MICROPY_HW_ENABLE_CC3K diff --git a/stmhal/cc3k/socket.h b/stmhal/cc3k/socket.h index 58e7ef13be..cb86609a05 100644 --- a/stmhal/cc3k/socket.h +++ b/stmhal/cc3k/socket.h @@ -3,14 +3,6 @@ * socket.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ @@ -91,7 +83,7 @@ extern "C" { //----------- Socket retunr codes ----------- -#define SOC_ERROR (-1) // error +#define SOC_ERROR (-1) // error #define SOC_IN_PROGRESS (-2) // socket in progress //----------- Socket Options ----------- @@ -99,12 +91,9 @@ extern "C" { #define SOCKOPT_RECV_NONBLOCK 0 // recv non block mode, set SOCK_ON or SOCK_OFF (default block mode) #define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout #define SOCKOPT_ACCEPT_NONBLOCK 2 // accept non block mode, set SOCK_ON or SOCK_OFF (default block mode) -#define SOCK_ON 0 // socket non-blocking mode is enabled +#define SOCK_ON 0 // socket non-blocking mode is enabled #define SOCK_OFF 1 // socket blocking mode is enabled -#define TCP_NODELAY 0x0001 -#define TCP_BSDURGENT 0x7000 - #define MAX_PACKET_SIZE 1500 #define MAX_LISTEN_QUEUE 4 @@ -118,10 +107,10 @@ extern "C" { #define __FD_SETSIZE 32 #define ASIC_ADDR_LEN 8 - + #define NO_QUERY_RECIVED -3 - - + + typedef struct _in_addr_t { unsigned long s_addr; // load with inet_aton() @@ -194,7 +183,7 @@ typedef struct #define FD_ZERO(fdsetp) __FD_ZERO (fdsetp) //Use in case of Big Endian only - + #define htonl(A) ((((unsigned long)(A) & 0xff000000) >> 24) | \ (((unsigned long)(A) & 0x00ff0000) >> 8) | \ (((unsigned long)(A) & 0x0000ff00) << 8) | \ @@ -209,13 +198,13 @@ typedef struct #define ntohs htons -// mDNS port - 5353 mDNS multicast address - 224.0.0.251 +// mDNS port - 5353 mDNS multicast address - 224.0.0.251 #define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \ sockaddr.sa_data[1] = 0xe9; \ sockaddr.sa_data[2] = 0xe0; \ sockaddr.sa_data[3] = 0x0; \ sockaddr.sa_data[4] = 0x0; \ - sockaddr.sa_data[5] = 0xfb; + sockaddr.sa_data[5] = 0xfb; //***************************************************************************** @@ -228,20 +217,20 @@ typedef struct // //! socket //! -//! @param domain selects the protocol family which will be used for +//! @param domain selects the protocol family which will be used for //! communication. On this version only AF_INET is supported -//! @param type specifies the communication semantics. On this version +//! @param type specifies the communication semantics. On this version //! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported -//! @param protocol specifies a particular protocol to be used with the -//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are +//! @param protocol specifies a particular protocol to be used with the +//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are //! supported. //! -//! @return On success, socket handle that is used for consequent socket +//! @return On success, socket handle that is used for consequent socket //! operations. On error, -1 is returned. //! //! @brief create an endpoint for communication -//! The socket function creates a socket that is bound to a specific -//! transport service provider. This function is called by the +//! The socket function creates a socket that is bound to a specific +//! transport service provider. This function is called by the //! application layer to obtain a socket handle. // //***************************************************************************** @@ -264,15 +253,15 @@ extern long closesocket(long sd); // //! accept //! -//! @param[in] sd socket descriptor (handle) +//! @param[in] sd socket descriptor (handle) //! @param[out] addr the argument addr is a pointer to a sockaddr structure -//! This structure is filled in with the address of the -//! peer socket, as known to the communications layer. -//! determined. The exact format of the address returned -//! addr is by the socket's address sockaddr. +//! This structure is filled in with the address of the +//! peer socket, as known to the communications layer. +//! determined. The exact format of the address returned +//! addr is by the socket's address sockaddr. //! On this version only AF_INET is supported. //! This argument returns in network order. -//! @param[out] addrlen the addrlen argument is a value-result argument: +//! @param[out] addrlen the addrlen argument is a value-result argument: //! it should initially contain the size of the structure //! pointed to by addr. //! @@ -284,21 +273,21 @@ extern long closesocket(long sd); //! - On failure, SOC_ERROR (-1) //! //! @brief accept a connection on a socket: -//! This function is used with connection-based socket types -//! (SOCK_STREAM). It extracts the first connection request on the +//! This function is used with connection-based socket types +//! (SOCK_STREAM). It extracts the first connection request on the //! queue of pending connections, creates a new connected socket, and //! returns a new file descriptor referring to that socket. -//! The newly created socket is not in the listening state. -//! The original socket sd is unaffected by this call. +//! The newly created socket is not in the listening state. +//! The original socket sd is unaffected by this call. //! The argument sd is a socket that has been created with socket(), -//! bound to a local address with bind(), and is listening for -//! connections after a listen(). The argument addr is a pointer -//! to a sockaddr structure. This structure is filled in with the +//! bound to a local address with bind(), and is listening for +//! connections after a listen(). The argument addr is a pointer +//! to a sockaddr structure. This structure is filled in with the //! address of the peer socket, as known to the communications layer. -//! The exact format of the address returned addr is determined by the +//! The exact format of the address returned addr is determined by the //! socket's address family. The addrlen argument is a value-result //! argument: it should initially contain the size of the structure -//! pointed to by addr, on return it will contain the actual +//! pointed to by addr, on return it will contain the actual //! length (in bytes) of the address returned. //! //! @sa socket ; bind ; listen @@ -310,8 +299,8 @@ extern long accept(long sd, sockaddr *addr, socklen_t *addrlen); // //! bind //! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr specifies the destination address. On this version +//! @param[in] sd socket descriptor (handle) +//! @param[out] addr specifies the destination address. On this version //! only AF_INET is supported. //! @param[out] addrlen contains the size of the structure pointed to by addr. //! @@ -319,8 +308,8 @@ extern long accept(long sd, sockaddr *addr, socklen_t *addrlen); //! //! @brief assign a name to a socket //! This function gives the socket the local address addr. -//! addr is addrlen bytes long. Traditionally, this is called when a -//! socket is created with socket, it exists in a name space (address +//! addr is addrlen bytes long. Traditionally, this is called when a +//! socket is created with socket, it exists in a name space (address //! family) but has no name assigned. //! It is necessary to assign a local address before a SOCK_STREAM //! socket may receive connections. @@ -334,7 +323,7 @@ extern long bind(long sd, const sockaddr *addr, long addrlen); // //! listen //! -//! @param[in] sd socket descriptor (handle) +//! @param[in] sd socket descriptor (handle) //! @param[in] backlog specifies the listen queue depth. On this version //! backlog is not supported. //! @return On success, zero is returned. On error, -1 is returned. @@ -345,7 +334,7 @@ extern long bind(long sd, const sockaddr *addr, long addrlen); //! and then the connections are accepted with accept. //! The listen() call applies only to sockets of type SOCK_STREAM //! The backlog parameter defines the maximum length the queue of -//! pending connections may grow to. +//! pending connections may grow to. //! //! @sa socket ; accept ; bind //! @@ -358,22 +347,22 @@ extern long listen(long sd, long backlog); // //! gethostbyname //! -//! @param[in] hostname host name -//! @param[in] usNameLen name length -//! @param[out] out_ip_addr This parameter is filled in with host IP address. -//! In case that host name is not resolved, -//! out_ip_addr is zero. +//! @param[in] hostname host name +//! @param[in] usNameLen name length +//! @param[out] out_ip_addr This parameter is filled in with host IP address. +//! In case that host name is not resolved, +//! out_ip_addr is zero. //! @return On success, positive is returned. On error, negative is returned //! -//! @brief Get host IP by name. Obtain the IP Address of machine on network, +//! @brief Get host IP by name. Obtain the IP Address of machine on network, //! by its name. //! //! @note On this version, only blocking mode is supported. Also note that //! the function requires DNS server to be configured prior to its usage. // //***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern int gethostbyname(const char * hostname, uint8_t usNameLen, uint32_t* out_ip_addr); +#ifndef CC3000_TINY_DRIVER +extern int gethostbyname(const char* hostname, unsigned short usNameLen, unsigned long* out_ip_addr); #endif @@ -381,25 +370,25 @@ extern int gethostbyname(const char * hostname, uint8_t usNameLen, uint32_t* out // //! connect //! -//! @param[in] sd socket descriptor (handle) +//! @param[in] sd socket descriptor (handle) //! @param[in] addr specifies the destination addr. On this version //! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr +//! @param[out] addrlen contains the size of the structure pointed to by addr //! @return On success, zero is returned. On error, -1 is returned //! -//! @brief initiate a connection on a socket -//! Function connects the socket referred to by the socket descriptor -//! sd, to the address specified by addr. The addrlen argument -//! specifies the size of addr. The format of the address in addr is -//! determined by the address space of the socket. If it is of type -//! SOCK_DGRAM, this call specifies the peer with which the socket is +//! @brief initiate a connection on a socket +//! Function connects the socket referred to by the socket descriptor +//! sd, to the address specified by addr. The addrlen argument +//! specifies the size of addr. The format of the address in addr is +//! determined by the address space of the socket. If it is of type +//! SOCK_DGRAM, this call specifies the peer with which the socket is //! to be associated; this address is that to which datagrams are to be -//! sent, and the only address from which datagrams are to be received. -//! If the socket is of type SOCK_STREAM, this call attempts to make a -//! connection to another socket. The other socket is specified by +//! sent, and the only address from which datagrams are to be received. +//! If the socket is of type SOCK_STREAM, this call attempts to make a +//! connection to another socket. The other socket is specified by //! address, which is an address in the communications space of the -//! socket. Note that the function implements only blocking behavior -//! thus the caller will be waiting either for the connection +//! socket. Note that the function implements only blocking behavior +//! thus the caller will be waiting either for the connection //! establishment or for the connection establishment failure. //! //! @sa socket @@ -412,12 +401,12 @@ extern long connect(long sd, const sockaddr *addr, long addrlen); //! select //! //! @param[in] nfds the highest-numbered file descriptor in any of the -//! three sets, plus 1. +//! three sets, plus 1. //! @param[out] writesds socket descriptors list for write monitoring -//! @param[out] readsds socket descriptors list for read monitoring +//! @param[out] readsds socket descriptors list for read monitoring //! @param[out] exceptsds socket descriptors list for exception monitoring //! @param[in] timeout is an upper bound on the amount of time elapsed -//! before select() returns. Null means infinity +//! before select() returns. Null means infinity //! timeout. The minimum timeout is 5 milliseconds, //! less than 5 milliseconds will be set //! automatically to 5 milliseconds. @@ -429,14 +418,14 @@ extern long connect(long sd, const sockaddr *addr, long addrlen); //! On error, -1 is returned. //! *readsds - return the sockets on which Read request will //! return without delay with valid data. -//! *writesds - return the sockets on which Write request +//! *writesds - return the sockets on which Write request //! will return without delay. //! *exceptsds - return the sockets which closed recently. //! -//! @brief Monitor socket activity +//! @brief Monitor socket activity //! Select allow a program to monitor multiple file descriptors, -//! waiting until one or more of the file descriptors become -//! "ready" for some class of I/O operation +//! waiting until one or more of the file descriptors become +//! "ready" for some class of I/O operation //! //! @Note If the timeout value set to less than 5ms it will automatically set //! to 5ms to prevent overload of the system @@ -462,38 +451,38 @@ extern int select(long nfds, fd_set *readsds, fd_set *writesds, //! This function manipulate the options associated with a socket. //! Options may exist at multiple protocol levels; they are always //! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - +//! When manipulating socket options the level at which the option +//! resides and the name of the option must be specified. +//! To manipulate options at the socket level, level is specified as +//! SOL_SOCKET. To manipulate options at any other level the protocol +//! number of the appropriate protocol controlling the option is +//! supplied. For example, to indicate that an option is to be +//! interpreted by the TCP protocol, level should be set to the +//! protocol number of TCP; +//! The parameters optval and optlen are used to access optval - //! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option +//! in which the value for the requested option(s) are to +//! be returned. For getsockopt(), optlen is a value-result +//! parameter, initially containing the size of the buffer +//! pointed to by option_value, and modified on return to +//! indicate the actual size of the value returned. If no option //! value is to be supplied or returned, option_value may be NULL. //! //! @Note On this version the following two socket options are enabled: //! The only protocol level supported in this version //! is SOL_SOCKET (level). //! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout +//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout //! in milliseconds. //! In that case optval should be pointer to unsigned long. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on +//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on //! or off. //! In that case optval should be SOCK_ON or SOCK_OFF (optval). //! //! @sa getsockopt // //***************************************************************************** -#ifndef CC3000_TINY_DRIVER +#ifndef CC3000_TINY_DRIVER extern int setsockopt(long sd, long level, long optname, const void *optval, socklen_t optlen); #endif @@ -512,31 +501,31 @@ extern int setsockopt(long sd, long level, long optname, const void *optval, //! This function manipulate the options associated with a socket. //! Options may exist at multiple protocol levels; they are always //! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - +//! When manipulating socket options the level at which the option +//! resides and the name of the option must be specified. +//! To manipulate options at the socket level, level is specified as +//! SOL_SOCKET. To manipulate options at any other level the protocol +//! number of the appropriate protocol controlling the option is +//! supplied. For example, to indicate that an option is to be +//! interpreted by the TCP protocol, level should be set to the +//! protocol number of TCP; +//! The parameters optval and optlen are used to access optval - //! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option +//! in which the value for the requested option(s) are to +//! be returned. For getsockopt(), optlen is a value-result +//! parameter, initially containing the size of the buffer +//! pointed to by option_value, and modified on return to +//! indicate the actual size of the value returned. If no option //! value is to be supplied or returned, option_value may be NULL. //! //! @Note On this version the following two socket options are enabled: //! The only protocol level supported in this version //! is SOL_SOCKET (level). //! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout +//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout //! in milliseconds. //! In that case optval should be pointer to unsigned long. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on +//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on //! or off. //! In that case optval should be SOCK_ON or SOCK_OFF (optval). //! @@ -552,9 +541,9 @@ extern int getsockopt(long sd, long level, long optname, void *optval, //! //! @param[in] sd socket handle //! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to +//! @param[in] len Specifies the length in bytes of the buffer pointed to //! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. +//! @param[in] flags Specifies the type of message reception. //! On this version, this parameter is not supported. //! //! @return Return the number of bytes received, or -1 if an error @@ -575,9 +564,9 @@ extern int recv(long sd, void *buf, long len, long flags); //! //! @param[in] sd socket handle //! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to +//! @param[in] len Specifies the length in bytes of the buffer pointed to //! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. +//! @param[in] flags Specifies the type of message reception. //! On this version, this parameter is not supported. //! @param[in] from pointer to an address structure indicating the source //! address: sockaddr. On this version only AF_INET is @@ -597,7 +586,7 @@ extern int recv(long sd, void *buf, long len, long flags); //! @Note On this version, only blocking mode is supported. // //***************************************************************************** -extern int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from, +extern int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from, socklen_t *fromlen); //***************************************************************************** @@ -613,7 +602,7 @@ extern int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from, //! error occurred //! //! @brief Write data to TCP socket -//! This function is used to transmit a message to another +//! This function is used to transmit a message to another //! socket. //! //! @Note On this version, only blocking mode is supported. @@ -641,7 +630,7 @@ extern int send(long sd, const void *buf, long len, long flags); //! error occurred //! //! @brief Write data to TCP socket -//! This function is used to transmit a message to another +//! This function is used to transmit a message to another //! socket. //! //! @Note On this version, only blocking mode is supported. @@ -650,7 +639,7 @@ extern int send(long sd, const void *buf, long len, long flags); // //***************************************************************************** -extern int sendto(long sd, const void *buf, long len, long flags, +extern int sendto(long sd, const void *buf, long len, long flags, const sockaddr *to, socklen_t tolen); //***************************************************************************** @@ -661,9 +650,9 @@ extern int sendto(long sd, const void *buf, long len, long flags, //! @param[in] deviceServiceName Service name as part of the published //! canonical domain name //! @param[in] deviceServiceNameLength Length of the service name -//! //! -//! @return On success, zero is returned, return SOC_ERROR if socket was not +//! +//! @return On success, zero is returned, return SOC_ERROR if socket was not //! opened successfully, or if an error occurred. //! //! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself. diff --git a/stmhal/cc3k/wlan.c b/stmhal/cc3k/wlan.c index b22796a7c8..4300bd995c 100644 --- a/stmhal/cc3k/wlan.c +++ b/stmhal/cc3k/wlan.c @@ -3,14 +3,6 @@ * wlan.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! - * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -60,7 +52,6 @@ #include "nvmem.h" #include "security.h" #include "evnt_handler.h" -#include "ccdebug.h" extern int errno; @@ -133,13 +124,12 @@ static void SimpleLink_Init_Start(unsigned short usPatchesAvailableAtHost) ptr = tSLInformation.pucTxCommandBuffer; args = (unsigned char *)(ptr + HEADERS_SIZE_CMD); - if (usPatchesAvailableAtHost > 2) - usPatchesAvailableAtHost = 2; - UINT8_TO_STREAM(args, usPatchesAvailableAtHost); + UINT8_TO_STREAM(args, ((usPatchesAvailableAtHost) ? SL_PATCHES_REQUEST_FORCE_NONE : SL_PATCHES_REQUEST_DEFAULT)); // IRQ Line asserted - send HCI_CMND_SIMPLE_LINK_START to CC3000 hci_command_send(HCI_CMND_SIMPLE_LINK_START, ptr, WLAN_SL_INIT_START_PARAMS_LEN); + SimpleLinkWaitEvent(HCI_CMND_SIMPLE_LINK_START, 0); } @@ -294,7 +284,7 @@ wlan_start(unsigned short usPatchesAvailableAtHost) // Check the IRQ line ulSpiIRQState = tSLInformation.ReadWlanInterruptPin(); - // ASIC 1273 chip enable: toggle WLAN EN line + // Chip enable: toggle WLAN EN line tSLInformation.WriteWlanPin( WLAN_ENABLE ); if (ulSpiIRQState) @@ -315,11 +305,9 @@ wlan_start(unsigned short usPatchesAvailableAtHost) { } } - DEBUGPRINT_F("SimpleLink start\n\r"); SimpleLink_Init_Start(usPatchesAvailableAtHost); // Read Buffer's size and finish - DEBUGPRINT_F("Read buffer\n\r"); hci_command_send(HCI_CMND_READ_BUFFER_SIZE, tSLInformation.pucTxCommandBuffer, 0); SimpleLinkWaitEvent(HCI_CMND_READ_BUFFER_SIZE, 0); } @@ -342,7 +330,7 @@ wlan_start(unsigned short usPatchesAvailableAtHost) void wlan_stop(void) { - // ASIC 1273 chip disable + // Chip disable tSLInformation.WriteWlanPin( WLAN_DISABLE ); // Wait till IRQ line goes high... @@ -371,7 +359,7 @@ wlan_stop(void) //! @param ssid up to 32 bytes and is ASCII SSID of the AP //! @param ssid_len length of the SSID //! @param bssid 6 bytes specified the AP bssid -//! @param key up to 16 bytes specified the AP security key +//! @param key up to 32 bytes specified the AP security key //! @param key_len key length //! //! @return On success, zero is returned. On error, negative is returned. @@ -576,13 +564,17 @@ wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, //! @param ulSsidLen ssid length //! @param ucBssid bssid 6 bytes //! @param ulPriority ulPriority profile priority. Lowest priority:0. +//! Important Note: Smartconfig process (in unencrypted mode) +//! stores the profile internally with priority 1, so changing +//! priorities when adding new profiles should be done with extra care //! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security //! @param ulGroupCipher_TxKeyIndex key index //! @param ulKeyMgmt KEY management //! @param ucPf_OrKey security key //! @param ulPassPhraseLen security key length for WPA\WPA2 //! -//! @return On success, zero is returned. On error, -1 is returned +//! @return On success, index (1-7) of the stored profile is returned. +//! On error, -1 is returned. //! //! @brief When auto start is enabled, the device connects to //! station from the profiles table. Up to 7 profiles are supported. diff --git a/stmhal/cc3k/wlan.h b/stmhal/cc3k/wlan.h index d5ccd363f5..2f5d5303c7 100644 --- a/stmhal/cc3k/wlan.h +++ b/stmhal/cc3k/wlan.h @@ -3,14 +3,6 @@ * wlan.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * -* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) -* & Limor Fried for Adafruit Industries -* This library works with the Adafruit CC3000 breakout -* ----> https://www.adafruit.com/products/1469 -* Adafruit invests time and resources providing this open source code, -* please support Adafruit and open-source hardware by purchasing -* products from Adafruit! -* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,33 +12,25 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - -Adapted for use with the Arduino/AVR by KTOWN for Adafruit Industries -This library works with the Adafruit CC3000 breakout - ----> https://www.adafruit.com/products/1469 -Adafruit invests time and resources providing this open source code, -please support Adafruit and open-source hardware by purchasing -products from Adafruit! - *****************************************************************************/ #ifndef __WLAN_H__ #define __WLAN_H__ @@ -79,41 +63,41 @@ extern "C" { // //! wlan_init //! -//! @param sWlanCB Asynchronous events callback. +//! @param sWlanCB Asynchronous events callback. //! 0 no event call back. //! -call back parameters: //! 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event, //! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event, //! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done, -//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report, -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR +//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report, +//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR //! HCI_EVNT_WLAN_KEEPALIVE keepalive. //! 2) data: pointer to extra data that received by the event //! (NULL no data). //! 3) length: data length. //! -Events with extra data: -//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask, +//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask, //! 4 bytes default gateway, 4 bytes DHCP server and 4 bytes //! for DNS server. -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent, -//! 4 bytes Packets received, 4 bytes Min round time, +//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent, +//! 4 bytes Packets received, 4 bytes Min round time, //! 4 bytes Max round time and 4 bytes for Avg round time. //! -//! @param sFWPatches 0 no patch or pointer to FW patches +//! @param sFWPatches 0 no patch or pointer to FW patches //! @param sDriverPatches 0 no patch or pointer to driver patches //! @param sBootLoaderPatches 0 no patch or pointer to bootloader patches -//! @param sReadWlanInterruptPin init callback. the callback read wlan +//! @param sReadWlanInterruptPin init callback. the callback read wlan //! interrupt status. -//! @param sWlanInterruptEnable init callback. the callback enable wlan +//! @param sWlanInterruptEnable init callback. the callback enable wlan //! interrupt. //! @param sWlanInterruptDisable init callback. the callback disable wlan //! interrupt. -//! @param sWriteWlanPin init callback. the callback write value -//! to device pin. +//! @param sWriteWlanPin init callback. the callback write value +//! to device pin. //! //! @return none //! -//! @sa wlan_set_event_mask , wlan_start , wlan_stop +//! @sa wlan_set_event_mask , wlan_start , wlan_stop //! //! @brief Initialize wlan driver //! @@ -136,22 +120,22 @@ extern void wlan_init( tWlanCB sWlanCB, //! wlan_start //! //! @param usPatchesAvailableAtHost - flag to indicate if patches available -//! from host or from EEPROM. Due to the +//! from host or from EEPROM. Due to the //! fact the patches are burn to the EEPROM -//! using the patch programmer utility, the +//! using the patch programmer utility, the //! patches will be available from the EEPROM //! and not from the host. //! //! @return none //! -//! @brief Start WLAN device. This function asserts the enable pin of +//! @brief Start WLAN device. This function asserts the enable pin of //! the device (WLAN_EN), starting the HW initialization process. //! The function blocked until device Initialization is completed. -//! Function also configure patches (FW, driver or bootloader) +//! Function also configure patches (FW, driver or bootloader) //! and calls appropriate device callbacks. //! //! @Note Prior calling the function wlan_init shall be called. -//! @Warning This function must be called after wlan_init and before any +//! @Warning This function must be called after wlan_init and before any //! other wlan API //! @sa wlan_init , wlan_stop //! @@ -179,23 +163,23 @@ extern void wlan_stop(void); //! wlan_connect //! //! @param sec_type security options: -//! WLAN_SEC_UNSEC, +//! WLAN_SEC_UNSEC, //! WLAN_SEC_WEP (ASCII support only), //! WLAN_SEC_WPA or WLAN_SEC_WPA2 //! @param ssid up to 32 bytes and is ASCII SSID of the AP //! @param ssid_len length of the SSID //! @param bssid 6 bytes specified the AP bssid -//! @param key up to 16 bytes specified the AP security key -//! @param key_len key length +//! @param key up to 32 bytes specified the AP security key +//! @param key_len key length //! -//! @return On success, zero is returned. On error, negative is returned. +//! @return On success, zero is returned. On error, negative is returned. //! Note that even though a zero is returned on success to trigger //! connection operation, it does not mean that CCC3000 is already -//! connected. An asynchronous "Connected" event is generated when +//! connected. An asynchronous "Connected" event is generated when //! actual association process finishes and CC3000 is connected to -//! the AP. If DHCP is set, An asynchronous "DHCP" event is +//! the AP. If DHCP is set, An asynchronous "DHCP" event is //! generated when DHCP process is finish. -//! +//! //! //! @brief Connect to AP //! @warning Please Note that when connection to AP configured with security @@ -216,9 +200,9 @@ extern long wlan_connect(const char *ssid, long ssid_len); // //! wlan_disconnect //! -//! @return 0 disconnected done, other CC3000 already disconnected +//! @return 0 disconnected done, other CC3000 already disconnected //! -//! @brief Disconnect connection from AP. +//! @brief Disconnect connection from AP. //! //! @sa wlan_connect // @@ -237,25 +221,25 @@ extern long wlan_disconnect(void); //! @param ulPriority ulPriority profile priority. Lowest priority:0. //! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security //! @param ulGroupCipher_TxKeyIndex key index -//! @param ulKeyMgmt KEY management +//! @param ulKeyMgmt KEY management //! @param ucPf_OrKey security key //! @param ulPassPhraseLen security key length for WPA\WPA2 //! -//! @return On success, zero is returned. On error, -1 is returned +//! @return On success, zero is returned. On error, -1 is returned //! //! @brief When auto start is enabled, the device connects to -//! station from the profiles table. Up to 7 profiles are supported. -//! If several profiles configured the device choose the highest -//! priority profile, within each priority group, device will choose -//! profile based on security policy, signal strength, etc +//! station from the profiles table. Up to 7 profiles are supported. +//! If several profiles configured the device choose the highest +//! priority profile, within each priority group, device will choose +//! profile based on security policy, signal strength, etc //! parameters. All the profiles are stored in CC3000 NVMEM. //! -//! @sa wlan_ioctl_del_profile +//! @sa wlan_ioctl_del_profile // //***************************************************************************** extern long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid, - unsigned long ulSsidLen, + unsigned long ulSsidLen, unsigned char *ucBssid, unsigned long ulPriority, unsigned long ulPairwiseCipher_Or_Key, @@ -272,13 +256,13 @@ extern long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid, //! //! @param index number of profile to delete //! -//! @return On success, zero is returned. On error, -1 is returned +//! @return On success, zero is returned. On error, -1 is returned //! -//! @brief Delete WLAN profile +//! @brief Delete WLAN profile //! //! @Note In order to delete all stored profile, set index to 255. //! -//! @sa wlan_add_profile +//! @sa wlan_add_profile // //***************************************************************************** extern long wlan_ioctl_del_profile(unsigned long ulIndex); @@ -298,10 +282,10 @@ extern long wlan_ioctl_del_profile(unsigned long ulIndex); //! HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission //! Saved: no. //! -//! @return On success, zero is returned. On error, -1 is returned +//! @return On success, zero is returned. On error, -1 is returned //! -//! @brief Mask event according to bit mask. In case that event is -//! masked (1), the device will not send the masked event to host. +//! @brief Mask event according to bit mask. In case that event is +//! masked (1), the device will not send the masked event to host. // //***************************************************************************** extern long wlan_set_event_mask(unsigned long ulMask); @@ -310,10 +294,10 @@ extern long wlan_set_event_mask(unsigned long ulMask); // //! wlan_ioctl_statusget //! -//! @param none +//! @param none //! -//! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, -//! STATUS_CONNECTING or WLAN_STATUS_CONNECTED +//! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, +//! STATUS_CONNECTING or WLAN_STATUS_CONNECTED //! //! @brief get wlan status: disconnected, scanning, connecting or connected // @@ -325,31 +309,31 @@ extern long wlan_ioctl_statusget(void); // //! wlan_ioctl_set_connection_policy //! -//! @param should_connect_to_open_ap enable(1), disable(0) connect to any -//! available AP. This parameter corresponds to the configuration of +//! @param should_connect_to_open_ap enable(1), disable(0) connect to any +//! available AP. This parameter corresponds to the configuration of //! item # 3 in the brief description. -//! @param should_use_fast_connect enable(1), disable(0). if enabled, tries -//! to connect to the last connected AP. This parameter corresponds +//! @param should_use_fast_connect enable(1), disable(0). if enabled, tries +//! to connect to the last connected AP. This parameter corresponds //! to the configuration of item # 1 in the brief description. -//! @param auto_start enable(1), disable(0) auto connect -//! after reset and periodically reconnect if needed. This +//! @param auto_start enable(1), disable(0) auto connect +//! after reset and periodically reconnect if needed. This //! configuration configures option 2 in the above description. //! -//! @return On success, zero is returned. On error, -1 is returned +//! @return On success, zero is returned. On error, -1 is returned //! -//! @brief When auto is enabled, the device tries to connect according +//! @brief When auto is enabled, the device tries to connect according //! the following policy: -//! 1) If fast connect is enabled and last connection is valid, -//! the device will try to connect to it without the scanning +//! 1) If fast connect is enabled and last connection is valid, +//! the device will try to connect to it without the scanning //! procedure (fast). The last connection will be marked as -//! invalid, due to adding/removing profile. -//! 2) If profile exists, the device will try to connect it +//! invalid, due to adding/removing profile. +//! 2) If profile exists, the device will try to connect it //! (Up to seven profiles). //! 3) If fast and profiles are not found, and open mode is //! enabled, the device will try to connect to any AP. //! * Note that the policy settings are stored in the CC3000 NVMEM. //! -//! @sa wlan_add_profile , wlan_ioctl_del_profile +//! @sa wlan_add_profile , wlan_ioctl_del_profile // //***************************************************************************** extern long wlan_ioctl_set_connection_policy( @@ -364,30 +348,30 @@ extern long wlan_ioctl_set_connection_policy( //! @param[in] scan_timeout parameter not supported //! @param[out] ucResults scan result (_wlan_full_scan_results_args_t) //! -//! @return On success, zero is returned. On error, -1 is returned +//! @return On success, zero is returned. On error, -1 is returned //! //! @brief Gets entry from scan result table. -//! The scan results are returned one by one, and each entry -//! represents a single AP found in the area. The following is a -//! format of the scan result: +//! The scan results are returned one by one, and each entry +//! represents a single AP found in the area. The following is a +//! format of the scan result: //! - 4 Bytes: number of networks found //! - 4 Bytes: The status of the scan: 0 - aged results, //! 1 - results valid, 2 - no results //! - 42 bytes: Result entry, where the bytes are arranged as follows: -//! +//! //! - 1 bit isValid - is result valid or not -//! - 7 bits rssi - RSSI value; +//! - 7 bits rssi - RSSI value; //! - 2 bits: securityMode - security mode of the AP: //! 0 - Open, 1 - WEP, 2 WPA, 3 WPA2 //! - 6 bits: SSID name length -//! - 2 bytes: the time at which the entry has entered into +//! - 2 bytes: the time at which the entry has entered into //! scans result table //! - 32 bytes: SSID name -//! - 6 bytes: BSSID +//! - 6 bytes: BSSID //! //! @Note scan_timeout, is not supported on this version. //! -//! @sa wlan_ioctl_set_scan_params +//! @sa wlan_ioctl_set_scan_params // //***************************************************************************** @@ -399,59 +383,59 @@ extern long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, // //! wlan_ioctl_set_scan_params //! -//! @param uiEnable - start/stop application scan: -//! 1 = start scan with default interval value of 10 min. -//! in order to set a different scan interval value apply the value +//! @param uiEnable - start/stop application scan: +//! 1 = start scan with default interval value of 10 min. +//! in order to set a different scan interval value apply the value //! in milliseconds. minimum 1 second. 0=stop). Wlan reset //! (wlan_stop() wlan_start()) is needed when changing scan interval //! value. Saved: No -//! @param uiMinDwellTime minimum dwell time value to be used for each +//! @param uiMinDwellTime minimum dwell time value to be used for each //! channel, in milliseconds. Saved: yes //! Recommended Value: 100 (Default: 20) //! @param uiMaxDwellTime maximum dwell time value to be used for each //! channel, in milliseconds. Saved: yes //! Recommended Value: 100 (Default: 30) -//! @param uiNumOfProbeRequests max probe request between dwell time. +//! @param uiNumOfProbeRequests max probe request between dwell time. //! Saved: yes. Recommended Value: 5 (Default:2) -//! @param uiChannelMask bitwise, up to 13 channels (0x1fff). +//! @param uiChannelMask bitwise, up to 13 channels (0x1fff). //! Saved: yes. Default: 0x7ff //! @param uiRSSIThreshold RSSI threshold. Saved: yes (Default: -80) //! @param uiSNRThreshold NSR threshold. Saved: yes (Default: 0) //! @param uiDefaultTxPower probe Tx power. Saved: yes (Default: 205) -//! @param aiIntervalList pointer to array with 16 entries (16 channels) -//! each entry (unsigned long) holds timeout between periodic scan +//! @param aiIntervalList pointer to array with 16 entries (16 channels) +//! each entry (unsigned long) holds timeout between periodic scan //! (connection scan) - in milliseconds. Saved: yes. Default 2000ms. //! -//! @return On success, zero is returned. On error, -1 is returned +//! @return On success, zero is returned. On error, -1 is returned //! -//! @brief start and stop scan procedure. Set scan parameters. +//! @brief start and stop scan procedure. Set scan parameters. //! //! @Note uiDefaultTxPower, is not supported on this version. //! -//! @sa wlan_ioctl_get_scan_results +//! @sa wlan_ioctl_get_scan_results // //***************************************************************************** -extern long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long +extern long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long uiMinDwellTime,unsigned long uiMaxDwellTime, unsigned long uiNumOfProbeRequests, unsigned long uiChannelMask, long iRSSIThreshold,unsigned long uiSNRThreshold, - unsigned long uiDefaultTxPower, + unsigned long uiDefaultTxPower, unsigned long *aiIntervalList); - + //***************************************************************************** // //! wlan_smart_config_start //! //! @param algoEncryptedFlag indicates whether the information is encrypted //! -//! @return On success, zero is returned. On error, -1 is returned +//! @return On success, zero is returned. On error, -1 is returned //! -//! @brief Start to acquire device profile. The device acquire its own +//! @brief Start to acquire device profile. The device acquire its own //! profile, if profile message is found. The acquired AP information //! is stored in CC3000 EEPROM only in case AES128 encryption is used. -//! In case AES128 encryption is not used, a profile is created by +//! In case AES128 encryption is not used, a profile is created by //! CC3000 internally. //! //! @Note An asynchronous event - Smart Config Done will be generated as soon @@ -459,7 +443,7 @@ extern long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long //! //! @sa wlan_smart_config_set_prefix , wlan_smart_config_stop // -//***************************************************************************** +//***************************************************************************** extern long wlan_smart_config_start(unsigned long algoEncryptedFlag); @@ -469,9 +453,9 @@ extern long wlan_smart_config_start(unsigned long algoEncryptedFlag); //! //! @param algoEncryptedFlag indicates whether the information is encrypted //! -//! @return On success, zero is returned. On error, -1 is returned +//! @return On success, zero is returned. On error, -1 is returned //! -//! @brief Stop the acquire profile procedure +//! @brief Stop the acquire profile procedure //! //! @sa wlan_smart_config_start , wlan_smart_config_set_prefix // @@ -482,11 +466,11 @@ extern long wlan_smart_config_stop(void); // //! wlan_smart_config_set_prefix //! -//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config. +//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config. //! -//! @return On success, zero is returned. On error, -1 is returned +//! @return On success, zero is returned. On error, -1 is returned //! -//! @brief Configure station ssid prefix. The prefix is used internally +//! @brief Configure station ssid prefix. The prefix is used internally //! in CC3000. It should always be TTT. //! //! @Note The prefix is stored in CC3000 NVMEM @@ -500,11 +484,11 @@ extern long wlan_smart_config_set_prefix(char* cNewPrefix); // //! wlan_smart_config_process //! -//! @param none +//! @param none //! -//! @return On success, zero is returned. On error, -1 is returned +//! @return On success, zero is returned. On error, -1 is returned //! -//! @brief process the acquired data and store it as a profile. The acquired +//! @brief process the acquired data and store it as a profile. The acquired //! AP information is stored in CC3000 EEPROM encrypted. //! The encrypted data is decrypted and stored as a profile. //! behavior is as defined by connection policy. diff --git a/stmhal/main.c b/stmhal/main.c index ac5e82ab9e..a0ee4dab44 100644 --- a/stmhal/main.c +++ b/stmhal/main.c @@ -35,6 +35,7 @@ #include "mpconfig.h" #include "qstr.h" #include "misc.h" +#include "nlr.h" #include "lexer.h" #include "parse.h" #include "obj.h" @@ -549,3 +550,13 @@ soft_reset: first_soft_reset = false; goto soft_reset; } + +STATIC NORETURN mp_obj_t mp_sys_exit(uint n_args, const mp_obj_t *args) { + int rc = 0; + if (n_args > 0) { + rc = mp_obj_get_int(args[0]); + } + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NotImplementedError, + "sys.exit(%d) called, is not fully implemented", rc)); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit); diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h index 0a99128bf0..43ef27f874 100644 --- a/stmhal/mpconfigport.h +++ b/stmhal/mpconfigport.h @@ -45,6 +45,7 @@ #define MICROPY_ENABLE_LFN (1) #define MICROPY_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ #define MICROPY_MOD_SYS_STDFILES (1) +#define MICROPY_SYS_EXIT (1) #define MICROPY_ENABLE_MOD_CMATH (1) // extra built in names to add to the global namespace diff --git a/stmhal/pybwlan.c b/stmhal/pybwlan.c index 46a3fbab03..15221091f1 100644 --- a/stmhal/pybwlan.c +++ b/stmhal/pybwlan.c @@ -136,33 +136,42 @@ mp_obj_t pyb_wlan_get_host(mp_obj_t host_name) { } mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) { - if (host_name == mp_const_none) { - last_ip = (192 << 24) | (168 << 16) | (0 << 8) | (3); + int port; + if (mp_obj_is_integer(host_name)) { + last_ip = (192 << 24) | (168 << 16) | (0 << 8) | (mp_obj_get_int(host_name)); + port = 8080; } else { if (pyb_wlan_get_host(host_name) == mp_const_none) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "unknown host")); } + port = 80; } int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sd < 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "socket failed: %d", sd)); } - //printf("socket seemed to work\n"); - //HAL_Delay(200); + + printf("socket seemed to work\n"); + sockaddr_in remote; memset(&remote, 0, sizeof(sockaddr_in)); remote.sin_family = AF_INET; - remote.sin_port = htons(80); + remote.sin_port = htons(port); remote.sin_addr.s_addr = htonl(last_ip); int ret = connect(sd, (sockaddr*)&remote, sizeof(sockaddr)); if (ret != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "connect failed: %d", ret)); } - //printf("connect seemed to work\n"); - //HAL_Delay(200); + + printf("connect seemed to work\n"); vstr_t *vstr = vstr_new(); - vstr_printf(vstr, "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: PYBv2\r\n\r\n", mp_obj_str_get_str(host_path), mp_obj_str_get_qstr(host_name)); + //vstr_printf(vstr, "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: PYBv2\r\n\r\n", mp_obj_str_get_str(host_path), mp_obj_str_get_str(host_name)); + if (mp_obj_is_integer(host_name)) { + vstr_printf(vstr, "GET %s HTTP/1.1\r\nHost: localhost\r\n\r\n", mp_obj_str_get_str(host_path)); + } else { + vstr_printf(vstr, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", mp_obj_str_get_str(host_path), mp_obj_str_get_str(host_name)); + } const char *query = vstr_str(vstr); // send query @@ -173,24 +182,49 @@ mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) { extern void SpiIntGPIOHandler(void); SpiIntGPIOHandler(); */ - //printf("sending %d bytes\n", strlen(query + sent)); - ret = send(sd, query + sent, strlen(query + sent), 0); - //printf("sent %d bytes\n", ret); + + // do a select() call on this socket + timeval timeout; + fd_set fd_write; + + FD_ZERO(&fd_write); + FD_SET(sd, &fd_write); + + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + printf("send select\n"); + int s = select(sd + 1, NULL, &fd_write, NULL, &timeout); + printf("send select returned %d\n", s); + if (s < 0) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "select failed %d", s)); + } else if (s == 0) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "send not ready")); + } + + printf("sending %d bytes\n", strlen(query + sent)); + int ret = send(sd, query + sent, strlen(query + sent), 0); + printf("sent %d bytes\n", ret); if (ret < 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "send failed")); } + + if (ret > strlen(query + sent)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "send sent too much")); + } sent += ret; + //HAL_Delay(200); } } - //printf("send seemed to work!\n"); + printf("send seemed to work!\n"); //HAL_Delay(5000); // receive reply mp_obj_t mp_ret = mp_const_none; { - //printf("doing receive\n"); + printf("doing receive\n"); char buf[64]; vstr_reset(vstr); @@ -202,20 +236,26 @@ mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) { memset(&fd_read, 0, sizeof(fd_read)); FD_SET(sd, &fd_read); - timeout.tv_sec = 0; - timeout.tv_usec = 500000; // 500 millisec + timeout.tv_sec = 1; + timeout.tv_usec = 0; - int s = select(sd+1, &fd_read, NULL, NULL, &timeout); - if (s == 0) { + printf("recv select\n"); + int s = select(sd + 1, &fd_read, NULL, NULL, &timeout); + printf("recv select done %d\n", s); + if (s < 0) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "select failed %d", s)); + } else if (s == 0) { // no data available + printf("no data!\n"); break; } // read data ret = recv(sd, buf, 64, 0); - if (ret < 0) { + if (ret <= 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "recv failed %d", ret)); } + printf("recv data: %.*s\n", ret, buf); vstr_add_strn(vstr, buf, ret); } diff --git a/stmhal/pyexec.c b/stmhal/pyexec.c index 166f0a6d15..45928427e1 100644 --- a/stmhal/pyexec.c +++ b/stmhal/pyexec.c @@ -163,7 +163,11 @@ raw_repl_reset: } mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0); - parse_compile_execute(lex, MP_PARSE_FILE_INPUT, false); + if (lex == NULL) { + printf("MemoryError\n"); + } else { + parse_compile_execute(lex, MP_PARSE_FILE_INPUT, false); + } // indicate end of output with EOF character stdout_tx_str("\004"); @@ -239,7 +243,11 @@ friendly_repl_reset: } mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0); - parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, true); + if (lex == NULL) { + printf("MemoryError\n"); + } else { + parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, true); + } } } diff --git a/stmhal/readline.c b/stmhal/readline.c index fa04f8a49d..d40bd4219b 100644 --- a/stmhal/readline.c +++ b/stmhal/readline.c @@ -55,11 +55,13 @@ void readline_init(void) { memset(readline_hist, 0, READLINE_HIST_SIZE * sizeof(const char*)); } -STATIC char *str_dup(const char *str) { +STATIC char *str_dup_maybe(const char *str) { uint32_t len = strlen(str); - char *s2 = m_new(char, len + 1); - memcpy(s2, str, len); - s2[len] = 0; + char *s2 = m_new_maybe(char, len + 1); + if (s2 == NULL) { + return NULL; + } + memcpy(s2, str, len + 1); return s2; } @@ -92,10 +94,13 @@ int readline(vstr_t *line, const char *prompt) { if (line->len > orig_line_len && (readline_hist[0] == NULL || strcmp(readline_hist[0], line->buf + orig_line_len) != 0)) { // a line which is not empty and different from the last one // so update the history - for (int i = READLINE_HIST_SIZE - 1; i > 0; i--) { - readline_hist[i] = readline_hist[i - 1]; + char *most_recent_hist = str_dup_maybe(line->buf + orig_line_len); + if (most_recent_hist != NULL) { + for (int i = READLINE_HIST_SIZE - 1; i > 0; i--) { + readline_hist[i] = readline_hist[i - 1]; + } + readline_hist[0] = most_recent_hist; } - readline_hist[0] = str_dup(line->buf + orig_line_len); } return 0; } else if (c == 27) { diff --git a/stmhal/rtc.c b/stmhal/rtc.c index 33982e9d5f..412816c396 100644 --- a/stmhal/rtc.c +++ b/stmhal/rtc.c @@ -214,26 +214,26 @@ void rtc_init(void) { static void RTC_CalendarConfig(void) { // set the date to 1st Jan 2014 RTC_DateTypeDef date; - date.Year = 0x14; - date.Month = RTC_MONTH_JANUARY; - date.Date = 0x01; + date.Year = 14; + date.Month = 1; + date.Date = 1; date.WeekDay = RTC_WEEKDAY_WEDNESDAY; - if(HAL_RTC_SetDate(&RTCHandle, &date, FORMAT_BCD) != HAL_OK) { + if(HAL_RTC_SetDate(&RTCHandle, &date, FORMAT_BIN) != HAL_OK) { // init error return; } // set the time to 00:00:00 RTC_TimeTypeDef time; - time.Hours = 0x00; - time.Minutes = 0x00; - time.Seconds = 0x00; + time.Hours = 0; + time.Minutes = 0; + time.Seconds = 0; time.TimeFormat = RTC_HOURFORMAT12_AM; time.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; time.StoreOperation = RTC_STOREOPERATION_RESET; - if (HAL_RTC_SetTime(&RTCHandle, &time, FORMAT_BCD) != HAL_OK) { + if (HAL_RTC_SetTime(&RTCHandle, &time, FORMAT_BIN) != HAL_OK) { // init error return; } @@ -316,7 +316,7 @@ mp_obj_t pyb_rtc_datetime(uint n_args, const mp_obj_t *args) { date.Month = mp_obj_get_int(items[1]); date.Date = mp_obj_get_int(items[2]); date.WeekDay = mp_obj_get_int(items[3]); - HAL_RTC_SetDate(&RTCHandle, &date, FORMAT_BCD); + HAL_RTC_SetDate(&RTCHandle, &date, FORMAT_BIN); RTC_TimeTypeDef time; time.Hours = mp_obj_get_int(items[4]); @@ -326,7 +326,7 @@ mp_obj_t pyb_rtc_datetime(uint n_args, const mp_obj_t *args) { time.TimeFormat = RTC_HOURFORMAT12_AM; time.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; time.StoreOperation = RTC_STOREOPERATION_SET; - HAL_RTC_SetTime(&RTCHandle, &time, FORMAT_BCD); + HAL_RTC_SetTime(&RTCHandle, &time, FORMAT_BIN); return mp_const_none; } diff --git a/stmhal/usbd_cdc_interface.c b/stmhal/usbd_cdc_interface.c index d01d13e1ca..323ca74382 100644 --- a/stmhal/usbd_cdc_interface.c +++ b/stmhal/usbd_cdc_interface.c @@ -313,7 +313,7 @@ void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void) { // the host waits for all data to arrive (ie, waits for a packet < max packet size). // To flush a packet of exactly max packet size, we need to send a zero-size packet. // See eg http://www.cypress.com/?id=4&rID=92719 - UserTxNeedEmptyPacket = (buffsize == CDC_DATA_FS_MAX_PACKET_SIZE && UserTxBufPtrOutShadow == UserTxBufPtrIn); + UserTxNeedEmptyPacket = (buffsize > 0 && buffsize % CDC_DATA_FS_MAX_PACKET_SIZE == 0 && UserTxBufPtrOutShadow == UserTxBufPtrIn); } } } diff --git a/tests/basics/class_store_class.py b/tests/basics/class_store_class.py new file mode 100644 index 0000000000..60f65220d9 --- /dev/null +++ b/tests/basics/class_store_class.py @@ -0,0 +1,47 @@ +# Inspired by urlparse.py from CPython 3.3 stdlib +# There was a bug in MicroPython that under some conditions class stored +# in instance attribute later was returned "bound" as if it was a method, +# which caused class constructor to receive extra argument. +try: + from collections import namedtuple +except ImportError: + from _collections import namedtuple + +_DefragResultBase = namedtuple('DefragResult', 'foo bar') + +class _ResultMixinStr(object): + def encode(self): + return self._encoded_counterpart(*(x.encode() for x in self)) + +class _ResultMixinBytes(object): + def decode(self): + return self._decoded_counterpart(*(x.decode() for x in self)) + +class DefragResult(_DefragResultBase, _ResultMixinStr): + pass + +class DefragResultBytes(_DefragResultBase, _ResultMixinBytes): + pass + + +DefragResult._encoded_counterpart = DefragResultBytes +DefragResultBytes._decoded_counterpart = DefragResult + +# Due to differences in type and native subclass printing, +# the best thing we can do here is to just test that no exceptions +# happen + +#print(DefragResult, DefragResult._encoded_counterpart) +#print(DefragResultBytes, DefragResultBytes._decoded_counterpart) + +o1 = DefragResult("a", "b") +#print(o1, type(o1)) +o2 = DefragResultBytes("a", "b") +#print(o2, type(o2)) + +#print(o1._encoded_counterpart) +_o1 = o1.encode() +print(_o1[0], _o1[1]) +#print(_o1, type(_o1)) + +print("All's ok") diff --git a/tests/basics/frozenset1.py b/tests/basics/frozenset1.py new file mode 100644 index 0000000000..02a5bf8c56 --- /dev/null +++ b/tests/basics/frozenset1.py @@ -0,0 +1,14 @@ +# basic sets + +try: + frozenset +except NameError: + print("SKIP") + import sys + sys.exit() + +s = frozenset({1}) +print(s) + +s = frozenset({3, 4, 3, 1}) +print(sorted(s)) diff --git a/tests/basics/frozenset_add.py b/tests/basics/frozenset_add.py new file mode 100644 index 0000000000..50615775bd --- /dev/null +++ b/tests/basics/frozenset_add.py @@ -0,0 +1,12 @@ +try: + frozenset +except NameError: + print("SKIP") + import sys + sys.exit() + +s = frozenset({1, 2, 3, 4}) +try: + print(s.add(5)) +except AttributeError: + print("AttributeError") diff --git a/tests/basics/frozenset_binop.py b/tests/basics/frozenset_binop.py new file mode 100644 index 0000000000..5cc07e9e15 --- /dev/null +++ b/tests/basics/frozenset_binop.py @@ -0,0 +1,36 @@ +try: + frozenset +except NameError: + print("SKIP") + import sys + sys.exit() + +sets = [ + frozenset(), frozenset({1}), frozenset({1, 2}), frozenset({1, 2, 3}), frozenset({2, 3}), + frozenset({2, 3, 5}), frozenset({5}), frozenset({7}) +] +for s in sets: + for t in sets: + print(sorted(s), '|', sorted(t), '=', sorted(s | t)) + print(sorted(s), '^', sorted(t), '=', sorted(s ^ t)) + print(sorted(s), '&', sorted(t), '=', sorted(s & t)) + print(sorted(s), '-', sorted(t), '=', sorted(s - t)) + u = s.copy() + u |= t + print(sorted(s), "|=", sorted(t), '-->', sorted(u)) + u = s.copy() + u ^= t + print(sorted(s), "^=", sorted(t), '-->', sorted(u)) + u = s.copy() + u &= t + print(sorted(s), "&=", sorted(t), "-->", sorted(u)) + u = s.copy() + u -= t + print(sorted(s), "-=", sorted(t), "-->", sorted(u)) + + print(sorted(s), '==', sorted(t), '=', s == t) + print(sorted(s), '!=', sorted(t), '=', s != t) + print(sorted(s), '>', sorted(t), '=', s > t) + print(sorted(s), '>=', sorted(t), '=', s >= t) + print(sorted(s), '<', sorted(t), '=', s < t) + print(sorted(s), '<=', sorted(t), '=', s <= t) diff --git a/tests/basics/frozenset_copy.py b/tests/basics/frozenset_copy.py new file mode 100644 index 0000000000..92e115d346 --- /dev/null +++ b/tests/basics/frozenset_copy.py @@ -0,0 +1,12 @@ +try: + frozenset +except NameError: + print("SKIP") + import sys + sys.exit() + +s = frozenset({1, 2, 3, 4}) +t = s.copy() +print(type(t)) +for i in s, t: + print(sorted(i)) diff --git a/tests/basics/frozenset_difference.py b/tests/basics/frozenset_difference.py new file mode 100644 index 0000000000..3d142f9595 --- /dev/null +++ b/tests/basics/frozenset_difference.py @@ -0,0 +1,21 @@ +try: + frozenset +except NameError: + print("SKIP") + import sys + sys.exit() + +l = [1, 2, 3, 4] +s = frozenset(l) +outs = [s.difference(), + s.difference(frozenset({1})), + s.difference(frozenset({1}), [1, 2]), + s.difference(frozenset({1}), {1, 2}, {2, 3})] +for out in outs: + print(type(out), sorted(out)) + +s = frozenset(l) +try: + print(s.difference_update({1})) +except AttributeError: + print("AttributeError") diff --git a/tests/basics/int1.py b/tests/basics/int1.py index 2daef9bf0e..e8a0a04683 100644 --- a/tests/basics/int1.py +++ b/tests/basics/int1.py @@ -46,6 +46,7 @@ print(int('0B100', 2)) print(int('0100', 2)) print(int(' \t 0o12', 8)) print(int('0o12 \t ', 8)) +print(int(b"12", 10)) def test(value, base): diff --git a/tests/basics/list_slice_assign.py b/tests/basics/list_slice_assign.py new file mode 100644 index 0000000000..baa9a00810 --- /dev/null +++ b/tests/basics/list_slice_assign.py @@ -0,0 +1,36 @@ +# test slices; only 2 argument version supported by Micro Python at the moment +x = list(range(10)) + +# Assignment +l = list(x) +l[1:3] = [10, 20] +print(l) +l = list(x) +l[1:3] = [10] +print(l) +l = list(x) +l[1:3] = [] +print(l) +l = list(x) +del l[1:3] +print(l) + +l = list(x) +l[:3] = [10, 20] +print(l) +l = list(x) +l[:3] = [] +print(l) +l = list(x) +del l[:3] +print(l) + +l = list(x) +l[:-3] = [10, 20] +print(l) +l = list(x) +l[:-3] = [] +print(l) +l = list(x) +del l[:-3] +print(l) diff --git a/tests/basics/namedtuple1.py b/tests/basics/namedtuple1.py index 98628cc545..05dd15bd17 100644 --- a/tests/basics/namedtuple1.py +++ b/tests/basics/namedtuple1.py @@ -16,6 +16,8 @@ print(bool(t)) print(t + t) print(t * 3) +print([f for f in t]) + print(isinstance(t, tuple)) try: diff --git a/tests/basics/string_partition.py b/tests/basics/string_partition.py index ad70d02509..fe0070a658 100644 --- a/tests/basics/string_partition.py +++ b/tests/basics/string_partition.py @@ -27,3 +27,14 @@ except ValueError: print("Raised ValueError") else: print("Did not raise ValueError") + +# Bytes +print(b"abba".partition(b'b')) +try: + print(b"abba".partition('b')) +except TypeError: + print("Raised TypeError") +try: + print("abba".partition(b'b')) +except TypeError: + print("Raised TypeError") diff --git a/tests/basics/string_strip.py b/tests/basics/string_strip.py index 8e03eff93a..4684c2a248 100644 --- a/tests/basics/string_strip.py +++ b/tests/basics/string_strip.py @@ -10,3 +10,13 @@ print('www.example.com'.lstrip('cmowz.')) print(' spacious '.rstrip()) print('mississippi'.rstrip('ipz')) + +print(b'mississippi'.rstrip(b'ipz')) +try: + print(b'mississippi'.rstrip('ipz')) +except TypeError: + print("TypeError") +try: + print('mississippi'.rstrip(b'ipz')) +except TypeError: + print("TypeError") diff --git a/tests/basics/string_upperlow.py b/tests/basics/string_upperlow.py new file mode 100644 index 0000000000..950ea24d11 --- /dev/null +++ b/tests/basics/string_upperlow.py @@ -0,0 +1,4 @@ +print("".lower()) +print(" t\tn\nr\rv\vf\f".upper()) +print(" T E S T".lower()) +print("*@a1b2cabc_[]/\\".upper()) diff --git a/tests/basics/subclass-native5.py b/tests/basics/subclass-native5.py new file mode 100644 index 0000000000..6127dae33d --- /dev/null +++ b/tests/basics/subclass-native5.py @@ -0,0 +1,12 @@ +# Subclass from 2 bases explicitly subclasses from object + +class Base1(object): + pass + +class Base2(object): + pass + +class Sub(Base1, Base2): + pass + +o = Sub() diff --git a/tests/basics/subclass_native_cmp.py b/tests/basics/subclass_native_cmp.py new file mode 100644 index 0000000000..1a095bfa1a --- /dev/null +++ b/tests/basics/subclass_native_cmp.py @@ -0,0 +1,9 @@ +# Test calling non-special method inherited from native type + +class mytuple(tuple): + pass + +t = mytuple((1, 2, 3)) +print(t) +print(t == (1, 2, 3)) +print((1, 2, 3) == t) diff --git a/tests/basics/subclass_native_specmeth.py b/tests/basics/subclass_native_specmeth.py new file mode 100644 index 0000000000..91ffc9624b --- /dev/null +++ b/tests/basics/subclass_native_specmeth.py @@ -0,0 +1,18 @@ +# Test calling non-special method inherited from native type + +class mylist(list): + pass + +l = mylist([1, 2, 3]) +print(l) +print([e for e in l]) + + +class mylist2(list): + + def __iter__(self): + return iter([10, 20, 30]) + +l = mylist2([1, 2, 3]) +print(l) +print([e for e in l]) diff --git a/tests/pyb/rtc.py b/tests/pyb/rtc.py index 853aa79577..219d0791af 100644 --- a/tests/pyb/rtc.py +++ b/tests/pyb/rtc.py @@ -3,6 +3,28 @@ from pyb import RTC rtc = RTC() print(rtc) + +# make sure that 1 second passes correctly rtc.datetime((2014, 1, 1, 1, 0, 0, 0, 0)) pyb.delay(1000) print(rtc.datetime()[:7]) + +def set_and_print(datetime): + rtc.datetime(datetime) + print(rtc.datetime()[:7]) + +# make sure that setting works correctly +set_and_print((2000, 1, 1, 1, 0, 0, 0, 0)) +set_and_print((2000, 1, 31, 1, 0, 0, 0, 0)) +set_and_print((2000, 12, 31, 1, 0, 0, 0, 0)) +set_and_print((2016, 12, 31, 1, 0, 0, 0, 0)) +set_and_print((2016, 12, 31, 7, 0, 0, 0, 0)) +set_and_print((2016, 12, 31, 7, 1, 0, 0, 0)) +set_and_print((2016, 12, 31, 7, 12, 0, 0, 0)) +set_and_print((2016, 12, 31, 7, 13, 0, 0, 0)) +set_and_print((2016, 12, 31, 7, 23, 0, 0, 0)) +set_and_print((2016, 12, 31, 7, 23, 1, 0, 0)) +set_and_print((2016, 12, 31, 7, 23, 59, 0, 0)) +set_and_print((2016, 12, 31, 7, 23, 59, 1, 0)) +set_and_print((2016, 12, 31, 7, 23, 59, 59, 0)) +set_and_print((2099, 12, 31, 7, 23, 59, 59, 0)) diff --git a/tests/pyb/rtc.py.exp b/tests/pyb/rtc.py.exp index d1ea2d9590..43ea70d95e 100644 --- a/tests/pyb/rtc.py.exp +++ b/tests/pyb/rtc.py.exp @@ -1,2 +1,16 @@ <RTC> (2014, 1, 1, 1, 0, 0, 1) +(2000, 1, 1, 1, 0, 0, 0) +(2000, 1, 31, 1, 0, 0, 0) +(2000, 12, 31, 1, 0, 0, 0) +(2016, 12, 31, 1, 0, 0, 0) +(2016, 12, 31, 7, 0, 0, 0) +(2016, 12, 31, 7, 1, 0, 0) +(2016, 12, 31, 7, 12, 0, 0) +(2016, 12, 31, 7, 13, 0, 0) +(2016, 12, 31, 7, 23, 0, 0) +(2016, 12, 31, 7, 23, 1, 0) +(2016, 12, 31, 7, 23, 59, 0) +(2016, 12, 31, 7, 23, 59, 1) +(2016, 12, 31, 7, 23, 59, 59) +(2099, 12, 31, 7, 23, 59, 59) diff --git a/tests/run-tests b/tests/run-tests index 9e837c3cb2..102655abea 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -25,6 +25,7 @@ def run_tests(pyb, tests): testcase_count = 0 passed_count = 0 failed_tests = [] + skipped_tests = [] running_under_travis = os.getenv('TRAVIS') == 'true' @@ -34,6 +35,7 @@ def run_tests(pyb, tests): for test_file in tests: if running_under_travis and test_file in skip_travis_tests: print("skip ", test_file) + skipped_tests.append(test_name) continue # get expected output @@ -42,8 +44,10 @@ def run_tests(pyb, tests): # expected output given by a file, so read that in with open(test_file_expected, 'rb') as f: output_expected = f.read() + if os.name == 'nt': + output_expected = output_expected.replace(b'\n', b'\r\n') else: - # run CPython to work out expeceted output + # run CPython to work out expected output try: output_expected = subprocess.check_output([CPYTHON3, '-B', test_file]) except subprocess.CalledProcessError: @@ -64,10 +68,16 @@ def run_tests(pyb, tests): except pyboard.PyboardError: output_mupy = b'CRASH' - testcase_count += len(output_expected.splitlines()) - test_basename = os.path.basename(test_file) test_name = os.path.splitext(test_basename)[0] + + if output_mupy == b'SKIP\n': + print("skip ", test_file) + skipped_tests.append(test_name) + continue + + testcase_count += len(output_expected.splitlines()) + filename_expected = test_basename + ".exp" filename_mupy = test_basename + ".out" @@ -89,6 +99,8 @@ def run_tests(pyb, tests): print("{} tests performed ({} individual testcases)".format(test_count, testcase_count)) print("{} tests passed".format(passed_count)) + if len(skipped_tests) > 0: + print("{} tests skipped: {}".format(len(skipped_tests), ' '.join(skipped_tests))) if len(failed_tests) > 0: print("{} tests failed: {}".format(len(failed_tests), ' '.join(failed_tests))) return False diff --git a/stmhal/gendoc.py b/tools/gendoc.py index 0122579ab8..5a33a8195d 100644 --- a/stmhal/gendoc.py +++ b/tools/gendoc.py @@ -67,6 +67,9 @@ class Lexer: print('({}:{}) {}'.format(self.filename, self.cur_line, msg)) raise Lexer.LexerError +class DocValidateError(Exception): + pass + class DocItem: def __init__(self): self.doc = [] @@ -216,6 +219,10 @@ class DocModule(DocItem): def process_constant(self, lex, d): self.cur_class.process_constant(lex, d) + def validate(self): + if self.descr is None: + raise DocValidateError('module {} referenced but never defined'.format(self.name)) + def dump(self): s = [] s.append('# module {}'.format(self.name)) @@ -262,15 +269,18 @@ class Doc: def process_module(self, lex, d): name = d['id'] - if name in self.modules: + if name not in self.modules: + self.modules[name] = DocModule(name, None) + self.cur_module = self.modules[name] + if self.cur_module.descr is not None: lex.error("multiple definition of module '{}'".format(name)) - self.cur_module = self.modules[name] = DocModule(name, d['descr']) + self.cur_module.descr = d['descr'] self.cur_module.add_doc(lex) def process_moduleref(self, lex, d): name = d['id'] if name not in self.modules: - lex.error('module {} referenced before definition'.format(name)) + self.modules[name] = DocModule(name, None) self.cur_module = self.modules[name] lex.opt_break() @@ -294,6 +304,10 @@ class Doc: self.check_module(lex) self.cur_module.process_constant(lex, d) + def validate(self): + for m in self.modules.values(): + m.validate() + def write(self, dir): for m in self.modules.values(): mod_dir = os.path.join(dir, 'module', m.name) @@ -339,17 +353,18 @@ def process_file(file, doc): def main(): cmd_parser = argparse.ArgumentParser(description='Generate documentation for pyboard API from C files.') cmd_parser.add_argument('--outdir', metavar='<output dir>', default='gendoc-out', help='ouput directory') - cmd_parser.add_argument('files', nargs='*', help='input files') + cmd_parser.add_argument('files', nargs='+', help='input files') args = cmd_parser.parse_args() - if len(args.files) == 0: - args.files = ['modpyb.c', 'accel.c', 'adc.c', 'dac.c', 'extint.c', 'i2c.c', 'led.c', 'pin.c', 'rng.c', 'servo.c', 'spi.c', 'uart.c', 'usrsw.c', 'timer.c', 'rtc.c'] - doc = Doc() for file in args.files: print('processing', file) if not process_file(file, doc): return + try: + doc.validate() + except DocValidateError as e: + print(e) doc.write(args.outdir) print('written to', args.outdir) diff --git a/unix/main.c b/unix/main.c index cc80811503..de296142b3 100644 --- a/unix/main.c +++ b/unix/main.c @@ -371,6 +371,15 @@ int main(int argc, char **argv) { return 0; } +STATIC mp_obj_t mp_sys_exit(uint n_args, const mp_obj_t *args) { + int rc = 0; + if (n_args > 0) { + rc = mp_obj_get_int(args[0]); + } + exit(rc); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit); + uint mp_import_stat(const char *path) { struct stat st; if (stat(path, &st) == 0) { diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h index ca470d9c29..38bb979c92 100644 --- a/unix/mpconfigport.h +++ b/unix/mpconfigport.h @@ -31,6 +31,7 @@ #define MICROPY_EMIT_INLINE_THUMB (0) #define MICROPY_ENABLE_GC (1) #define MICROPY_ENABLE_FINALISER (1) +#define MICROPY_ENABLE_FROZENSET (1) #define MICROPY_MEM_STATS (1) #define MICROPY_DEBUG_PRINTERS (1) #define MICROPY_ENABLE_REPL_HELPERS (1) @@ -43,6 +44,7 @@ #define MICROPY_USE_COMPUTED_GOTO (1) #define MICROPY_MOD_SYS_STDFILES (1) #define MICROPY_ENABLE_MOD_CMATH (1) +#define MICROPY_SYS_EXIT (1) // Define to MICROPY_ERROR_REPORTING_DETAILED to get function, etc. // names in exception messages (may require more RAM). #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_DETAILED) |