diff options
| author | Scott Shawcroft <scott@chickadee.tech> | 2016-09-19 13:32:29 -0700 |
|---|---|---|
| committer | Scott Shawcroft <scott@chickadee.tech> | 2016-09-19 13:32:29 -0700 |
| commit | bb03afdb77c95b9cb23e531e5763167ccb09c8e4 (patch) | |
| tree | 509722778a03b10c933963a35c93eb5670a5cdb5 /stmhal | |
| parent | 345dd1484c4e68f53ea242c5778a2de99119db9a (diff) | |
| parent | 60592fd23c8acd4ed4f70d8fbe8f8b11ea58082c (diff) | |
Merge remote-tracking branch 'micropython/master'
Diffstat (limited to 'stmhal')
| -rw-r--r-- | stmhal/Makefile | 4 | ||||
| -rw-r--r-- | stmhal/accel.c | 9 | ||||
| -rw-r--r-- | stmhal/boards/OLIMEX_E407/mpconfigboard.h | 6 | ||||
| -rw-r--r-- | stmhal/boards/STM32F7DISC/mpconfigboard.h | 13 | ||||
| -rw-r--r-- | stmhal/boards/pllvalues.py | 115 | ||||
| -rw-r--r-- | stmhal/dac.c | 8 | ||||
| -rw-r--r-- | stmhal/extint.c | 7 | ||||
| -rw-r--r-- | stmhal/lcd.c | 26 | ||||
| -rw-r--r-- | stmhal/main.c | 3 | ||||
| -rw-r--r-- | stmhal/modmachine.c | 65 | ||||
| -rw-r--r-- | stmhal/modmachine.h | 2 | ||||
| -rw-r--r-- | stmhal/wdt.c | 108 | ||||
| -rw-r--r-- | stmhal/wdt.h | 27 |
13 files changed, 354 insertions, 39 deletions
diff --git a/stmhal/Makefile b/stmhal/Makefile index 2c6ea806e..b320e0c89 100644 --- a/stmhal/Makefile +++ b/stmhal/Makefile @@ -111,7 +111,6 @@ SRC_LIB = $(addprefix lib/,\ timeutils/timeutils.c \ utils/pyexec.c \ utils/pyhelp.c \ - utils/printf.c \ ) SRC_C = \ @@ -138,6 +137,7 @@ SRC_C = \ uart.c \ can.c \ usb.c \ + wdt.c \ gccollect.c \ pybstdio.c \ help.c \ @@ -284,7 +284,7 @@ endif ifneq ($(FROZEN_MPY_DIR),) # To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and # then invoke make with FROZEN_MPY_DIR=frozen (be sure to build from scratch). -FROZEN_MPY_PY_FILES := $(shell find $(FROZEN_MPY_DIR) -type f -name '*.py') +FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool CFLAGS += -DMICROPY_MODULE_FROZEN_MPY diff --git a/stmhal/accel.c b/stmhal/accel.c index 34e9d8e0e..e75f1c994 100644 --- a/stmhal/accel.c +++ b/stmhal/accel.c @@ -27,8 +27,7 @@ #include <stdio.h> #include <string.h> -#include STM32_HAL_H - +#include "py/mphal.h" #include "py/nlr.h" #include "py/runtime.h" #include "pin.h" @@ -61,7 +60,7 @@ void accel_init(void) { GPIO_InitTypeDef GPIO_InitStructure; // PB5 is connected to AVDD; pull high to enable MMA accel device - MICROPY_HW_MMA_AVDD_PIN.gpio->BSRRH = MICROPY_HW_MMA_AVDD_PIN.pin_mask; // turn off AVDD + GPIO_clear_pin(MICROPY_HW_MMA_AVDD_PIN.gpio, MICROPY_HW_MMA_AVDD_PIN.pin_mask); // turn off AVDD GPIO_InitStructure.Pin = MICROPY_HW_MMA_AVDD_PIN.pin_mask; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Speed = GPIO_SPEED_LOW; @@ -82,9 +81,9 @@ STATIC void accel_start(void) { i2c_init(&I2CHandle1); // turn off AVDD, wait 30ms, turn on AVDD, wait 30ms again - MICROPY_HW_MMA_AVDD_PIN.gpio->BSRRH = MICROPY_HW_MMA_AVDD_PIN.pin_mask; // turn off + GPIO_clear_pin(MICROPY_HW_MMA_AVDD_PIN.gpio, MICROPY_HW_MMA_AVDD_PIN.pin_mask); // turn off HAL_Delay(30); - MICROPY_HW_MMA_AVDD_PIN.gpio->BSRRL = MICROPY_HW_MMA_AVDD_PIN.pin_mask; // turn on + GPIO_set_pin(MICROPY_HW_MMA_AVDD_PIN.gpio, MICROPY_HW_MMA_AVDD_PIN.pin_mask); // turn on HAL_Delay(30); HAL_StatusTypeDef status; diff --git a/stmhal/boards/OLIMEX_E407/mpconfigboard.h b/stmhal/boards/OLIMEX_E407/mpconfigboard.h index 4d1f7ff83..c9241fe63 100644 --- a/stmhal/boards/OLIMEX_E407/mpconfigboard.h +++ b/stmhal/boards/OLIMEX_E407/mpconfigboard.h @@ -23,10 +23,8 @@ #define MICROPY_HW_CLK_PLLQ (7) // UART config -#if MICROPY_HW_HAS_SWITCH == 0 #define MICROPY_HW_UART1_PORT (GPIOB) #define MICROPY_HW_UART1_PINS (GPIO_PIN_6 | GPIO_PIN_7) -#endif #define MICROPY_HW_UART2_PORT (GPIOA) #define MICROPY_HW_UART2_PINS (GPIO_PIN_2 | GPIO_PIN_3) @@ -50,8 +48,8 @@ #define MICROPY_HW_UART6_PINS (GPIO_PIN_6 | GPIO_PIN_7) // I2C busses -#define MICROPY_HW_I2C1_SCL (pin_B6) -#define MICROPY_HW_I2C1_SDA (pin_B7) +#define MICROPY_HW_I2C1_SCL (pin_B8) +#define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) diff --git a/stmhal/boards/STM32F7DISC/mpconfigboard.h b/stmhal/boards/STM32F7DISC/mpconfigboard.h index c0e47c3ce..a1dbc0f46 100644 --- a/stmhal/boards/STM32F7DISC/mpconfigboard.h +++ b/stmhal/boards/STM32F7DISC/mpconfigboard.h @@ -20,12 +20,19 @@ void STM32F7DISC_board_early_init(void); // HSE is 25MHz +// VCOClock = HSE * PLLN / PLLM = 25 MHz * 432 / 25 = 432 MHz +// SYSCLK = VCOClock / PLLP = 432 MHz / 2 = 216 MHz +// USB/SDMMC/RNG Clock = VCOClock / PLLQ = 432 MHz / 9 = 48 MHz #define MICROPY_HW_CLK_PLLM (25) -#define MICROPY_HW_CLK_PLLN (336) +#define MICROPY_HW_CLK_PLLN (432) #define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) -#define MICROPY_HW_CLK_PLLQ (7) +#define MICROPY_HW_CLK_PLLQ (9) -#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_6 +// From the reference manual, for 2.7V to 3.6V +// 151-180 MHz => 5 wait states +// 181-210 MHz => 6 wait states +// 211-216 MHz => 7 wait states +#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_7 // 210-216 MHz needs 7 wait states // UART config #define MICROPY_HW_UART1_TX_PORT (GPIOA) diff --git a/stmhal/boards/pllvalues.py b/stmhal/boards/pllvalues.py new file mode 100644 index 000000000..183313f30 --- /dev/null +++ b/stmhal/boards/pllvalues.py @@ -0,0 +1,115 @@ +""" +This is an auxiliary script that is used to compute valid PLL values to set +the CPU frequency to a given value. The algorithm here appears as C code +for the machine.freq() function. +""" + +def close_int(x): + return abs(x - round(x)) < 0.01 + +# original version that requires N/M to be an integer (for simplicity) +def compute_pll(hse, sys): + for P in (2, 4, 6, 8): # allowed values of P + Q = sys * P / 48 + NbyM = sys * P / hse + # N/M and Q must be integers + if not (close_int(NbyM) and close_int(Q)): + continue + # VCO_OUT must be between 192MHz and 432MHz + if not (192 <= hse * NbyM <= 432): + continue + # compute M + M = int(192 // NbyM) + while hse > 2 * M or NbyM * M < 192: + M += 1 + # VCO_IN must be between 1MHz and 2MHz (2MHz recommended) + if not (M <= hse): + continue + # compute N + N = NbyM * M + # N and Q are restricted + if not (192 <= N <= 432 and 2 <= Q <= 15): + continue + # found valid values + assert NbyM == N // M + return (M, N, P, Q) + # no valid values found + return None + +# improved version that doesn't require N/M to be an integer +def compute_pll2(hse, sys): + for P in (2, 4, 6, 8): # allowed values of P + Q = sys * P / 48 + # Q must be an integer in a set range + if not (close_int(Q) and 2 <= Q <= 15): + continue + NbyM = sys * P / hse + # VCO_OUT must be between 192MHz and 432MHz + if not (192 <= hse * NbyM <= 432): + continue + # compute M + M = 192 // NbyM # starting value + while hse > 2 * M or NbyM * M < 192 or not close_int(NbyM * M): + M += 1 + # VCO_IN must be between 1MHz and 2MHz (2MHz recommended) + if not (M <= hse): + continue + # compute N + N = NbyM * M + # N must be an integer + if not close_int(N): + continue + # N is restricted + if not (192 <= N <= 432): + continue + # found valid values + return (M, N, P, Q) + # no valid values found + return None + +def verify_and_print_pll(hse, sys, pll): + M, N, P, Q = pll + + # compute derived quantities + vco_in = hse / M + vco_out = hse * N / M + pllck = hse / M * N / P + pll48ck = hse / M * N / Q + + # verify ints + assert close_int(M) + assert close_int(N) + assert close_int(P) + assert close_int(Q) + + # verify range + assert 2 <= M <= 63 + assert 192 <= N <= 432 + assert P in (2, 4, 6, 8) + assert 2 <= Q <= 15 + assert 1 <= vco_in <= 2 + assert 192 <= vco_out <= 432 + + # print out values + print(out_format % (sys, M, N, P, Q, vco_in, vco_out, pllck, pll48ck)) + +def main(): + global out_format + import sys + if len(sys.argv) != 2: + print("usage: pllvalues.py <hse in MHz>") + sys.exit(1) + hse_value = int(sys.argv[1]) + print("HSE =", hse_value, "MHz") + print("sys : M N P Q : VCO_IN VCO_OUT PLLCK PLL48CK") + out_format = "%3u : %2u %.1f %.2f %.2f : %5.2f %6.2f %6.2f %6.2f" + n_valid = 0 + for sysclk in range(1, 217): + pll = compute_pll2(hse_value, sysclk) + if pll is not None: + n_valid += 1 + verify_and_print_pll(hse_value, sysclk, pll) + print("found %u valid configurations" % n_valid) + +if __name__ == "__main__": + main() diff --git a/stmhal/dac.c b/stmhal/dac.c index 7493bb59a..a9b1b9eca 100644 --- a/stmhal/dac.c +++ b/stmhal/dac.c @@ -171,6 +171,14 @@ STATIC mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, mp_uint_t n_args, const #endif // stop anything already going on + __DMA1_CLK_ENABLE(); + DMA_HandleTypeDef DMA_Handle; + /* Get currently configured dma */ + dma_init_handle(&DMA_Handle, self->tx_dma_descr, (void*)NULL); + // Need to deinit DMA first + DMA_Handle.State = HAL_DMA_STATE_READY; + HAL_DMA_DeInit(&DMA_Handle); + HAL_DAC_Stop(&DAC_Handle, self->dac_channel); if ((self->dac_channel == DAC_CHANNEL_1 && DAC_Handle.DMA_Handle1 != NULL) || (self->dac_channel == DAC_CHANNEL_2 && DAC_Handle.DMA_Handle2 != NULL)) { diff --git a/stmhal/extint.c b/stmhal/extint.c index c0471719b..02b06fde5 100644 --- a/stmhal/extint.c +++ b/stmhal/extint.c @@ -251,10 +251,13 @@ void extint_swint(uint line) { if (line >= EXTI_NUM_VECTORS) { return; } + // we need 0 to 1 transition to trigger the interrupt #if defined(MCU_SERIES_L4) - EXTI->SWIER1 = (1 << line); + EXTI->SWIER1 &= ~(1 << line); + EXTI->SWIER1 |= (1 << line); #else - EXTI->SWIER = (1 << line); + EXTI->SWIER &= ~(1 << line); + EXTI->SWIER |= (1 << line); #endif } diff --git a/stmhal/lcd.c b/stmhal/lcd.c index 143ef9bbd..92f19b818 100644 --- a/stmhal/lcd.c +++ b/stmhal/lcd.c @@ -26,8 +26,8 @@ #include <stdio.h> #include <string.h> -#include STM32_HAL_H +#include "py/mphal.h" #include "py/nlr.h" #include "py/runtime.h" @@ -113,14 +113,16 @@ STATIC void lcd_delay(void) { STATIC void lcd_out(pyb_lcd_obj_t *lcd, int instr_data, uint8_t i) { lcd_delay(); - lcd->pin_cs1->gpio->BSRRH = lcd->pin_cs1->pin_mask; // CS=0; enable + GPIO_clear_pin(lcd->pin_cs1->gpio, lcd->pin_cs1->pin_mask); // CS=0; enable if (instr_data == LCD_INSTR) { - lcd->pin_a0->gpio->BSRRH = lcd->pin_a0->pin_mask; // A0=0; select instr reg + GPIO_clear_pin(lcd->pin_a0->gpio, lcd->pin_a0->pin_mask); // A0=0; select instr reg } else { - lcd->pin_a0->gpio->BSRRL = lcd->pin_a0->pin_mask; // A0=1; select data reg + GPIO_set_pin(lcd->pin_a0->gpio, lcd->pin_a0->pin_mask); // A0=1; select data reg } lcd_delay(); HAL_SPI_Transmit(lcd->spi, &i, 1, 1000); + lcd_delay(); + GPIO_set_pin(lcd->pin_cs1->gpio, lcd->pin_cs1->pin_mask); // CS=1; disable } // write a string to the LCD at the current cursor location @@ -260,10 +262,10 @@ STATIC mp_obj_t pyb_lcd_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp spi_init(lcd->spi, false); // set the pins to default values - lcd->pin_cs1->gpio->BSRRL = lcd->pin_cs1->pin_mask; - lcd->pin_rst->gpio->BSRRL = lcd->pin_rst->pin_mask; - lcd->pin_a0->gpio->BSRRL = lcd->pin_a0->pin_mask; - lcd->pin_bl->gpio->BSRRH = lcd->pin_bl->pin_mask; + GPIO_set_pin(lcd->pin_cs1->gpio, lcd->pin_cs1->pin_mask); + GPIO_set_pin(lcd->pin_rst->gpio, lcd->pin_rst->pin_mask); + GPIO_set_pin(lcd->pin_a0->gpio, lcd->pin_a0->pin_mask); + GPIO_clear_pin(lcd->pin_bl->gpio, lcd->pin_bl->pin_mask); // init the pins to be push/pull outputs GPIO_InitTypeDef GPIO_InitStructure; @@ -285,9 +287,9 @@ STATIC mp_obj_t pyb_lcd_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp // init the LCD HAL_Delay(1); // wait a bit - lcd->pin_rst->gpio->BSRRH = lcd->pin_rst->pin_mask; // RST=0; reset + GPIO_clear_pin(lcd->pin_rst->gpio, lcd->pin_rst->pin_mask); // RST=0; reset HAL_Delay(1); // wait for reset; 2us min - lcd->pin_rst->gpio->BSRRL = lcd->pin_rst->pin_mask; // RST=1; enable + GPIO_set_pin(lcd->pin_rst->gpio, lcd->pin_rst->pin_mask); // RST=1; enable HAL_Delay(1); // wait for reset; 2us min lcd_out(lcd, LCD_INSTR, 0xa0); // ADC select, normal lcd_out(lcd, LCD_INSTR, 0xc0); // common output mode select, normal (this flips the display) @@ -370,9 +372,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_lcd_contrast_obj, pyb_lcd_contrast); STATIC mp_obj_t pyb_lcd_light(mp_obj_t self_in, mp_obj_t value) { pyb_lcd_obj_t *self = self_in; if (mp_obj_is_true(value)) { - self->pin_bl->gpio->BSRRL = self->pin_bl->pin_mask; // set pin high to turn backlight on + GPIO_set_pin(self->pin_bl->gpio, self->pin_bl->pin_mask); // set pin high to turn backlight on } else { - self->pin_bl->gpio->BSRRH = self->pin_bl->pin_mask; // set pin low to turn backlight off + GPIO_clear_pin(self->pin_bl->gpio, self->pin_bl->pin_mask); // set pin low to turn backlight off } return mp_const_none; } diff --git a/stmhal/main.c b/stmhal/main.c index 32baae532..244622503 100644 --- a/stmhal/main.c +++ b/stmhal/main.c @@ -44,6 +44,7 @@ #include "pendsv.h" #include "gccollect.h" #include "readline.h" +#include "modmachine.h" #include "i2c.h" #include "spi.h" #include "uart.h" @@ -410,6 +411,8 @@ soft_reset: led_state(4, 0); uint reset_mode = update_reset_mode(1); + machine_init(); + #if MICROPY_HW_ENABLE_RTC if (first_soft_reset) { rtc_init_start(false); diff --git a/stmhal/modmachine.c b/stmhal/modmachine.c index 0b01058fa..ca17eff80 100644 --- a/stmhal/modmachine.c +++ b/stmhal/modmachine.c @@ -44,6 +44,50 @@ #include "rtc.h" #include "i2c.h" #include "spi.h" +#include "wdt.h" + +#if defined(MCU_SERIES_F4) +// the HAL does not define these constants +#define RCC_CSR_IWDGRSTF (0x20000000) +#define RCC_CSR_PINRSTF (0x04000000) +#elif defined(MCU_SERIES_L4) +// L4 does not have a POR, so use BOR instead +#define RCC_CSR_PORRSTF RCC_CSR_BORRSTF +#endif + +#define PYB_RESET_SOFT (0) +#define PYB_RESET_POWER_ON (1) +#define PYB_RESET_HARD (2) +#define PYB_RESET_WDT (3) +#define PYB_RESET_DEEPSLEEP (4) + +STATIC uint32_t reset_cause; + +void machine_init(void) { + #if defined(MCU_SERIES_F4) + if (PWR->CSR & PWR_CSR_SBF) { + // came out of standby + reset_cause = PYB_RESET_DEEPSLEEP; + PWR->CR = PWR_CR_CSBF; + } else + #endif + { + // get reset cause from RCC flags + uint32_t state = RCC->CSR; + if (state & RCC_CSR_IWDGRSTF || state & RCC_CSR_WWDGRSTF) { + reset_cause = PYB_RESET_WDT; + } else if (state & RCC_CSR_PORRSTF || state & RCC_CSR_BORRSTF) { + reset_cause = PYB_RESET_POWER_ON; + } else if (state & RCC_CSR_PINRSTF) { + reset_cause = PYB_RESET_HARD; + } else { + // default is soft reset + reset_cause = PYB_RESET_SOFT; + } + } + // clear RCC reset flags + RCC->CSR = RCC_CSR_RMVF; +} // machine.info([dump_alloc_table]) // Print out lots of information about the board. @@ -447,13 +491,10 @@ STATIC mp_obj_t machine_deepsleep(void) { } MP_DEFINE_CONST_FUN_OBJ_0(machine_deepsleep_obj, machine_deepsleep); -#if 0 STATIC mp_obj_t machine_reset_cause(void) { - return mp_obj_new_int(0); - //return mp_obj_new_int(pyb_sleep_get_reset_cause()); + return MP_OBJ_NEW_SMALL_INT(reset_cause); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause); -#endif STATIC const mp_map_elem_t machine_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_umachine) }, @@ -468,8 +509,8 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_idle), (mp_obj_t)&pyb_wfi_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&machine_sleep_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_deepsleep), (mp_obj_t)&machine_deepsleep_obj }, -#if 0 { MP_OBJ_NEW_QSTR(MP_QSTR_reset_cause), (mp_obj_t)&machine_reset_cause_obj }, +#if 0 { MP_OBJ_NEW_QSTR(MP_QSTR_wake_reason), (mp_obj_t)&machine_wake_reason_obj }, #endif @@ -490,10 +531,10 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = { // initialize master mode on the peripheral. { MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&machine_i2c_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_SPI), (mp_obj_t)&pyb_spi_type }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WDT), (mp_obj_t)&pyb_wdt_type }, #if 0 { MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&pyb_uart_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_Timer), (mp_obj_t)&pyb_timer_type }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WDT), (mp_obj_t)&pyb_wdt_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_HeartBeat), (mp_obj_t)&pyb_heartbeat_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sd_type }, @@ -501,11 +542,13 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_IDLE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) }, { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_POWER_ON), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_HARD_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HARD_RESET) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WDT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WDT_RESET) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HIB_RESET) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SOFT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_SOFT_RESET) }, +#endif + { MP_OBJ_NEW_QSTR(MP_QSTR_PWRON_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_POWER_ON) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_HARD_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_HARD) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WDT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_WDT) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_DEEPSLEEP) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SOFT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_SOFT) }, +#if 0 { MP_OBJ_NEW_QSTR(MP_QSTR_WLAN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_WLAN) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PIN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_GPIO) }, { MP_OBJ_NEW_QSTR(MP_QSTR_RTC_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_RTC) }, diff --git a/stmhal/modmachine.h b/stmhal/modmachine.h index 981728c27..042afb850 100644 --- a/stmhal/modmachine.h +++ b/stmhal/modmachine.h @@ -31,6 +31,8 @@ #include "py/nlr.h" #include "py/obj.h" +void machine_init(void); + MP_DECLARE_CONST_FUN_OBJ(machine_info_obj); MP_DECLARE_CONST_FUN_OBJ(machine_unique_id_obj); MP_DECLARE_CONST_FUN_OBJ(machine_reset_obj); diff --git a/stmhal/wdt.c b/stmhal/wdt.c new file mode 100644 index 000000000..d9a089d01 --- /dev/null +++ b/stmhal/wdt.c @@ -0,0 +1,108 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <stdio.h> + +#include STM32_HAL_H + +#include "py/runtime.h" +#include "wdt.h" + +typedef struct _pyb_wdt_obj_t { + mp_obj_base_t base; +} pyb_wdt_obj_t; + +STATIC pyb_wdt_obj_t pyb_wdt = {{&pyb_wdt_type}}; + +STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + // parse arguments + enum { ARG_id, ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_timeout, MP_ARG_INT, {.u_int = 5000} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t id = args[ARG_id].u_int; + if (id != 0) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "WDT(%d) does not exist", id)); + } + + // timeout is in milliseconds + mp_int_t timeout = args[ARG_timeout].u_int; + + // compute prescaler + uint32_t prescaler; + for (prescaler = 0; prescaler < 6 && timeout >= 512; ++prescaler, timeout /= 2) { + } + + // convert milliseconds to ticks + timeout *= 8; // 32kHz / 4 = 8 ticks per millisecond (approx) + if (timeout <= 0) { + mp_raise_ValueError("WDT timeout too short"); + } else if (timeout > 0xfff) { + mp_raise_ValueError("WDT timeout too long"); + } + timeout -= 1; + + // set the reload register + while (IWDG->SR & 2) { + } + IWDG->KR = 0x5555; + IWDG->RLR = timeout; + + // set the prescaler + while (IWDG->SR & 1) { + } + IWDG->KR = 0x5555; + IWDG->PR = prescaler; + + // start the watch dog + IWDG->KR = 0xcccc; + + return (mp_obj_t)&pyb_wdt; +} + +STATIC mp_obj_t pyb_wdt_feed(mp_obj_t self_in) { + (void)self_in; + IWDG->KR = 0xaaaa; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_wdt_feed_obj, pyb_wdt_feed); + +STATIC const mp_map_elem_t pyb_wdt_locals_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_feed), (mp_obj_t)&pyb_wdt_feed_obj }, +}; + +STATIC MP_DEFINE_CONST_DICT(pyb_wdt_locals_dict, pyb_wdt_locals_dict_table); + +const mp_obj_type_t pyb_wdt_type = { + { &mp_type_type }, + .name = MP_QSTR_WDT, + .make_new = pyb_wdt_make_new, + .locals_dict = (mp_obj_t)&pyb_wdt_locals_dict, +}; diff --git a/stmhal/wdt.h b/stmhal/wdt.h new file mode 100644 index 000000000..362d6ef68 --- /dev/null +++ b/stmhal/wdt.h @@ -0,0 +1,27 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +extern const mp_obj_type_t pyb_wdt_type; |
