summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cc3200/boards/cc3200_af.csv38
-rw-r--r--cc3200/boards/make-pins.py3
-rw-r--r--cc3200/misc/mperror.c4
-rw-r--r--cc3200/mods/pybpin.c19
-rw-r--r--cc3200/mods/pybpin.h6
-rw-r--r--cc3200/mods/pybtimer.c185
-rw-r--r--cc3200/qstrdefsport.h6
-rw-r--r--docs/library/machine.Timer.rst104
-rw-r--r--docs/wipy/quickref.rst4
9 files changed, 123 insertions, 246 deletions
diff --git a/cc3200/boards/cc3200_af.csv b/cc3200/boards/cc3200_af.csv
index a31002058..a93cb54a5 100644
--- a/cc3200/boards/cc3200_af.csv
+++ b/cc3200/boards/cc3200_af.csv
@@ -1,11 +1,11 @@
Pin,Name,Default,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15,ADC
-1,GP10,GP10,GP10,I2C0_SCL,,TIM3_PWM0,,,SD0_CLK,UART1_TX,,,,,TIM0_CC1,,,,
-2,GP11,GP11,GP11,I2C0_SDA,,TIM3_PWM1,pXCLK(XVCLK),,SD0_CMD,UART1_RX,,,,,TIM1_CC0,I2S0_FS,,,
-3,GP12,GP12,GP12,,,I2S0_CLK,pVS(VSYNC),I2C0_SCL,,UART0_TX,,,,,TIM1_CC1,,,,
-4,GP13,GP13,GP13,,,,pHS(HSYNC),I2C0_SDA,,UART0_RX,,,,,TIM2_CC0,,,,
-5,GP14,GP14,GP14,,,,pDATA8(CAM_D4),I2C0_SCL,,SPI0_CLK,,,,,TIM2_CC1,,,,
-6,GP15,GP15,GP15,,,,pDATA9(CAM_D5),I2C0_SDA,,SPI0_MISO,SD0_DAT0,,,,,TIM3_CC0,,,
-7,GP16,GP16,GP16,,,,pDATA10(CAM_D6),UART1_TX,,SPI0_MOSI,SD0_CLK,,,,,TIM3_CC1,,,
+1,GP10,GP10,GP10,I2C0_SCL,,TIM3_PWM,,,SD0_CLK,UART1_TX,,,,,TIM0_CC,,,,
+2,GP11,GP11,GP11,I2C0_SDA,,TIM3_PWM,pXCLK(XVCLK),,SD0_CMD,UART1_RX,,,,,TIM1_CC,I2S0_FS,,,
+3,GP12,GP12,GP12,,,I2S0_CLK,pVS(VSYNC),I2C0_SCL,,UART0_TX,,,,,TIM1_CC,,,,
+4,GP13,GP13,GP13,,,,pHS(HSYNC),I2C0_SDA,,UART0_RX,,,,,TIM2_CC,,,,
+5,GP14,GP14,GP14,,,,pDATA8(CAM_D4),I2C0_SCL,,SPI0_CLK,,,,,TIM2_CC,,,,
+6,GP15,GP15,GP15,,,,pDATA9(CAM_D5),I2C0_SDA,,SPI0_MISO,SD0_DAT0,,,,,TIM3_CC,,,
+7,GP16,GP16,GP16,,,,pDATA10(CAM_D6),UART1_TX,,SPI0_MOSI,SD0_CLK,,,,,TIM3_CC,,,
8,GP17,GP17,GP17,,,,pDATA11(CAM_D7),UART1_RX,,SPI0_CS0,SD0_CMD,,,,,,,,
9,VDD_DIG1,VDD_DIG1,VDD_DIG1,,,,,,,,,,,,,,,,
10,VIN_IO1,VIN_IO1,VIN_IO1,,,,,,,,,,,,,,,,
@@ -13,13 +13,13 @@ Pin,Name,Default,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF1
12,FLASH_SPI_DOUT,FLASH_SPI_DOUT,FLASH_SPI_DOUT,,,,,,,,,,,,,,,,
13,FLASH_SPI_DIN,FLASH_SPI_DIN,FLASH_SPI_DIN,,,,,,,,,,,,,,,,
14,FLASH_SPI_CS,FLASH_SPI_CS,FLASH_SPI_CS,,,,,,,,,,,,,,,,
-15,GP22,GP22,GP22,,,,,TIM2_CC0,,I2S0_FS,,,,,,,,,
+15,GP22,GP22,GP22,,,,,TIM2_CC,,I2S0_FS,,,,,,,,,
16,GP23,TDI,GP23,TDI,UART1_TX,,,,,,,I2C0_SCL,,,,,,,
-17,GP24,TDO,GP24,TDO,UART1_RX,,TIM3_CC0,TIM0_PWM0,I2S0_FS,,,I2C0_SDA,,,,,,,
+17,GP24,TDO,GP24,TDO,UART1_RX,,TIM3_CC,TIM0_PWM,I2S0_FS,,,I2C0_SDA,,,,,,,
18,GP28,GP28,GP28,,,,,,,,,,,,,,,,
-19,TCK,TCK,,TCK,,,,,,,TIM1_PWM2,,,,,,,,
+19,TCK,TCK,,TCK,,,,,,,TIM1_PWM,,,,,,,,
20,GP29,TMS,GP29,TMS,,,,,,,,,,,,,,,
-21,GP25,SOP2,GP25,,I2S0_FS,,,,,,,TIM1_PWM0,,,,,,,
+21,GP25,SOP2,GP25,,I2S0_FS,,,,,,,TIM1_PWM,,,,,,,
22,WLAN_XTAL_N,WLAN_XTAL_N,WLAN_XTAL_N,,,,,,,,,,,,,,,,
23,WLAN_XTAL_P,WLAN_XTAL_P,WLAN_XTAL_P,,,,,,,,,,,,,,,,
24,VDD_PLL,VDD_PLL,VDD_PLL,,,,,,,,,,,,,,,,
@@ -48,19 +48,19 @@ Pin,Name,Default,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF1
47,VDD_ANA2,VDD_ANA2,VDD_ANA2,,,,,,,,,,,,,,,,
48,VDD_ANA1,VDD_ANA1,VDD_ANA1,,,,,,,,,,,,,,,,
49,VDD_RAM,VDD_RAM,VDD_RAM,,,,,,,,,,,,,,,,
-50,GP0,GP0,GP0,,,UART0_RTS,I2S0_DAT0,,I2S0_DAT1,TIM0_CC0,,SPI0_CS0,UART1_RTS,,UART0_CTS,,,,
+50,GP0,GP0,GP0,,,UART0_RTS,I2S0_DAT0,,I2S0_DAT1,TIM0_CC,,SPI0_CS0,UART1_RTS,,UART0_CTS,,,,
51,RTC_XTAL_P,RTC_XTAL_P,RTC_XTAL_P,,,,,,,,,,,,,,,,
52,RTC_XTAL_N,RTC_XTAL_N,GP32,,I2S0_CLK,,I2S0_DAT0,,UART0_RTS,,SPI0_MOSI,,,,,,,,
-53,GP30,GP30,GP30,,I2S0_CLK,I2S0_FS,TIM2_CC1,,,SPI0_MISO,,UART0_TX,,,,,,,
+53,GP30,GP30,GP30,,I2S0_CLK,I2S0_FS,TIM2_CC,,,SPI0_MISO,,UART0_TX,,,,,,,
54,VIN_IO2,VIN_IO2,VIN_IO2,,,,,,,,,,,,,,,,
-55,GP1,GP1,GP1,,,UART0_TX,pCLK (PIXCLK),,UART1_TX,TIM0_CC1,,,,,,,,,
+55,GP1,GP1,GP1,,,UART0_TX,pCLK (PIXCLK),,UART1_TX,TIM0_CC,,,,,,,,,
56,VDD_DIG2,VDD_DIG2,VDD_DIG2,,,,,,,,,,,,,,,,
-57,GP2,GP2,GP2,,,UART0_RX,,,UART1_RX,TIM1_CC0,,,,,,,,,ADC0_CH0
+57,GP2,GP2,GP2,,,UART0_RX,,,UART1_RX,TIM1_CC,,,,,,,,,ADC0_CH0
58,GP3,GP3,GP3,,,,pDATA7(CAM_D3),,UART1_TX,,,,,,,,,,ADC0_CH1
59,GP4,GP4,GP4,,,,pDATA6(CAM_D2),,UART1_RX,,,,,,,,,,ADC0_CH2
-60,GP5,GP5,GP5,,,,pDATA5(CAM_D1),,I2S0_DAT1,TIM2_CC1,,,,,,,,,ADC0_CH3
-61,GP6,GP6,GP6,,,UART1_CTS,pDATA4(CAM_D0),UART0_RTS,UART0_CTS,TIM3_CC0,,,,,,,,,
+60,GP5,GP5,GP5,,,,pDATA5(CAM_D1),,I2S0_DAT1,TIM2_CC,,,,,,,,,ADC0_CH3
+61,GP6,GP6,GP6,,,UART1_CTS,pDATA4(CAM_D0),UART0_RTS,UART0_CTS,TIM3_CC,,,,,,,,,
62,GP7,GP7,GP7,,,UART1_RTS,,,,,,,UART0_RTS,UART0_TX,,I2S0_CLK,,,
-63,GP8,GP8,GP8,,,,,,SD0_IRQ,I2S0_FS,,,,,TIM3_CC0,,,,
-64,GP9,GP9,GP9,,,TIM2_PWM1,,,SD0_DAT0,I2S0_DAT0,,,,,TIM0_CC0,,,,
+63,GP8,GP8,GP8,,,,,,SD0_IRQ,I2S0_FS,,,,,TIM3_CC,,,,
+64,GP9,GP9,GP9,,,TIM2_PWM,,,SD0_DAT0,I2S0_DAT0,,,,,TIM0_CC,,,,
65,GND_TAB,GND_TAB,GND_TAB,,,,,,,,,,,,,,,,
diff --git a/cc3200/boards/make-pins.py b/cc3200/boards/make-pins.py
index 676896803..26ca5a0b9 100644
--- a/cc3200/boards/make-pins.py
+++ b/cc3200/boards/make-pins.py
@@ -12,7 +12,7 @@ SUPPORTED_AFS = { 'UART': ('TX', 'RX', 'RTS', 'CTS'),
'SPI': ('CLK', 'MOSI', 'MISO', 'CS0'),
#'I2S': ('CLK', 'FS', 'DAT0', 'DAT1'),
'I2C': ('SDA', 'SCL'),
- 'TIM': ('PWM0', 'PWM1', 'CC0', 'CC1'),
+ 'TIM': ('PWM'),
'SD': ('CLK', 'CMD', 'DAT0'),
'ADC': ('CH0', 'CH1', 'CH2', 'CH3')
}
@@ -44,6 +44,7 @@ class AF:
def print(self):
print (' AF({:16s}, {:4d}, {:8s}, {:4d}, {:8s}), // {}'.format(self.name, self.idx, self.fn, self.unit, self.type, self.name))
+
class Pin:
"""Holds the information associated with a pin."""
def __init__(self, name, port, gpio_bit, pin_num):
diff --git a/cc3200/misc/mperror.c b/cc3200/misc/mperror.c
index 73a6b6fc1..5561b0305 100644
--- a/cc3200/misc/mperror.c
+++ b/cc3200/misc/mperror.c
@@ -196,6 +196,10 @@ void nlr_jump_fail(void *val) {
void mperror_enable_heartbeat (bool enable) {
if (enable) {
+ #ifndef BOOTLOADER
+ // configure the led again
+ pin_config ((pin_obj_t *)&MICROPY_SYS_LED_GPIO, PIN_MODE_0, GPIO_DIR_MODE_OUT, PIN_TYPE_STD, 0, PIN_STRENGTH_6MA);
+ #endif
mperror_heart_beat.enabled = true;
mperror_heart_beat.do_disable = false;
mperror_heartbeat_switch_off();
diff --git a/cc3200/mods/pybpin.c b/cc3200/mods/pybpin.c
index a8a19a1bd..ce304404b 100644
--- a/cc3200/mods/pybpin.c
+++ b/cc3200/mods/pybpin.c
@@ -60,7 +60,6 @@ DECLARE PRIVATE FUNCTIONS
STATIC pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name);
STATIC pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit);
STATIC int8_t pin_obj_find_af (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type);
-STATIC int8_t pin_find_af_index (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type);
STATIC void pin_free_af_from_pins (uint8_t fn, uint8_t unit, uint8_t type);
STATIC void pin_deassign (pin_obj_t* pin);
STATIC void pin_obj_configure (const pin_obj_t *self);
@@ -199,6 +198,14 @@ uint8_t pin_find_peripheral_type (const mp_obj_t pin, uint8_t fn, uint8_t unit)
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
+int8_t pin_find_af_index (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type) {
+ int8_t af = pin_obj_find_af(pin, fn, unit, type);
+ if (af < 0) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ }
+ return af;
+}
+
/******************************************************************************
DEFINE PRIVATE FUNCTIONS
******************************************************************************/
@@ -231,14 +238,6 @@ STATIC int8_t pin_obj_find_af (const pin_obj_t* pin, uint8_t fn, uint8_t unit, u
return -1;
}
-STATIC int8_t pin_find_af_index (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type) {
- int8_t af = pin_obj_find_af(pin, fn, unit, type);
- if (af < 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
- }
- return af;
-}
-
STATIC void pin_free_af_from_pins (uint8_t fn, uint8_t unit, uint8_t type) {
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_board_pins_locals_dict);
for (uint i = 0; i < named_map->used - 1; i++) {
@@ -248,7 +247,7 @@ STATIC void pin_free_af_from_pins (uint8_t fn, uint8_t unit, uint8_t type) {
// check if the pin supports the target af
int af = pin_obj_find_af(pin, fn, unit, type);
if (af > 0 && af == pin->af) {
- // the pin is assigned to the target af, de-assign it
+ // the pin supports the target af, de-assign it
pin_deassign (pin);
}
}
diff --git a/cc3200/mods/pybpin.h b/cc3200/mods/pybpin.h
index 3e7784926..ad02cc777 100644
--- a/cc3200/mods/pybpin.h
+++ b/cc3200/mods/pybpin.h
@@ -72,10 +72,7 @@ enum {
};
enum {
- PIN_TYPE_TIM_PWM0 = 0,
- PIN_TYPE_TIM_PWM1,
- PIN_TYPE_TIM_CC0,
- PIN_TYPE_TIM_CC1,
+ PIN_TYPE_TIM_PWM = 0,
};
enum {
@@ -139,5 +136,6 @@ pin_obj_t *pin_find(mp_obj_t user_obj);
void pin_assign_pins_af (mp_obj_t *pins, uint32_t n_pins, uint32_t pull, uint32_t fn, uint32_t unit);
uint8_t pin_find_peripheral_unit (const mp_obj_t pin, uint8_t fn, uint8_t type);
uint8_t pin_find_peripheral_type (const mp_obj_t pin, uint8_t fn, uint8_t unit);
+int8_t pin_find_af_index (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type);;
#endif // PYBPIN_H_
diff --git a/cc3200/mods/pybtimer.c b/cc3200/mods/pybtimer.c
index 9220487eb..048b1795f 100644
--- a/cc3200/mods/pybtimer.c
+++ b/cc3200/mods/pybtimer.c
@@ -43,7 +43,10 @@
#include "interrupt.h"
#include "prcm.h"
#include "timer.h"
+#include "pin.h"
#include "pybtimer.h"
+#include "pybpin.h"
+#include "pins.h"
#include "mpirq.h"
#include "pybsleep.h"
#include "mpexception.h"
@@ -55,30 +58,8 @@
/// 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,
+/// event, and the counter resets back to zero. By using the irq method,
/// the timer event can call a Python function.
-///
-/// Example usage to toggle an LED at a fixed frequency:
-///
-/// tim = pyb.Timer(3) # create a timer object using timer 3
-/// tim.init(mode=Timer.PERIODIC) # initialize it in periodic mode
-/// tim_ch = tim.channel(Timer.A, freq=2) # configure channel A at a frequency of 2Hz
-/// tim_ch.callback(handler=lambda t:led.toggle()) # toggle a LED on every cycle of the timer
-///
-/// Further examples:
-///
-/// tim1 = pyb.Timer(2, mode=Timer.EVENT_COUNT) # initialize it capture mode
-/// tim2 = pyb.Timer(1, mode=Timer.PWM) # initialize it in PWM mode
-/// tim_ch = tim1.channel(Timer.A, freq=1, polarity=Timer.POSITIVE) # start the event counter with a frequency of 1Hz and triggered by positive edges
-/// tim_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=50) # start the PWM on channel B with a 50% duty cycle
-/// tim_ch.time() # get the current time in usec (can also be set)
-/// tim_ch.freq(20) # set the frequency (can also get)
-/// tim_ch.duty_cycle(30) # set the duty cycle to 30% (can also get)
-/// tim_ch.duty_cycle(30, Timer.NEGATIVE) # set the duty cycle to 30% and change the polarity to negative
-/// tim_ch.event_count() # get the number of captured events
-/// tim_ch.event_time() # get the the time of the last captured event
-/// tim_ch.period(2000000) # change the period to 2 seconds
-///
/******************************************************************************
DECLARE PRIVATE CONSTANTS
@@ -89,7 +70,6 @@
#define PYBTIMER_TIMEOUT_TRIGGER (0x01)
#define PYBTIMER_MATCH_TRIGGER (0x02)
-#define PYBTIMER_EVENT_TRIGGER (0x04)
#define PYBTIMER_SRC_FREQ_HZ HAL_FCPU_HZ
@@ -112,8 +92,8 @@ typedef struct _pyb_timer_channel_obj_t {
uint32_t frequency;
uint32_t period;
uint16_t channel;
+ uint16_t duty_cycle;
uint8_t polarity;
- uint8_t duty_cycle;
} pyb_timer_channel_obj_t;
/******************************************************************************
@@ -125,6 +105,7 @@ STATIC pyb_timer_obj_t pyb_timer_obj[PYBTIMER_NUM_TIMERS] = {{.timer = TIMERA0_B
{.timer = TIMERA2_BASE, .peripheral = PRCM_TIMERA2},
{.timer = TIMERA3_BASE, .peripheral = PRCM_TIMERA3}};
STATIC const mp_obj_type_t pyb_timer_channel_type;
+STATIC const mp_obj_t pyb_timer_pwm_pin[8] = {&pin_GP24, MP_OBJ_NULL, &pin_GP25, MP_OBJ_NULL, MP_OBJ_NULL, &pin_GP9, &pin_GP10, &pin_GP11};
/******************************************************************************
DECLARE PRIVATE FUNCTIONS
@@ -231,9 +212,13 @@ STATIC uint32_t compute_prescaler_period_and_match_value(pyb_timer_channel_obj_t
// check limit values for the duty cycle
if (ch->duty_cycle == 0) {
*match_out = period_c - 1;
- }
- else {
- *match_out = period_c - ((period_c * ch->duty_cycle) / 100);
+ } else {
+ if (period_c > 0xFFFF) {
+ uint32_t match = (period_c * 100) / 10000;
+ *match_out = period_c - ((match * ch->duty_cycle) / 100);
+ } else {
+ *match_out = period_c - ((period_c * ch->duty_cycle) / 10000);
+ }
}
return prescaler;
@@ -304,31 +289,12 @@ STATIC void pyb_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_
case TIMER_CFG_A_PERIODIC_UP:
mode_qst = MP_QSTR_PERIODIC;
break;
- case TIMER_CFG_A_CAP_COUNT:
- mode_qst = MP_QSTR_EDGE_COUNT;
- break;
- case TIMER_CFG_A_CAP_TIME:
- mode_qst = MP_QSTR_EDGE_TIME;
- break;
default:
break;
}
mp_printf(print, "Timer(%u, mode=Timer.%q)", (tim->id + 1), mode_qst);
}
-/// \method init(mode, *, width)
-/// Initialise the timer. Initialisation must give the desired mode
-/// and an optional timer width
-///
-/// tim.init(mode=Timer.ONE_SHOT, width=32) # one shot mode
-/// tim.init(mode=Timer.PERIODIC) # configure in free running periodic mode
-/// split into two 16-bit independent timers
-///
-/// Keyword arguments:
-///
-/// - `width` - specifies the width of the timer. Default is 32 bit mode. When in 16 bit mode
-/// the timer is splitted into 2 independent channels.
-///
STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *tim, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, },
@@ -341,8 +307,7 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *tim, mp_uint_t n_args, co
// check the mode
uint32_t _mode = args[0].u_int;
- if (_mode != TIMER_CFG_A_ONE_SHOT_UP && _mode != TIMER_CFG_A_PERIODIC_UP && _mode != TIMER_CFG_A_CAP_COUNT &&
- _mode != TIMER_CFG_A_CAP_TIME && _mode != TIMER_CFG_A_PWM) {
+ if (_mode != TIMER_CFG_A_ONE_SHOT_UP && _mode != TIMER_CFG_A_PERIODIC_UP && _mode != TIMER_CFG_A_PWM) {
goto error;
}
@@ -368,11 +333,7 @@ error:
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
-/// \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 4
-STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_timer_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
// check arguments
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
@@ -395,15 +356,11 @@ STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, mp_uint_t n_args,
return (mp_obj_t)tim;
}
-// \method init()
-/// initializes the timer
STATIC mp_obj_t pyb_timer_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
return pyb_timer_init_helper(args[0], n_args - 1, args + 1, kw_args);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_init_obj, 1, pyb_timer_init);
-// \method deinit()
-/// disables the timer
STATIC mp_obj_t pyb_timer_deinit(mp_obj_t self_in) {
pyb_timer_obj_t *self = self_in;
timer_disable(self);
@@ -411,24 +368,6 @@ 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 channel(channel, *, freq, period, polarity, duty_cycle)
-/// Initialise the timer channel. Initialization requires at least a frequency param. With no
-/// extra params given besides the channel id, the channel is returned with the previous configuration
-/// os 'None', if it hasn't been initialized before.
-///
-/// tim1.channel(Timer.A, freq=1000) # set channel A frequency to 1KHz
-/// tim2.channel(Timer.AB, freq=10) # both channels (because it's a 32 bit timer) combined to create a 10Hz timer
-///
-/// when initialiazing the channel of a 32-bit timer, channel ID MUST be = Timer.AB
-///
-/// Keyword arguments:
-///
-/// - `freq` - specifies the frequency in Hz.
-/// - `period` - specifies the period in microseconds.
-/// - `polarity` - in PWM specifies the polarity of the pulse. In capture mode specifies the edge to capture.
-/// in order to capture on both negative and positive edges, make it = Timer.POSITIVE | Timer.NEGATIVE.
-/// - `duty_cycle` - sets the duty cycle value
-///
STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
@@ -490,10 +429,22 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp
ch->frequency = args[0].u_int;
ch->period = args[1].u_int;
ch->polarity = args[2].u_int;
- ch->duty_cycle = MIN(100, MAX(0, args[3].u_int));
+ ch->duty_cycle = MIN(10000, MAX(0, args[3].u_int));
timer_channel_init(ch);
+ // assign the pin
+ if ((ch->timer->config & 0x0F) == TIMER_CFG_A_PWM) {
+ uint32_t ch_idx = (ch->channel == TIMER_A) ? 0 : 1;
+ // use the default pin if available
+ mp_obj_t pin_o = (mp_obj_t)pyb_timer_pwm_pin[(ch->timer->id * 2) + ch_idx];
+ if (pin_o != MP_OBJ_NULL) {
+ pin_obj_t *pin = pin_find(pin_o);
+ pin_config (pin, pin_find_af_index(pin, PIN_FN_TIM, ch->timer->id, PIN_TYPE_TIM_PWM),
+ 0, PIN_TYPE_STD, -1, PIN_STRENGTH_4MA);
+ }
+ }
+
// add the timer to the list
pyb_timer_channel_add(ch);
@@ -515,14 +466,11 @@ STATIC const mp_map_elem_t pyb_timer_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_B), MP_OBJ_NEW_SMALL_INT(TIMER_B) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ONE_SHOT), MP_OBJ_NEW_SMALL_INT(TIMER_CFG_A_ONE_SHOT_UP) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PERIODIC), MP_OBJ_NEW_SMALL_INT(TIMER_CFG_A_PERIODIC_UP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_EDGE_COUNT), MP_OBJ_NEW_SMALL_INT(TIMER_CFG_A_CAP_COUNT) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_EDGE_TIME), MP_OBJ_NEW_SMALL_INT(TIMER_CFG_A_CAP_TIME) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PWM), MP_OBJ_NEW_SMALL_INT(TIMER_CFG_A_PWM) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_POSITIVE), MP_OBJ_NEW_SMALL_INT(PYBTIMER_POLARITY_POS) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_NEGATIVE), MP_OBJ_NEW_SMALL_INT(PYBTIMER_POLARITY_NEG) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_TIMEOUT), MP_OBJ_NEW_SMALL_INT(PYBTIMER_TIMEOUT_TRIGGER) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_MATCH), MP_OBJ_NEW_SMALL_INT(PYBTIMER_MATCH_TRIGGER) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_EVENT), MP_OBJ_NEW_SMALL_INT(PYBTIMER_EVENT_TRIGGER) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_timer_locals_dict, pyb_timer_locals_dict_table);
@@ -610,14 +558,12 @@ STATIC void pyb_timer_channel_print(const mp_print_t *print, mp_obj_t self_in, m
break;
}
if (mode == TIMER_CFG_A_PWM) {
- mp_printf(print, ", %q=%u", MP_QSTR_duty_cycle, ch->duty_cycle);
+ mp_printf(print, ", %q=%u.%02u", MP_QSTR_duty_cycle, ch->duty_cycle / 100, ch->duty_cycle % 100);
}
}
mp_printf(print, ")");
}
-/// \method freq([value])
-/// get or set the frequency of the timer channel
STATIC mp_obj_t pyb_timer_channel_freq(mp_uint_t n_args, const mp_obj_t *args) {
pyb_timer_channel_obj_t *ch = args[0];
if (n_args == 1) {
@@ -637,8 +583,6 @@ STATIC mp_obj_t pyb_timer_channel_freq(mp_uint_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_channel_freq_obj, 1, 2, pyb_timer_channel_freq);
-/// \method period([value])
-/// get or set the period of the timer channel in microseconds
STATIC mp_obj_t pyb_timer_channel_period(mp_uint_t n_args, const mp_obj_t *args) {
pyb_timer_channel_obj_t *ch = args[0];
if (n_args == 1) {
@@ -658,59 +602,6 @@ STATIC mp_obj_t pyb_timer_channel_period(mp_uint_t n_args, const mp_obj_t *args)
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_channel_period_obj, 1, 2, pyb_timer_channel_period);
-/// \method time([value])
-/// get or set the value of the timer channel in microseconds
-STATIC mp_obj_t pyb_timer_channel_time(mp_uint_t n_args, const mp_obj_t *args) {
- pyb_timer_channel_obj_t *ch = args[0];
- uint32_t value;
- // calculate the period, the prescaler and the match value
- uint32_t period_c;
- uint32_t match;
- (void)compute_prescaler_period_and_match_value(ch, &period_c, &match);
- if (n_args == 1) {
- // get
- value = (ch->channel == TIMER_B) ? HWREG(ch->timer->timer + TIMER_O_TBV) : HWREG(ch->timer->timer + TIMER_O_TAV);
- // return the current timer value in microseconds
- uint32_t time_t = (1000 * value) / period_c;
- return mp_obj_new_int((time_t * 1000) / ch->frequency);
- } else {
- // set
- value = (mp_obj_get_int(args[1]) * ((ch->frequency * period_c) / 1000)) / 1000;
- if ((value > 0xFFFF) && (ch->timer->config & TIMER_CFG_SPLIT_PAIR)) {
- // this exceeds the maximum value of a 16-bit timer
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
- }
- // write period minus value since we are always operating in count-down mode
- TimerValueSet (ch->timer->timer, ch->channel, (period_c - value));
- return mp_const_none;
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_channel_time_obj, 1, 2, pyb_timer_channel_time);
-
-/// \method event_count()
-/// get the number of events triggered by the configured edge
-STATIC mp_obj_t pyb_timer_channel_event_count(mp_obj_t self_in) {
- pyb_timer_channel_obj_t *ch = self_in;
- return mp_obj_new_int(MAP_TimerValueGet(ch->timer->timer, ch->channel == (TIMER_A | TIMER_B) ? TIMER_A : ch->channel));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_timer_channel_event_count_obj, pyb_timer_channel_event_count);
-
-/// \method event_time()
-/// get the time at which the last event was triggered
-STATIC mp_obj_t pyb_timer_channel_event_time(mp_obj_t self_in) {
- pyb_timer_channel_obj_t *ch = self_in;
- // calculate the period, the prescaler and the match value
- uint32_t period_c;
- uint32_t match;
- (void)compute_prescaler_period_and_match_value(ch, &period_c, &match);
- uint32_t value = MAP_TimerValueGet(ch->timer->timer, ch->channel == (TIMER_A | TIMER_B) ? TIMER_A : ch->channel);
- uint32_t time_t = (1000 * value) / period_c;
- return mp_obj_new_int((time_t * 1000) / ch->frequency);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_timer_channel_event_time_obj, pyb_timer_channel_event_time);
-
-/// \method duty_cycle()
-/// get or set the duty cycle when in PWM mode
STATIC mp_obj_t pyb_timer_channel_duty_cycle(mp_uint_t n_args, const mp_obj_t *args) {
pyb_timer_channel_obj_t *ch = args[0];
if (n_args == 1) {
@@ -721,7 +612,7 @@ STATIC mp_obj_t pyb_timer_channel_duty_cycle(mp_uint_t n_args, const mp_obj_t *a
// calculate the period, the prescaler and the match value
uint32_t period_c;
uint32_t match;
- ch->duty_cycle = MIN(100, MAX(0, mp_obj_get_int(args[1])));
+ ch->duty_cycle = MIN(10000, MAX(0, mp_obj_get_int(args[1])));
compute_prescaler_period_and_match_value(ch, &period_c, &match);
if (n_args == 3) {
// set the new polarity if requested
@@ -735,7 +626,6 @@ STATIC mp_obj_t pyb_timer_channel_duty_cycle(mp_uint_t n_args, const mp_obj_t *a
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_channel_duty_cycle_obj, 1, 3, pyb_timer_channel_duty_cycle);
-/// \method irq(trigger, priority, handler, wake)
STATIC mp_obj_t pyb_timer_channel_irq (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
mp_arg_val_t args[mp_irq_INIT_NUM_ARGS];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mp_irq_INIT_NUM_ARGS, mp_irq_init_args, args);
@@ -766,18 +656,6 @@ STATIC mp_obj_t pyb_timer_channel_irq (mp_uint_t n_args, const mp_obj_t *pos_arg
goto invalid_args;
}
break;
- case TIMER_CFG_A_CAP_COUNT:
- ch->timer->irq_trigger |= TIMER_CAPA_MATCH << shift;
- if (trigger != PYBTIMER_MATCH_TRIGGER) {
- goto invalid_args;
- }
- break;
- case TIMER_CFG_A_CAP_TIME:
- ch->timer->irq_trigger |= TIMER_CAPA_EVENT << shift;
- if (trigger != PYBTIMER_EVENT_TRIGGER) {
- goto invalid_args;
- }
- break;
case TIMER_CFG_A_PWM:
// special case for the PWM match interrupt
ch->timer->irq_trigger |= ((ch->channel & TIMER_A) == TIMER_A) ? TIMER_TIMA_MATCH : TIMER_TIMB_MATCH;
@@ -855,9 +733,6 @@ STATIC const mp_map_elem_t pyb_timer_channel_locals_dict_table[] = {
// instance methods
{ MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&pyb_timer_channel_freq_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_period), (mp_obj_t)&pyb_timer_channel_period_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&pyb_timer_channel_time_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_event_count), (mp_obj_t)&pyb_timer_channel_event_count_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_event_time), (mp_obj_t)&pyb_timer_channel_event_time_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_duty_cycle), (mp_obj_t)&pyb_timer_channel_duty_cycle_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_irq), (mp_obj_t)&pyb_timer_channel_irq_obj },
};
diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h
index 9a461d812..2bd7daa11 100644
--- a/cc3200/qstrdefsport.h
+++ b/cc3200/qstrdefsport.h
@@ -365,21 +365,15 @@ Q(width)
Q(channel)
Q(polarity)
Q(duty_cycle)
-Q(time)
-Q(event_count)
-Q(event_time)
Q(A)
Q(B)
Q(ONE_SHOT)
Q(PERIODIC)
-Q(EDGE_COUNT)
-Q(EDGE_TIME)
Q(PWM)
Q(POSITIVE)
Q(NEGATIVE)
Q(TIMEOUT)
Q(MATCH)
-Q(EVENT)
// for uhashlib module
//Q(uhashlib)
diff --git a/docs/library/machine.Timer.rst b/docs/library/machine.Timer.rst
index 8464c7b36..751f6536a 100644
--- a/docs/library/machine.Timer.rst
+++ b/docs/library/machine.Timer.rst
@@ -5,11 +5,6 @@ class Timer -- control internal timers
.. only:: port_wipy
- .. note::
-
- Contrary with the rest of the API, timer IDs start at 1, not a t zero. This is because
- the ``Timer`` API is still provisional. A new MicroPython wide API will come soon.
-
Timers can be used for a great variety of tasks, calling a function periodically,
counting events, and generating a PWM signal are among the most common use cases.
Each timer consists of 2 16-bit channels and this channels can be tied together to
@@ -20,40 +15,39 @@ class Timer -- control internal timers
Example usage to toggle an LED at a fixed frequency::
from machine import Timer
- tim = Timer(4) # create a timer object using timer 4
+ from machine import Pin
+ led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED
+ tim = Timer(3) # create a timer object using timer 3
tim.init(mode=Timer.PERIODIC) # initialize it in periodic mode
- tim_ch = tim.channel(Timer.A, freq=2) # configure channel A at a frequency of 2Hz
- tim_ch.callback(handler=lambda t:led.toggle()) # toggle a LED on every cycle of the timer
+ tim_ch = tim.channel(Timer.A, freq=5) # configure channel A at a frequency of 5Hz
+ tim_ch.irq(handler=lambda t:led.toggle()) # toggle a LED on every cycle of the timer
Example using named function for the callback::
from machine import Timer
- tim = Timer(1, mode=Timer.PERIODIC)
- tim_a = tim.channel(Timer.A, freq=1000)
+ from machine import Pin
+ tim = Timer(1, mode=Timer.PERIODIC, width=32)
+ tim_a = tim.channel(Timer.A | Timer.B, freq=1) # 1 Hz frequency requires a 32 bit timer
- led = Pin('GPIO2', mode=Pin.OUT)
+ led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED
def tick(timer): # we will receive the timer object when being called
print(timer.time()) # show current timer's time value (is microseconds)
led.toggle() # toggle the LED
- tim_a.callback(handler=tick)
+ tim_a.irq(handler=tick) # create the interrupt
Further examples::
from machine import Timer
- tim1 = Timer(2, mode=Timer.EVENT_COUNT) # initialize it capture mode
- tim2 = Timer(1, mode=Timer.PWM) # initialize it in PWM mode
- tim_ch = tim1.channel(Timer.A, freq=1, polarity=Timer.POSITIVE) # start the event counter with a frequency of 1Hz and triggered by positive edges
- tim_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=50) # start the PWM on channel B with a 50% duty cycle
- tim_ch.time() # get the current time in usec (can also be set)
- tim_ch.freq(20) # set the frequency (can also get)
- tim_ch.duty_cycle(30) # set the duty cycle to 30% (can also get)
- tim_ch.duty_cycle(30, Timer.NEGATIVE) # set the duty cycle to 30% and change the polarity to negative
- tim_ch.event_count() # get the number of captured events
- tim_ch.event_time() # get the the time of the last captured event
- tim_ch.period(2000000) # change the period to 2 seconds
-
+ tim1 = Timer(2, mode=Timer.ONE_SHOT) # initialize it in one shot mode
+ tim2 = Timer(1, mode=Timer.PWM) # initialize it in PWM mode
+ tim1_ch = tim1.channel(Timer.A, freq=10, polarity=Timer.POSITIVE) # start the event counter with a frequency of 10Hz and triggered by positive edges
+ tim2_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=50) # start the PWM on channel B with a 50% duty cycle
+ tim2_ch.freq(20) # set the frequency (can also get)
+ tim2_ch.duty_cycle(30) # set the duty cycle to 30% (can also get)
+ tim2_ch.duty_cycle(30, Timer.NEGATIVE) # set the duty cycle to 30% and change the polarity to negative
+ tim2_ch.period(2000000) # change the period to 2 seconds
.. note::
@@ -69,9 +63,7 @@ Constructors
.. only:: port_wipy
- 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 4.
+ Construct a new timer object of the given id. ``id`` can take values from 0 to 3.
Methods
@@ -94,10 +86,9 @@ Methods
period of the channel expires.
- ``Timer.PERIODIC`` - The timer runs periodically at the configured
frequency of the channel.
- - ``Timer.EDGE_TIME`` - Meaure the time pin level changes.
- - ``Timer.EDGE_COUNT`` - Count the number of pin level changes.
+ - ``Timer.PWM`` - Output a PWM signal on a pin.
- - ``width`` must be either 16 or 32 (bits). For really low frequencies <= ~1Hz
+ - ``width`` must be either 16 or 32 (bits). For really low frequencies < 5Hz
(or large periods), 32-bit timers should be used. 32-bit mode is only available
for ``ONE_SHOT`` AND ``PERIODIC`` modes.
@@ -112,7 +103,7 @@ Methods
If only a channel identifier passed, then a previously initialized channel
object is returned (or ``None`` if there is no previous channel).
-
+
Othwerwise, a TimerChannel object is initialized and returned.
The operating mode is is the one configured to the Timer object that was used to
@@ -130,12 +121,11 @@ Methods
Either ``freq`` or ``period`` must be given, never both.
- - ``polarity`` this is applicable for:
-
- - ``PWM``, defines the polarity of the duty cycle
- - ``EDGE_TIME`` and ``EDGE_COUNT``, defines the polarity of the pin level change to detect.
- To detect both rising and falling edges, make ``polarity=Timer.POSITIVE | Timer.NEGATIVE``.
- - ``duty_cycle`` only applicable to ``PWM``. It's a percentage (0-100)
+ - ``polarity`` this is applicable for ``PWM``, and defines the polarity of the duty cycle
+ - ``duty_cycle`` only applicable to ``PWM``. It's a percentage (0.00-100.00). Since the WiPy
+ doesn't support floating point numbers the duty cycle must be specified in the range 0-10000,
+ where 10000 would represent 100.00, 5050 represents 50.50, and so on.
+
class TimerChannel --- setup a channel for a timer
==================================================
@@ -166,31 +156,47 @@ Methods
- ``priority`` level of the interrupt. Can take values in the range 1-7.
Higher values represent higher priorities.
- ``handler`` is an optional function to be called when the interrupt is triggered.
+ - ``trigger`` must be ``Timer.TIMEOUT`` when the operating mode is either ``Timer.PERIODIC`` or
+ ``Timer.ONE_SHOT``. In the case that mode is ``Timer.PWM`` then trigger must be equal to
+ ``Timer.MATCH``.
Returns a callback object.
.. only:: port_wipy
.. method:: timerchannel.freq([value])
-
+
Get or set the timer channel frequency (in Hz).
.. method:: timerchannel.period([value])
Get or set the timer channel period (in microseconds).
-
- .. method:: timerchannel.time([value])
- Get or set the timer channel current **time** value (in microseconds).
-
- .. method:: timerchannel.event_count()
+ .. method:: timerchannel.duty_cycle([value])
- Get the number of edge events counted.
+ Get or set the duty cycle of the PWM signal (in the range of 0-100).
- .. method:: timerchannel.event_time()
+Constants
+---------
- Get the time of ocurrance of the last event.
+.. data:: Timer.ONE_SHOT
+.. data:: Timer.PERIODIC
+.. data:: Timer.PWM
- .. method:: timerchannel.duty_cycle([value])
-
- Get or set the duty cycle of the PWM signal (in the range of 0-100).
+ Selects the timer operating mode.
+
+.. data:: Timer.A
+.. data:: Timer.B
+
+ Selects the timer channel. Must be ORed (``Timer.A`` | ``Timer.B``) when
+ using a 32-bit timer.
+
+.. data:: Timer.POSITIVE
+.. data:: Timer.NEGATIVE
+
+ Timer channel polarity selection (only relevant in PWM mode).
+
+.. data:: Timer.TIMEOUT
+.. data:: Timer.MATCH
+
+ Timer channel IRQ triggers.
diff --git a/docs/wipy/quickref.rst b/docs/wipy/quickref.rst
index a30eec2aa..6c2cf0de7 100644
--- a/docs/wipy/quickref.rst
+++ b/docs/wipy/quickref.rst
@@ -49,10 +49,10 @@ See :ref:`machine.Timer <machine.Timer>` and :ref:`machine.Pin <machine.Pin>`. :
from machine import Timer
from machine import Pin
- tim = Timer(1, mode=Timer.PERIODIC)
+ tim = Timer(0, mode=Timer.PERIODIC)
tim_a = tim.channel(Timer.A, freq=1000)
tim_a.time() # get the value in microseconds
- tim_a.freq(1) # 1 Hz
+ tim_a.freq(5) # 5 Hz
p_out = Pin('GP2', mode=Pin.OUT)
tim_a.irq(handler=lambda t: p_out.toggle())