Commit 7f9d1d6a authored by Damien George's avatar Damien George
Browse files

py: Overhaul and simplify printf/pfenv mechanism.

Previous to this patch the printing mechanism was a bit of a tangled
mess.  This patch attempts to consolidate printing into one interface.

All (non-debug) printing now uses the mp_print* family of functions,
mainly mp_printf.  All these functions take an mp_print_t structure as
their first argument, and this structure defines the printing backend
through the "print_strn" function of said structure.

Printing from the uPy core can reach the platform-defined print code via
two paths: either through mp_sys_stdout_obj (defined pert port) in
conjunction with mp_stream_write; or through the mp_plat_print structure
which uses the MP_PLAT_PRINT_STRN macro to define how string are printed
on the platform.  The former is only used when MICROPY_PY_IO is defined.

With this new scheme printing is generally more efficient (less layers
to go through, less arguments to pass), and, given an mp_print_t*
structure, one can call mp_print_str for efficiency instead of
mp_printf("%s", ...).  Code size is also reduced by around 200 bytes on
Thumb2 archs.
parent 56beb017
......@@ -11,7 +11,6 @@
#include "py/stackctrl.h"
#include "py/gc.h"
#include "py/repl.h"
#include "py/pfenv.h"
#include "tinytest.h"
#include "tinytest_macros.h"
......@@ -39,7 +38,7 @@ inline void do_str(const char *src) {
tinytest_set_test_skipped_();
return;
}
mp_obj_print_exception(printf_wrapper, NULL, exc);
mp_obj_print_exception(&mp_extern_printf_wrapper, exc);
tt_abort_msg("Uncaught exception");
}
end:
......
......@@ -138,11 +138,11 @@ STATIC uint32_t adc_read_channel(ADC_HandleTypeDef *adcHandle) {
/******************************************************************************/
/* Micro Python bindings : adc object (single channel) */
STATIC void adc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_obj_adc_t *self = self_in;
print(env, "<ADC on ");
mp_obj_print_helper(print, env, self->pin_name, PRINT_STR);
print(env, " channel=%lu>", self->channel);
mp_print_str(print, "<ADC on ");
mp_obj_print_helper(print, self->pin_name, PRINT_STR);
mp_printf(print, " channel=%lu>", self->channel);
}
/// \classmethod \constructor(pin)
......
......@@ -33,7 +33,6 @@
#include "py/objtuple.h"
#include "py/runtime.h"
#include "py/gc.h"
#include "py/pfenv.h"
#include "bufhelper.h"
#include "can.h"
#include "pybioctl.h"
......@@ -174,12 +173,12 @@ STATIC void can_clearfilter(uint32_t f) {
/******************************************************************************/
// Micro Python bindings
STATIC void pyb_can_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void pyb_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_can_obj_t *self = self_in;
if (!self->is_enabled) {
print(env, "CAN(%u)", self->can_id);
mp_printf(print, "CAN(%u)", self->can_id);
} else {
print(env, "CAN(%u, CAN.", self->can_id);
mp_printf(print, "CAN(%u, CAN.", self->can_id);
qstr mode;
switch (self->can.Init.Mode) {
case CAN_MODE_NORMAL: mode = MP_QSTR_NORMAL; break;
......@@ -187,13 +186,13 @@ STATIC void pyb_can_print(void (*print)(void *env, const char *fmt, ...), void *
case CAN_MODE_SILENT: mode = MP_QSTR_SILENT; break;
case CAN_MODE_SILENT_LOOPBACK: default: mode = MP_QSTR_SILENT_LOOPBACK; break;
}
print(env, "%s, extframe=", qstr_str(mode));
mp_printf(print, "%s, extframe=", qstr_str(mode));
if (self->extframe) {
mode = MP_QSTR_True;
} else {
mode = MP_QSTR_False;
}
print(env, "%s)", qstr_str(mode));
mp_printf(print, "%s)", qstr_str(mode));
}
}
......@@ -714,7 +713,7 @@ void can_rx_irq_handler(uint can_id, uint fifo_id) {
// Uncaught exception; disable the callback so it doesn't run again.
pyb_can_rxcallback(self, MP_OBJ_NEW_SMALL_INT(fifo_id), mp_const_none);
printf("uncaught exception in CAN(%u) rx interrupt handler\n", self->can_id);
mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val);
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
gc_unlock();
}
......
......@@ -31,7 +31,7 @@
#include "py/nlr.h"
#include "py/runtime.h"
#include "py/gc.h"
#include "py/pfenv.h"
#include MICROPY_HAL_H
#include "pin.h"
#include "extint.h"
......@@ -296,9 +296,9 @@ STATIC mp_obj_t extint_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_
return self;
}
STATIC void extint_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void extint_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
extint_obj_t *self = self_in;
print(env, "<ExtInt line=%u>", self->line);
mp_printf(print, "<ExtInt line=%u>", self->line);
}
STATIC const mp_map_elem_t extint_locals_dict_table[] = {
......@@ -356,7 +356,7 @@ void Handle_EXTI_Irq(uint32_t line) {
*cb = mp_const_none;
extint_disable(line);
printf("Uncaught exception in ExtInt interrupt handler line %lu\n", line);
mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val);
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
gc_unlock();
}
......
......@@ -65,8 +65,8 @@ typedef struct _pyb_file_obj_t {
FIL fp;
} pyb_file_obj_t;
void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
print(env, "<io.%s %p>", mp_obj_get_type_str(self_in), self_in);
void file_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
mp_printf(print, "<io.%s %p>", mp_obj_get_type_str(self_in), self_in);
}
STATIC mp_uint_t file_obj_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
......
......@@ -183,7 +183,7 @@ STATIC const pyb_i2c_obj_t pyb_i2c_obj[] = {
{{&pyb_i2c_type}, &I2CHandle2}
};
STATIC void pyb_i2c_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void pyb_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_i2c_obj_t *self = self_in;
uint i2c_num;
......@@ -191,12 +191,12 @@ STATIC void pyb_i2c_print(void (*print)(void *env, const char *fmt, ...), void *
else { i2c_num = 2; }
if (self->i2c->State == HAL_I2C_STATE_RESET) {
print(env, "I2C(%u)", i2c_num);
mp_printf(print, "I2C(%u)", i2c_num);
} else {
if (in_master_mode(self)) {
print(env, "I2C(%u, I2C.MASTER, baudrate=%u)", i2c_num, self->i2c->Init.ClockSpeed);
mp_printf(print, "I2C(%u, I2C.MASTER, baudrate=%u)", i2c_num, self->i2c->Init.ClockSpeed);
} else {
print(env, "I2C(%u, I2C.SLAVE, addr=0x%02x)", i2c_num, (self->i2c->Instance->OAR1 >> 1) & 0x7f);
mp_printf(print, "I2C(%u, I2C.SLAVE, addr=0x%02x)", i2c_num, (self->i2c->Instance->OAR1 >> 1) & 0x7f);
}
}
}
......
......@@ -210,9 +210,9 @@ void led_debug(int n, int delay) {
/******************************************************************************/
/* Micro Python bindings */
void led_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
void led_obj_print(const mp_print_t *print, 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_printf(print, "LED(%lu)", self->led_id);
}
/// \classmethod \constructor(id)
......
......@@ -68,9 +68,9 @@ typedef struct _stm_mem_obj_t {
uint32_t elem_size; // in bytes
} stm_mem_obj_t;
STATIC void stm_mem_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void stm_mem_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
stm_mem_obj_t *self = self_in;
print(env, "<%u-bit memory>", 8 * self->elem_size);
mp_printf(print, "<%u-bit memory>", 8 * self->elem_size);
}
STATIC mp_obj_t stm_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
......
......@@ -183,6 +183,9 @@ typedef void *machine_ptr_t; // must be of pointer size
typedef const void *machine_const_ptr_t; // must be of pointer size
typedef long mp_off_t;
void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len);
#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
// We have inlined IRQ functions for efficiency (they are generally
// 1 machine instruction).
//
......
......@@ -180,17 +180,17 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) {
/// \method __str__()
/// Return a string describing the pin object.
STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pin_obj_t *self = self_in;
// pin name
print(env, "Pin(Pin.cpu.%s, mode=Pin.", qstr_str(self->name));
mp_printf(print, "Pin(Pin.cpu.%s, mode=Pin.", qstr_str(self->name));
uint32_t mode = pin_get_mode(self);
if (mode == GPIO_MODE_ANALOG) {
// analog
print(env, "ANALOG)");
mp_print_str(print, "ANALOG)");
} else {
// IO mode
......@@ -210,7 +210,7 @@ STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env,
mode_qst = MP_QSTR_AF_OD;
}
}
print(env, qstr_str(mode_qst)); // safe because mode_qst has no formating chars
mp_print_str(print, qstr_str(mode_qst));
// pull mode
qstr pull_qst = MP_QSTR_NULL;
......@@ -221,7 +221,7 @@ STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env,
pull_qst = MP_QSTR_PULL_DOWN;
}
if (pull_qst != MP_QSTR_NULL) {
print(env, ", pull=Pin.%s", qstr_str(pull_qst));
mp_printf(print, ", pull=Pin.%s", qstr_str(pull_qst));
}
// AF mode
......@@ -229,12 +229,12 @@ STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env,
mp_uint_t af_idx = pin_get_af(self);
const pin_af_obj_t *af_obj = pin_find_af_by_index(self, af_idx);
if (af_obj == NULL) {
print(env, ", af=%d)", af_idx);
mp_printf(print, ", af=%d)", af_idx);
} else {
print(env, ", af=Pin.%s)", qstr_str(af_obj->name));
mp_printf(print, ", af=Pin.%s)", qstr_str(af_obj->name));
}
} else {
print(env, ")");
mp_print_str(print, ")");
}
}
}
......@@ -616,9 +616,9 @@ const mp_obj_type_t pin_type = {
/// \method __str__()
/// Return a string describing the alternate function.
STATIC void pin_af_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void pin_af_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pin_af_obj_t *self = self_in;
print(env, "Pin.%s", qstr_str(self->name));
mp_printf(print, "Pin.%s", qstr_str(self->name));
}
/// \method index()
......
......@@ -31,9 +31,9 @@
#include MICROPY_HAL_H
#include "pin.h"
STATIC void pin_named_pins_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void pin_named_pins_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pin_named_pins_obj_t *self = self_in;
print(env, "<Pin.%s>", qstr_str(self->name));
mp_printf(print, "<Pin.%s>", qstr_str(self->name));
}
const mp_obj_type_t pin_cpu_pins_obj_type = {
......
......@@ -29,7 +29,6 @@
#include <stdarg.h>
#include "py/obj.h"
#include "py/pfenv.h"
#ifdef MICROPY_HAL_H
#include MICROPY_HAL_H
#endif
......@@ -38,22 +37,16 @@
#include "py/formatfloat.h"
#endif
STATIC void stdout_print_strn(void *dummy_env, const char *str, mp_uint_t len) {
mp_hal_stdout_tx_strn_cooked(str, len);
}
STATIC const pfenv_t pfenv_stdout = {0, stdout_print_strn};
int printf(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
int ret = pfenv_vprintf(&pfenv_stdout, fmt, ap);
int ret = mp_vprintf(&mp_plat_print, fmt, ap);
va_end(ap);
return ret;
}
int vprintf(const char *fmt, va_list ap) {
return pfenv_vprintf(&pfenv_stdout, fmt, ap);
return mp_vprintf(&mp_plat_print, fmt, ap);
}
#if MICROPY_DEBUG_PRINTERS
......@@ -62,7 +55,7 @@ mp_uint_t mp_verbose_flag = 1;
int DEBUG_printf(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
int ret = pfenv_vprintf(&pfenv_stdout, fmt, ap);
int ret = mp_vprintf(&mp_plat_print, fmt, ap);
va_end(ap);
return ret;
}
......@@ -71,47 +64,43 @@ int DEBUG_printf(const char *fmt, ...) {
// need this because gcc optimises printf("%c", c) -> putchar(c), and printf("a") -> putchar('a')
int putchar(int c) {
char chr = c;
stdout_print_strn(0, &chr, 1);
mp_hal_stdout_tx_strn_cooked(&chr, 1);
return chr;
}
// need this because gcc optimises printf("string\n") -> puts("string")
int puts(const char *s) {
stdout_print_strn(0, s, strlen(s));
mp_hal_stdout_tx_strn_cooked(s, strlen(s));
char chr = '\n';
stdout_print_strn(0, &chr, 1);
mp_hal_stdout_tx_strn_cooked(&chr, 1);
return 1;
}
typedef struct _strn_pfenv_t {
typedef struct _strn_print_env_t {
char *cur;
size_t remain;
} strn_pfenv_t;
} strn_print_env_t;
STATIC void strn_print_strn(void *data, const char *str, mp_uint_t len) {
strn_pfenv_t *strn_pfenv = data;
if (len > strn_pfenv->remain) {
len = strn_pfenv->remain;
strn_print_env_t *strn_print_env = data;
if (len > strn_print_env->remain) {
len = strn_print_env->remain;
}
memcpy(strn_pfenv->cur, str, len);
strn_pfenv->cur += len;
strn_pfenv->remain -= len;
memcpy(strn_print_env->cur, str, len);
strn_print_env->cur += len;
strn_print_env->remain -= len;
}
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) {
strn_pfenv_t strn_pfenv;
strn_pfenv.cur = str;
strn_pfenv.remain = size;
pfenv_t pfenv;
pfenv.data = &strn_pfenv;
pfenv.print_strn = strn_print_strn;
int len = pfenv_vprintf(&pfenv, fmt, ap);
strn_print_env_t strn_print_env = {str, size};
mp_print_t print = {&strn_print_env, strn_print_strn};
int len = mp_vprintf(&print, fmt, ap);
// add terminating null byte
if (size > 0) {
if (strn_pfenv.remain == 0) {
strn_pfenv.cur[-1] = 0;
if (strn_print_env.remain == 0) {
strn_print_env.cur[-1] = 0;
} else {
strn_pfenv.cur[0] = 0;
strn_print_env.cur[0] = 0;
}
}
return len;
......
......@@ -48,9 +48,9 @@ typedef struct _pyb_stdio_obj_t {
int fd;
} pyb_stdio_obj_t;
void stdio_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
void stdio_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_stdio_obj_t *self = self_in;
print(env, "<io.FileIO %d>", self->fd);
mp_printf(print, "<io.FileIO %d>", self->fd);
}
STATIC mp_uint_t stdio_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
......
......@@ -33,7 +33,6 @@
#include "py/runtime.h"
#include "py/repl.h"
#include "py/gc.h"
#include "py/pfenv.h"
#ifdef MICROPY_HAL_H
#include MICROPY_HAL_H
#endif
......@@ -87,7 +86,7 @@ STATIC int parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_ki
// at the moment, the value of SystemExit is unused
ret = PYEXEC_FORCED_EXIT;
} else {
mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val);
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
ret = 0;
}
}
......
......@@ -178,9 +178,9 @@ STATIC mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse) {
MP_DEFINE_CONST_FUN_OBJ_2(pyb_pwm_set_obj, pyb_pwm_set);
STATIC void pyb_servo_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void pyb_servo_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_servo_obj_t *self = self_in;
print(env, "<Servo %lu at %luus>", self->servo_id, 10 * self->pulse_cur);
mp_printf(print, "<Servo %lu at %luus>", self->servo_id, 10 * self->pulse_cur);
}
/// \classmethod \constructor(id)
......
......@@ -335,7 +335,7 @@ SPI_HandleTypeDef *spi_get_handle(mp_obj_t o) {
return self->spi;
}
STATIC void pyb_spi_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_spi_obj_t *self = self_in;
uint spi_num;
......@@ -344,7 +344,7 @@ STATIC void pyb_spi_print(void (*print)(void *env, const char *fmt, ...), void *
else { spi_num = 3; }
if (self->spi->State == HAL_SPI_STATE_RESET) {
print(env, "SPI(%u)", spi_num);
mp_printf(print, "SPI(%u)", spi_num);
} else {
if (self->spi->Init.Mode == SPI_MODE_MASTER) {
// compute baudrate
......@@ -358,15 +358,15 @@ STATIC void pyb_spi_print(void (*print)(void *env, const char *fmt, ...), void *
}
uint log_prescaler = (self->spi->Init.BaudRatePrescaler >> 3) + 1;
uint baudrate = spi_clock >> log_prescaler;
print(env, "SPI(%u, SPI.MASTER, baudrate=%u, prescaler=%u", spi_num, baudrate, 1 << log_prescaler);
mp_printf(print, "SPI(%u, SPI.MASTER, baudrate=%u, prescaler=%u", spi_num, baudrate, 1 << log_prescaler);
} else {
print(env, "SPI(%u, SPI.SLAVE", spi_num);
mp_printf(print, "SPI(%u, SPI.SLAVE", spi_num);
}
print(env, ", polarity=%u, phase=%u, bits=%u", self->spi->Init.CLKPolarity == SPI_POLARITY_LOW ? 0 : 1, self->spi->Init.CLKPhase == SPI_PHASE_1EDGE ? 0 : 1, self->spi->Init.DataSize == SPI_DATASIZE_8BIT ? 8 : 16);
mp_printf(print, ", polarity=%u, phase=%u, bits=%u", self->spi->Init.CLKPolarity == SPI_POLARITY_LOW ? 0 : 1, self->spi->Init.CLKPhase == SPI_PHASE_1EDGE ? 0 : 1, self->spi->Init.DataSize == SPI_DATASIZE_8BIT ? 8 : 16);
if (self->spi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED) {
print(env, ", crc=0x%x", self->spi->Init.CRCPolynomial);
mp_printf(print, ", crc=0x%x", self->spi->Init.CRCPolynomial);
}
print(env, ")");
mp_print_str(print, ")");
}
}
......
......@@ -35,7 +35,7 @@
#include "py/nlr.h"
#include "py/runtime.h"
#include "py/gc.h"
#include "py/pfenv.h"
#include MICROPY_HAL_H
#include "timer.h"
#include "servo.h"
#include "pin.h"
......@@ -468,17 +468,17 @@ STATIC void config_deadtime(pyb_timer_obj_t *self, mp_int_t ticks) {
HAL_TIMEx_ConfigBreakDeadTime(&self->tim, &deadTimeConfig);
}
STATIC void pyb_timer_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void pyb_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_timer_obj_t *self = self_in;
if (self->tim.State == HAL_TIM_STATE_RESET) {
print(env, "Timer(%u)", self->tim_id);
mp_printf(print, "Timer(%u)", self->tim_id);
} else {
uint32_t prescaler = self->tim.Instance->PSC & 0xffff;
uint32_t period = __HAL_TIM_GetAutoreload(&self->tim) & TIMER_CNT_MASK(self);
// for efficiency, we compute and print freq as an int (not a float)
uint32_t freq = timer_get_source_freq(self->tim_id) / ((prescaler + 1) * (period + 1));
print(env, "Timer(%u, freq=%u, prescaler=%u, period=%u, mode=%s, div=%u",
mp_printf(print, "Timer(%u, freq=%u, prescaler=%u, period=%u, mode=%s, div=%u",
self->tim_id,
freq,
prescaler,
......@@ -488,9 +488,10 @@ STATIC void pyb_timer_print(void (*print)(void *env, const char *fmt, ...), void
self->tim.Init.ClockDivision == TIM_CLOCKDIVISION_DIV4 ? 4 :
self->tim.Init.ClockDivision == TIM_CLOCKDIVISION_DIV2 ? 2 : 1);
if (IS_TIM_ADVANCED_INSTANCE(self->tim.Instance)) {
print(env, ", deadtime=%u", compute_ticks_from_dtg(self->tim.Instance->BDTR & TIM_BDTR_DTG));
mp_printf(print, ", deadtime=%u",
compute_ticks_from_dtg(self->tim.Instance->BDTR & TIM_BDTR_DTG));
}
print(env, ")");
mp_print_str(print, ")");
}
}
......@@ -1166,10 +1167,10 @@ const mp_obj_type_t pyb_timer_type = {
/// Timer channels are used to generate/capture a signal using a timer.
///
/// TimerChannel objects are created using the Timer.channel() method.
STATIC void pyb_timer_channel_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void pyb_timer_channel_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_timer_channel_obj_t *self = self_in;
print(env, "TimerChannel(timer=%u, channel=%u, mode=%s)",
mp_printf(print, "TimerChannel(timer=%u, channel=%u, mode=%s)",
self->timer->tim_id,
self->channel,
qstr_str(channel_mode_info[self->mode].name));
......@@ -1308,7 +1309,7 @@ STATIC void timer_handle_irq_channel(pyb_timer_obj_t *tim, uint8_t channel, mp_o
} else {
printf("uncaught exception in Timer(%u) channel %u interrupt handler\n", tim->tim_id, channel);
}
mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val);
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
gc_unlock();
}
......
......@@ -330,23 +330,23 @@ void uart_irq_handler(mp_uint_t uart_id) {
/******************************************************************************/
/* Micro Python bindings */
STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_uart_obj_t *self = self_in;
if (!self->is_enabled) {
print(env, "UART(%u)", self->uart_id);
mp_printf(print, "UART(%u)", self->uart_id);
} else {
mp_int_t bits = (self->uart.Init.WordLength == UART_WORDLENGTH_8B ? 8 : 9);
if (self->uart.Init.Parity != UART_PARITY_NONE) {
bits -= 1;
}
print(env, "UART(%u, baudrate=%u, bits=%u, parity=",
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=",
self->uart_id, self->uart.Init.BaudRate, bits);
if (self->uart.Init.Parity == UART_PARITY_NONE) {
print(env, "None");
mp_print_str(print, "None");
} else {
print(env, "%u", self->uart.Init.Parity == UART_PARITY_EVEN ? 0 : 1);
mp_printf(print, "%u", self->uart.Init.Parity == UART_PARITY_EVEN ? 0 : 1);
}
print(env, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u)",
mp_printf(print, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u)",
self->uart.Init.StopBits == UART_STOPBITS_1 ? 1 : 2,
self->timeout, self->timeout_char, self->read_buf_len);
}
......
......@@ -314,8 +314,8 @@ typedef struct _pyb_usb_vcp_obj_t {
STATIC const pyb_usb_vcp_obj_t pyb_usb_vcp_obj = {{&pyb_usb_vcp_type}};
STATIC void pyb_usb_vcp_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
print(env, "USB_VCP()");
STATIC void pyb_usb_vcp_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
mp_print_str(print, "USB_VCP()");
}
/// \classmethod \constructor()
......
......@@ -75,8 +75,8 @@ typedef struct _pyb_switch_obj_t {
STATIC const pyb_switch_obj_t pyb_switch_obj = {{&pyb_switch_type}};
void pyb_switch_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
print(env, "Switch()");
void pyb_switch_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
mp_print_str(print, "Switch()");
}
/// \classmethod \constructor()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment