mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Remove old peripheral modules
* Remove old peripheral modules * Use MP's built-in modules
This commit is contained in:
parent
74d6fa4314
commit
6d2fafa947
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* Clock Python module.
|
||||
*
|
||||
*/
|
||||
#include <mp.h>
|
||||
#include "systick.h"
|
||||
#include "py_clock.h"
|
||||
|
||||
/* Clock Type */
|
||||
typedef struct _py_clock_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint32_t t_start;
|
||||
uint32_t t_ticks;
|
||||
uint32_t t_frame;
|
||||
} py_clock_obj_t;
|
||||
|
||||
mp_obj_t py_clock_tick(py_clock_obj_t *clock)
|
||||
{
|
||||
clock->t_start = systick_current_millis();
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t py_clock_fps(py_clock_obj_t *clock)
|
||||
{
|
||||
clock->t_frame++;
|
||||
clock->t_ticks += (systick_current_millis()-clock->t_start);
|
||||
return mp_obj_new_float(1000.0f/(clock->t_ticks/(float)clock->t_frame));
|
||||
}
|
||||
|
||||
mp_obj_t py_clock_avg(py_clock_obj_t *clock)
|
||||
{
|
||||
clock->t_frame++;
|
||||
clock->t_ticks += (systick_current_millis()-clock->t_start);
|
||||
return mp_obj_new_float(clock->t_ticks/(float)clock->t_frame);
|
||||
}
|
||||
|
||||
mp_obj_t py_clock_reset(py_clock_obj_t *clock)
|
||||
{
|
||||
clock->t_start = 0;
|
||||
clock->t_ticks = 0;
|
||||
clock->t_frame = 0;
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static void py_clock_print(void (*print)(void *env, const char *fmt, ...),
|
||||
void *env, mp_obj_t self_in, mp_print_kind_t kind)
|
||||
{
|
||||
py_clock_obj_t *self = self_in;
|
||||
|
||||
/* print some info */
|
||||
print(env, "t_start:%d t_ticks:%d t_frame:%d\n",
|
||||
self->t_start, self->t_ticks, self->t_frame);
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(py_clock_tick_obj, py_clock_tick);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(py_clock_fps_obj, py_clock_fps);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(py_clock_avg_obj, py_clock_avg);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(py_clock_reset_obj, py_clock_reset);
|
||||
|
||||
static const mp_map_elem_t locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_tick), (mp_obj_t)&py_clock_tick_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_fps), (mp_obj_t)&py_clock_fps_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_avg), (mp_obj_t)&py_clock_avg_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&py_clock_reset_obj},
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(locals_dict, locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t py_clock_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Clock,
|
||||
.print = py_clock_print,
|
||||
.locals_dict = (mp_obj_t)&locals_dict,
|
||||
};
|
||||
|
||||
mp_obj_t py_clock()
|
||||
{
|
||||
py_clock_obj_t *clock =NULL;
|
||||
clock = m_new_obj(py_clock_obj_t);
|
||||
clock->base.type = &py_clock_type;
|
||||
clock->t_start = 0;
|
||||
clock->t_ticks = 0;
|
||||
clock->t_frame = 0;
|
||||
|
||||
return clock;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* Clock Python module.
|
||||
*
|
||||
*/
|
||||
#ifndef __PY_CLOCK_H__
|
||||
#define __PY_CLOCK_H__
|
||||
mp_obj_t py_clock();
|
||||
#endif // __PY_CLOCK_H__
|
||||
@ -1,146 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* File Python module.
|
||||
*
|
||||
*/
|
||||
#include <mp.h>
|
||||
#include "py_assert.h"
|
||||
#include "py_file.h"
|
||||
typedef struct _py_file_obj_t {
|
||||
mp_obj_base_t base;
|
||||
FIL fp;
|
||||
} py_file_obj_t;
|
||||
|
||||
const char *ffs_strerror(FRESULT res)
|
||||
{
|
||||
static const char *ffs_errors[]={
|
||||
"Succeeded",
|
||||
"A hard error occurred in the low level disk I/O layer",
|
||||
"Assertion failed",
|
||||
"The physical drive cannot work",
|
||||
"Could not find the file",
|
||||
"Could not find the path",
|
||||
"The path name format is invalid",
|
||||
"Access denied due to prohibited access or directory full",
|
||||
"Access denied due to prohibited access",
|
||||
"The file/directory object is invalid",
|
||||
"The physical drive is write protected",
|
||||
"The logical drive number is invalid",
|
||||
"The volume has no work area",
|
||||
"There is no valid FAT volume",
|
||||
"The f_mkfs() aborted due to any parameter error",
|
||||
"Could not get a grant to access the volume within defined period",
|
||||
"The operation is rejected according to the file sharing policy",
|
||||
"LFN working buffer could not be allocated",
|
||||
"Number of open files > _FS_SHARE",
|
||||
"Given parameter is invalid",
|
||||
};
|
||||
|
||||
if (res>sizeof(ffs_errors)/sizeof(ffs_errors[0])) {
|
||||
return "unknown error";
|
||||
} else {
|
||||
return ffs_errors[res];
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t py_file_close(py_file_obj_t *file)
|
||||
{
|
||||
f_close(&file->fp);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t py_file_read(py_file_obj_t *file, mp_obj_t n_obj)
|
||||
{
|
||||
UINT n_out;
|
||||
UINT n = mp_obj_get_int(n_obj);
|
||||
|
||||
char *buf = m_new(char, n);
|
||||
f_read(&file->fp, buf, n, &n_out);
|
||||
return mp_obj_new_str(buf, n_out, false);
|
||||
}
|
||||
|
||||
mp_obj_t py_file_write(py_file_obj_t *file, mp_obj_t buf)
|
||||
{
|
||||
uint len;
|
||||
const char *str;
|
||||
FRESULT res;
|
||||
|
||||
str = mp_obj_str_get_data(buf, &len);
|
||||
|
||||
res = f_write(&file->fp, str, len, &len);
|
||||
if (res != FR_OK) {
|
||||
nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res)));
|
||||
}
|
||||
|
||||
return mp_obj_new_int(len);
|
||||
}
|
||||
|
||||
void py_file_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind)
|
||||
{
|
||||
print(env, "<file>");
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(py_file_close_obj, py_file_close);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(py_file_read_obj, py_file_read);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(py_file_write_obj, py_file_write);
|
||||
|
||||
static const mp_map_elem_t locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&py_file_close_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&py_file_read_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&py_file_write_obj},
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(locals_dict, locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t py_file_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_file,
|
||||
.print = py_file_print,
|
||||
.locals_dict = (mp_obj_t)&locals_dict,
|
||||
};
|
||||
|
||||
mp_obj_t py_file_open(mp_obj_t path, mp_obj_t mode_str)
|
||||
{
|
||||
BYTE mode=0;
|
||||
FRESULT res;
|
||||
py_file_obj_t *o;
|
||||
|
||||
switch (mp_obj_str_get_str(mode_str)[0]) {
|
||||
case 'r':
|
||||
/* Open file for reading, fail if the file is not existing. */
|
||||
mode = FA_READ|FA_OPEN_EXISTING;
|
||||
break;
|
||||
case 'w':
|
||||
/* Open file for reading/writing, create the file if not existing. */
|
||||
mode = FA_READ|FA_WRITE|FA_OPEN_ALWAYS;
|
||||
break;
|
||||
case 'a':
|
||||
/* Open file for reading/writing, fail if the file is not existing. */
|
||||
mode = FA_READ|FA_WRITE|FA_OPEN_EXISTING;
|
||||
break;
|
||||
default:
|
||||
nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid open mode"));
|
||||
}
|
||||
|
||||
/* Create new python file obj */
|
||||
o = m_new_obj(py_file_obj_t);
|
||||
o->base.type = &py_file_type;
|
||||
|
||||
/* Open underlying file handle */
|
||||
res = f_open(&o->fp, mp_obj_str_get_str(path), mode);
|
||||
if (res != FR_OK) {
|
||||
nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res)));
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
void *py_file_cobj(mp_obj_t file)
|
||||
{
|
||||
PY_ASSERT_TYPE(file, &py_file_type);
|
||||
return &((py_file_obj_t *)file)->fp;
|
||||
}
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* File Python module.
|
||||
*
|
||||
*/
|
||||
#ifndef __PY_FILE_H__
|
||||
#define __PY_FILE_H__
|
||||
#include <ff.h>
|
||||
const char *ffs_strerror(FRESULT res);
|
||||
mp_obj_t py_file_open(mp_obj_t path, mp_obj_t mode);
|
||||
void *py_file_cobj(mp_obj_t file);
|
||||
#endif // __PY_FILE_H__
|
||||
@ -1,179 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* GPIO Python module.
|
||||
*
|
||||
*/
|
||||
#include "mp.h"
|
||||
#include "pincfg.h"
|
||||
#include "py_gpio.h"
|
||||
#include "py_assert.h"
|
||||
#define EXTI_MAX 16
|
||||
|
||||
typedef struct _py_gpio_obj_t {
|
||||
mp_obj_base_t base;
|
||||
const gpio_t *info;
|
||||
} py_gpio_obj_t;
|
||||
|
||||
static mp_obj_t extint_vector[EXTI_MAX];
|
||||
static const uint8_t nvic_irq_channel[EXTI_MAX] = {
|
||||
EXTI0_IRQn,
|
||||
EXTI1_IRQn,
|
||||
EXTI2_IRQn,
|
||||
EXTI3_IRQn,
|
||||
EXTI4_IRQn,
|
||||
EXTI9_5_IRQn,
|
||||
EXTI9_5_IRQn,
|
||||
EXTI9_5_IRQn,
|
||||
EXTI9_5_IRQn,
|
||||
EXTI9_5_IRQn,
|
||||
EXTI15_10_IRQn,
|
||||
EXTI15_10_IRQn,
|
||||
EXTI15_10_IRQn,
|
||||
EXTI15_10_IRQn,
|
||||
EXTI15_10_IRQn,
|
||||
EXTI15_10_IRQn,
|
||||
};
|
||||
|
||||
static void gpio_init(const gpio_t *gpio)
|
||||
{
|
||||
/* Configure the GPIO pin */
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.Pin = gpio->pin;
|
||||
GPIO_InitStructure.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
HAL_GPIO_Init(gpio->port, &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
void gpio_init_exti(const gpio_t *gpio, mp_obj_t cb, uint32_t priority, uint32_t sub_priority)
|
||||
{
|
||||
/* Configure the GPIO pin */
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.Pin = gpio->pin;
|
||||
GPIO_InitStructure.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
|
||||
HAL_GPIO_Init(gpio->port, &GPIO_InitStructure);
|
||||
|
||||
int line = 32-__CLZ(gpio->pin)-1;
|
||||
printf("line %d\n", line);
|
||||
// add cb to exti vector
|
||||
extint_vector[line] = cb;
|
||||
|
||||
/* Enable and set NVIC Interrupt to the lowest priority */
|
||||
HAL_NVIC_SetPriority(nvic_irq_channel[line], priority, sub_priority);
|
||||
HAL_NVIC_EnableIRQ(nvic_irq_channel[line]);
|
||||
}
|
||||
|
||||
const mp_obj_module_t *py_gpio_init()
|
||||
{
|
||||
for (int i=0; i<EXTI_MAX; i++) {
|
||||
extint_vector[i] = mp_const_none;
|
||||
}
|
||||
return &gpio_module;
|
||||
}
|
||||
|
||||
static mp_obj_t py_gpio_low(py_gpio_obj_t *gpio)
|
||||
{
|
||||
HAL_GPIO_WritePin(gpio->info->port, gpio->info->pin, GPIO_PIN_RESET);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t py_gpio_high(py_gpio_obj_t *gpio)
|
||||
{
|
||||
HAL_GPIO_WritePin(gpio->info->port, gpio->info->pin, GPIO_PIN_SET);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static void py_gpio_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind)
|
||||
{
|
||||
print(env, "<gpio>");
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_gpio_low_obj, py_gpio_low);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_gpio_high_obj, py_gpio_high);
|
||||
|
||||
static const mp_map_elem_t locals_dict_table[] = {
|
||||
{MP_OBJ_NEW_QSTR(MP_QSTR_low), (mp_obj_t)&py_gpio_low_obj},
|
||||
{MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&py_gpio_high_obj},
|
||||
{NULL, NULL },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(locals_dict, locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t py_gpio_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_gpio,
|
||||
.print = py_gpio_print,
|
||||
.locals_dict = (mp_obj_t)&locals_dict,
|
||||
};
|
||||
|
||||
mp_obj_t py_gpio_new(mp_obj_t id_obj)
|
||||
{
|
||||
gpio_id_t id = mp_obj_get_int(id_obj);
|
||||
py_gpio_obj_t *gpio_obj=mp_const_none;
|
||||
|
||||
if (id < GPIO_ID_MAX) {
|
||||
gpio_init(&gpio_pins[id]);
|
||||
gpio_obj = m_new_obj(py_gpio_obj_t);
|
||||
gpio_obj->base.type = &py_gpio_type;
|
||||
gpio_obj->info = &gpio_pins[id];
|
||||
}
|
||||
return gpio_obj;
|
||||
}
|
||||
|
||||
mp_obj_t py_gpio_exti(mp_obj_t id_obj, mp_obj_t cb_obj)
|
||||
{
|
||||
gpio_id_t id = mp_obj_get_int(id_obj);
|
||||
if (id < GPIO_ID_MAX) {
|
||||
gpio_init_exti(&gpio_pins[id], cb_obj, 0x0F, 0x0F);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_gpio_new_obj, py_gpio_new);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_gpio_exti_obj, py_gpio_exti);
|
||||
|
||||
static const mp_map_elem_t globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_gpio) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_GPIO), (mp_obj_t)&py_gpio_new_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_EXTI), (mp_obj_t)&py_gpio_exti_obj },
|
||||
GPIO_PINS_QSTR, //exports pin names
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table);
|
||||
|
||||
const mp_obj_module_t gpio_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_gpio,
|
||||
.globals = (mp_obj_t)&globals_dict,
|
||||
};
|
||||
|
||||
// EXTI handler
|
||||
void Handle_EXTI_Irq(uint32_t line)
|
||||
{
|
||||
if (__HAL_GPIO_EXTI_GET_FLAG(1 << line)) {
|
||||
__HAL_GPIO_EXTI_CLEAR_FLAG(1 << line);
|
||||
mp_obj_t cb = extint_vector[line];
|
||||
if (cb != mp_const_none) {
|
||||
// When executing code within a handler we must lock the GC to prevent
|
||||
// any memory allocations. We must also catch any exceptions.
|
||||
gc_lock();
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_call_function_1(cb, MP_OBJ_NEW_SMALL_INT(line));
|
||||
nlr_pop();
|
||||
} else {
|
||||
// Uncaught exception; disable the callback so it doesn't run again.
|
||||
extint_vector[line] = mp_const_none;
|
||||
HAL_NVIC_DisableIRQ(nvic_irq_channel[line]);
|
||||
printf("Uncaught exception in ExtInt interrupt handler line %lu\n", line);
|
||||
mp_obj_print_exception((mp_obj_t)nlr.ret_val);
|
||||
}
|
||||
gc_unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* GPIO Python module.
|
||||
*
|
||||
*/
|
||||
#ifndef __PY_GPIO_H__
|
||||
#define __PY_GPIO_H__
|
||||
const mp_obj_module_t *py_gpio_init();
|
||||
#endif // __PY_GPIO_H__
|
||||
|
||||
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* LED Python module.
|
||||
*
|
||||
*/
|
||||
#include "mp.h"
|
||||
#include "pincfg.h"
|
||||
#include "py_led.h"
|
||||
void led_init(enum led_id id)
|
||||
{
|
||||
led_state(id, 1);
|
||||
}
|
||||
|
||||
void led_toggle(enum led_id id)
|
||||
{
|
||||
if (id >= 0 && id < LED_MAX) {
|
||||
/* Invert LED state */
|
||||
HAL_GPIO_TogglePin(led_pins[id].port, led_pins[id].pin);
|
||||
}
|
||||
}
|
||||
|
||||
void led_state(enum led_id id, int state)
|
||||
{
|
||||
if (id >= 0 && id < LED_MAX) {
|
||||
#ifdef OPENMV2
|
||||
if (id == LED_IR) { //IR LED is inverted
|
||||
state = !state;
|
||||
}
|
||||
#endif
|
||||
HAL_GPIO_WritePin(led_pins[id].port,
|
||||
led_pins[id].pin, (state)? GPIO_PIN_RESET:GPIO_PIN_SET);
|
||||
}
|
||||
}
|
||||
|
||||
static mp_obj_t py_led_on(mp_obj_t led_id) {
|
||||
led_state(mp_obj_get_int(led_id), 1);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t py_led_off(mp_obj_t led_id) {
|
||||
led_state(mp_obj_get_int(led_id), 0);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t py_led_toggle(mp_obj_t led_id) {
|
||||
led_toggle(mp_obj_get_int(led_id));
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_led_on_obj, py_led_on);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_led_off_obj, py_led_off);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_led_toggle_obj, py_led_toggle);
|
||||
|
||||
static const mp_map_elem_t globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_led) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RED), MP_OBJ_NEW_SMALL_INT(LED_RED)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_GREEN), MP_OBJ_NEW_SMALL_INT(LED_GREEN)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_BLUE), MP_OBJ_NEW_SMALL_INT(LED_BLUE)},
|
||||
#ifdef OPENMV2
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IR), MP_OBJ_NEW_SMALL_INT(LED_IR)},
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_on), (mp_obj_t)&py_led_on_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_off), (mp_obj_t)&py_led_off_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&py_led_toggle_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table);
|
||||
|
||||
const mp_obj_module_t led_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_led,
|
||||
.globals = (mp_obj_t)&globals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_module_t *py_led_init()
|
||||
{
|
||||
/* Init LED */
|
||||
led_init(LED_BLUE);
|
||||
return &led_module;
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* LED Python module.
|
||||
*
|
||||
*/
|
||||
#ifndef __PY_LED_H__
|
||||
#define __PY_LED_H__
|
||||
enum led_id {
|
||||
LED_RED=0,
|
||||
LED_GREEN,
|
||||
LED_BLUE,
|
||||
#ifdef OPENMV2
|
||||
LED_IR,
|
||||
#endif
|
||||
LED_MAX,
|
||||
};
|
||||
|
||||
void led_init(enum led_id color);
|
||||
void led_toggle(enum led_id color);
|
||||
void led_state(enum led_id color, int state);
|
||||
const mp_obj_module_t *py_led_init();
|
||||
#endif // __PY_LED_H__
|
||||
@ -1,144 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* Select Python module.
|
||||
*
|
||||
*/
|
||||
#include <mp.h>
|
||||
#include <cc3000_common.h>
|
||||
#include <evnt_handler.h>
|
||||
#include <socket.h>
|
||||
#include <inet_pton.h>
|
||||
#include <inet_ntop.h>
|
||||
#include <py_wlan.h>
|
||||
#include <py_socket.h>
|
||||
#include <py_select.h>
|
||||
#include <py_assert.h>
|
||||
|
||||
#define min(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
#define max(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
// select helper functions
|
||||
static void set_fds(int *nfds, mp_obj_t *fdlist, uint fdlist_len, fd_set *fdset)
|
||||
{
|
||||
FD_ZERO(fdset);
|
||||
|
||||
/* add sockets to fd set*/
|
||||
for (int i=0; i<fdlist_len; i++) {
|
||||
socket_t *s = fdlist[i];
|
||||
|
||||
/* check arg type*/
|
||||
PY_ASSERT_TYPE(s, &socket_type);
|
||||
|
||||
/* add to fd set */
|
||||
FD_SET(s->fd, fdset);
|
||||
|
||||
if (s->fd > (*nfds)) {
|
||||
*nfds = s->fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void get_fds(mp_obj_t *fdlist, uint fdlist_len, mp_obj_t *fdlist_out, fd_set *fdset)
|
||||
{
|
||||
for (int i=0; i<fdlist_len; i++) {
|
||||
socket_t *s = fdlist[i];
|
||||
if (FD_ISSET(s->fd, fdset)) {
|
||||
socket_t *socket_obj = m_new_obj_with_finaliser(socket_t);
|
||||
socket_obj->base.type = (mp_obj_t)&socket_type;
|
||||
socket_obj->fd = s->fd;
|
||||
mp_obj_list_append(fdlist_out, socket_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static mp_obj_t py_select(uint n_args, const mp_obj_t *args)
|
||||
{
|
||||
int nfds=0; //highest-numbered fd plus 1
|
||||
timeval tv={0};
|
||||
fd_set rfds, wfds, xfds;
|
||||
|
||||
mp_obj_t *rlist, *wlist, *xlist;
|
||||
uint rlist_len, wlist_len, xlist_len;
|
||||
|
||||
/* read args */
|
||||
mp_obj_get_array(args[0], &rlist_len, &rlist);
|
||||
mp_obj_get_array(args[1], &wlist_len, &wlist);
|
||||
mp_obj_get_array(args[2], &xlist_len, &xlist);
|
||||
|
||||
if (n_args == 4) {
|
||||
float timeout = mp_obj_get_float(args[3]);
|
||||
tv.tv_sec = (int)timeout;
|
||||
tv.tv_usec = (timeout-(int)timeout)*1000*1000;
|
||||
}
|
||||
|
||||
// add fds to their respective sets
|
||||
set_fds(&nfds, rlist, rlist_len, &rfds);
|
||||
set_fds(&nfds, wlist, wlist_len, &wfds);
|
||||
set_fds(&nfds, xlist, xlist_len, &xfds);
|
||||
|
||||
// call select
|
||||
nfds = select(nfds+1, &rfds, &wfds, &xfds, &tv);
|
||||
|
||||
// if any of the read sockets is closed, we add it to the read fd set,
|
||||
// a subsequent call to recv() returns 0. This behavior is consistent with BSD.
|
||||
for (int i=0; i<rlist_len; i++) {
|
||||
socket_t *s = rlist[i];
|
||||
if (wlan_get_fd_state(s->fd)) {
|
||||
FD_SET(s->fd, &rfds);
|
||||
nfds = max(nfds, s->fd);
|
||||
}
|
||||
}
|
||||
|
||||
// return value; a tuple of 3 lists
|
||||
mp_obj_t fds[3] = {
|
||||
mp_obj_new_list(0, NULL),
|
||||
mp_obj_new_list(0, NULL),
|
||||
mp_obj_new_list(0, NULL)
|
||||
};
|
||||
|
||||
// On success, select() returns the number of file descriptors contained
|
||||
// in the three returned descriptor sets which may be zero if the timeout
|
||||
// expires before anything interesting happens, -1 is returned on error.
|
||||
if (nfds == -1) { // select failed
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "select failed"));
|
||||
} else if (nfds) { // an fd is ready
|
||||
get_fds(rlist, rlist_len, fds[0], &rfds);
|
||||
get_fds(wlist, wlist_len, fds[1], &wfds);
|
||||
get_fds(xlist, xlist_len, fds[2], &xfds);
|
||||
} // select timedout
|
||||
|
||||
return mp_obj_new_tuple(3, fds);
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_select_obj, 3, 4, py_select);
|
||||
// select module
|
||||
static const mp_map_elem_t module_globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_select) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_select), (mp_obj_t)&py_select_obj },
|
||||
};
|
||||
|
||||
static MP_DEFINE_CONST_DICT(module_globals_dict, module_globals_dict_table);
|
||||
|
||||
const mp_obj_module_t select_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_select,
|
||||
.globals = (mp_obj_dict_t*)&module_globals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_module_t *py_select_init()
|
||||
{
|
||||
return &select_module;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* Select Python module.
|
||||
*
|
||||
*/
|
||||
#ifndef __PY_SELECT_H__
|
||||
#define __PY_SELECT_H__
|
||||
const mp_obj_module_t *py_select_init();
|
||||
#endif // __PY_SELECT_H__
|
||||
@ -1,293 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* Socket Python module.
|
||||
*
|
||||
*/
|
||||
#include <mp.h>
|
||||
#include <cc3000_common.h>
|
||||
#include <evnt_handler.h>
|
||||
#include <socket.h>
|
||||
#include <inet_pton.h>
|
||||
#include <inet_ntop.h>
|
||||
#include <py_wlan.h>
|
||||
#include <py_socket.h>
|
||||
#include <py_assert.h>
|
||||
|
||||
#define MAX_FD (8)
|
||||
#define MAX_ADDRSTRLEN (128)
|
||||
#define MAX_RX_PACKET (CC3000_RX_BUFFER_SIZE-CC3000_MINIMAL_RX_SIZE-1)
|
||||
#define MAX_TX_PACKET (CC3000_TX_BUFFER_SIZE-CC3000_MINIMAL_TX_SIZE-1)
|
||||
#define min(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
#define max(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
const mp_obj_type_t socket_type;
|
||||
|
||||
void socket_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind)
|
||||
{
|
||||
printf("<%s %p>", mp_obj_get_type_str(self_in), self_in);
|
||||
}
|
||||
|
||||
static mp_uint_t socket_send(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode)
|
||||
{
|
||||
int bytes = 0;
|
||||
socket_t *self = self_in;
|
||||
|
||||
if (wlan_get_fd_state(self->fd)) {
|
||||
closesocket(self->fd);
|
||||
*errcode = 32;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* send packets */
|
||||
while (bytes < size) {
|
||||
int n = min((size-bytes), MAX_TX_PACKET);
|
||||
n = send(self->fd, buf+bytes, n, 0);
|
||||
if (n <= 0) {
|
||||
bytes = n;
|
||||
*errcode = errno;
|
||||
break;
|
||||
}
|
||||
bytes += n;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static mp_uint_t socket_recv(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode)
|
||||
{
|
||||
int bytes = 0;
|
||||
socket_t *self = self_in;
|
||||
|
||||
if (wlan_get_fd_state(self->fd)) {
|
||||
closesocket(self->fd);
|
||||
*errcode = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* recv packets */
|
||||
while (bytes < size) {
|
||||
int n = min((size-bytes), MAX_RX_PACKET);
|
||||
n = recv(self->fd, buf+bytes, n, 0);
|
||||
if (n == 0) {
|
||||
break;
|
||||
} else if (n < 0) {
|
||||
bytes = n;
|
||||
*errcode = errno;
|
||||
break;
|
||||
}
|
||||
bytes += n;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_obj)
|
||||
{
|
||||
socket_t *self = self_in;
|
||||
|
||||
mp_obj_t *addr;
|
||||
mp_obj_get_array_fixed_n(addr_obj, 2, &addr);
|
||||
|
||||
/* fill sockaddr */
|
||||
int port = mp_obj_get_int(addr[1]);
|
||||
sockaddr_in addr_in = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons(port),
|
||||
.sin_addr.s_addr = 0,// INADDR_ANY
|
||||
.sin_zero = {0}
|
||||
};
|
||||
|
||||
const char *host = mp_obj_str_get_str(addr[0]);
|
||||
if (strlen(host) && !inet_pton(AF_INET, host, &addr_in.sin_addr.s_addr)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "invalid IP address"));
|
||||
}
|
||||
|
||||
/* bind socket */
|
||||
if (bind(self->fd, (sockaddr*) &addr_in, sizeof(sockaddr_in)) < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "bind failed"));
|
||||
}
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
static mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog)
|
||||
{
|
||||
socket_t *self = self_in;
|
||||
if (listen(self->fd, mp_obj_get_int(backlog)) < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "listen failed"));
|
||||
}
|
||||
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
static mp_obj_t socket_accept(mp_obj_t self_in)
|
||||
{
|
||||
int fd;
|
||||
socket_t *self = self_in;
|
||||
|
||||
sockaddr addr;
|
||||
socklen_t addr_len = sizeof(sockaddr);
|
||||
|
||||
// accept incoming connection
|
||||
if ((fd = accept(self->fd, &addr, &addr_len)) < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "accept failed"));
|
||||
}
|
||||
|
||||
// clear socket state
|
||||
wlan_clear_fd_state(fd);
|
||||
|
||||
// create new socket object
|
||||
socket_t *socket_obj = m_new_obj_with_finaliser(socket_t);
|
||||
socket_obj->base.type = (mp_obj_t)&socket_type;
|
||||
socket_obj->fd = fd;
|
||||
|
||||
|
||||
char buf[MAX_ADDRSTRLEN]={0};
|
||||
if (inet_ntop(addr.sa_family,
|
||||
&(((sockaddr_in*)&addr)->sin_addr), buf, MAX_ADDRSTRLEN) == NULL) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "invalid IP address"));
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *cli = mp_obj_new_tuple(2, NULL);
|
||||
mp_obj_tuple_t *cli_addr = mp_obj_new_tuple(2, NULL);
|
||||
|
||||
cli->items[0] = socket_obj;
|
||||
cli->items[1] = cli_addr;
|
||||
cli_addr->items[0] = mp_obj_new_str(buf, strlen(buf), false);
|
||||
cli_addr->items[1] = mp_obj_new_int(((sockaddr_in*)&addr)->sin_port);
|
||||
|
||||
return cli;
|
||||
}
|
||||
|
||||
static mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout)
|
||||
{
|
||||
socket_t *self = self_in;
|
||||
int optval = mp_obj_get_int(timeout);
|
||||
socklen_t optlen = sizeof(optval);
|
||||
|
||||
if (setsockopt(self->fd, SOL_SOCKET, SOCKOPT_RECV_TIMEOUT, &optval, optlen) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "setsockopt failed"));
|
||||
}
|
||||
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
static mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking)
|
||||
{
|
||||
socket_t *self = self_in;
|
||||
int optval;
|
||||
socklen_t optlen = sizeof(optval);
|
||||
|
||||
if (mp_obj_get_int(blocking)) {
|
||||
optval = SOCK_OFF; // Enable non-blocking
|
||||
} else {
|
||||
optval = SOCK_ON;
|
||||
}
|
||||
|
||||
if (setsockopt(self->fd, SOL_SOCKET, SOCKOPT_RECV_NONBLOCK, &optval, optlen) != 0 ||
|
||||
setsockopt(self->fd, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen) != 0 ) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "setsockopt failed"));
|
||||
}
|
||||
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
static mp_obj_t socket_close(mp_obj_t self_in)
|
||||
{
|
||||
closesocket(((socket_t *)self_in)->fd);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t socket_new(mp_obj_t domain, mp_obj_t type, mp_obj_t protocol)
|
||||
{
|
||||
socket_t *socket_obj = m_new_obj_with_finaliser(socket_t);
|
||||
socket_obj->base.type = (mp_obj_t)&socket_type;
|
||||
|
||||
/* create new socket */
|
||||
socket_obj->fd = socket(mp_obj_get_int(domain), mp_obj_get_int(type), mp_obj_get_int(protocol));
|
||||
if (socket_obj->fd < 0) {
|
||||
m_del_obj(socket_t, socket_obj);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "socket failed"));
|
||||
}
|
||||
|
||||
// clear socket state
|
||||
wlan_clear_fd_state(socket_obj->fd);
|
||||
return socket_obj;
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(socket_settimeout_obj, socket_settimeout);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj,socket_setblocking);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(socket_close_obj, socket_close);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_3(socket_new_obj, socket_new);
|
||||
|
||||
static const mp_map_elem_t socket_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&mp_stream_write_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&mp_stream_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_bind), (mp_obj_t)&socket_bind_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listen), (mp_obj_t)&socket_listen_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_accept), (mp_obj_t)&socket_accept_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_settimeout), (mp_obj_t)&socket_settimeout_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_setblocking), (mp_obj_t)&socket_setblocking_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&socket_close_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&socket_close_obj },
|
||||
};
|
||||
|
||||
static MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table);
|
||||
|
||||
static const mp_stream_p_t socket_stream_p = {
|
||||
.read = socket_recv,
|
||||
.write = socket_send,
|
||||
};
|
||||
|
||||
const mp_obj_type_t socket_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_socket,
|
||||
.print = socket_print,
|
||||
.getiter = NULL,
|
||||
.iternext = NULL,
|
||||
.stream_p = &socket_stream_p,
|
||||
.locals_dict = (mp_obj_t)&socket_locals_dict,
|
||||
};
|
||||
|
||||
/* Socket module */
|
||||
static const mp_map_elem_t module_globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_socket) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&socket_new_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET), MP_OBJ_NEW_SMALL_INT(AF_INET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET6), MP_OBJ_NEW_SMALL_INT(AF_INET6) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_STREAM), MP_OBJ_NEW_SMALL_INT(SOCK_STREAM) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_DGRAM), MP_OBJ_NEW_SMALL_INT(SOCK_DGRAM) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_RAW), MP_OBJ_NEW_SMALL_INT(SOCK_RAW) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IP) , MP_OBJ_NEW_SMALL_INT(IPPROTO_IP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_ICMP), MP_OBJ_NEW_SMALL_INT(IPPROTO_ICMP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IPV4), MP_OBJ_NEW_SMALL_INT(IPPROTO_IPV4) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_TCP), MP_OBJ_NEW_SMALL_INT(IPPROTO_TCP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_UDP), MP_OBJ_NEW_SMALL_INT(IPPROTO_UDP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IPV6), MP_OBJ_NEW_SMALL_INT(IPPROTO_IPV6) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_RAW), MP_OBJ_NEW_SMALL_INT(IPPROTO_RAW) },
|
||||
};
|
||||
|
||||
static MP_DEFINE_CONST_DICT(module_globals_dict, module_globals_dict_table);
|
||||
|
||||
const mp_obj_module_t socket_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_socket,
|
||||
.globals = (mp_obj_dict_t*)&module_globals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_module_t *py_socket_init()
|
||||
{
|
||||
return &socket_module;
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* Socket Python module.
|
||||
*
|
||||
*/
|
||||
#ifndef __PY_SOCKET_H__
|
||||
#define __PY_SOCKET_H__
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
int fd;
|
||||
} socket_t;
|
||||
extern const mp_obj_type_t socket_type;
|
||||
const mp_obj_module_t *py_socket_init();
|
||||
#endif // __PY_SOCKET_H__
|
||||
@ -1,165 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* SPI Python module.
|
||||
*
|
||||
*/
|
||||
#include "mp.h"
|
||||
#include "pincfg.h"
|
||||
#include "spi.h"
|
||||
#include "py_spi.h"
|
||||
#include "py_assert.h"
|
||||
#include "py_image.h"
|
||||
#include "imlib.h"
|
||||
|
||||
#define SPI_TIMEOUT (500) /* in ms */
|
||||
|
||||
#define SPIx_DMA_RX_IRQn DMA2_Stream3_IRQn
|
||||
#define SPIx_RX_DMA_STREAM DMA2_Stream3
|
||||
#define SPIx_RX_DMA_CHANNEL DMA_CHANNEL_5
|
||||
|
||||
#define SPIx_DMA_TX_IRQn DMA2_Stream4_IRQn
|
||||
#define SPIx_TX_DMA_STREAM DMA2_Stream4
|
||||
#define SPIx_TX_DMA_CHANNEL DMA_CHANNEL_5
|
||||
|
||||
SPI_HandleTypeDef SPIHandle;
|
||||
static DMA_HandleTypeDef hdma_tx;
|
||||
static DMA_HandleTypeDef hdma_rx;
|
||||
|
||||
static mp_obj_t py_spi_read(mp_obj_t obj)
|
||||
{
|
||||
mp_buffer_info_t bufinfo;
|
||||
|
||||
if (MP_OBJ_IS_INT(obj)) {
|
||||
bufinfo.len = mp_obj_get_int(obj);
|
||||
bufinfo.typecode = 'B';
|
||||
mp_obj_str_builder_start(&mp_type_bytes, bufinfo.len, (byte**)&(bufinfo.buf));
|
||||
} else {
|
||||
mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_WRITE);
|
||||
}
|
||||
|
||||
if (HAL_SPI_Receive_DMA(&SPIHandle, bufinfo.buf, bufinfo.len) != HAL_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_Exception, "HAL_SPI_Receive failed"));
|
||||
}
|
||||
|
||||
// wait for transfer to finish
|
||||
while (HAL_SPI_GetState(&SPIHandle) != HAL_SPI_STATE_READY) {
|
||||
}
|
||||
|
||||
return mp_obj_new_int(bufinfo.len);
|
||||
}
|
||||
|
||||
static mp_obj_t py_spi_write(mp_obj_t obj)
|
||||
{
|
||||
byte buf[1];
|
||||
mp_buffer_info_t bufinfo;
|
||||
|
||||
if (MP_OBJ_IS_INT(obj)) {
|
||||
buf[0] = mp_obj_get_int(obj);
|
||||
bufinfo.buf = buf;
|
||||
bufinfo.len = 1;
|
||||
bufinfo.typecode = 'B';
|
||||
} else {
|
||||
mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_READ);
|
||||
}
|
||||
|
||||
if (bufinfo.len > 1) {
|
||||
// start DMA transfer
|
||||
if (HAL_SPI_Transmit_DMA(&SPIHandle, bufinfo.buf, bufinfo.len) != HAL_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_Exception, "HAL_SPI_Transmit failed"));
|
||||
}
|
||||
// wait for transfer to finish
|
||||
while (HAL_SPI_GetState(&SPIHandle) != HAL_SPI_STATE_READY) {
|
||||
}
|
||||
} else {
|
||||
// don't use DMA for small buffers
|
||||
if (HAL_SPI_Transmit(&SPIHandle, bufinfo.buf, bufinfo.len, SPI_TIMEOUT) != HAL_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_Exception, "HAL_SPI_Transmit failed"));
|
||||
}
|
||||
}
|
||||
|
||||
return mp_obj_new_int(bufinfo.len);
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_spi_read_obj, py_spi_read);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_spi_write_obj, py_spi_write);
|
||||
|
||||
static const mp_map_elem_t globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_spi) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&py_spi_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&py_spi_write_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table);
|
||||
|
||||
const mp_obj_module_t spi_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_spi,
|
||||
.globals = (mp_obj_t)&globals_dict,
|
||||
};
|
||||
|
||||
static void config_dma_stream(SPI_HandleTypeDef *hspi,
|
||||
DMA_HandleTypeDef *hdma, DMA_Stream_TypeDef *instance, uint32_t channel)
|
||||
{
|
||||
hdma->Instance = instance;
|
||||
hdma->Init.Channel = channel;
|
||||
hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma->Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma->Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma->Init.Mode = DMA_NORMAL;
|
||||
hdma->Init.Priority = DMA_PRIORITY_LOW; //SET to HIGH for rx
|
||||
hdma->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
hdma->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
|
||||
hdma->Init.MemBurst = DMA_MBURST_SINGLE;
|
||||
hdma->Init.PeriphBurst = DMA_PBURST_SINGLE;
|
||||
HAL_DMA_Init(hdma);
|
||||
}
|
||||
|
||||
const mp_obj_module_t *py_spi_init()
|
||||
{
|
||||
/* SPI configuration */
|
||||
SPIHandle.Instance = USR_SPI;
|
||||
SPIHandle.Init.Mode = SPI_MODE_MASTER;
|
||||
SPIHandle.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
SPIHandle.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
SPIHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
SPIHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
SPIHandle.Init.NSS = SPI_NSS_SOFT;
|
||||
SPIHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
|
||||
SPIHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
SPIHandle.Init.TIMode = SPI_TIMODE_DISABLED;
|
||||
SPIHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
|
||||
SPIHandle.Init.CRCPolynomial = 7;
|
||||
|
||||
/* Configure TX DMA stream */
|
||||
config_dma_stream(&SPIHandle, &hdma_tx, SPIx_TX_DMA_STREAM, SPIx_TX_DMA_CHANNEL);
|
||||
__HAL_LINKDMA(&SPIHandle, hdmatx, hdma_tx);
|
||||
|
||||
/* Configure RX DMA stream */
|
||||
config_dma_stream(&SPIHandle, &hdma_rx, SPIx_RX_DMA_STREAM, SPIx_RX_DMA_CHANNEL);
|
||||
__HAL_LINKDMA(&SPIHandle, hdmarx, hdma_rx);
|
||||
|
||||
/* Configure TX DMA stream IRQ */
|
||||
HAL_NVIC_SetPriority(SPIx_DMA_TX_IRQn, 1, 1);
|
||||
HAL_NVIC_EnableIRQ(SPIx_DMA_TX_IRQn);
|
||||
|
||||
/* Configure RX DMA stream IRQ */
|
||||
HAL_NVIC_SetPriority(SPIx_DMA_RX_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(SPIx_DMA_RX_IRQn);
|
||||
|
||||
/* Initialize the user SPI */
|
||||
if (HAL_SPI_Init(&SPIHandle) != HAL_OK) {
|
||||
/* Initialization Error */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t buf[1];
|
||||
/* dummy read */
|
||||
HAL_SPI_Receive(&SPIHandle, buf, sizeof(buf), SPI_TIMEOUT);
|
||||
|
||||
return &spi_module;
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* SPI Python module.
|
||||
*
|
||||
*/
|
||||
#ifndef __PY_SPI_H__
|
||||
#define __PY_SPI_H__
|
||||
const mp_obj_module_t *py_spi_init();
|
||||
#endif // __PY_SPI_H__
|
||||
|
||||
@ -1,208 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* WLAN Python module.
|
||||
*
|
||||
*/
|
||||
#include <mp.h>
|
||||
#include <cc3k.h>
|
||||
#include <stm32f4xx_hal.h>
|
||||
#include "py_led.h"
|
||||
#define IS_WLAN_SEC(sec) \
|
||||
(sec>WLAN_SEC_UNSEC && sec<=WLAN_SEC_WPA2)
|
||||
#define MAX_PACKET_LENGTH (1024)
|
||||
|
||||
static volatile int fd_state=0;
|
||||
static volatile int ip_obtained = 0;
|
||||
static volatile int wlan_connected = 0;
|
||||
|
||||
int wlan_get_fd_state(int fd)
|
||||
{
|
||||
return (fd_state & (1<<fd));
|
||||
}
|
||||
|
||||
void wlan_clear_fd_state(int fd)
|
||||
{
|
||||
// reset socket state
|
||||
fd_state &= ~(1<<fd);
|
||||
}
|
||||
|
||||
void sWlanCallback(long lEventType, char * data, unsigned char length)
|
||||
{
|
||||
switch (lEventType) {
|
||||
case HCI_EVNT_WLAN_UNSOL_CONNECT:
|
||||
wlan_connected = 1;
|
||||
break;
|
||||
case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
|
||||
/* Link down */
|
||||
wlan_connected = 0;
|
||||
led_state(LED_RED, 1);
|
||||
break;
|
||||
case HCI_EVNT_WLAN_UNSOL_DHCP:
|
||||
ip_obtained = 1;
|
||||
break;
|
||||
case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
|
||||
// mark socket for closure
|
||||
fd_state |= (1<<((uint8_t)data[0]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static mp_obj_t mod_wlan_init()
|
||||
{
|
||||
/* Initialize WLAN module */
|
||||
wlan_init(sWlanCallback, NULL, NULL, NULL,
|
||||
ReadWlanInterruptPin, SpiResumeSpi, SpiPauseSpi, WriteWlanPin);
|
||||
|
||||
/* Start WLAN module */
|
||||
if (wlan_start(0) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(
|
||||
&mp_type_OSError, "Failed to init wlan module"));
|
||||
}
|
||||
|
||||
/* Set connection policy */
|
||||
// wlan_ioctl_set_connection_policy(0, 0, 0);
|
||||
|
||||
/* Mask out all non-required events from the CC3000 */
|
||||
wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|
|
||||
HCI_EVNT_WLAN_UNSOL_INIT|
|
||||
HCI_EVNT_WLAN_ASYNC_PING_REPORT|
|
||||
HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t mod_wlan_ifconfig()
|
||||
{
|
||||
tNetappIpconfigRetArgs ipconfig;
|
||||
uint8_t *ip = &ipconfig.aucIP[0];
|
||||
uint8_t *mask= &ipconfig.aucSubnetMask[0];
|
||||
uint8_t *gw= &ipconfig.aucDefaultGateway[0];
|
||||
uint8_t *dhcp= &ipconfig.aucDHCPServer[0];
|
||||
uint8_t *dns= &ipconfig.aucDNSServer[0];
|
||||
uint8_t *mac= &ipconfig.uaMacAddr[0];
|
||||
// uint8_t *ssid= &ipconfig.uaSSID[0]; //32
|
||||
|
||||
netapp_ipconfig(&ipconfig);
|
||||
|
||||
printf ("IP:%d.%d.%d.%d\n" \
|
||||
"Mask:%d.%d.%d.%d\n"\
|
||||
"GW:%d.%d.%d.%d\n" \
|
||||
"DHCP:%d.%d.%d.%d\n"\
|
||||
"DNS:%d.%d.%d.%d\n" \
|
||||
"MAC:%02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
ip[3], ip[2], ip[1], ip[0],
|
||||
mask[3], mask[2], mask[1], mask[0],
|
||||
gw[3], gw[2], gw[1], gw[0],
|
||||
dhcp[3], dhcp[2], dhcp[1], dhcp[0],
|
||||
dns[3], dns[2], dns[1], dns[0],
|
||||
mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t mod_wlan_connect(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
{
|
||||
int ssid_len =0;
|
||||
const char *ssid = NULL;
|
||||
const char *bssid = NULL;
|
||||
|
||||
int key_len =0;
|
||||
int sec = WLAN_SEC_UNSEC;
|
||||
const char *key = NULL;
|
||||
|
||||
mp_map_elem_t *kw_key, *kw_sec, *kw_bssid;
|
||||
|
||||
ssid = mp_obj_str_get_str(args[0]);
|
||||
ssid_len = strlen(ssid);
|
||||
|
||||
/* get KW args */
|
||||
kw_key = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("key")), MP_MAP_LOOKUP);
|
||||
kw_sec = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("sec")), MP_MAP_LOOKUP);
|
||||
kw_bssid = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("bssid")), MP_MAP_LOOKUP);
|
||||
|
||||
/* get key and sec */
|
||||
if (kw_key && kw_sec) {
|
||||
key = mp_obj_str_get_str(kw_key->value);
|
||||
key_len = strlen(key);
|
||||
|
||||
sec = mp_obj_get_int(kw_sec->value);
|
||||
if (!IS_WLAN_SEC(sec)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(
|
||||
&mp_type_ValueError, "Invalid security mode"));
|
||||
return mp_const_false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* get bssid */
|
||||
if (kw_bssid != NULL) {
|
||||
bssid = mp_obj_str_get_str(kw_bssid->value);
|
||||
}
|
||||
|
||||
/* connect to AP */
|
||||
if (wlan_connect(sec, (char*) ssid, ssid_len, (uint8_t*)bssid, (uint8_t*)key, key_len) != 0) {
|
||||
return mp_const_false;
|
||||
}
|
||||
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
static mp_obj_t mod_wlan_connected()
|
||||
{
|
||||
if (wlan_connected && ip_obtained) {
|
||||
return mp_const_true;
|
||||
}
|
||||
return mp_const_false;
|
||||
}
|
||||
|
||||
static mp_obj_t mod_wlan_patch_version()
|
||||
{
|
||||
uint8_t pver[2];
|
||||
mp_obj_tuple_t *t_pver = mp_obj_new_tuple(2, NULL);
|
||||
|
||||
nvmem_read_sp_version(pver);
|
||||
t_pver->items[0] = mp_obj_new_int(pver[0]);
|
||||
t_pver->items[1] = mp_obj_new_int(pver[1]);
|
||||
return t_pver;
|
||||
}
|
||||
|
||||
static mp_obj_t mod_wlan_patch_program()
|
||||
{
|
||||
//patch_prog_start();
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0 (py_wlan_init_obj, mod_wlan_init);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0 (py_wlan_ifconfig_obj, mod_wlan_ifconfig);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_wlan_connect_obj, 1, mod_wlan_connect);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0 (py_wlan_connected_obj, mod_wlan_connected);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0 (py_wlan_patch_version_obj,mod_wlan_patch_version);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0 (py_wlan_patch_program_obj,mod_wlan_patch_program);
|
||||
|
||||
static const mp_map_elem_t globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_wlan) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WEP), MP_OBJ_NEW_SMALL_INT(WLAN_SEC_WEP)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WPA), MP_OBJ_NEW_SMALL_INT(WLAN_SEC_WPA)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WPA2), MP_OBJ_NEW_SMALL_INT(WLAN_SEC_WPA2)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&py_wlan_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ifconfig), (mp_obj_t)&py_wlan_ifconfig_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&py_wlan_connect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_connected), (mp_obj_t)&py_wlan_connected_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_patch_version), (mp_obj_t)&py_wlan_patch_version_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_patch_program), (mp_obj_t)&py_wlan_patch_program_obj },
|
||||
};
|
||||
|
||||
static MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table);
|
||||
|
||||
const mp_obj_module_t wlan_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_wlan,
|
||||
.globals = (mp_obj_t)&globals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_module_t *py_wlan_init()
|
||||
{
|
||||
return &wlan_module;
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* WLAN Python module.
|
||||
*
|
||||
*/
|
||||
#ifndef __PY_WLAN_H__
|
||||
#define __PY_WLAN_H__
|
||||
int wlan_get_fd_state(int fd);
|
||||
void wlan_clear_fd_state(int fd);
|
||||
const mp_obj_module_t *py_wlan_init();
|
||||
#endif // __PY_WLAN_H__
|
||||
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* UART Python module.
|
||||
*
|
||||
*/
|
||||
#include "mp.h"
|
||||
#include "pincfg.h"
|
||||
#include "uart.h"
|
||||
#define UART_TIMEOUT (1000)
|
||||
UART_HandleTypeDef UARTHandle;
|
||||
|
||||
static mp_obj_t py_uart_read(mp_obj_t obj)
|
||||
{
|
||||
mp_buffer_info_t bufinfo;
|
||||
|
||||
if (MP_OBJ_IS_INT(obj)) {
|
||||
bufinfo.len = mp_obj_get_int(obj);
|
||||
bufinfo.typecode = 'B';
|
||||
mp_obj_str_builder_start(&mp_type_bytes, bufinfo.len, (byte**)&(bufinfo.buf));
|
||||
} else {
|
||||
mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_WRITE);
|
||||
}
|
||||
|
||||
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
|
||||
if (HAL_UART_Receive(&UARTHandle, bufinfo.buf, bufinfo.len, UART_TIMEOUT) != HAL_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_Exception, "HAL_UART_Receive failed"));
|
||||
}
|
||||
MICROPY_END_ATOMIC_SECTION(atomic_state);
|
||||
|
||||
return mp_obj_new_int(bufinfo.len);
|
||||
}
|
||||
|
||||
static mp_obj_t py_uart_write(mp_obj_t obj)
|
||||
{
|
||||
byte buf[1];
|
||||
mp_buffer_info_t bufinfo;
|
||||
|
||||
if (MP_OBJ_IS_INT(obj)) {
|
||||
buf[0] = mp_obj_get_int(obj);
|
||||
bufinfo.buf = buf;
|
||||
bufinfo.len = 1;
|
||||
bufinfo.typecode = 'B';
|
||||
} else {
|
||||
mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_READ);
|
||||
}
|
||||
|
||||
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
|
||||
if (HAL_UART_Transmit(&UARTHandle, bufinfo.buf, bufinfo.len, UART_TIMEOUT) != HAL_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_Exception, "HAL_UART_Transmit failed"));
|
||||
}
|
||||
MICROPY_END_ATOMIC_SECTION(atomic_state);
|
||||
|
||||
return mp_obj_new_int(bufinfo.len);
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_uart_read_obj, py_uart_read);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_uart_write_obj, py_uart_write);
|
||||
|
||||
static const mp_map_elem_t globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_UART) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&py_uart_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&py_uart_write_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table);
|
||||
|
||||
const mp_obj_module_t uart_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_UART,
|
||||
.globals = (mp_obj_t)&globals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_module_t *py_uart_init()
|
||||
{
|
||||
UARTHandle.Instance = UARTx;
|
||||
UARTHandle.Init.BaudRate = 38400;
|
||||
UARTHandle.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
UARTHandle.Init.StopBits = UART_STOPBITS_1;
|
||||
UARTHandle.Init.Parity = UART_PARITY_NONE;
|
||||
UARTHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
UARTHandle.Init.Mode = UART_MODE_TX_RX;
|
||||
|
||||
if (HAL_UART_Init(&UARTHandle) != HAL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &uart_module;
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* UART Python module.
|
||||
*
|
||||
*/
|
||||
#ifndef __UART_H__
|
||||
#define __UART_H__
|
||||
const mp_obj_module_t *py_uart_init();
|
||||
#endif // __UART_H__
|
||||
|
||||
Loading…
Reference in New Issue
Block a user