mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Add Initial Support for MicroPython
* Add pre-compiled MicroPython library and headers. * Change Makefile to link libmp.a remove libusbgeneric * Change linker script to support MicroPython memory layout. * Change OTG handle name in stm32f4xx_it.c * Change main to init libmp and export Python functions. * Add MicroPython bindings to src
This commit is contained in:
parent
659ffc73cc
commit
a44540f793
1
include/MicroPython/compile.h
Normal file
1
include/MicroPython/compile.h
Normal file
@ -0,0 +1 @@
|
||||
mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl);
|
||||
20
include/MicroPython/gc.h
Normal file
20
include/MicroPython/gc.h
Normal file
@ -0,0 +1,20 @@
|
||||
void gc_init(void *start, void *end);
|
||||
void gc_collect_start(void);
|
||||
void gc_collect_root(void **ptrs, machine_uint_t len);
|
||||
void gc_collect_end(void);
|
||||
void gc_collect(void);
|
||||
void *gc_alloc(machine_uint_t n_bytes);
|
||||
void gc_free(void *ptr);
|
||||
machine_uint_t gc_nbytes(void *ptr);
|
||||
void *gc_realloc(void *ptr, machine_uint_t n_bytes);
|
||||
|
||||
typedef struct _gc_info_t {
|
||||
machine_uint_t total;
|
||||
machine_uint_t used;
|
||||
machine_uint_t free;
|
||||
machine_uint_t num_1block;
|
||||
machine_uint_t num_2block;
|
||||
machine_uint_t max_block;
|
||||
} gc_info_t;
|
||||
|
||||
void gc_info(gc_info_t *info);
|
||||
8
include/MicroPython/gccollect.h
Normal file
8
include/MicroPython/gccollect.h
Normal file
@ -0,0 +1,8 @@
|
||||
extern uint32_t _ram_start;
|
||||
extern uint32_t _heap_start;
|
||||
extern uint32_t _ram_end;
|
||||
extern uint32_t _heap_end;
|
||||
|
||||
void gc_collect(void);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_gc_obj);
|
||||
140
include/MicroPython/lexer.h
Normal file
140
include/MicroPython/lexer.h
Normal file
@ -0,0 +1,140 @@
|
||||
/* lexer.h -- simple tokeniser for Micro Python
|
||||
*
|
||||
* Uses (byte) length instead of null termination.
|
||||
* Tokens are the same - UTF-8 with (byte) length.
|
||||
*/
|
||||
|
||||
typedef enum _mp_token_kind_t {
|
||||
MP_TOKEN_END, // 0
|
||||
|
||||
MP_TOKEN_INVALID,
|
||||
MP_TOKEN_DEDENT_MISMATCH,
|
||||
MP_TOKEN_LONELY_STRING_OPEN,
|
||||
MP_TOKEN_BAD_LINE_CONTINUATION,
|
||||
|
||||
MP_TOKEN_NEWLINE, // 5
|
||||
MP_TOKEN_INDENT, // 6
|
||||
MP_TOKEN_DEDENT, // 7
|
||||
|
||||
MP_TOKEN_NAME, // 8
|
||||
MP_TOKEN_NUMBER,
|
||||
MP_TOKEN_STRING,
|
||||
MP_TOKEN_BYTES,
|
||||
|
||||
MP_TOKEN_ELLIPSIS,
|
||||
|
||||
MP_TOKEN_KW_FALSE, // 13
|
||||
MP_TOKEN_KW_NONE,
|
||||
MP_TOKEN_KW_TRUE,
|
||||
MP_TOKEN_KW_AND,
|
||||
MP_TOKEN_KW_AS,
|
||||
MP_TOKEN_KW_ASSERT,
|
||||
MP_TOKEN_KW_BREAK,
|
||||
MP_TOKEN_KW_CLASS,
|
||||
MP_TOKEN_KW_CONTINUE,
|
||||
MP_TOKEN_KW_DEF, // 22
|
||||
MP_TOKEN_KW_DEL,
|
||||
MP_TOKEN_KW_ELIF,
|
||||
MP_TOKEN_KW_ELSE,
|
||||
MP_TOKEN_KW_EXCEPT,
|
||||
MP_TOKEN_KW_FINALLY,
|
||||
MP_TOKEN_KW_FOR,
|
||||
MP_TOKEN_KW_FROM,
|
||||
MP_TOKEN_KW_GLOBAL,
|
||||
MP_TOKEN_KW_IF,
|
||||
MP_TOKEN_KW_IMPORT, // 32
|
||||
MP_TOKEN_KW_IN,
|
||||
MP_TOKEN_KW_IS,
|
||||
MP_TOKEN_KW_LAMBDA,
|
||||
MP_TOKEN_KW_NONLOCAL,
|
||||
MP_TOKEN_KW_NOT,
|
||||
MP_TOKEN_KW_OR,
|
||||
MP_TOKEN_KW_PASS,
|
||||
MP_TOKEN_KW_RAISE,
|
||||
MP_TOKEN_KW_RETURN,
|
||||
MP_TOKEN_KW_TRY, // 42
|
||||
MP_TOKEN_KW_WHILE,
|
||||
MP_TOKEN_KW_WITH,
|
||||
MP_TOKEN_KW_YIELD,
|
||||
|
||||
MP_TOKEN_OP_PLUS, // 46
|
||||
MP_TOKEN_OP_MINUS,
|
||||
MP_TOKEN_OP_STAR,
|
||||
MP_TOKEN_OP_DBL_STAR,
|
||||
MP_TOKEN_OP_SLASH,
|
||||
MP_TOKEN_OP_DBL_SLASH,
|
||||
MP_TOKEN_OP_PERCENT,
|
||||
MP_TOKEN_OP_LESS,
|
||||
MP_TOKEN_OP_DBL_LESS,
|
||||
MP_TOKEN_OP_MORE,
|
||||
MP_TOKEN_OP_DBL_MORE, // 56
|
||||
MP_TOKEN_OP_AMPERSAND,
|
||||
MP_TOKEN_OP_PIPE,
|
||||
MP_TOKEN_OP_CARET,
|
||||
MP_TOKEN_OP_TILDE,
|
||||
MP_TOKEN_OP_LESS_EQUAL,
|
||||
MP_TOKEN_OP_MORE_EQUAL,
|
||||
MP_TOKEN_OP_DBL_EQUAL,
|
||||
MP_TOKEN_OP_NOT_EQUAL,
|
||||
|
||||
MP_TOKEN_DEL_PAREN_OPEN, // 65
|
||||
MP_TOKEN_DEL_PAREN_CLOSE,
|
||||
MP_TOKEN_DEL_BRACKET_OPEN,
|
||||
MP_TOKEN_DEL_BRACKET_CLOSE,
|
||||
MP_TOKEN_DEL_BRACE_OPEN,
|
||||
MP_TOKEN_DEL_BRACE_CLOSE,
|
||||
MP_TOKEN_DEL_COMMA,
|
||||
MP_TOKEN_DEL_COLON,
|
||||
MP_TOKEN_DEL_PERIOD,
|
||||
MP_TOKEN_DEL_SEMICOLON,
|
||||
MP_TOKEN_DEL_AT, // 75
|
||||
MP_TOKEN_DEL_EQUAL,
|
||||
MP_TOKEN_DEL_PLUS_EQUAL,
|
||||
MP_TOKEN_DEL_MINUS_EQUAL,
|
||||
MP_TOKEN_DEL_STAR_EQUAL,
|
||||
MP_TOKEN_DEL_SLASH_EQUAL,
|
||||
MP_TOKEN_DEL_DBL_SLASH_EQUAL,
|
||||
MP_TOKEN_DEL_PERCENT_EQUAL,
|
||||
MP_TOKEN_DEL_AMPERSAND_EQUAL,
|
||||
MP_TOKEN_DEL_PIPE_EQUAL,
|
||||
MP_TOKEN_DEL_CARET_EQUAL, // 85
|
||||
MP_TOKEN_DEL_DBL_MORE_EQUAL,
|
||||
MP_TOKEN_DEL_DBL_LESS_EQUAL,
|
||||
MP_TOKEN_DEL_DBL_STAR_EQUAL,
|
||||
MP_TOKEN_DEL_MINUS_MORE,
|
||||
} mp_token_kind_t;
|
||||
|
||||
typedef struct _mp_token_t {
|
||||
uint src_line; // source line
|
||||
uint src_column; // source column
|
||||
|
||||
mp_token_kind_t kind; // kind of token
|
||||
const char *str; // string of token (valid only while this token is current token)
|
||||
uint len; // (byte) length of string of token
|
||||
} mp_token_t;
|
||||
|
||||
// the next-char function must return the next character in the stream
|
||||
// it must return MP_LEXER_CHAR_EOF if end of stream
|
||||
// it can be called again after returning MP_LEXER_CHAR_EOF, and in that case must return MP_LEXER_CHAR_EOF
|
||||
#define MP_LEXER_CHAR_EOF (-1)
|
||||
typedef unichar (*mp_lexer_stream_next_char_t)(void*);
|
||||
typedef void (*mp_lexer_stream_close_t)(void*);
|
||||
|
||||
typedef struct _mp_lexer_t mp_lexer_t;
|
||||
|
||||
void mp_token_show(const mp_token_t *tok);
|
||||
|
||||
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 *mp_lexer_new_from_str_len(qstr src_name, const char *str, uint len, uint free_len);
|
||||
|
||||
void mp_lexer_free(mp_lexer_t *lex);
|
||||
qstr mp_lexer_source_name(mp_lexer_t *lex);
|
||||
void mp_lexer_to_next(mp_lexer_t *lex);
|
||||
const mp_token_t *mp_lexer_cur(const mp_lexer_t *lex);
|
||||
bool mp_lexer_is_kind(mp_lexer_t *lex, mp_token_kind_t kind);
|
||||
|
||||
bool mp_lexer_show_error_pythonic_prefix(mp_lexer_t *lex);
|
||||
bool mp_lexer_show_error_pythonic(mp_lexer_t *lex, const char *msg);
|
||||
|
||||
// used to import a module; must be implemented for a specific port
|
||||
mp_lexer_t *mp_import_open_file(qstr mod_name);
|
||||
1
include/MicroPython/lexerfatfs.h
Normal file
1
include/MicroPython/lexerfatfs.h
Normal file
@ -0,0 +1 @@
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename);
|
||||
29
include/MicroPython/libmp.h
Normal file
29
include/MicroPython/libmp.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef __LIBMP_H__
|
||||
#define __LIBMP_H__
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "std.h"
|
||||
#include "misc.h"
|
||||
#include "ff.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "lexer.h"
|
||||
#include "lexerfatfs.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "compile.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
#include "repl.h"
|
||||
#include "gc.h"
|
||||
#include "gccollect.h"
|
||||
#include "storage.h"
|
||||
#include "usb.h"
|
||||
#include "systick.h"
|
||||
|
||||
int libmp_init();
|
||||
void libmp_do_repl(void);
|
||||
bool libmp_do_file(const char *filename);
|
||||
#endif /* __LIBMP_H__ */
|
||||
92
include/MicroPython/misc.h
Normal file
92
include/MicroPython/misc.h
Normal file
@ -0,0 +1,92 @@
|
||||
// a mini library of useful types and functions
|
||||
|
||||
#ifndef _INCLUDED_MINILIB_H
|
||||
#define _INCLUDED_MINILIB_H
|
||||
|
||||
/** types *******************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned int uint;
|
||||
|
||||
/** memomry allocation ******************************************/
|
||||
|
||||
// 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_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)))
|
||||
#define m_renew(type, ptr, old_num, new_num) ((type*)(m_realloc((ptr), sizeof(type) * (old_num), sizeof(type) * (new_num))))
|
||||
#define m_del(type, ptr, num) m_free(ptr, sizeof(type) * (num))
|
||||
#define m_del_obj(type, ptr) (m_del(type, ptr, 1))
|
||||
#define m_del_var(obj_type, var_type, var_num, ptr) (m_free(ptr, sizeof(obj_type) + sizeof(var_type) * (var_num)))
|
||||
|
||||
void *m_malloc(int num_bytes);
|
||||
void *m_malloc0(int num_bytes);
|
||||
void *m_realloc(void *ptr, int old_num_bytes, int new_num_bytes);
|
||||
void m_free(void *ptr, int num_bytes);
|
||||
|
||||
int m_get_total_bytes_allocated(void);
|
||||
int m_get_current_bytes_allocated(void);
|
||||
int m_get_peak_bytes_allocated(void);
|
||||
|
||||
/** unichar / UTF-8 *********************************************/
|
||||
|
||||
typedef int unichar; // TODO
|
||||
|
||||
unichar utf8_get_char(const char *s);
|
||||
char *utf8_next_char(const char *s);
|
||||
|
||||
bool unichar_isspace(unichar c);
|
||||
bool unichar_isalpha(unichar c);
|
||||
bool unichar_isprint(unichar c);
|
||||
bool unichar_isdigit(unichar c);
|
||||
bool unichar_isxdigit(unichar c);
|
||||
|
||||
/** string ******************************************************/
|
||||
|
||||
/*
|
||||
#define streq(s1, s2) (strcmp((s1), (s2)) == 0)
|
||||
*/
|
||||
|
||||
long strtonum(const char *restrict s, int base);
|
||||
|
||||
/** variable string *********************************************/
|
||||
|
||||
typedef struct _vstr_t {
|
||||
int alloc;
|
||||
int len;
|
||||
char *buf;
|
||||
bool had_error;
|
||||
} vstr_t;
|
||||
|
||||
void vstr_init(vstr_t *vstr, int alloc);
|
||||
void vstr_clear(vstr_t *vstr);
|
||||
vstr_t *vstr_new(void);
|
||||
vstr_t *vstr_new_size(int alloc);
|
||||
void vstr_free(vstr_t *vstr);
|
||||
void vstr_reset(vstr_t *vstr);
|
||||
bool vstr_had_error(vstr_t *vstr);
|
||||
char *vstr_str(vstr_t *vstr);
|
||||
int vstr_len(vstr_t *vstr);
|
||||
void vstr_hint_size(vstr_t *vstr, int size);
|
||||
char *vstr_extend(vstr_t *vstr, int size);
|
||||
bool vstr_set_size(vstr_t *vstr, int size);
|
||||
bool vstr_shrink(vstr_t *vstr);
|
||||
char *vstr_add_len(vstr_t *vstr, int len);
|
||||
void vstr_add_byte(vstr_t *vstr, byte v);
|
||||
void vstr_add_char(vstr_t *vstr, unichar chr);
|
||||
void vstr_add_str(vstr_t *vstr, const char *str);
|
||||
void vstr_add_strn(vstr_t *vstr, const char *str, int len);
|
||||
//void vstr_add_le16(vstr_t *vstr, unsigned short v);
|
||||
//void vstr_add_le32(vstr_t *vstr, unsigned int v);
|
||||
void vstr_cut_tail(vstr_t *vstr, int len);
|
||||
void vstr_printf(vstr_t *vstr, const char *fmt, ...);
|
||||
|
||||
#ifdef va_start
|
||||
void vstr_vprintf(vstr_t *vstr, const char *fmt, va_list ap);
|
||||
#endif
|
||||
|
||||
#endif // _INCLUDED_MINILIB_H
|
||||
123
include/MicroPython/mpconfig.h
Normal file
123
include/MicroPython/mpconfig.h
Normal file
@ -0,0 +1,123 @@
|
||||
// This file contains default configuration settings for MicroPython.
|
||||
// You can override any of these options using mpconfigport.h file located
|
||||
// in a directory of your port.
|
||||
|
||||
#include <mpconfigport.h>
|
||||
|
||||
// Any options not explicitly set in mpconfigport.h will get default
|
||||
// values below.
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Micro Python emitters */
|
||||
|
||||
// Whether to emit CPython byte codes (for debugging/testing)
|
||||
// Enabling this overrides all other emitters
|
||||
#ifndef MICROPY_EMIT_CPYTHON
|
||||
#define MICROPY_EMIT_CPYTHON (0)
|
||||
#endif
|
||||
|
||||
// Whether to emit x64 native code
|
||||
#ifndef MICROPY_EMIT_X64
|
||||
#define MICROPY_EMIT_X64 (0)
|
||||
#endif
|
||||
|
||||
// Whether to emit thumb native code
|
||||
#ifndef MICROPY_EMIT_THUMB
|
||||
#define MICROPY_EMIT_THUMB (0)
|
||||
#endif
|
||||
|
||||
// Whether to enable the thumb inline assembler
|
||||
#ifndef MICROPY_EMIT_INLINE_THUMB
|
||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Internal debugging stuff */
|
||||
|
||||
// Whether to collect memory allocation stats
|
||||
#ifndef MICROPY_MEM_STATS
|
||||
#define MICROPY_MEM_STATS (0)
|
||||
#endif
|
||||
|
||||
// Whether to build functions that print debugging info:
|
||||
// mp_byte_code_print
|
||||
// mp_parse_node_print
|
||||
#ifndef MICROPY_DEBUG_PRINTERS
|
||||
#define MICROPY_DEBUG_PRINTERS (0)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Fine control over Python features */
|
||||
|
||||
// Whether to include the garbage collector
|
||||
#ifndef MICROPY_ENABLE_GC
|
||||
#define MICROPY_ENABLE_GC (0)
|
||||
#endif
|
||||
|
||||
// Whether to include REPL helper function
|
||||
#ifndef MICROPY_ENABLE_REPL_HELPERS
|
||||
#define MICROPY_ENABLE_REPL_HELPERS (0)
|
||||
#endif
|
||||
|
||||
// Whether to include lexer helper function for unix
|
||||
#ifndef MICROPY_ENABLE_LEXER_UNIX
|
||||
#define MICROPY_ENABLE_LEXER_UNIX (0)
|
||||
#endif
|
||||
|
||||
// Long int implementation
|
||||
#define MICROPY_LONGINT_IMPL_NONE (0)
|
||||
#define MICROPY_LONGINT_IMPL_LONGLONG (1)
|
||||
|
||||
#ifndef MICROPY_LONGINT_IMPL
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
|
||||
#endif
|
||||
|
||||
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
|
||||
typedef long long mp_longint_impl_t;
|
||||
#endif
|
||||
|
||||
// Whether to include information in the byte code to determine source
|
||||
// line number (increases RAM usage, but doesn't slow byte code execution)
|
||||
#ifndef MICROPY_ENABLE_SOURCE_LINE
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (0)
|
||||
#endif
|
||||
|
||||
// Whether to support float and complex types
|
||||
#ifndef MICROPY_ENABLE_FLOAT
|
||||
#define MICROPY_ENABLE_FLOAT (0)
|
||||
#endif
|
||||
|
||||
// Whether to support slice object and correspondingly
|
||||
// slice subscript operators
|
||||
#ifndef MICROPY_ENABLE_SLICE
|
||||
#define MICROPY_ENABLE_SLICE (1)
|
||||
#endif
|
||||
|
||||
// Enable features which improve CPython compatibility
|
||||
// but may lead to more code size/memory usage.
|
||||
// TODO: Originally intended as generic category to not
|
||||
// add bunch of once-off options. May need refactoring later
|
||||
#ifndef MICROPY_CPYTHON_COMPAT
|
||||
#define MICROPY_CPYTHON_COMPAT (1)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Miscellaneous settings */
|
||||
|
||||
#define BITS_PER_BYTE (8)
|
||||
#define BITS_PER_WORD (BITS_PER_BYTE * BYTES_PER_WORD)
|
||||
// machine_int_t value with most significant bit set
|
||||
#define WORD_MSBIT_HIGH (((machine_uint_t)1) << (BYTES_PER_WORD * 8 - 1))
|
||||
|
||||
// printf format spec to use for machine_int_t and friends
|
||||
#ifndef INT_FMT
|
||||
#ifdef __LP64__
|
||||
// Archs where machine_int_t == long, long != int
|
||||
#define UINT_FMT "%lu"
|
||||
#define INT_FMT "%ld"
|
||||
#else
|
||||
// Archs where machine_int_t == int
|
||||
#define UINT_FMT "%u"
|
||||
#define INT_FMT "%d"
|
||||
#endif
|
||||
#endif //INT_FMT
|
||||
165
include/MicroPython/mpconfigport.h
Normal file
165
include/MicroPython/mpconfigport.h
Normal file
@ -0,0 +1,165 @@
|
||||
#include <stdint.h>
|
||||
|
||||
// options to control how Micro Python is built
|
||||
|
||||
#define MICROPY_EMIT_THUMB (1)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (1)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_ENABLE_REPL_HELPERS (1)
|
||||
#define MICROPY_ENABLE_FLOAT (1)
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
#define BYTES_PER_WORD (4)
|
||||
|
||||
typedef int32_t machine_int_t; // must be pointer size
|
||||
typedef uint32_t machine_uint_t; // must be pointer size
|
||||
typedef void *machine_ptr_t; // must be of pointer size
|
||||
typedef const void *machine_const_ptr_t; // must be of pointer size
|
||||
typedef float machine_float_t;
|
||||
|
||||
machine_float_t machine_sqrt(machine_float_t x);
|
||||
|
||||
// board specific definitions
|
||||
|
||||
// choose 1 of these boards
|
||||
//#define PYBOARD3
|
||||
//#define PYBOARD4
|
||||
#define STM32F4DISC
|
||||
|
||||
#if defined (PYBOARD3)
|
||||
#define MICROPY_HW_BOARD_NAME "PYBv3"
|
||||
|
||||
#define MICROPY_HW_HAS_SWITCH (1)
|
||||
#define MICROPY_HW_HAS_SDCARD (1)
|
||||
#define MICROPY_HW_HAS_MMA7660 (1)
|
||||
#define MICROPY_HW_HAS_LIS3DSH (0)
|
||||
#define MICROPY_HW_HAS_LCD (0)
|
||||
#define MICROPY_HW_HAS_WLAN (0)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
#define MICROPY_HW_ENABLE_TIMER (1)
|
||||
#define MICROPY_HW_ENABLE_SERVO (1)
|
||||
#define MICROPY_HW_ENABLE_AUDIO (0)
|
||||
|
||||
#define USRSW_PORT (GPIOA)
|
||||
#define USRSW_PIN (GPIO_Pin_13)
|
||||
#define USRSW_PUPD (GPIO_PuPd_UP)
|
||||
#define USRSW_EXTI_PIN (EXTI_PinSource13)
|
||||
#define USRSW_EXTI_PORT (EXTI_PortSourceGPIOA)
|
||||
#define USRSW_EXTI_LINE (EXTI_Line13)
|
||||
#define USRSW_EXTI_IRQN (EXTI15_10_IRQn)
|
||||
#define USRSW_EXTI_EDGE (EXTI_Trigger_Rising)
|
||||
|
||||
/* LED */
|
||||
#define PYB_LED1_PORT (GPIOA)
|
||||
#define PYB_LED1_PIN (GPIO_Pin_8)
|
||||
|
||||
#define PYB_LED2_PORT (GPIOA)
|
||||
#define PYB_LED2_PIN (GPIO_Pin_10)
|
||||
|
||||
#define PYB_LED3_PORT (GPIOC)
|
||||
#define PYB_LED3_PIN (GPIO_Pin_4)
|
||||
|
||||
#define PYB_LED4_PORT (GPIOC)
|
||||
#define PYB_LED4_PIN (GPIO_Pin_5)
|
||||
|
||||
#define PYB_OTYPE (GPIO_OType_OD)
|
||||
|
||||
#define PYB_LED_ON(port, pin) (port->BSRRH = pin)
|
||||
#define PYB_LED_OFF(port, pin) (port->BSRRL = pin)
|
||||
|
||||
#elif defined (PYBOARD4)
|
||||
#define MICROPY_HW_BOARD_NAME "PYBv4"
|
||||
|
||||
#define MICROPY_HW_HAS_SWITCH (1)
|
||||
#define MICROPY_HW_HAS_SDCARD (1)
|
||||
#define MICROPY_HW_HAS_MMA7660 (1)
|
||||
#define MICROPY_HW_HAS_LIS3DSH (0)
|
||||
#define MICROPY_HW_HAS_LCD (1)
|
||||
#define MICROPY_HW_HAS_WLAN (0)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
#define MICROPY_HW_ENABLE_TIMER (1)
|
||||
#define MICROPY_HW_ENABLE_SERVO (1)
|
||||
#define MICROPY_HW_ENABLE_AUDIO (0)
|
||||
|
||||
#define USRSW_PORT (GPIOB)
|
||||
#define USRSW_PIN (GPIO_Pin_3)
|
||||
#define USRSW_PUPD (GPIO_PuPd_UP)
|
||||
#define USRSW_EXTI_PIN (EXTI_PinSource3)
|
||||
#define USRSW_EXTI_PORT (EXTI_PortSourceGPIOB)
|
||||
#define USRSW_EXTI_LINE (EXTI_Line3)
|
||||
#define USRSW_EXTI_IRQN (EXTI15_10_IRQn)
|
||||
#define USRSW_EXTI_EDGE (EXTI_Trigger_Rising)
|
||||
|
||||
/* LED */
|
||||
#define PYB_LED1_PORT (GPIOA)
|
||||
#define PYB_LED1_PIN (GPIO_Pin_13)
|
||||
|
||||
#define PYB_LED2_PORT (GPIOA)
|
||||
#define PYB_LED2_PIN (GPIO_Pin_14)
|
||||
|
||||
#define PYB_LED3_PORT (GPIOA)
|
||||
#define PYB_LED3_PIN (GPIO_Pin_15)
|
||||
|
||||
#define PYB_LED4_PORT (GPIOB)
|
||||
#define PYB_LED4_PIN (GPIO_Pin_4)
|
||||
|
||||
#define PYB_OTYPE (GPIO_OType_PP)
|
||||
|
||||
#define PYB_LED_ON(port, pin) (port->BSRRL = pin)
|
||||
#define PYB_LED_OFF(port, pin) (port->BSRRH = pin)
|
||||
|
||||
#elif defined (STM32F4DISC)
|
||||
#define MICROPY_HW_BOARD_NAME "F4DISC"
|
||||
|
||||
#define MICROPY_HW_HAS_SWITCH (0)
|
||||
#define MICROPY_HW_HAS_SDCARD (0)
|
||||
#define MICROPY_HW_HAS_MMA7660 (0)
|
||||
#define MICROPY_HW_HAS_LIS3DSH (0)
|
||||
#define MICROPY_HW_HAS_LCD (0)
|
||||
#define MICROPY_HW_HAS_WLAN (0)
|
||||
#define MICROPY_HW_ENABLE_RNG (0)
|
||||
#define MICROPY_HW_ENABLE_RTC (0)
|
||||
#define MICROPY_HW_ENABLE_TIMER (0)
|
||||
#define MICROPY_HW_ENABLE_SERVO (0)
|
||||
#define MICROPY_HW_ENABLE_AUDIO (0)
|
||||
|
||||
#define USRSW_PORT (GPIOA)
|
||||
#define USRSW_PIN (GPIO_Pin_0)
|
||||
#define USRSW_PUPD (GPIO_PuPd_NOPULL)
|
||||
#define USRSW_EXTI_PIN (EXTI_PinSource0)
|
||||
#define USRSW_EXTI_PORT (EXTI_PortSourceGPIOA)
|
||||
#define USRSW_EXTI_LINE (EXTI_Line0)
|
||||
#define USRSW_EXTI_IRQN (EXTI0_IRQn)
|
||||
#define USRSW_EXTI_EDGE (EXTI_Trigger_Falling)
|
||||
|
||||
/* LED */
|
||||
#define PYB_LED1_PORT (GPIOD)
|
||||
#define PYB_LED1_PIN (GPIO_Pin_14)
|
||||
|
||||
#define PYB_LED2_PORT (GPIOD)
|
||||
#define PYB_LED2_PIN (GPIO_Pin_12)
|
||||
|
||||
#define PYB_LED3_PORT (GPIOD)
|
||||
#define PYB_LED3_PIN (GPIO_Pin_15)
|
||||
|
||||
#define PYB_LED4_PORT (GPIOD)
|
||||
#define PYB_LED4_PIN (GPIO_Pin_13)
|
||||
|
||||
#define PYB_OTYPE (GPIO_OType_PP)
|
||||
|
||||
#define PYB_LED_ON(port, pin) (port->BSRRL = pin)
|
||||
#define PYB_LED_OFF(port, pin) (port->BSRRH = pin)
|
||||
|
||||
#endif
|
||||
|
||||
//#define STM32F40_41xxx
|
||||
//#define USE_STDPERIPH_DRIVER
|
||||
//#define HSE_VALUE (8000000)
|
||||
#define USE_DEVICE_MODE
|
||||
//#define USE_HOST_MODE
|
||||
|
||||
#define sys_tick_counter systick_current_millis()
|
||||
#define sys_tick_has_passed systick_has_passed
|
||||
28
include/MicroPython/nlr.h
Normal file
28
include/MicroPython/nlr.h
Normal file
@ -0,0 +1,28 @@
|
||||
// non-local return
|
||||
// exception handling, basically a stack of setjmp/longjmp buffers
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
//#ifndef __WORDSIZE
|
||||
//#error __WORDSIZE needs to be defined
|
||||
//#endif
|
||||
|
||||
typedef struct _nlr_buf_t nlr_buf_t;
|
||||
struct _nlr_buf_t {
|
||||
// the entries here must all be machine word size
|
||||
nlr_buf_t *prev;
|
||||
void *ret_val;
|
||||
#if __WORDSIZE == 32
|
||||
void *regs[6];
|
||||
#elif __WORDSIZE == 64
|
||||
void *regs[8];
|
||||
#else
|
||||
// hack for thumb
|
||||
void *regs[10];
|
||||
//#error Unsupported __WORDSIZE
|
||||
#endif
|
||||
};
|
||||
|
||||
unsigned int nlr_push(nlr_buf_t *);
|
||||
void nlr_pop(void);
|
||||
void nlr_jump(void *val) __attribute__((noreturn));
|
||||
397
include/MicroPython/obj.h
Normal file
397
include/MicroPython/obj.h
Normal file
@ -0,0 +1,397 @@
|
||||
// All Micro Python objects are at least this type
|
||||
// It must be of pointer size
|
||||
|
||||
typedef machine_ptr_t mp_obj_t;
|
||||
typedef machine_const_ptr_t mp_const_obj_t;
|
||||
|
||||
// Integers that fit in a pointer have this type
|
||||
// (do we need to expose this in the public API?)
|
||||
|
||||
typedef machine_int_t mp_small_int_t;
|
||||
|
||||
// The machine floating-point type used for float and complex numbers
|
||||
|
||||
#if MICROPY_ENABLE_FLOAT
|
||||
typedef machine_float_t mp_float_t;
|
||||
#endif
|
||||
|
||||
// Anything that wants to be a Micro Python object must have
|
||||
// mp_obj_base_t as its first member (except NULL and small ints)
|
||||
|
||||
struct _mp_obj_type_t;
|
||||
struct _mp_obj_base_t {
|
||||
const struct _mp_obj_type_t *type;
|
||||
};
|
||||
typedef struct _mp_obj_base_t mp_obj_base_t;
|
||||
|
||||
// The NULL object is used to indicate the absence of an object
|
||||
// It *cannot* be used when an mp_obj_t is expected, except where explicitly allowed
|
||||
|
||||
#define MP_OBJ_NULL ((mp_obj_t)NULL)
|
||||
|
||||
// These macros check for small int, qstr or object, and access small int and qstr values
|
||||
// - xxxx...xxx1: a small int, bits 1 and above are the value
|
||||
// - xxxx...xx10: a qstr, bits 2 and above are the value
|
||||
// - xxxx...xx00: a pointer to an mp_obj_base_t
|
||||
|
||||
// In SMALL_INT, next-to-highest bits is used as sign, so both must match for value in range
|
||||
#define MP_OBJ_FITS_SMALL_INT(n) ((((n) ^ ((n) << 1)) & WORD_MSBIT_HIGH) == 0)
|
||||
#define MP_OBJ_IS_SMALL_INT(o) ((((mp_small_int_t)(o)) & 1) != 0)
|
||||
#define MP_OBJ_IS_QSTR(o) ((((mp_small_int_t)(o)) & 3) == 2)
|
||||
#define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 3) == 0)
|
||||
#define MP_OBJ_IS_TYPE(o, t) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type == (t))) // this does not work for checking a string, use below macro for that
|
||||
#define MP_OBJ_IS_INT(o) (MP_OBJ_IS_SMALL_INT(o) || MP_OBJ_IS_TYPE(o, &int_type))
|
||||
#define MP_OBJ_IS_STR(o) (MP_OBJ_IS_QSTR(o) || MP_OBJ_IS_TYPE(o, &str_type))
|
||||
|
||||
#define MP_OBJ_SMALL_INT_VALUE(o) (((mp_small_int_t)(o)) >> 1)
|
||||
#define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)(((small_int) << 1) | 1))
|
||||
|
||||
#define MP_OBJ_QSTR_VALUE(o) (((mp_small_int_t)(o)) >> 2)
|
||||
#define MP_OBJ_NEW_QSTR(qstr) ((mp_obj_t)((((machine_uint_t)qstr) << 2) | 2))
|
||||
|
||||
// These macros are used to declare and define constant function objects
|
||||
// You can put "static" in front of the definitions to make them local
|
||||
|
||||
#define MP_DECLARE_CONST_FUN_OBJ(obj_name) extern const mp_obj_fun_native_t obj_name
|
||||
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, is_kw, n_args_min, n_args_max, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, is_kw, n_args_min, n_args_max, (void *)fun_name}
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 0, 0, (mp_fun_0_t)fun_name)
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 1, 1, (mp_fun_1_t)fun_name)
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 2, 2, (mp_fun_2_t)fun_name)
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 3, 3, (mp_fun_3_t)fun_name)
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, (~((machine_uint_t)0)), (mp_fun_var_t)fun_name)
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, n_args_max, (mp_fun_var_t)fun_name)
|
||||
#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, true, n_args_min, (~((machine_uint_t)0)), (mp_fun_kw_t)fun_name)
|
||||
|
||||
// These macros are used to declare and define constant staticmethond and classmethod objects
|
||||
// You can put "static" in front of the definitions to make them local
|
||||
|
||||
#define MP_DECLARE_CONST_STATICMETHOD_OBJ(obj_name) extern const mp_obj_staticmethod_t obj_name
|
||||
#define MP_DECLARE_CONST_CLASSMETHOD_OBJ(obj_name) extern const mp_obj_classmethod_t obj_name
|
||||
|
||||
#define MP_DEFINE_CONST_STATICMETHOD_OBJ(obj_name, fun_name) const mp_obj_staticmethod_t obj_name = {{&mp_type_staticmethod}, fun_name}
|
||||
#define MP_DEFINE_CONST_CLASSMETHOD_OBJ(obj_name, fun_name) const mp_obj_classmethod_t obj_name = {{&mp_type_classmethod}, fun_name}
|
||||
|
||||
// Need to declare this here so we are not dependent on map.h
|
||||
struct _mp_map_t;
|
||||
struct _mp_map_elem_t;
|
||||
enum _mp_map_lookup_kind_t;
|
||||
|
||||
// Type definitions for methods
|
||||
|
||||
typedef mp_obj_t (*mp_fun_0_t)(void);
|
||||
typedef mp_obj_t (*mp_fun_1_t)(mp_obj_t);
|
||||
typedef mp_obj_t (*mp_fun_2_t)(mp_obj_t, mp_obj_t);
|
||||
typedef mp_obj_t (*mp_fun_3_t)(mp_obj_t, mp_obj_t, mp_obj_t);
|
||||
typedef mp_obj_t (*mp_fun_t)(void);
|
||||
typedef mp_obj_t (*mp_fun_var_t)(uint n, const mp_obj_t *);
|
||||
typedef mp_obj_t (*mp_fun_kw_t)(uint n, const mp_obj_t *, struct _mp_map_t *);
|
||||
|
||||
typedef enum {
|
||||
PRINT_STR, PRINT_REPR
|
||||
} mp_print_kind_t;
|
||||
|
||||
typedef void (*mp_print_fun_t)(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o, mp_print_kind_t kind);
|
||||
typedef mp_obj_t (*mp_make_new_fun_t)(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args);
|
||||
typedef mp_obj_t (*mp_call_fun_t)(mp_obj_t fun, uint n_args, uint n_kw, const mp_obj_t *args);
|
||||
typedef mp_obj_t (*mp_unary_op_fun_t)(int op, mp_obj_t);
|
||||
typedef mp_obj_t (*mp_binary_op_fun_t)(int op, mp_obj_t, mp_obj_t);
|
||||
typedef void (*mp_load_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t *dest); // for fail, do nothing; for attr, dest[0] = value; for method, dest[0] = method, dest[1] = self
|
||||
typedef bool (*mp_store_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t value); // return true if store succeeded
|
||||
typedef bool (*mp_store_item_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value); // return true if store succeeded
|
||||
|
||||
typedef struct _mp_method_t {
|
||||
const char *name;
|
||||
mp_const_obj_t fun;
|
||||
} mp_method_t;
|
||||
|
||||
// Buffer protocol
|
||||
typedef struct _buffer_info_t {
|
||||
// if we'd bother to support various versions of structure
|
||||
// (with different number of fields), we can distinguish
|
||||
// them with ver = sizeof(struct). Cons: overkill for *micro*?
|
||||
//int ver; // ?
|
||||
|
||||
void *buf;
|
||||
machine_int_t len;
|
||||
|
||||
// Rationale: have array.array and have SIMD operations on them
|
||||
// Cons: users can pass item size to processing functions themselves,
|
||||
// though that's not "plug&play"
|
||||
// int itemsize;
|
||||
|
||||
// Rationale: to load arbitrary-sized sprites directly to LCD
|
||||
// Cons: a bit adhoc usecase
|
||||
// int stride;
|
||||
} buffer_info_t;
|
||||
#define BUFFER_READ (1)
|
||||
#define BUFFER_WRITE (2)
|
||||
#define BUFFER_RW (BUFFER_READ | BUFFER_WRITE)
|
||||
typedef struct _mp_buffer_p_t {
|
||||
machine_int_t (*get_buffer)(mp_obj_t obj, buffer_info_t *bufinfo, int flags);
|
||||
} mp_buffer_p_t;
|
||||
|
||||
// Stream protocol
|
||||
typedef struct _mp_stream_p_t {
|
||||
// On error, functions should return -1 and fill in *errcode (values are
|
||||
// implementation-dependent, but will be exposed to user, e.g. via exception).
|
||||
machine_int_t (*read)(mp_obj_t obj, void *buf, machine_uint_t size, int *errcode);
|
||||
machine_int_t (*write)(mp_obj_t obj, const void *buf, machine_uint_t size, int *errcode);
|
||||
// add seek() ?
|
||||
} mp_stream_p_t;
|
||||
|
||||
struct _mp_obj_type_t {
|
||||
mp_obj_base_t base;
|
||||
const char *name;
|
||||
mp_print_fun_t print;
|
||||
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_fun_1_t getiter;
|
||||
mp_fun_1_t iternext;
|
||||
|
||||
// Alternatively, pointer(s) to interfaces to save space
|
||||
// in mp_obj_type_t at the expense of extra pointer and extra dereference
|
||||
// when actually used.
|
||||
mp_buffer_p_t buffer_p;
|
||||
mp_stream_p_t stream_p;
|
||||
|
||||
const mp_method_t *methods;
|
||||
|
||||
mp_load_attr_fun_t load_attr;
|
||||
mp_store_attr_fun_t store_attr;
|
||||
// Implements container[index] = val; note that load_item is implemented
|
||||
// by binary_op(RT_BINARY_OP_SUBSCR)
|
||||
mp_store_item_fun_t store_item;
|
||||
|
||||
// these are for dynamically created types (classes)
|
||||
mp_obj_t bases_tuple;
|
||||
mp_obj_t locals_dict;
|
||||
|
||||
/*
|
||||
What we might need to add here:
|
||||
|
||||
store_subscr list dict
|
||||
|
||||
len str tuple list map
|
||||
abs float complex
|
||||
hash bool int none str
|
||||
equal int str
|
||||
less int
|
||||
get_array_n tuple list
|
||||
|
||||
unpack seq list tuple
|
||||
*/
|
||||
};
|
||||
|
||||
typedef struct _mp_obj_type_t mp_obj_type_t;
|
||||
|
||||
// Constant objects, globally accessible
|
||||
|
||||
extern const mp_obj_type_t mp_const_type;
|
||||
extern const mp_obj_t mp_const_none;
|
||||
extern const mp_obj_t mp_const_false;
|
||||
extern const mp_obj_t mp_const_true;
|
||||
extern const mp_obj_t mp_const_empty_tuple;
|
||||
extern const mp_obj_t mp_const_ellipsis;
|
||||
extern const mp_obj_t mp_const_stop_iteration; // special object indicating end of iteration (not StopIteration exception!)
|
||||
|
||||
// General API for objects
|
||||
|
||||
mp_obj_t mp_obj_new_type(const char *name, mp_obj_t bases_tuple, mp_obj_t locals_dict);
|
||||
mp_obj_t mp_obj_new_none(void);
|
||||
mp_obj_t mp_obj_new_bool(bool value);
|
||||
mp_obj_t mp_obj_new_cell(mp_obj_t obj);
|
||||
mp_obj_t mp_obj_new_int(machine_int_t value);
|
||||
mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value);
|
||||
mp_obj_t mp_obj_new_int_from_long_str(const char *s);
|
||||
mp_obj_t mp_obj_new_str(const byte* data, uint len, bool make_qstr_if_not_already);
|
||||
mp_obj_t mp_obj_new_bytes(const byte* data, uint len);
|
||||
#if MICROPY_ENABLE_FLOAT
|
||||
mp_obj_t mp_obj_new_float(mp_float_t val);
|
||||
mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
|
||||
#endif
|
||||
mp_obj_t mp_obj_new_exception(qstr id);
|
||||
mp_obj_t mp_obj_new_exception_msg(qstr id, const char *msg);
|
||||
mp_obj_t mp_obj_new_exception_msg_1_arg(qstr id, const char *fmt, const char *a1);
|
||||
mp_obj_t mp_obj_new_exception_msg_2_args(qstr id, const char *fmt, const char *a1, const char *a2);
|
||||
mp_obj_t mp_obj_new_exception_msg_varg(qstr id, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
|
||||
mp_obj_t mp_obj_new_range(int start, int stop, int step);
|
||||
mp_obj_t mp_obj_new_range_iterator(int cur, int stop, int step);
|
||||
mp_obj_t mp_obj_new_fun_bc(int n_args, uint n_state, const byte *code);
|
||||
mp_obj_t mp_obj_new_fun_asm(uint n_args, void *fun);
|
||||
mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun);
|
||||
mp_obj_t mp_obj_new_gen_instance(const byte *bytecode, uint n_state, int n_args, const mp_obj_t *args);
|
||||
mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_obj_t closure_tuple);
|
||||
mp_obj_t mp_obj_new_tuple(uint n, const mp_obj_t *items);
|
||||
mp_obj_t mp_obj_new_list(uint n, mp_obj_t *items);
|
||||
mp_obj_t mp_obj_new_dict(int n_args);
|
||||
mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items);
|
||||
mp_obj_t mp_obj_new_slice(mp_obj_t start, mp_obj_t stop, mp_obj_t step);
|
||||
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);
|
||||
|
||||
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);
|
||||
void mp_obj_print_exception(mp_obj_t exc);
|
||||
|
||||
bool mp_obj_is_callable(mp_obj_t o_in);
|
||||
machine_int_t mp_obj_hash(mp_obj_t o_in);
|
||||
bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2);
|
||||
bool mp_obj_less(mp_obj_t o1, mp_obj_t o2);
|
||||
|
||||
machine_int_t mp_obj_get_int(mp_obj_t arg);
|
||||
#if MICROPY_ENABLE_FLOAT
|
||||
mp_float_t mp_obj_get_float(mp_obj_t self_in);
|
||||
void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
|
||||
#endif
|
||||
//qstr mp_obj_get_qstr(mp_obj_t arg);
|
||||
mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o, machine_int_t n);
|
||||
uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index);
|
||||
mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); /* may return NULL */
|
||||
|
||||
// none
|
||||
extern const mp_obj_type_t none_type;
|
||||
|
||||
// bool
|
||||
extern const mp_obj_type_t bool_type;
|
||||
#define MP_BOOL(x) (x ? mp_const_true : mp_const_false)
|
||||
|
||||
// cell
|
||||
mp_obj_t mp_obj_cell_get(mp_obj_t self_in);
|
||||
void mp_obj_cell_set(mp_obj_t self_in, mp_obj_t obj);
|
||||
|
||||
// int
|
||||
extern const mp_obj_type_t int_type;
|
||||
// For long int, returns value truncated to machine_int_t
|
||||
machine_int_t mp_obj_int_get(mp_obj_t self_in);
|
||||
// Will rains exception if value doesn't fit into machine_int_t
|
||||
machine_int_t mp_obj_int_get_checked(mp_obj_t self_in);
|
||||
|
||||
// exception
|
||||
extern const mp_obj_type_t exception_type;
|
||||
qstr mp_obj_exception_get_type(mp_obj_t self_in);
|
||||
void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, machine_uint_t line, qstr block);
|
||||
void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine_uint_t **values);
|
||||
|
||||
// str
|
||||
extern const mp_obj_type_t str_type;
|
||||
mp_obj_t mp_obj_str_builder_start(const mp_obj_type_t *type, uint len, byte **data);
|
||||
mp_obj_t mp_obj_str_builder_end(mp_obj_t o_in);
|
||||
bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2);
|
||||
uint mp_obj_str_get_hash(mp_obj_t self_in);
|
||||
uint mp_obj_str_get_len(mp_obj_t self_in);
|
||||
qstr mp_obj_str_get_qstr(mp_obj_t self_in); // use this if you will anyway convert the string to a qstr
|
||||
const char *mp_obj_str_get_str(mp_obj_t self_in); // use this only if you need the string to be null terminated
|
||||
const byte *mp_obj_str_get_data(mp_obj_t self_in, uint *len);
|
||||
void mp_str_print_quoted(void (*print)(void *env, const char *fmt, ...), void *env, const byte *str_data, uint str_len);
|
||||
|
||||
// bytes
|
||||
extern const mp_obj_type_t bytes_type;
|
||||
|
||||
#if MICROPY_ENABLE_FLOAT
|
||||
// float
|
||||
extern const mp_obj_type_t float_type;
|
||||
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);
|
||||
|
||||
// complex
|
||||
extern const mp_obj_type_t complex_type;
|
||||
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);
|
||||
#endif
|
||||
|
||||
// tuple
|
||||
extern const mp_obj_type_t tuple_type;
|
||||
void mp_obj_tuple_get(mp_obj_t self_in, uint *len, mp_obj_t **items);
|
||||
void mp_obj_tuple_del(mp_obj_t self_in);
|
||||
|
||||
// list
|
||||
extern const mp_obj_type_t list_type;
|
||||
mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg);
|
||||
void mp_obj_list_get(mp_obj_t self_in, uint *len, mp_obj_t **items);
|
||||
void mp_obj_list_store(mp_obj_t self_in, mp_obj_t index, mp_obj_t value);
|
||||
mp_obj_t mp_obj_list_sort(uint n_args, const mp_obj_t *args, struct _mp_map_t *kwargs);
|
||||
|
||||
// map (the python builtin, not the dict implementation detail)
|
||||
extern const mp_obj_type_t map_type;
|
||||
|
||||
// enumerate
|
||||
extern const mp_obj_type_t enumerate_type;
|
||||
|
||||
// filter
|
||||
extern const mp_obj_type_t filter_type;
|
||||
|
||||
// dict
|
||||
extern const mp_obj_type_t dict_type;
|
||||
uint mp_obj_dict_len(mp_obj_t self_in);
|
||||
mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value);
|
||||
struct _mp_map_t *mp_obj_dict_get_map(mp_obj_t self_in);
|
||||
|
||||
// set
|
||||
extern const mp_obj_type_t set_type;
|
||||
void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item);
|
||||
|
||||
// slice
|
||||
extern const mp_obj_type_t slice_type;
|
||||
void mp_obj_slice_get(mp_obj_t self_in, machine_int_t *start, machine_int_t *stop, machine_int_t *step);
|
||||
|
||||
// zip
|
||||
extern const mp_obj_type_t zip_type;
|
||||
|
||||
// array
|
||||
extern const mp_obj_type_t array_type;
|
||||
uint mp_obj_array_len(mp_obj_t self_in);
|
||||
mp_obj_t mp_obj_new_bytearray_by_ref(uint n, void *items);
|
||||
|
||||
// functions
|
||||
typedef struct _mp_obj_fun_native_t { // need this so we can define const objects (to go in ROM)
|
||||
mp_obj_base_t base;
|
||||
bool is_kw : 1;
|
||||
machine_uint_t n_args_min : (sizeof(machine_uint_t) - 1); // inclusive
|
||||
machine_uint_t n_args_max; // inclusive
|
||||
void *fun;
|
||||
// TODO add mp_map_t *globals
|
||||
// for const function objects, make an empty, const map
|
||||
// such functions won't be able to access the global scope, but that's probably okay
|
||||
} mp_obj_fun_native_t;
|
||||
|
||||
extern const mp_obj_type_t fun_native_type;
|
||||
extern const mp_obj_type_t fun_bc_type;
|
||||
void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code);
|
||||
|
||||
mp_obj_t mp_identity(mp_obj_t self);
|
||||
|
||||
// generator
|
||||
extern const mp_obj_type_t gen_instance_type;
|
||||
|
||||
// module
|
||||
extern const mp_obj_type_t module_type;
|
||||
mp_obj_t mp_obj_new_module(qstr module_name);
|
||||
mp_obj_t mp_obj_module_get(qstr module_name);
|
||||
struct _mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in);
|
||||
|
||||
// staticmethod and classmethod types; defined here so we can make const versions
|
||||
|
||||
extern const mp_obj_type_t mp_type_staticmethod;
|
||||
extern const mp_obj_type_t mp_type_classmethod;
|
||||
|
||||
typedef struct _mp_obj_staticmethod_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t fun;
|
||||
} mp_obj_staticmethod_t;
|
||||
|
||||
typedef struct _mp_obj_classmethod_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t fun;
|
||||
} mp_obj_classmethod_t;
|
||||
|
||||
// sequence helpers
|
||||
void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest);
|
||||
67
include/MicroPython/parse.h
Normal file
67
include/MicroPython/parse.h
Normal file
@ -0,0 +1,67 @@
|
||||
struct _mp_lexer_t;
|
||||
|
||||
// a mp_parse_node_t is:
|
||||
// - 0000...0000: no node
|
||||
// - xxxx...0001: an identifier; bits 4 and above are the qstr
|
||||
// - xxxx...0011: a small integer; bits 4 and above are the signed value, 2's complement
|
||||
// - xxxx...0101: an integer; bits 4 and above are the qstr holding the value
|
||||
// - xxxx...0111: a decimal; bits 4 and above are the qstr holding the value
|
||||
// - xxxx...1001: a string; bits 4 and above are the qstr holding the value
|
||||
// - xxxx...1011: a string with triple quotes; bits 4 and above are the qstr holding the value
|
||||
// - xxxx...1101: a token; bits 4 and above are mp_token_kind_t
|
||||
// - xxxx...xxx0: pointer to mp_parse_node_struct_t
|
||||
|
||||
// makes sure the top 5 bits of x are all cleared (positive number) or all set (negavite number)
|
||||
// these macros can probably go somewhere else because they are used more than just in the parser
|
||||
#define MP_UINT_HIGH_5_BITS (~((~((machine_uint_t)0)) >> 5))
|
||||
#define MP_FIT_SMALL_INT(x) (((((machine_uint_t)(x)) & MP_UINT_HIGH_5_BITS) == 0) || ((((machine_uint_t)(x)) & MP_UINT_HIGH_5_BITS) == MP_UINT_HIGH_5_BITS))
|
||||
|
||||
#define MP_PARSE_NODE_NULL (0)
|
||||
#define MP_PARSE_NODE_ID (0x1)
|
||||
#define MP_PARSE_NODE_SMALL_INT (0x3)
|
||||
#define MP_PARSE_NODE_INTEGER (0x5)
|
||||
#define MP_PARSE_NODE_DECIMAL (0x7)
|
||||
#define MP_PARSE_NODE_STRING (0x9)
|
||||
#define MP_PARSE_NODE_BYTES (0xb)
|
||||
#define MP_PARSE_NODE_TOKEN (0xd)
|
||||
|
||||
typedef machine_uint_t mp_parse_node_t; // must be pointer size
|
||||
|
||||
typedef struct _mp_parse_node_struct_t {
|
||||
uint32_t source_line; // line number in source file
|
||||
uint32_t kind_num_nodes; // parse node kind, and number of nodes
|
||||
mp_parse_node_t nodes[]; // nodes
|
||||
} mp_parse_node_struct_t;
|
||||
|
||||
// macros for mp_parse_node_t usage
|
||||
// some of these evaluate their argument more than once
|
||||
|
||||
#define MP_PARSE_NODE_IS_NULL(pn) ((pn) == MP_PARSE_NODE_NULL)
|
||||
#define MP_PARSE_NODE_IS_LEAF(pn) ((pn) & 1)
|
||||
#define MP_PARSE_NODE_IS_STRUCT(pn) ((pn) != MP_PARSE_NODE_NULL && ((pn) & 1) == 0)
|
||||
#define MP_PARSE_NODE_IS_STRUCT_KIND(pn, k) ((pn) != MP_PARSE_NODE_NULL && ((pn) & 1) == 0 && MP_PARSE_NODE_STRUCT_KIND((mp_parse_node_struct_t*)(pn)) == (k))
|
||||
|
||||
#define MP_PARSE_NODE_IS_ID(pn) (((pn) & 0xf) == MP_PARSE_NODE_ID)
|
||||
#define MP_PARSE_NODE_IS_SMALL_INT(pn) (((pn) & 0xf) == MP_PARSE_NODE_SMALL_INT)
|
||||
#define MP_PARSE_NODE_IS_TOKEN(pn) (((pn) & 0xf) == MP_PARSE_NODE_TOKEN)
|
||||
#define MP_PARSE_NODE_IS_TOKEN_KIND(pn, k) ((pn) == (MP_PARSE_NODE_TOKEN | (k << 4)))
|
||||
|
||||
#define MP_PARSE_NODE_LEAF_KIND(pn) ((pn) & 0xf)
|
||||
// TODO should probably have int and uint versions of this macro
|
||||
#define MP_PARSE_NODE_LEAF_ARG(pn) (((machine_int_t)(pn)) >> 4)
|
||||
#define MP_PARSE_NODE_STRUCT_KIND(pns) ((pns)->kind_num_nodes & 0xff)
|
||||
#define MP_PARSE_NODE_STRUCT_NUM_NODES(pns) ((pns)->kind_num_nodes >> 8)
|
||||
|
||||
mp_parse_node_t mp_parse_node_new_leaf(machine_int_t kind, machine_int_t arg);
|
||||
uint mp_parse_node_free(mp_parse_node_t pn);
|
||||
|
||||
void mp_parse_node_print(mp_parse_node_t pn, int indent);
|
||||
|
||||
typedef enum {
|
||||
MP_PARSE_SINGLE_INPUT,
|
||||
MP_PARSE_FILE_INPUT,
|
||||
MP_PARSE_EVAL_INPUT,
|
||||
} mp_parse_input_kind_t;
|
||||
|
||||
// returns MP_PARSE_NODE_NULL on error, and then exc_id_out and exc_msg_out are valid
|
||||
mp_parse_node_t mp_parse(struct _mp_lexer_t *lex, mp_parse_input_kind_t input_kind, qstr *exc_id_out, const char **exc_msg_out);
|
||||
40
include/MicroPython/qstr.h
Normal file
40
include/MicroPython/qstr.h
Normal file
@ -0,0 +1,40 @@
|
||||
// See qstrraw.h for a list of qstr's that are available as constants.
|
||||
// Reference them as MP_QSTR_xxxx.
|
||||
//
|
||||
// Note: it would be possible to define MP_QSTR_xxx as qstr_from_str_static("xxx")
|
||||
// for qstrs that are referenced this way, but you don't want to have them in ROM.
|
||||
|
||||
enum {
|
||||
MP_QSTR_NULL = 0, // indicates invalid/no qstr
|
||||
MP_QSTR_ = 1, // the empty qstr
|
||||
#define Q(id, str) MP_QSTR_##id,
|
||||
// TODO having 'build/py.' here is a bit of a hack, should take config variable from Makefile
|
||||
#include "qstrdefs.generated.h"
|
||||
#undef Q
|
||||
MP_QSTR_number_of,
|
||||
} category_t;
|
||||
|
||||
typedef machine_uint_t qstr;
|
||||
|
||||
#define QSTR_FROM_STR_STATIC(s) (qstr_from_strn((s), strlen(s)))
|
||||
|
||||
void qstr_init(void);
|
||||
|
||||
machine_uint_t qstr_compute_hash(const byte *data, uint len);
|
||||
qstr qstr_find_strn(const byte *str, uint str_len); // returns MP_QSTR_NULL if not found
|
||||
|
||||
qstr qstr_from_str(const char *str);
|
||||
qstr qstr_from_strn(const char *str, uint len);
|
||||
//qstr qstr_from_str_static(const char *str);
|
||||
qstr qstr_from_strn_take(char *str, uint alloc_len, uint len);
|
||||
//qstr qstr_from_strn_copy(const char *str, int len);
|
||||
|
||||
byte* qstr_build_start(uint len, byte **q_ptr);
|
||||
qstr qstr_build_end(byte *q_ptr);
|
||||
|
||||
machine_uint_t qstr_hash(qstr q);
|
||||
const char* qstr_str(qstr q);
|
||||
uint qstr_len(qstr q);
|
||||
const byte* qstr_data(qstr q, uint *len);
|
||||
|
||||
void qstr_pool_info(uint *n_pool, uint *n_qstr, uint *n_str_data_bytes, uint *n_total_bytes);
|
||||
108
include/MicroPython/qstrdefs.generated.h
Normal file
108
include/MicroPython/qstrdefs.generated.h
Normal file
@ -0,0 +1,108 @@
|
||||
// This file was automatically generated by makeqstrdata.py
|
||||
|
||||
Q(__build_class__, (const byte*)"\x01\x06\x0f\x00" "__build_class__")
|
||||
Q(__class__, (const byte*)"\x92\x03\x09\x00" "__class__")
|
||||
Q(__doc__, (const byte*)"\xb2\x02\x07\x00" "__doc__")
|
||||
Q(__init__, (const byte*)"\x30\x03\x08\x00" "__init__")
|
||||
Q(__locals__, (const byte*)"\xfa\x03\x0a\x00" "__locals__")
|
||||
Q(__main__, (const byte*)"\x21\x03\x08\x00" "__main__")
|
||||
Q(__module__, (const byte*)"\x02\x04\x0a\x00" "__module__")
|
||||
Q(__name__, (const byte*)"\x1d\x03\x08\x00" "__name__")
|
||||
Q(__next__, (const byte*)"\x3b\x03\x08\x00" "__next__")
|
||||
Q(__qualname__, (const byte*)"\xd0\x04\x0c\x00" "__qualname__")
|
||||
Q(__repl_print__, (const byte*)"\xbb\x05\x0e\x00" "__repl_print__")
|
||||
Q(__bool__, (const byte*)"\x28\x03\x08\x00" "__bool__")
|
||||
Q(__len__, (const byte*)"\xbb\x02\x07\x00" "__len__")
|
||||
Q(__getitem__, (const byte*)"\x6b\x04\x0b\x00" "__getitem__")
|
||||
Q(__add__, (const byte*)"\xa5\x02\x07\x00" "__add__")
|
||||
Q(__sub__, (const byte*)"\xc6\x02\x07\x00" "__sub__")
|
||||
Q(micropython, (const byte*)"\xbc\x04\x0b\x00" "micropython")
|
||||
Q(byte_code, (const byte*)"\xae\x03\x09\x00" "byte_code")
|
||||
Q(native, (const byte*)"\x87\x02\x06\x00" "native")
|
||||
Q(viper, (const byte*)"\x26\x02\x05\x00" "viper")
|
||||
Q(asm_thumb, (const byte*)"\xc0\x03\x09\x00" "asm_thumb")
|
||||
Q(Ellipsis, (const byte*)"\x45\x03\x08\x00" "Ellipsis")
|
||||
Q(StopIteration, (const byte*)"\x55\x05\x0d\x00" "StopIteration")
|
||||
Q(AssertionError, (const byte*)"\xc2\x05\x0e\x00" "AssertionError")
|
||||
Q(AttributeError, (const byte*)"\xbe\x05\x0e\x00" "AttributeError")
|
||||
Q(IndentationError, (const byte*)"\x87\x06\x10\x00" "IndentationError")
|
||||
Q(IndexError, (const byte*)"\x02\x04\x0a\x00" "IndexError")
|
||||
Q(KeyError, (const byte*)"\x33\x03\x08\x00" "KeyError")
|
||||
Q(NameError, (const byte*)"\x8b\x03\x09\x00" "NameError")
|
||||
Q(OSError, (const byte*)"\xac\x02\x07\x00" "OSError")
|
||||
Q(SyntaxError, (const byte*)"\x91\x04\x0b\x00" "SyntaxError")
|
||||
Q(TypeError, (const byte*)"\xac\x03\x09\x00" "TypeError")
|
||||
Q(ValueError, (const byte*)"\x07\x04\x0a\x00" "ValueError")
|
||||
Q(OverflowError, (const byte*)"\x5e\x05\x0d\x00" "OverflowError")
|
||||
Q(abs, (const byte*)"\x36\x01\x03\x00" "abs")
|
||||
Q(all, (const byte*)"\x39\x01\x03\x00" "all")
|
||||
Q(any, (const byte*)"\x48\x01\x03\x00" "any")
|
||||
Q(array, (const byte*)"\x1f\x02\x05\x00" "array")
|
||||
Q(bool, (const byte*)"\xac\x01\x04\x00" "bool")
|
||||
Q(bytearray, (const byte*)"\xd3\x03\x09\x00" "bytearray")
|
||||
Q(bytes, (const byte*)"\x27\x02\x05\x00" "bytes")
|
||||
Q(callable, (const byte*)"\x30\x03\x08\x00" "callable")
|
||||
Q(chr, (const byte*)"\x3d\x01\x03\x00" "chr")
|
||||
Q(complex, (const byte*)"\xf8\x02\x07\x00" "complex")
|
||||
Q(dict, (const byte*)"\xa4\x01\x04\x00" "dict")
|
||||
Q(divmod, (const byte*)"\x83\x02\x06\x00" "divmod")
|
||||
Q(enumerate, (const byte*)"\xc6\x03\x09\x00" "enumerate")
|
||||
Q(eval, (const byte*)"\xa8\x01\x04\x00" "eval")
|
||||
Q(filter, (const byte*)"\x86\x02\x06\x00" "filter")
|
||||
Q(float, (const byte*)"\x16\x02\x05\x00" "float")
|
||||
Q(hash, (const byte*)"\xa4\x01\x04\x00" "hash")
|
||||
Q(int, (const byte*)"\x4b\x01\x03\x00" "int")
|
||||
Q(isinstance, (const byte*)"\x31\x04\x0a\x00" "isinstance")
|
||||
Q(issubclass, (const byte*)"\x3c\x04\x0a\x00" "issubclass")
|
||||
Q(iter, (const byte*)"\xb4\x01\x04\x00" "iter")
|
||||
Q(len, (const byte*)"\x3f\x01\x03\x00" "len")
|
||||
Q(list, (const byte*)"\xbc\x01\x04\x00" "list")
|
||||
Q(map, (const byte*)"\x3e\x01\x03\x00" "map")
|
||||
Q(max, (const byte*)"\x46\x01\x03\x00" "max")
|
||||
Q(min, (const byte*)"\x44\x01\x03\x00" "min")
|
||||
Q(next, (const byte*)"\xbf\x01\x04\x00" "next")
|
||||
Q(ord, (const byte*)"\x45\x01\x03\x00" "ord")
|
||||
Q(pow, (const byte*)"\x56\x01\x03\x00" "pow")
|
||||
Q(print, (const byte*)"\x2d\x02\x05\x00" "print")
|
||||
Q(range, (const byte*)"\x0d\x02\x05\x00" "range")
|
||||
Q(repr, (const byte*)"\xb9\x01\x04\x00" "repr")
|
||||
Q(set, (const byte*)"\x4c\x01\x03\x00" "set")
|
||||
Q(sorted, (const byte*)"\x91\x02\x06\x00" "sorted")
|
||||
Q(sum, (const byte*)"\x55\x01\x03\x00" "sum")
|
||||
Q(str, (const byte*)"\x59\x01\x03\x00" "str")
|
||||
Q(tuple, (const byte*)"\x2a\x02\x05\x00" "tuple")
|
||||
Q(type, (const byte*)"\xc2\x01\x04\x00" "type")
|
||||
Q(zip, (const byte*)"\x53\x01\x03\x00" "zip")
|
||||
Q(append, (const byte*)"\x78\x02\x06\x00" "append")
|
||||
Q(pop, (const byte*)"\x4f\x01\x03\x00" "pop")
|
||||
Q(sort, (const byte*)"\xc8\x01\x04\x00" "sort")
|
||||
Q(join, (const byte*)"\xb0\x01\x04\x00" "join")
|
||||
Q(strip, (const byte*)"\x32\x02\x05\x00" "strip")
|
||||
Q(format, (const byte*)"\x89\x02\x06\x00" "format")
|
||||
Q(_lt_module_gt_, (const byte*)"\x00\x03\x08\x00" "<module>")
|
||||
Q(_lt_lambda_gt_, (const byte*)"\xdb\x02\x08\x00" "<lambda>")
|
||||
Q(_lt_listcomp_gt_, (const byte*)"\xe5\x03\x0a\x00" "<listcomp>")
|
||||
Q(_lt_dictcomp_gt_, (const byte*)"\xcd\x03\x0a\x00" "<dictcomp>")
|
||||
Q(_lt_setcomp_gt_, (const byte*)"\x75\x03\x09\x00" "<setcomp>")
|
||||
Q(_lt_genexpr_gt_, (const byte*)"\x73\x03\x09\x00" "<genexpr>")
|
||||
Q(_lt_string_gt_, (const byte*)"\x11\x03\x08\x00" "<string>")
|
||||
Q(_lt_stdin_gt_, (const byte*)"\x9c\x02\x07\x00" "<stdin>")
|
||||
Q(help, (const byte*)"\xa9\x01\x04\x00" "help")
|
||||
Q(pyb, (const byte*)"\x4b\x01\x03\x00" "pyb")
|
||||
Q(info, (const byte*)"\xac\x01\x04\x00" "info")
|
||||
Q(stop, (const byte*)"\xc6\x01\x04\x00" "stop")
|
||||
Q(standby, (const byte*)"\xf5\x02\x07\x00" "standby")
|
||||
Q(source_dir, (const byte*)"\x2f\x04\x0a\x00" "source_dir")
|
||||
Q(main, (const byte*)"\xa5\x01\x04\x00" "main")
|
||||
Q(sync, (const byte*)"\xbd\x01\x04\x00" "sync")
|
||||
Q(gc, (const byte*)"\xca\x00\x02\x00" "gc")
|
||||
Q(delay, (const byte*)"\x0f\x02\x05\x00" "delay")
|
||||
Q(switch, (const byte*)"\x92\x02\x06\x00" "switch")
|
||||
Q(pwm, (const byte*)"\x54\x01\x03\x00" "pwm")
|
||||
Q(time, (const byte*)"\xaf\x01\x04\x00" "time")
|
||||
Q(rand, (const byte*)"\xa5\x01\x04\x00" "rand")
|
||||
Q(Led, (const byte*)"\x15\x01\x03\x00" "Led")
|
||||
Q(vcp_connected, (const byte*)"\x5b\x05\x0d\x00" "vcp_connected")
|
||||
Q(Usart, (const byte*)"\x0f\x02\x05\x00" "Usart")
|
||||
Q(ADC, (const byte*)"\xc8\x00\x03\x00" "ADC")
|
||||
Q(open, (const byte*)"\xb2\x01\x04\x00" "open")
|
||||
3
include/MicroPython/repl.h
Normal file
3
include/MicroPython/repl.h
Normal file
@ -0,0 +1,3 @@
|
||||
#if MICROPY_ENABLE_REPL_HELPERS
|
||||
bool mp_repl_is_compound_stmt(const char *line);
|
||||
#endif
|
||||
47
include/MicroPython/runtime.h
Normal file
47
include/MicroPython/runtime.h
Normal file
@ -0,0 +1,47 @@
|
||||
int rt_is_true(mp_obj_t arg);
|
||||
|
||||
mp_obj_t rt_load_const_dec(qstr qstr);
|
||||
mp_obj_t rt_load_const_str(qstr qstr);
|
||||
mp_obj_t rt_load_const_bytes(qstr qstr);
|
||||
mp_obj_t rt_load_name(qstr qstr);
|
||||
mp_obj_t rt_load_global(qstr qstr);
|
||||
mp_obj_t rt_load_build_class(void);
|
||||
mp_obj_t rt_get_cell(mp_obj_t cell);
|
||||
void rt_set_cell(mp_obj_t cell, mp_obj_t val);
|
||||
void rt_store_name(qstr qstr, mp_obj_t obj);
|
||||
void rt_store_global(qstr qstr, mp_obj_t obj);
|
||||
mp_obj_t rt_unary_op(int op, mp_obj_t arg);
|
||||
mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs);
|
||||
mp_obj_t rt_make_function_from_id(int unique_code_id);
|
||||
mp_obj_t rt_make_function_n(int n_args, void *fun); // fun must have the correct signature for n_args fixed arguments
|
||||
mp_obj_t rt_make_function_var(int n_args_min, mp_fun_var_t fun);
|
||||
mp_obj_t rt_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var_t fun); // min and max are inclusive
|
||||
mp_obj_t rt_make_closure_from_id(int unique_code_id, mp_obj_t closure_tuple);
|
||||
mp_obj_t rt_call_function_0(mp_obj_t fun);
|
||||
mp_obj_t rt_call_function_1(mp_obj_t fun, mp_obj_t arg);
|
||||
mp_obj_t rt_call_function_2(mp_obj_t fun, mp_obj_t arg1, mp_obj_t arg2);
|
||||
mp_obj_t rt_call_function_n_kw(mp_obj_t fun, uint n_args, uint n_kw, const mp_obj_t *args);
|
||||
mp_obj_t rt_call_method_n_kw(uint n_args, uint n_kw, const mp_obj_t *args);
|
||||
mp_obj_t rt_build_tuple(int n_args, mp_obj_t *items);
|
||||
mp_obj_t rt_build_list(int n_args, mp_obj_t *items);
|
||||
mp_obj_t rt_list_append(mp_obj_t list, mp_obj_t arg);
|
||||
mp_obj_t rt_build_set(int n_args, mp_obj_t *items);
|
||||
mp_obj_t rt_store_set(mp_obj_t set, mp_obj_t item);
|
||||
void rt_unpack_sequence(mp_obj_t seq, uint num, mp_obj_t *items);
|
||||
mp_obj_t rt_build_map(int n_args);
|
||||
mp_obj_t rt_store_map(mp_obj_t map, mp_obj_t key, mp_obj_t value);
|
||||
mp_obj_t rt_load_attr(mp_obj_t base, qstr attr);
|
||||
void rt_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest);
|
||||
void rt_store_attr(mp_obj_t base, qstr attr, mp_obj_t val);
|
||||
void rt_store_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t val);
|
||||
mp_obj_t rt_getiter(mp_obj_t o);
|
||||
mp_obj_t rt_iternext(mp_obj_t o);
|
||||
mp_obj_t rt_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level);
|
||||
mp_obj_t rt_import_from(mp_obj_t module, qstr name);
|
||||
|
||||
struct _mp_map_t;
|
||||
struct _mp_map_t *rt_locals_get(void);
|
||||
void rt_locals_set(struct _mp_map_t *m);
|
||||
struct _mp_map_t *rt_globals_get(void);
|
||||
void rt_globals_set(struct _mp_map_t *m);
|
||||
struct _mp_map_t *rt_loaded_modules_get(void);
|
||||
87
include/MicroPython/runtime0.h
Normal file
87
include/MicroPython/runtime0.h
Normal file
@ -0,0 +1,87 @@
|
||||
typedef enum {
|
||||
RT_UNARY_OP_BOOL, // __bool__
|
||||
RT_UNARY_OP_LEN, // __len__
|
||||
RT_UNARY_OP_POSITIVE,
|
||||
RT_UNARY_OP_NEGATIVE,
|
||||
RT_UNARY_OP_INVERT,
|
||||
// Used only for CPython-compatible codegeneration
|
||||
RT_UNARY_OP_NOT,
|
||||
} rt_unary_op_t;
|
||||
|
||||
typedef enum {
|
||||
RT_BINARY_OP_SUBSCR,
|
||||
RT_BINARY_OP_OR,
|
||||
RT_BINARY_OP_XOR,
|
||||
RT_BINARY_OP_AND,
|
||||
RT_BINARY_OP_LSHIFT,
|
||||
RT_BINARY_OP_RSHIFT,
|
||||
RT_BINARY_OP_ADD,
|
||||
RT_BINARY_OP_SUBTRACT,
|
||||
RT_BINARY_OP_MULTIPLY,
|
||||
RT_BINARY_OP_FLOOR_DIVIDE,
|
||||
RT_BINARY_OP_TRUE_DIVIDE,
|
||||
RT_BINARY_OP_MODULO,
|
||||
RT_BINARY_OP_POWER,
|
||||
RT_BINARY_OP_INPLACE_OR,
|
||||
RT_BINARY_OP_INPLACE_XOR,
|
||||
RT_BINARY_OP_INPLACE_AND,
|
||||
RT_BINARY_OP_INPLACE_LSHIFT,
|
||||
RT_BINARY_OP_INPLACE_RSHIFT,
|
||||
RT_BINARY_OP_INPLACE_ADD,
|
||||
RT_BINARY_OP_INPLACE_SUBTRACT,
|
||||
RT_BINARY_OP_INPLACE_MULTIPLY,
|
||||
RT_BINARY_OP_INPLACE_FLOOR_DIVIDE,
|
||||
RT_BINARY_OP_INPLACE_TRUE_DIVIDE,
|
||||
RT_BINARY_OP_INPLACE_MODULO,
|
||||
RT_BINARY_OP_INPLACE_POWER,
|
||||
// TODO probably should rename these COMPARE->BINARY
|
||||
RT_COMPARE_OP_LESS,
|
||||
RT_COMPARE_OP_MORE,
|
||||
RT_COMPARE_OP_EQUAL,
|
||||
RT_COMPARE_OP_LESS_EQUAL,
|
||||
RT_COMPARE_OP_MORE_EQUAL,
|
||||
RT_COMPARE_OP_NOT_EQUAL,
|
||||
RT_COMPARE_OP_IN,
|
||||
RT_COMPARE_OP_NOT_IN,
|
||||
RT_COMPARE_OP_IS,
|
||||
RT_COMPARE_OP_IS_NOT,
|
||||
RT_COMPARE_OP_EXCEPTION_MATCH,
|
||||
} rt_binary_op_t;
|
||||
|
||||
typedef enum {
|
||||
RT_F_LOAD_CONST_DEC = 0,
|
||||
RT_F_LOAD_CONST_STR,
|
||||
RT_F_LOAD_NAME,
|
||||
RT_F_LOAD_GLOBAL,
|
||||
RT_F_LOAD_BUILD_CLASS,
|
||||
RT_F_LOAD_ATTR,
|
||||
RT_F_LOAD_METHOD,
|
||||
RT_F_STORE_NAME,
|
||||
RT_F_STORE_ATTR,
|
||||
RT_F_STORE_SUBSCR,
|
||||
RT_F_IS_TRUE,
|
||||
RT_F_UNARY_OP,
|
||||
RT_F_BUILD_TUPLE,
|
||||
RT_F_BUILD_LIST,
|
||||
RT_F_LIST_APPEND,
|
||||
RT_F_BUILD_MAP,
|
||||
RT_F_STORE_MAP,
|
||||
RT_F_BUILD_SET,
|
||||
RT_F_STORE_SET,
|
||||
RT_F_MAKE_FUNCTION_FROM_ID,
|
||||
RT_F_CALL_FUNCTION_N,
|
||||
RT_F_CALL_METHOD_N,
|
||||
RT_F_BINARY_OP,
|
||||
RT_F_GETITER,
|
||||
RT_F_ITERNEXT,
|
||||
RT_F_NUMBER_OF,
|
||||
} rt_fun_kind_t;
|
||||
|
||||
extern void *const rt_fun_table[RT_F_NUMBER_OF];
|
||||
|
||||
void rt_init(void);
|
||||
void rt_deinit(void);
|
||||
uint rt_get_unique_code_id(void);
|
||||
void rt_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, bool is_generator);
|
||||
void rt_assign_native_code(uint unique_code_id, void *f, uint len, int n_args);
|
||||
void rt_assign_inline_asm_code(uint unique_code_id, void *f, uint len, int n_args);
|
||||
24
include/MicroPython/std.h
Normal file
24
include/MicroPython/std.h
Normal file
@ -0,0 +1,24 @@
|
||||
typedef unsigned int size_t;
|
||||
|
||||
void __assert_func(void);
|
||||
|
||||
void *malloc(size_t n);
|
||||
void free(void *ptr);
|
||||
void *calloc(size_t sz, size_t n);
|
||||
void *realloc(void *ptr, size_t n);
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
|
||||
size_t strlen(const char *str);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
char *strndup(const char *s, size_t n);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strcat(char *dest, const char *src);
|
||||
char *strchr(const char *s, int c);
|
||||
char *strstr(const char *haystack, const char *needle);
|
||||
|
||||
int printf(const char *fmt, ...);
|
||||
int snprintf(char *str, size_t size, const char *fmt, ...);
|
||||
7
include/MicroPython/storage.h
Normal file
7
include/MicroPython/storage.h
Normal file
@ -0,0 +1,7 @@
|
||||
void storage_init(void);
|
||||
uint32_t storage_get_block_size(void);
|
||||
uint32_t storage_get_block_count(void);
|
||||
bool storage_needs_flush(void);
|
||||
void storage_flush(void);
|
||||
bool storage_read_block(uint8_t *dest, uint32_t block);
|
||||
bool storage_write_block(const uint8_t *src, uint32_t block);
|
||||
18
include/MicroPython/usb.h
Normal file
18
include/MicroPython/usb.h
Normal file
@ -0,0 +1,18 @@
|
||||
#define VCP_CHAR_NONE (0)
|
||||
#define VCP_CHAR_CTRL_C (3)
|
||||
#define VCP_CHAR_CTRL_D (4)
|
||||
|
||||
void pyb_usb_dev_init(void);
|
||||
bool usb_vcp_is_enabled(void);
|
||||
bool usb_vcp_is_connected(void);
|
||||
void usb_vcp_set_interrupt_char(int c);
|
||||
int usb_vcp_rx_any(void);
|
||||
char usb_vcp_rx_get(void);
|
||||
void usb_vcp_send_str(const char* str);
|
||||
void usb_vcp_send_strn(const char* str, int len);
|
||||
void usb_vcp_send_strn_cooked(const char *str, int len);
|
||||
void usb_hid_send_report(uint8_t *buf); // 4 bytes for mouse: ?, x, y, ?
|
||||
|
||||
void pyb_usb_host_init(void);
|
||||
void pyb_usb_host_process(void);
|
||||
uint pyb_usb_host_get_keyboard(void);
|
||||
BIN
lib/libmp.a
Normal file
BIN
lib/libmp.a
Normal file
Binary file not shown.
53
src/Makefile
53
src/Makefile
@ -2,54 +2,63 @@ CC = arm-none-eabi-gcc
|
||||
AS = arm-none-eabi-as
|
||||
LD = arm-none-eabi-ld
|
||||
AR = arm-none-eabi-ar
|
||||
RM = rm -f
|
||||
RM = rm
|
||||
SIZE = arm-none-eabi-size
|
||||
STRIP = arm-none-eabi-strip -s
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
OBJDUMP = arm-none-eabi-objdump
|
||||
|
||||
#Debugging/Optimization
|
||||
# General
|
||||
BIN=openmv
|
||||
BUILD_DIR=build
|
||||
|
||||
# Debugging/Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS = -O0 -ggdb
|
||||
else
|
||||
CFLAGS = -O2 -ggdb
|
||||
endif
|
||||
|
||||
#Compiler Flags
|
||||
# Compiler Flags
|
||||
CFLAGS += -Wall -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4
|
||||
CFLAGS += -fsingle-precision-constant -Wdouble-promotion -mfpu=fpv4-sp-d16 -mfloat-abi=hard
|
||||
CFLAGS += -I. -I../include/CMSIS -I../include/StdPeriph -I../include/USB_OTG -I../include/FatFS -DSTM32F40_41xxx -DUSE_USB_OTG_FS -DARM_MATH_CM4 -D__FPU_PRESENT
|
||||
CFLAGS += -I. -I../include/CMSIS -I../include/StdPeriph -I../include/USB_OTG -I../include/FatFS -I../include/MicroPython\
|
||||
-I../include/MicroPython/py -I./py -DSTM32F40_41xxx -DUSE_USB_OTG_FS -DARM_MATH_CM4 -D__FPU_PRESENT -std=gnu99
|
||||
|
||||
#Linker Flags
|
||||
# Linker Flags
|
||||
LDFLAGS = -mcpu=cortex-m4 -mthumb -mcpu=cortex-m4 -mthumb -mthumb-interwork -mlittle-endian -mfloat-abi=hard -mfpu=fpv4-sp-d16
|
||||
LDFLAGS += -Wl,-Map=$(BIN).map -Tstm32f4xx.ld -L. -L../lib
|
||||
LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(BIN).map -Tstm32f4xx.ld -L. -L../lib
|
||||
|
||||
# Sources
|
||||
BIN = "openmv"
|
||||
SRCS = $(wildcard *.c)
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
#Libraries
|
||||
LIB = -lc -lm -ldsp -lusbgeneric -lusbdevcore -lusbcore -lfatfs -lstdperiph
|
||||
SRCS = $(wildcard *.c) $(wildcard py/*.c)
|
||||
OBJS = $(addprefix $(BUILD_DIR)/, $(SRCS:.c=.o))
|
||||
|
||||
all:: $(BIN)
|
||||
# Libraries
|
||||
LIB = -lmp -lc -lm -ldsp -lstdperiph -lusbcore -lusbdevcore
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(OBJS) $(LIB) -o $(BIN).elf
|
||||
$(OBJCOPY) -Oihex -j .text -j .data $(BIN).elf $(BIN).hex
|
||||
$(OBJCOPY) -Obinary $(BIN).elf $(BIN).bin
|
||||
$(OBJDUMP) -d $(BIN).elf > $(BIN).dis
|
||||
all:: $(BUILD_DIR) $(BUILD_DIR) $(BUILD_DIR)/$(BIN).bin
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir $@
|
||||
mkdir $@/py
|
||||
|
||||
$(BUILD_DIR)/$(BIN).bin: $(BUILD_DIR)/$(BIN).elf
|
||||
$(OBJCOPY) -Obinary $^ $@
|
||||
|
||||
$(BUILD_DIR)/$(BIN).elf: $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(OBJS) $(LIB) -o $@
|
||||
|
||||
stats: $(BIN).elf
|
||||
$(SIZE) $(BIN).elf
|
||||
|
||||
clean:
|
||||
$(RM) *.o *.elf *.bin *.map *.hex *.dis
|
||||
$(RM) -fr $(BUILD_DIR)
|
||||
|
||||
.c.o :
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
$(BUILD_DIR)/%.o : %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
.s.o :
|
||||
$(BUILD_DIR)/%.o : %.s
|
||||
$(AS) $(AFLAGS) $< -o $@
|
||||
|
||||
flash::
|
||||
dfu-util -d 0483:df11 -c 1 -i 0 -a 0 -s 0x08000000 -D $(BIN).bin
|
||||
dfu-util -d 0483:df11 -c 1 -i 0 -a 0 -s 0x08000000 -D $(BUILD_DIR)/$(BIN).bin
|
||||
|
||||
614
src/main.c
614
src/main.c
@ -1,324 +1,290 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stm32f4xx_rcc.h>
|
||||
#include <stm32f4xx_gpio.h>
|
||||
#include <stm32f4xx_syscfg.h>
|
||||
#include <stm32f4xx_misc.h>
|
||||
#include "sensor.h"
|
||||
#include "rgb_led.h"
|
||||
#include "usart.h"
|
||||
#include "imlib.h"
|
||||
#include "array.h"
|
||||
#include "systick.h"
|
||||
#include "usb_generic.h"
|
||||
#include "ff.h"
|
||||
#include "rcc_ctrl.h"
|
||||
|
||||
#define BREAK() __asm__ volatile ("BKPT");
|
||||
|
||||
enum sensor_result run_command(struct sensor_dev *sensor, uint8_t *args)
|
||||
{
|
||||
switch (args[0]) {
|
||||
case CMD_RESET_SENSOR:
|
||||
sensor_reset(sensor);
|
||||
break;
|
||||
|
||||
case CMD_READ_REGISTER:
|
||||
//sensor_read_reg(sensor, args[1]);
|
||||
break;
|
||||
|
||||
case CMD_WRITE_REGISTER:
|
||||
sensor_write_reg(sensor, args[1], args[2]);
|
||||
break;
|
||||
|
||||
case CMD_SET_BRIGHTNESS:
|
||||
sensor_set_brightness(sensor, args[1]);
|
||||
break;
|
||||
|
||||
case CMD_SET_PIXFORMAT:
|
||||
/* Configure image size and format and FPS */
|
||||
if (sensor_set_pixformat(sensor, args[1]) != 0) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_SET_FRAMESIZE:
|
||||
/* Configure image size and format and FPS */
|
||||
if (sensor_set_framesize(sensor, args[1]) != 0) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_SET_FRAMERATE:
|
||||
/* Configure framerate */
|
||||
if (sensor_set_framerate(sensor, args[1]) != 0) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_SET_GAINCEILING:
|
||||
/* Configure framerate */
|
||||
if (sensor_set_gainceiling(sensor, args[1]) != 0) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_SNAPSHOT: {
|
||||
if (sensor_snapshot(sensor) != 0) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_COLOR_TRACK: {
|
||||
struct point point= {0};
|
||||
struct frame_buffer *fb = &sensor->frame_buffer;
|
||||
#if 0
|
||||
struct color hsv;
|
||||
hsv.h = usart_recv();
|
||||
hsv.s = usart_recv();
|
||||
hsv.v = usart_recv();
|
||||
#else
|
||||
/* red */
|
||||
struct color hsv= {.h = 340, .s = 50, .v = 50};
|
||||
#endif
|
||||
|
||||
if (sensor_snapshot(sensor) != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
imlib_color_track(fb, &hsv, &point, 10);
|
||||
if (point.x && point.y) {
|
||||
struct rectangle r = {.x=point.x-5, .y=point.y-5, .w=10, .h=10};
|
||||
imlib_draw_rectangle(fb, &r);
|
||||
|
||||
/* Send point coords from 0%..100% */
|
||||
usart_send(point.x*100/fb->width);
|
||||
usart_send(point.y*100/fb->height);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_MOTION_DETECTION: {
|
||||
int i;
|
||||
int pixels;
|
||||
struct frame_buffer *fb = &sensor->frame_buffer;
|
||||
uint8_t *background = malloc(fb->width * fb->height * 1);//grayscale
|
||||
|
||||
if (background == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (sensor->pixformat != PIXFORMAT_YUV422) {
|
||||
/* Switch sensor to YUV422 to get
|
||||
a grayscale image from the Y channel */
|
||||
// if (sensor_config(&sensor, sensor_QQVGA_YUV422, sensor_30FPS) != 0) {
|
||||
// goto error;
|
||||
// }
|
||||
}
|
||||
|
||||
if (sensor_snapshot(sensor) != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Save this frame as background */
|
||||
for (i=0; i<(fb->width*fb->height); i++) {
|
||||
background[i] = fb->pixels[i*2];
|
||||
}
|
||||
|
||||
while (1) {
|
||||
systick_sleep(1000);
|
||||
|
||||
if (sensor_snapshot(sensor) != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (i=0, pixels=0; i<(fb->width*fb->height); i++) {
|
||||
uint8_t y = fb->pixels[i*2];
|
||||
int diff = (y-background[i]) * (y-background[i]);
|
||||
|
||||
/* consider pixel changed if change more than 25% */
|
||||
if ((diff*100)/(255*255) > 25) {
|
||||
pixels++;
|
||||
/* reuse the frame buffer */
|
||||
fb->pixels[i] = 0xff;
|
||||
} else {
|
||||
fb->pixels[i] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
/* send if more than 10% of the image changed */
|
||||
if ((pixels*100)/(fb->width*fb->height)>5) {
|
||||
uint8_t kernel[] = {1,1,1,
|
||||
1,1,1,
|
||||
1,1,1};
|
||||
|
||||
/* free background frame */
|
||||
free(background);
|
||||
|
||||
/* perform image erosion */
|
||||
imlib_erosion_filter(fb, kernel, 3);
|
||||
|
||||
for (i=0; i<(fb->width*fb->height); i++) {
|
||||
/* send twice because lcd expects RGB565 */
|
||||
usart_send(fb->pixels[i]);
|
||||
usart_send(fb->pixels[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_FACE_DETECTION: {
|
||||
/* detection objects array */
|
||||
struct array *objects;
|
||||
|
||||
/* detection parameters */
|
||||
struct cascade cascade = {
|
||||
.step = 2,
|
||||
.n_stages = 12,
|
||||
.window = {24, 24},
|
||||
.scale_factor = 1.25f,
|
||||
};
|
||||
|
||||
if (sensor->framesize > FRAMESIZE_QQVGA) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
if (sensor_snapshot(sensor) != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
objects = imlib_detect_objects(&cascade, &sensor->frame_buffer);
|
||||
|
||||
int x_pos=0,y_pos=0;
|
||||
int objs = array_length(objects);
|
||||
if (objs) {
|
||||
int i;
|
||||
for (i=0; i<objs; i++) {
|
||||
imlib_draw_rectangle(&sensor->frame_buffer, array_at(objects, i));
|
||||
}
|
||||
struct rectangle *r = array_at(objects, 0);
|
||||
x_pos = r->x+r->w/2;
|
||||
y_pos = r->y+r->h/2;
|
||||
/* Send point coords from 0%..100% */
|
||||
usart_send(x_pos*100/sensor->frame_buffer.width);
|
||||
usart_send(y_pos*100/sensor->frame_buffer.height);
|
||||
}
|
||||
array_free(objects);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_ACK;
|
||||
error:
|
||||
return CMD_NACK;
|
||||
}
|
||||
|
||||
static int frame_tx_bytes;
|
||||
|
||||
void usb_data_in(void *buffer, int *length, void *user_data)
|
||||
{
|
||||
int usb_tx_length=64;
|
||||
struct sensor_dev *sensor = user_data;
|
||||
struct frame_buffer *fb = &sensor->frame_buffer;
|
||||
int size = (fb->width*fb->height*fb->bpp);
|
||||
|
||||
if (frame_tx_bytes < size) {
|
||||
memcpy(buffer, fb->pixels+frame_tx_bytes, *length);
|
||||
*length = usb_tx_length;
|
||||
frame_tx_bytes += usb_tx_length;
|
||||
} else {
|
||||
*length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void usb_data_out(void *buffer, int *length, void *user_data)
|
||||
{
|
||||
int usb_tx_length=64;
|
||||
struct sensor_dev *sensor = user_data;
|
||||
struct frame_buffer *fb = &sensor->frame_buffer;
|
||||
|
||||
enum sensor_result ret;
|
||||
uint8_t *cmd_buf = ((uint8_t*)buffer);
|
||||
ret = run_command(sensor, cmd_buf);
|
||||
|
||||
switch (cmd_buf[0]) {
|
||||
case CMD_SNAPSHOT:
|
||||
case CMD_COLOR_TRACK:
|
||||
case CMD_MOTION_DETECTION:
|
||||
case CMD_FACE_DETECTION:
|
||||
/* send back frame */
|
||||
memcpy(buffer, fb->pixels, usb_tx_length);
|
||||
*length = usb_tx_length;
|
||||
/* reset bytes counter */
|
||||
frame_tx_bytes = usb_tx_length;
|
||||
break;
|
||||
default:
|
||||
/* send back ACK/NACK */
|
||||
//*length = 1;
|
||||
*length =0; //ignore it for now
|
||||
cmd_buf[0] = ret;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* sensor handle */
|
||||
struct sensor_dev sensor;
|
||||
|
||||
/* USB callback */
|
||||
struct usb_user_cb usb_cb = {
|
||||
&sensor,
|
||||
usb_data_in,
|
||||
usb_data_out,
|
||||
};
|
||||
|
||||
rcc_ctrl_set_frequency(SYSCLK_168_MHZ);
|
||||
|
||||
/* Init SysTick timer */
|
||||
systick_init();
|
||||
|
||||
/* init USART */
|
||||
usart_init(9600);
|
||||
|
||||
/* init RGB LED module */
|
||||
rgb_led_init(LED_BLUE);
|
||||
|
||||
/* init sensor module */
|
||||
if (sensor_init(&sensor) != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init usb device */
|
||||
usb_dev_init(&usb_cb);
|
||||
|
||||
// systick_sleep(3000);
|
||||
rgb_led_set_color(LED_GREEN);
|
||||
|
||||
#if 0
|
||||
/* FPS test */
|
||||
while (1) {
|
||||
volatile int fps = 0;
|
||||
uint8_t args[]= {CMD_FACE_DETECTION};
|
||||
uint32_t ticks = systick_current_millis();
|
||||
while ((systick_current_millis()-ticks)<1000) {
|
||||
run_command(&sensor, args);
|
||||
fps++;
|
||||
}
|
||||
BREAK();
|
||||
}
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
}
|
||||
|
||||
error:
|
||||
rgb_led_set_color(LED_RED);
|
||||
while (1) {
|
||||
/* Do nothing */
|
||||
}
|
||||
}
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_rcc.h>
|
||||
#include <stm32f4xx_syscfg.h>
|
||||
#include <stm32f4xx_gpio.h>
|
||||
#include <stm32f4xx_exti.h>
|
||||
#include <stm32f4xx_tim.h>
|
||||
#include <stm32f4xx_pwr.h>
|
||||
#include <stm32f4xx_rtc.h>
|
||||
#include <stm32f4xx_usart.h>
|
||||
#include <stm32f4xx_rng.h>
|
||||
#include <stm32f4xx_misc.h>
|
||||
#include "libmp.h"
|
||||
#include "systick.h"
|
||||
#include "rcc_ctrl.h"
|
||||
#include "led_py.h"
|
||||
|
||||
int errno;
|
||||
|
||||
static FATFS fatfs0;
|
||||
|
||||
void __fatal_error(const char *msg) {
|
||||
printf("%s\n", msg);
|
||||
while (1) {
|
||||
led_state(LED_RED, 1);
|
||||
systick_sleep(250);
|
||||
led_state(LED_RED, 0);
|
||||
systick_sleep(250);
|
||||
}
|
||||
}
|
||||
|
||||
// sync all file systems
|
||||
mp_obj_t pyb_sync(void) {
|
||||
storage_flush();
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t pyb_delay(mp_obj_t count) {
|
||||
systick_sleep(mp_obj_get_int(count));
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t pyb_vcp_connected() {
|
||||
bool connected = usb_vcp_is_connected();
|
||||
return mp_obj_new_int(connected);
|
||||
}
|
||||
|
||||
void fatality(void) {
|
||||
led_state(LED_RED, 1);
|
||||
led_state(LED_GREEN, 1);
|
||||
led_state(LED_BLUE, 1);
|
||||
while (1);
|
||||
}
|
||||
|
||||
static const char fresh_boot_py[] =
|
||||
"# boot.py -- run on boot-up\n"
|
||||
"# can run arbitrary Python, but best to keep it minimal\n"
|
||||
"\n"
|
||||
"pyb.source_dir('/src')\n"
|
||||
"pyb.main('main.py')\n"
|
||||
"#pyb.usb_usr('VCP')\n"
|
||||
"#pyb.usb_msd(True, 'dual partition')\n"
|
||||
"#pyb.flush_cache(False)\n"
|
||||
"#pyb.error_log('error.txt')\n"
|
||||
;
|
||||
|
||||
static const char fresh_main_py[] =
|
||||
"# main.py -- put your code here!\n"
|
||||
"led = pyb.Led(32)\n"
|
||||
"while(pyb.vcp_connected()==0):\n"
|
||||
" led.on()\n"
|
||||
" pyb.delay(500)\n"
|
||||
" led.off()\n"
|
||||
" pyb.delay(500)\n"
|
||||
;
|
||||
|
||||
static const char *help_text =
|
||||
"Welcome to Micro Python!\n\n"
|
||||
"This is a *very* early version of Micro Python and has minimal functionality.\n\n"
|
||||
"Specific commands for the board:\n"
|
||||
" pyb.info() -- print some general information\n"
|
||||
" pyb.gc() -- run the garbage collector\n"
|
||||
" pyb.repl_info(<val>) -- enable/disable printing of info after each command\n"
|
||||
" pyb.delay(<n>) -- wait for n milliseconds\n"
|
||||
" pyb.Led(<n>) -- create Led object for LED n (n=1,2)\n"
|
||||
" Led methods: on(), off()\n"
|
||||
" pyb.Servo(<n>) -- create Servo object for servo n (n=1,2,3,4)\n"
|
||||
" Servo methods: angle(<x>)\n"
|
||||
" pyb.switch() -- return True/False if switch pressed or not\n"
|
||||
" pyb.accel() -- get accelerometer values\n"
|
||||
" pyb.rand() -- get a 16-bit random number\n"
|
||||
" pyb.gpio(<port>) -- get port value (port='A4' for example)\n"
|
||||
" pyb.gpio(<port>, <val>) -- set port value, True or False, 1 or 0\n"
|
||||
" pyb.ADC(<port>) -- make an analog port object (port='C0' for example)\n"
|
||||
" ADC methods: read()\n"
|
||||
;
|
||||
|
||||
// get some help about available functions
|
||||
static mp_obj_t pyb_help(void) {
|
||||
printf("%s", help_text);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
// get lots of info about the board
|
||||
static mp_obj_t pyb_info(void) {
|
||||
// get and print unique id; 96 bits
|
||||
{
|
||||
byte *id = (byte*)0x1fff7a10;
|
||||
printf("ID=%02x%02x%02x%02x:%02x%02x%02x%02x:%02x%02x%02x%02x\n", id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], id[9], id[10], id[11]);
|
||||
}
|
||||
|
||||
// get and print clock speeds
|
||||
// SYSCLK=168MHz, HCLK=168MHz, PCLK1=42MHz, PCLK2=84MHz
|
||||
{
|
||||
RCC_ClocksTypeDef rcc_clocks;
|
||||
RCC_GetClocksFreq(&rcc_clocks);
|
||||
printf("S=%lu\nH=%lu\nP1=%lu\nP2=%lu\n", rcc_clocks.SYSCLK_Frequency, rcc_clocks.HCLK_Frequency, rcc_clocks.PCLK1_Frequency, rcc_clocks.PCLK2_Frequency);
|
||||
}
|
||||
|
||||
// to print info about memory
|
||||
{
|
||||
extern void *_sidata;
|
||||
extern void *_sdata;
|
||||
extern void *_edata;
|
||||
extern void *_sbss;
|
||||
extern void *_ebss;
|
||||
extern void *_estack;
|
||||
extern void *_etext;
|
||||
printf("_etext=%p\n", &_etext);
|
||||
printf("_sidata=%p\n", &_sidata);
|
||||
printf("_sdata=%p\n", &_sdata);
|
||||
printf("_edata=%p\n", &_edata);
|
||||
printf("_sbss=%p\n", &_sbss);
|
||||
printf("_ebss=%p\n", &_ebss);
|
||||
printf("_estack=%p\n", &_estack);
|
||||
printf("_ram_start=%p\n", &_ram_start);
|
||||
printf("_heap_start=%p\n", &_heap_start);
|
||||
printf("_heap_end=%p\n", &_heap_end);
|
||||
printf("_ram_end=%p\n", &_ram_end);
|
||||
}
|
||||
|
||||
// qstr info
|
||||
{
|
||||
uint n_pool, n_qstr, n_str_data_bytes, n_total_bytes;
|
||||
qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes);
|
||||
printf("qstr:\n n_pool=%u\n n_qstr=%u\n n_str_data_bytes=%u\n n_total_bytes=%u\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes);
|
||||
}
|
||||
|
||||
// GC info
|
||||
{
|
||||
gc_info_t info;
|
||||
gc_info(&info);
|
||||
printf("GC:\n");
|
||||
printf(" %lu total\n", info.total);
|
||||
printf(" %lu : %lu\n", info.used, info.free);
|
||||
printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block);
|
||||
}
|
||||
|
||||
// free space on flash
|
||||
{
|
||||
DWORD nclst;
|
||||
FATFS *fatfs;
|
||||
f_getfree("0:", &nclst, &fatfs);
|
||||
printf("LFS free: %u bytes\n", (uint)(nclst * fatfs->csize * 512));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static void SYSCLKConfig_STOP(void) {
|
||||
/* After wake-up from STOP reconfigure the system clock */
|
||||
/* Enable HSE */
|
||||
RCC_HSEConfig(RCC_HSE_ON);
|
||||
|
||||
/* Wait till HSE is ready */
|
||||
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) {
|
||||
}
|
||||
|
||||
/* Enable PLL */
|
||||
RCC_PLLCmd(ENABLE);
|
||||
|
||||
/* Wait till PLL is ready */
|
||||
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {
|
||||
}
|
||||
|
||||
/* Select PLL as system clock source */
|
||||
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
|
||||
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while (RCC_GetSYSCLKSource() != 0x08) {
|
||||
}
|
||||
}
|
||||
|
||||
static mp_obj_t pyb_stop(void) {
|
||||
PWR_EnterSTANDBYMode();
|
||||
//PWR_FlashPowerDownCmd(ENABLE); don't know what the logic is with this
|
||||
|
||||
/* Enter Stop Mode */
|
||||
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
|
||||
|
||||
/* Configures system clock after wake-up from STOP: enable HSE, PLL and select
|
||||
* PLL as system clock source (HSE and PLL are disabled in STOP mode) */
|
||||
SYSCLKConfig_STOP();
|
||||
|
||||
//PWR_FlashPowerDownCmd(DISABLE);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t pyb_standby(void) {
|
||||
PWR_EnterSTANDBYMode();
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t pyb_rng_get(void) {
|
||||
return mp_obj_new_int(RNG_GetRandomNumber() >> 16);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
rcc_ctrl_set_frequency(SYSCLK_168_MHZ);
|
||||
|
||||
/* Init MicroPython */
|
||||
libmp_init();
|
||||
|
||||
/* Init SysTick timer */
|
||||
systick_init();
|
||||
|
||||
/* init RGB LED module */
|
||||
led_init(LED_BLUE);
|
||||
|
||||
// add some functions to the python namespace
|
||||
rt_store_name(MP_QSTR_help, rt_make_function_n(0, pyb_help));
|
||||
|
||||
mp_obj_t m = mp_obj_new_module(MP_QSTR_pyb);
|
||||
rt_store_attr(m, MP_QSTR_vcp_connected, rt_make_function_n(0, pyb_vcp_connected));
|
||||
rt_store_attr(m, MP_QSTR_info, rt_make_function_n(0, pyb_info));
|
||||
rt_store_attr(m, MP_QSTR_gc, (mp_obj_t)&pyb_gc_obj);
|
||||
rt_store_attr(m, MP_QSTR_Led, (mp_obj_t)&pyb_Led_obj);
|
||||
rt_store_attr(m, MP_QSTR_stop, rt_make_function_n(0, pyb_stop));
|
||||
rt_store_attr(m, MP_QSTR_standby, rt_make_function_n(0, pyb_standby));
|
||||
rt_store_attr(m, MP_QSTR_sync, rt_make_function_n(0, pyb_sync));
|
||||
rt_store_attr(m, MP_QSTR_delay, rt_make_function_n(1, pyb_delay));
|
||||
rt_store_name(MP_QSTR_pyb, m);
|
||||
|
||||
/* Try to mount the flash fs */
|
||||
bool reset_filesystem = true;
|
||||
FRESULT res = f_mount(&fatfs0, "0:", 1);
|
||||
if (!reset_filesystem && res == FR_OK) {
|
||||
/* Mount sucessful */
|
||||
} else if (reset_filesystem || res == FR_NO_FILESYSTEM) {
|
||||
/* No filesystem, so create a fresh one */
|
||||
res = f_mkfs("0:", 0, 0);
|
||||
if (res != FR_OK) {
|
||||
__fatal_error("could not create LFS");
|
||||
}
|
||||
|
||||
/* Create main.py */
|
||||
FIL fp;
|
||||
f_open(&fp, "0:/main.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
UINT n;
|
||||
f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n);
|
||||
// TODO check we could write n bytes
|
||||
f_close(&fp);
|
||||
} else {
|
||||
__fatal_error("could not access LFS");
|
||||
}
|
||||
|
||||
/* Init USB device */
|
||||
pyb_usb_dev_init();
|
||||
|
||||
/* Try to run user script first */
|
||||
if (!libmp_do_file("0:/user.py")) {
|
||||
/* no user script */
|
||||
}
|
||||
|
||||
/* Fall back to main script */
|
||||
if (!libmp_do_file("0:/main.py")) {
|
||||
__fatal_error("failed to run main script");
|
||||
}
|
||||
|
||||
libmp_do_repl();
|
||||
|
||||
printf("PYB: sync filesystems\n");
|
||||
pyb_sync();
|
||||
|
||||
printf("PYB: soft reboot\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
60
src/py/led_py.c
Normal file
60
src/py/led_py.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include <stdlib.h>
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "led.h"
|
||||
#include "led_py.h"
|
||||
|
||||
typedef struct _pyb_led_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint led_id;
|
||||
} pyb_led_obj_t;
|
||||
|
||||
void led_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
print(env, "<LED %lu>", self->led_id);
|
||||
}
|
||||
|
||||
mp_obj_t led_obj_on(mp_obj_t self_in) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
led_state(self->led_id, 1);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t led_obj_off(mp_obj_t self_in) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
led_state(self->led_id, 0);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t led_obj_toggle(mp_obj_t self_in) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
// led_toggle(self->led_id);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
|
||||
|
||||
static const mp_method_t led_methods[] = {
|
||||
{ "on", &led_obj_on_obj },
|
||||
{ "off", &led_obj_off_obj },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
static const mp_obj_type_t led_obj_type = {
|
||||
{ &mp_const_type },
|
||||
"Led",
|
||||
.print = led_obj_print,
|
||||
.methods = led_methods,
|
||||
};
|
||||
|
||||
static mp_obj_t pyb_Led(mp_obj_t led_id) {
|
||||
pyb_led_obj_t *o = m_new_obj(pyb_led_obj_t);
|
||||
o->base.type = &led_obj_type;
|
||||
o->led_id = mp_obj_get_int(led_id);
|
||||
return o;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(pyb_Led_obj, pyb_Led);
|
||||
3
src/py/led_py.h
Normal file
3
src/py/led_py.h
Normal file
@ -0,0 +1,3 @@
|
||||
#include "led.h"
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_Led_obj);
|
||||
|
||||
@ -5,21 +5,24 @@
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
_Min_Stack_Size = 0x1000; /* required amount of stack */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
|
||||
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K
|
||||
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 512K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||
CCM (w!rx) : ORIGIN = 0x10000000, LENGTH = 64K
|
||||
}
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
_estack = 0x10010000; /* Stack is allocated on CCM block */
|
||||
_heap_start = 0x20000000; /* Heap starts at the main RAM block */
|
||||
_heap_end = 0x20020000; /* Heap is given the whole RAM block */
|
||||
|
||||
_ram_start = 0x10000000;
|
||||
_ram_end = 0x10010000; /* 64KB CCM */
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
_stack_size = 0x1000; /* required amount of stack */
|
||||
_heap_size = 0x4000; /* required amount of heap */
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
@ -30,7 +33,7 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
} >FLASH_ISR
|
||||
|
||||
/* The program code and other data goes into FLASH */
|
||||
.text :
|
||||
@ -50,21 +53,24 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbols at end of code */
|
||||
_exit = .;
|
||||
} >FLASH
|
||||
} >FLASH_TEXT
|
||||
|
||||
.ARM.extab : {
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} >FLASH_TEXT
|
||||
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
|
||||
.ARM : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
} >FLASH_TEXT
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array*))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} >FLASH
|
||||
} >FLASH_TEXT
|
||||
|
||||
.init_array :
|
||||
{
|
||||
@ -72,7 +78,7 @@ SECTIONS
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array*))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
} >FLASH
|
||||
} >FLASH_TEXT
|
||||
|
||||
.fini_array :
|
||||
{
|
||||
@ -80,7 +86,7 @@ SECTIONS
|
||||
KEEP (*(.fini_array*))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >FLASH
|
||||
} >FLASH_TEXT
|
||||
|
||||
/* used by the startup to initialize data */
|
||||
_sidata = .;
|
||||
@ -114,21 +120,32 @@ SECTIONS
|
||||
__bss_end__ = _ebss;
|
||||
} >CCM
|
||||
|
||||
._heap :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_heap_start = .;
|
||||
. = . + _heap_size;
|
||||
. = ALIGN(4);
|
||||
_heap_end = .;
|
||||
} >CCM
|
||||
|
||||
/* Make sure there is enough RAM left for the stack */
|
||||
._user_heap_stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
. = . + _Min_Stack_Size;
|
||||
. = . + _stack_size;
|
||||
. = ALIGN(4);
|
||||
} >CCM
|
||||
|
||||
/* Remove information from the standard libraries */
|
||||
/*
|
||||
/DISCARD/ :
|
||||
{
|
||||
libc.a ( * )
|
||||
libm.a ( * )
|
||||
libgcc.a ( * )
|
||||
}
|
||||
*/
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#include <stm32f4xx_exti.h>
|
||||
#define BREAK() __asm__ volatile ("BKPT");
|
||||
|
||||
extern USB_OTG_CORE_HANDLE USB_OTG_dev;
|
||||
extern USB_OTG_CORE_HANDLE USB_OTG_Core;
|
||||
extern uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);
|
||||
|
||||
/**
|
||||
@ -87,17 +87,17 @@ void PendSV_Handler(void)
|
||||
void OTG_FS_WKUP_IRQHandler(void)
|
||||
{
|
||||
BREAK();
|
||||
if(USB_OTG_dev.cfg.low_power)
|
||||
if(USB_OTG_Core.cfg.low_power)
|
||||
{
|
||||
*(uint32_t *)(0xE000ED10) &= 0xFFFFFFF9 ;
|
||||
SystemInit();
|
||||
USB_OTG_UngateClock(&USB_OTG_dev);
|
||||
USB_OTG_UngateClock(&USB_OTG_Core);
|
||||
}
|
||||
EXTI_ClearITPendingBit(EXTI_Line18);
|
||||
}
|
||||
|
||||
void OTG_FS_IRQHandler(void)
|
||||
{
|
||||
USBD_OTG_ISR_Handler (&USB_OTG_dev);
|
||||
USBD_OTG_ISR_Handler (&USB_OTG_Core);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user