diff options
author | Damien George <damien.p.george@gmail.com> | 2014-05-02 16:58:15 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-05-02 16:58:15 +0100 |
commit | 3eb8163b16bc5b6ea30428b54dee60e5c7e9c98f (patch) | |
tree | ca06f877c8be5ed7610cde5e4f92fb753db0b3ca | |
parent | ba742ed6396cf14151dd397e7dbe6c9d2d2ecf93 (diff) | |
download | micropython-3eb8163b16bc5b6ea30428b54dee60e5c7e9c98f.tar.gz micropython-3eb8163b16bc5b6ea30428b54dee60e5c7e9c98f.zip |
stmhal: Add documentation for DAC and Timer classes.
-rw-r--r-- | stmhal/dac.c | 50 | ||||
-rw-r--r-- | stmhal/gendoc.py | 2 | ||||
-rw-r--r-- | stmhal/timer.c | 66 |
3 files changed, 102 insertions, 16 deletions
diff --git a/stmhal/dac.c b/stmhal/dac.c index cd62f017fb..b440bcbf50 100644 --- a/stmhal/dac.c +++ b/stmhal/dac.c @@ -16,6 +16,31 @@ /// \moduleref pyb /// \class DAC - digital to analog conversion /// +/// The DAC is used to output analog values (a specific voltage) on pin X5 or pin X6. +/// The voltage will be between 0 and 3.3V. +/// +/// *This module will undergo changes to the API.* +/// +/// Example usage: +/// +/// from pyb import DAC +/// +/// dac = DAC(1) # create DAC 1 on pin X5 +/// dac.write(128) # write a value to the DAC (makes X5 1.65V) +/// +/// To output a continuous sine-wave: +/// +/// import math +/// from pyb import DAC +/// +/// # create a buffer containing a sine-wave +/// buf = bytearray(100) +/// for i in range(len(buf)): +/// buf[i] = 128 + 127 * math.sin(2 * math.pi * i / len(buf)) +/// +/// # output the sine-wave at 400Hz +/// dac = DAC(1) +/// dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR) STATIC DAC_HandleTypeDef DAC_Handle; @@ -52,6 +77,10 @@ typedef struct _pyb_dac_obj_t { // create the dac object // currently support either DAC1 on X5 (id = 1) or DAC2 on X6 (id = 2) +/// \classmethod \constructor(id) +/// Construct a new DAC object. +/// +/// `id` can be 1 or 2: DAC 1 is on pin X5 and DAC 2 is on pin X6. STATIC mp_obj_t pyb_dac_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // check arguments mp_arg_check_num(n_args, n_kw, 1, 1, false); @@ -93,6 +122,9 @@ STATIC mp_obj_t pyb_dac_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const return dac; } +/// \method noise(freq) +/// Generate a pseudo-random noise signal. A new random sample is written +/// to the DAC output at the given frequency. STATIC mp_obj_t pyb_dac_noise(mp_obj_t self_in, mp_obj_t freq) { pyb_dac_obj_t *self = self_in; @@ -117,6 +149,10 @@ STATIC mp_obj_t pyb_dac_noise(mp_obj_t self_in, mp_obj_t freq) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_dac_noise_obj, pyb_dac_noise); +/// \method triangle(freq) +/// Generate a triangle wave. The value on the DAC output changes at +/// the given frequency, and the frequence of the repeating triangle wave +/// itself is 256 (or 1024, need to check) times smaller. STATIC mp_obj_t pyb_dac_triangle(mp_obj_t self_in, mp_obj_t freq) { pyb_dac_obj_t *self = self_in; @@ -141,7 +177,8 @@ STATIC mp_obj_t pyb_dac_triangle(mp_obj_t self_in, mp_obj_t freq) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_dac_triangle_obj, pyb_dac_triangle); -// direct access to DAC (8 bit only at the moment) +/// \method write(value) +/// Direct access to the DAC output (8 bit only at the moment). STATIC mp_obj_t pyb_dac_write(mp_obj_t self_in, mp_obj_t val) { pyb_dac_obj_t *self = self_in; @@ -160,12 +197,15 @@ STATIC mp_obj_t pyb_dac_write(mp_obj_t self_in, mp_obj_t val) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_dac_write_obj, pyb_dac_write); -// initiates a burst of RAM->DAC using DMA -// input data is treated as an array of bytes (8 bit data) -// TIM6 is used to set the frequency of the transfer +/// \method write_timed(data, freq, *, mode=DAC.NORMAL) +/// Initiates a burst of RAM to DAC using a DMA transfer. +/// The input data is treated as an array of bytes (8 bit data). +/// +/// `mode` can be `DAC.NORMAL` or `DAC.CIRCULAR`. +/// +/// TIM6 is used to control the frequency of the transfer. // TODO add callback argument, to call when transfer is finished // TODO add double buffer argument - STATIC const mp_arg_t pyb_dac_write_timed_args[] = { { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_freq, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, diff --git a/stmhal/gendoc.py b/stmhal/gendoc.py index 42882ad277..e52ca5d8aa 100644 --- a/stmhal/gendoc.py +++ b/stmhal/gendoc.py @@ -343,7 +343,7 @@ def main(): args = cmd_parser.parse_args() if len(args.files) == 0: - args.files = ['modpyb.c', 'accel.c', 'adc.c', 'dac.c', 'extint.c', 'i2c.c', 'led.c', 'pin.c', 'rng.c', 'servo.c', 'spi.c', 'uart.c', 'usrsw.c'] + args.files = ['modpyb.c', 'accel.c', 'adc.c', 'dac.c', 'extint.c', 'i2c.c', 'led.c', 'pin.c', 'rng.c', 'servo.c', 'spi.c', 'uart.c', 'usrsw.c', 'timer.c'] doc = Doc() for file in args.files: diff --git a/stmhal/timer.c b/stmhal/timer.c index 1578e9b1d9..e1d55e14a0 100644 --- a/stmhal/timer.c +++ b/stmhal/timer.c @@ -16,6 +16,38 @@ #include "timer.h" #include "servo.h" +/// \moduleref pyb +/// \class Timer - periodically call a function +/// +/// Timers can be used for a great variety of tasks. At the moment, only +/// the simplest case is implemented: that of calling a function periodically. +/// +/// Each timer consists of a counter that counts up at a certain rate. The rate +/// at which it counts is the peripheral clock frequency (in Hz) divided by the +/// timer prescaler. When the counter reaches the timer period it triggers an +/// event, and the counter resets back to zero. By using the callback method, +/// the timer event can call a Python function. +/// +/// Example usage to toggle an LED at a fixed frequency: +/// +/// tim = pyb.Timer(4) # create a timer object using timer 4 +/// tim.init(freq=2) # trigger at 2Hz +/// tim.callback(lambda t:pyb.LED(1).toggle()) +/// +/// Further examples: +/// +/// tim = pyb.Timer(4, freq=100) # freq in Hz +/// tim = pyb.Timer(4, prescaler=1, period=100) +/// tim.counter() # get counter (can also set) +/// tim.prescaler(2) # set prescaler (can also get) +/// tim.period(200) # set period (can also get) +/// tim.callback(lambda t: ...) # set callback for update interrupt (t=tim instance) +/// tim.callback(None) # clear callback +/// +/// *Note:* Timer 3 is reserved for internal use. Timer 5 controls +/// the servo driver, and Timer 6 is used for timed ADC/DAC reading/writing. +/// It is recommended to use the other timers in your programs. + // The timers can be used by multiple drivers, and need a common point for // the interrupts to be dispatched, so they are all collected here. // @@ -29,16 +61,6 @@ // // TIM6: // - ADC, DAC for read_timed and write_timed -// -// Python usage model: -// -// tim = pyb.Timer(4, freq=100) # freq in Hz -// tim = pyb.Timer(4, prescaler=1, period=100) -// tim.counter() # get counter (can also set) -// tim.prescaler(2) # set prescaler (can also get) -// tim.period(200) # set period (can also get) -// tim.callback(lambda t: ...) # set callback for update interrupt (t=tim instance) -// tim.callback(None) # clear callback typedef struct _pyb_timer_obj_t { mp_obj_base_t base; @@ -173,6 +195,12 @@ STATIC void pyb_timer_print(void (*print)(void *env, const char *fmt, ...), void } } +/// \method init(*, freq, prescaler, period) +/// Initialise the timer. Initialisation must be either by frequency (in Hz) +/// or by prescaler and period: +/// +/// tim.init(freq=100) # set the timer to trigger at 100Hz +/// tim.init(prescaler=100, period=300) # set the prescaler and period directly STATIC const mp_arg_t pyb_timer_init_args[] = { { MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0xffffffff} }, { MP_QSTR_prescaler, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0xffffffff} }, @@ -257,6 +285,10 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, uint n_args, const return mp_const_none; } +/// \classmethod \constructor(id, ...) +/// Construct a new timer object of the given id. If additional +/// arguments are given, then the timer is initialised by `init(...)`. +/// `id` can be 1 to 14, excluding 3. STATIC mp_obj_t pyb_timer_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // check arguments mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); @@ -308,6 +340,10 @@ STATIC mp_obj_t pyb_timer_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_a } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_init_obj, 1, pyb_timer_init); +/// \method deinit() +/// Deinitialises the timer. +/// +/// *This function is not yet implemented.* STATIC mp_obj_t pyb_timer_deinit(mp_obj_t self_in) { //pyb_timer_obj_t *self = self_in; // TODO implement me @@ -315,6 +351,8 @@ STATIC mp_obj_t pyb_timer_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_timer_deinit_obj, pyb_timer_deinit); +/// \method counter([value]) +/// Get or set the timer counter. mp_obj_t pyb_timer_counter(uint n_args, const mp_obj_t *args) { pyb_timer_obj_t *self = args[0]; if (n_args == 1) { @@ -328,6 +366,8 @@ mp_obj_t pyb_timer_counter(uint n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_counter_obj, 1, 2, pyb_timer_counter); +/// \method prescaler([value]) +/// Get or set the prescaler for the timer. mp_obj_t pyb_timer_prescaler(uint n_args, const mp_obj_t *args) { pyb_timer_obj_t *self = args[0]; if (n_args == 1) { @@ -341,6 +381,8 @@ mp_obj_t pyb_timer_prescaler(uint n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_prescaler_obj, 1, 2, pyb_timer_prescaler); +/// \method period([value]) +/// Get or set the period of the timer. mp_obj_t pyb_timer_period(uint n_args, const mp_obj_t *args) { pyb_timer_obj_t *self = args[0]; if (n_args == 1) { @@ -354,6 +396,10 @@ mp_obj_t pyb_timer_period(uint n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_period_obj, 1, 2, pyb_timer_period); +/// \method callback(fun) +/// Set the function to be called when the timer triggers. +/// `fun` is passed 1 argument, the timer object. +/// If `fun` is `None` then the callback will be disabled. STATIC mp_obj_t pyb_timer_callback(mp_obj_t self_in, mp_obj_t callback) { pyb_timer_obj_t *self = self_in; if (callback == mp_const_none) { |