STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { // parse args mp_arg_val_t vals[PYB_TIMER_INIT_NUM_ARGS]; mp_arg_parse_all(n_args, args, kw_args, PYB_TIMER_INIT_NUM_ARGS, pyb_timer_init_args, vals); FTM_HandleTypeDef *ftm = &self->ftm; // set the TIM configuration values FTM_Base_InitTypeDef *init = &ftm->Init; if (vals[0].u_int != 0xffffffff) { // set prescaler and period from frequency if (vals[0].u_int == 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "can't have 0 frequency")); } uint32_t period = MAX(1, F_BUS / vals[0].u_int); uint32_t prescaler_shift = 0; while (period > 0xffff && prescaler_shift < 7) { period >>= 1; prescaler_shift++; } if (period > 0xffff) { period = 0xffff; } init->PrescalerShift = prescaler_shift; init->Period = period; } else if (vals[1].u_int != 0xffffffff && vals[2].u_int != 0xffffffff) {
STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { // parse args mp_arg_val_t vals[PYB_UART_INIT_NUM_ARGS]; mp_arg_parse_all(n_args, args, kw_args, PYB_UART_INIT_NUM_ARGS, pyb_uart_init_args, vals); // set the UART configuration values memset(&self->uart, 0, sizeof(self->uart)); UART_InitTypeDef *init = &self->uart.Init; init->BaudRate = vals[0].u_int; init->WordLength = vals[1].u_int == 8 ? UART_WORDLENGTH_8B : UART_WORDLENGTH_9B; switch (vals[2].u_int) { case 1: init->StopBits = UART_STOPBITS_1; break; default: init->StopBits = UART_STOPBITS_2; break; } if (vals[3].u_obj == mp_const_none) { init->Parity = UART_PARITY_NONE; } else { machine_int_t parity = mp_obj_get_int(vals[3].u_obj); init->Parity = (parity & 1) ? UART_PARITY_ODD : UART_PARITY_EVEN; } init->Mode = UART_MODE_TX_RX; init->HwFlowCtl = UART_HWCONTROL_NONE; init->OverSampling = UART_OVERSAMPLING_16; // init UART (if it fails, it's because the port doesn't exist) if (!uart_init2(self)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "UART port %d does not exist", self->uart_id)); } return mp_const_none; }
STATIC mp_obj_t pyb_uart_recv(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { // TODO assumes transmission size is 8-bits wide pyb_uart_obj_t *self = args[0]; // parse args mp_arg_val_t vals[PYB_UART_RECV_NUM_ARGS]; mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_UART_RECV_NUM_ARGS, pyb_uart_recv_args, vals); // get the buffer to receive into mp_buffer_info_t bufinfo; mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &bufinfo); // receive the data HAL_StatusTypeDef status = HAL_UART_Receive(&self->uart, bufinfo.buf, bufinfo.len, vals[1].u_int); if (status != HAL_OK) { // TODO really need a HardwareError object, or something nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "HAL_UART_Receive failed with code %d", status)); } // return the received data if (o_ret == MP_OBJ_NULL) { return vals[0].u_obj; } else { return mp_obj_str_builder_end(o_ret); } }
/// \method mem_write(data, addr, memaddr, timeout=5000, addr_size=8) /// /// Write to the memory of an I2C device: /// /// - `data` can be an integer or a buffer to write from /// - `addr` is the I2C device address /// - `memaddr` is the memory location within the I2C device /// - `timeout` is the timeout in milliseconds to wait for the write /// - `addr_size` selects width of memaddr: 8 or 16 bits /// /// Returns `None`. /// This is only valid in master mode. STATIC mp_obj_t pyb_i2c_mem_write(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { pyb_i2c_obj_t *self = args[0]; if (!in_master_mode(self)) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "I2C must be a master")); } // parse args (same as mem_read) mp_arg_val_t vals[PYB_I2C_MEM_READ_NUM_ARGS]; mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_MEM_READ_NUM_ARGS, pyb_i2c_mem_read_args, vals); // get the buffer to write from mp_buffer_info_t bufinfo; uint8_t data[1]; pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data); // get the addresses mp_uint_t i2c_addr = vals[1].u_int << 1; mp_uint_t mem_addr = vals[2].u_int; // determine width of mem_addr; default is 8 bits, entering any other value gives 16 bit width mp_uint_t mem_addr_size = I2C_MEMADD_SIZE_8BIT; if (vals[4].u_int != 8) { mem_addr_size = I2C_MEMADD_SIZE_16BIT; } HAL_StatusTypeDef status = HAL_I2C_Mem_Write(self->i2c, i2c_addr, mem_addr, mem_addr_size, bufinfo.buf, bufinfo.len, vals[3].u_int); if (status != HAL_OK) { // TODO really need a HardwareError object, or something nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "HAL_I2C_Mem_Write failed with code %d", status)); } return mp_const_none; }
STATIC mp_obj_t pyb_i2c_send(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { pyb_i2c_obj_t *self = args[0]; // parse args mp_arg_val_t vals[PYB_I2C_SEND_NUM_ARGS]; mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_SEND_NUM_ARGS, pyb_i2c_send_args, vals); // get the buffer to send from mp_buffer_info_t bufinfo; uint8_t data[1]; pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data); // send the data HAL_StatusTypeDef status; if (in_master_mode(self)) { if (vals[1].u_int == PYB_I2C_MASTER_ADDRESS) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "addr argument required")); } mp_uint_t i2c_addr = vals[1].u_int << 1; status = HAL_I2C_Master_Transmit(self->i2c, i2c_addr, bufinfo.buf, bufinfo.len, vals[2].u_int); } else { status = HAL_I2C_Slave_Transmit(self->i2c, bufinfo.buf, bufinfo.len, vals[2].u_int); } if (status != HAL_OK) { // TODO really need a HardwareError object, or something nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "HAL_I2C_xxx_Transmit failed with code %d", status)); } return mp_const_none; }
STATIC mp_obj_t pyb_i2c_recv(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { pyb_i2c_obj_t *self = args[0]; // parse args mp_arg_val_t vals[PYB_I2C_RECV_NUM_ARGS]; mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_RECV_NUM_ARGS, pyb_i2c_recv_args, vals); // get the buffer to receive into mp_buffer_info_t bufinfo; mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &bufinfo); // receive the data HAL_StatusTypeDef status; if (in_master_mode(self)) { if (vals[1].u_int == PYB_I2C_MASTER_ADDRESS) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "addr argument required")); } mp_uint_t i2c_addr = vals[1].u_int << 1; status = HAL_I2C_Master_Receive(self->i2c, i2c_addr, bufinfo.buf, bufinfo.len, vals[2].u_int); } else { status = HAL_I2C_Slave_Receive(self->i2c, bufinfo.buf, bufinfo.len, vals[2].u_int); } if (status != HAL_OK) { // TODO really need a HardwareError object, or something nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "HAL_I2C_xxx_Receive failed with code %d", status)); } // return the received data if (o_ret == MP_OBJ_NULL) { return vals[0].u_obj; } else { return mp_obj_str_builder_end(o_ret); } }
STATIC mp_obj_t wlan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { // parse args mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args); mp_arg_val_t args[MP_ARRAY_SIZE(wlan_init_args)]; mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), wlan_init_args, args); // setup the object wlan_obj_t *self = &wlan_obj; self->base.type = (mp_obj_t)&mod_network_nic_type_wlan; // give it to the sleep module pyb_sleep_set_wlan_obj(self); if (n_args > 1 || n_kw > 0) { // check the peripheral id if (args[0].u_int != 0) { mp_raise_OSError(MP_ENODEV); } // start the peripheral wlan_init_helper(self, &args[1]); } return (mp_obj_t)self; }
STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { // parse args mp_arg_val_t vals[PYB_I2C_INIT_NUM_ARGS]; mp_arg_parse_all(n_args, args, kw_args, PYB_I2C_INIT_NUM_ARGS, pyb_i2c_init_args, vals); // set the I2C configuration values I2C_InitTypeDef *init = &self->i2c->Init; if (vals[0].u_int == PYB_I2C_MASTER) { // use a special address to indicate we are a master init->OwnAddress1 = PYB_I2C_MASTER_ADDRESS; } else { init->OwnAddress1 = (vals[1].u_int << 1) & 0xfe; } init->AddressingMode = I2C_ADDRESSINGMODE_7BIT; init->ClockSpeed = MIN(vals[2].u_int, 400000); init->DualAddressMode = I2C_DUALADDRESS_DISABLED; init->DutyCycle = I2C_DUTYCYCLE_16_9; init->GeneralCallMode = vals[3].u_bool ? I2C_GENERALCALL_ENABLED : I2C_GENERALCALL_DISABLED; init->NoStretchMode = I2C_NOSTRETCH_DISABLED; init->OwnAddress2 = 0xfe; // unused // init the I2C bus i2c_init(self->i2c); return mp_const_none; }
STATIC mp_obj_t pyb_uart_send(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { // TODO assumes transmission size is 8-bits wide pyb_uart_obj_t *self = args[0]; // parse args mp_arg_val_t vals[PYB_UART_SEND_NUM_ARGS]; mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_UART_SEND_NUM_ARGS, pyb_uart_send_args, vals); #if 0 // get the buffer to send from mp_buffer_info_t bufinfo; uint8_t data[1]; pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data); // send the data HAL_StatusTypeDef status = HAL_UART_Transmit(&self->uart, bufinfo.buf, bufinfo.len, vals[1].u_int); if (status != HAL_OK) { // TODO really need a HardwareError object, or something nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "HAL_UART_Transmit failed with code %d", status)); } #else (void)self; #endif return mp_const_none; }
STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // parse args mp_arg_val_t args[pin_INIT_NUM_ARGS]; mp_arg_parse_all(n_args, pos_args, kw_args, pin_INIT_NUM_ARGS, pin_init_args, args); // get the io mode uint mode = args[0].u_int; pin_validate_mode(mode); // get the pull type uint pull; if (args[1].u_obj == mp_const_none) { pull = PIN_TYPE_STD; } else { pull = mp_obj_get_int(args[1].u_obj); pin_validate_pull (pull); } // get the value int value = -1; if (args[2].u_obj != MP_OBJ_NULL) { if (mp_obj_is_true(args[2].u_obj)) { value = 1; } else { value = 0; } } // get the strenght uint strength = args[3].u_int; pin_validate_drive(strength); // get the alternate function int af = args[4].u_int; if (mode != GPIO_DIR_MODE_ALT && mode != GPIO_DIR_MODE_ALT_OD) { if (af == -1) { af = 0; } else { goto invalid_args; } } else if (af < -1 || af > 15) { goto invalid_args; } // check for a valid af and then free it from any other pins if (af > PIN_MODE_0) { uint8_t fn, unit, type; pin_validate_af (self, af, &fn, &unit, &type); pin_free_af_from_pins(fn, unit, type); } pin_config (self, af, mode, pull, value, strength); return mp_const_none; invalid_args: nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); }
/** * Create a new Pin object associated with the id. If additional * arguments are given, they are used to initialise the pin. See * `init`. */ static mp_obj_t class_pin_make_new(const mp_obj_type_t *type_p, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args_p) { struct class_pin_t *self_p; mp_map_t kwargs; static const mp_arg_t allowed_args[] = { { MP_QSTR_device, MP_ARG_REQUIRED | MP_ARG_INT }, { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT } }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; int device; int mode; mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); /* Parse args. */ mp_map_init(&kwargs, 0); mp_arg_parse_all(n_args, args_p, &kwargs, MP_ARRAY_SIZE(allowed_args), allowed_args, args); device = args[0].u_int; mode = args[1].u_int; if ((device < 0) || (device >= PIN_DEVICE_MAX)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "bad pin device %d", device)); } if ((mode != PIN_INPUT) && (mode != PIN_OUTPUT)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "bad pin mode %d", mode)); } /* Create a new Pin object. */ self_p = m_new0(struct class_pin_t, 1); self_p->base.type = &module_drivers_class_pin; if (pin_init((struct pin_driver_t *)&self_p->drv, &pin_device[device], mode) != 0) { return (mp_const_none); } return (self_p); }
STATIC mp_obj_t pyb_usb_vcp_send(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // parse args mp_arg_val_t vals[PYB_USB_VCP_SEND_NUM_ARGS]; mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_USB_VCP_SEND_NUM_ARGS, pyb_usb_vcp_send_args, vals); // get the buffer to send from mp_buffer_info_t bufinfo; uint8_t data[1]; pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data); // send the data int ret = USBD_CDC_Tx(bufinfo.buf, bufinfo.len, vals[1].u_int); return mp_obj_new_int(ret); }
STATIC mp_obj_t pyb_sd_make_new (const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) { // parse args mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args); mp_arg_val_t args[MP_ARRAY_SIZE(pyb_sd_init_args)]; mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_sd_init_args, args); // check the peripheral id if (args[0].u_int != 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable)); } // setup and initialize the object mp_obj_t self = &pybsd_obj; pybsd_obj.base.type = &pyb_sd_type; pyb_sd_init_helper (self, &args[1]); return self; }
STATIC mp_obj_t pyb_sd_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { // parse args mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args); mp_arg_val_t args[MP_ARRAY_SIZE(pyb_sd_init_args)]; mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_sd_init_args, args); // check the peripheral id if (args[0].u_int != 0) { mp_raise_OSError(MP_ENODEV); } // setup and initialize the object mp_obj_t self = &pybsd_obj; pybsd_obj.base.type = &pyb_sd_type; pyb_sd_init_helper (self, &args[1]); return self; }
/** * Create a new Sd object. */ static mp_obj_t class_sd_make_new(const mp_obj_type_t *type_p, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args_p) { static const mp_arg_t allowed_args[] = { { MP_QSTR_spi, MP_ARG_REQUIRED | MP_ARG_OBJ } }; struct class_sd_t *self_p; mp_map_t kwargs; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; struct class_spi_t *spi_p; mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); /* Parse the arguments. */ mp_map_init(&kwargs, 0); mp_arg_parse_all(n_args, args_p, &kwargs, MP_ARRAY_SIZE(allowed_args), allowed_args, args); /* Validate SPI driver argument. */ spi_p = args[0].u_obj; if (spi_p->base.type != &module_drivers_class_spi) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "expected spi driver")); } /* Create a new SD object. */ self_p = m_new_obj(struct class_sd_t); self_p->base.type = &module_drivers_class_sd; self_p->spi_p = spi_p; if (sd_init(&self_p->drv, &spi_p->drv) != 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "sd_init() failed")); } return (self_p); }
/// \method recv(data, *, timeout=5000) /// /// Receive data on the bus: /// /// - `data` can be an integer, which is the number of bytes to receive, /// or a mutable buffer, which will be filled with received bytes. /// - `timeout` is the timeout in milliseconds to wait for the receive. /// /// Return value: if `data` is an integer then a new buffer of the bytes received, /// otherwise the number of bytes read into `data` is returned. STATIC mp_obj_t pyb_usb_vcp_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // parse args mp_arg_val_t vals[PYB_USB_VCP_SEND_NUM_ARGS]; mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_USB_VCP_SEND_NUM_ARGS, pyb_usb_vcp_send_args, vals); // get the buffer to receive into mp_buffer_info_t bufinfo; mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &bufinfo); // receive the data int ret = USBD_CDC_Rx(bufinfo.buf, bufinfo.len, vals[1].u_int); // return the received data if (o_ret == MP_OBJ_NULL) { return mp_obj_new_int(ret); // number of bytes read into given buffer } else { return mp_obj_str_builder_end_with_len(o_ret, ret); // create a new buffer } }
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) { // check the arguments mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args); mp_arg_val_t args[MP_ARRAY_SIZE(pyb_wdt_init_args)]; mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_wdt_init_args, args); if (args[0].u_obj != mp_const_none && mp_obj_get_int(args[0].u_obj) > 0) { mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable); } uint timeout_ms = args[1].u_int; if (timeout_ms < PYBWDT_MIN_TIMEOUT_MS) { mp_raise_ValueError(mpexception_value_invalid_arguments); } if (pyb_wdt_obj.running) { mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible); } // Enable the WDT peripheral clock MAP_PRCMPeripheralClkEnable(PRCM_WDT, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK); // Unlock to be able to configure the registers MAP_WatchdogUnlock(WDT_BASE); #ifdef DEBUG // make the WDT stall when the debugger stops on a breakpoint MAP_WatchdogStallEnable (WDT_BASE); #endif // set the watchdog timer reload value // the WDT trigger a system reset after the second timeout // so, divide by 2 the timeout value received MAP_WatchdogReloadSet(WDT_BASE, PYBWDT_MILLISECONDS_TO_TICKS(timeout_ms / 2)); // start the timer. Once it's started, it cannot be disabled. MAP_WatchdogEnable(WDT_BASE); pyb_wdt_obj.base.type = &pyb_wdt_type; pyb_wdt_obj.running = true; return (mp_obj_t)&pyb_wdt_obj; }
STATIC mp_obj_t network_server_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { // parse args mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args); mp_arg_val_t args[MP_ARRAY_SIZE(network_server_args)]; mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), network_server_args, args); // check the server id if (args[0].u_obj != MP_OBJ_NULL) { if (mp_obj_get_int(args[0].u_obj) != 0) { mp_raise_OSError(MP_ENODEV); } } // setup the object and initialize it network_server_obj_t *self = &network_server_obj; self->base.type = &network_server_type; network_server_init_helper(self, &args[1]); return (mp_obj_t)self; }
STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // parse args mp_arg_val_t vals[PYB_TIMER_INIT_NUM_ARGS]; mp_arg_parse_all(n_args, args, kw_args, PYB_TIMER_INIT_NUM_ARGS, pyb_timer_init_args, vals); // set the TIM configuration values TIM_Base_InitTypeDef *init = &self->tim.Init; if (vals[0].u_int != 0xffffffff) { // set prescaler and period from frequency if (vals[0].u_int == 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "can't have 0 frequency")); } // work out TIM's clock source uint tim_clock; if (self->tim_id == 1 || (8 <= self->tim_id && self->tim_id <= 11)) { // TIM{1,8,9,10,11} are on APB2 tim_clock = HAL_RCC_GetPCLK2Freq(); } else { // TIM{2,3,4,5,6,7,12,13,14} are on APB1 tim_clock = HAL_RCC_GetPCLK1Freq(); } // Compute the prescaler value so TIM triggers at freq-Hz // On STM32F405/407/415/417 there are 2 cases for how the clock freq is set. // If the APB prescaler is 1, then the timer clock is equal to its respective // APB clock. Otherwise (APB prescaler > 1) the timer clock is twice its // respective APB clock. See DM00031020 Rev 4, page 115. uint32_t period = MAX(1, 2 * tim_clock / vals[0].u_int); uint32_t prescaler = 1; while (period > TIMER_CNT_MASK(self)) { period >>= 1; prescaler <<= 1; } init->Prescaler = prescaler - 1; init->Period = period - 1; } else if (vals[1].u_int != 0xffffffff && vals[2].u_int != 0xffffffff) {
STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // parse args mp_arg_val_t args[pin_INIT_NUM_ARGS]; mp_arg_parse_all(n_args, pos_args, kw_args, pin_INIT_NUM_ARGS, pin_init_args, args); // get the af uint af = args[0].u_int; if (af < PIN_MODE_0 || af > PIN_MODE_15) { goto invalid_args; } // get the io mode uint mode = args[1].u_int; // checking the mode only makes sense if af == GPIO if (af == PIN_MODE_0) { if (mode != GPIO_DIR_MODE_IN && mode != GPIO_DIR_MODE_OUT) { goto invalid_args; } } // get the type uint type = args[2].u_int; if (type != PIN_TYPE_STD && type != PIN_TYPE_STD_PU && type != PIN_TYPE_STD_PD && type != PIN_TYPE_OD && type != PIN_TYPE_OD_PU && type != PIN_TYPE_OD_PD) { goto invalid_args; } // get the strenght uint strength = args[3].u_int; if (strength != PIN_STRENGTH_2MA && strength != PIN_STRENGTH_4MA && strength != PIN_STRENGTH_6MA) { goto invalid_args; } // configure the pin as requested pin_config (self, af, mode, type, strength); return mp_const_none; invalid_args: nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); }
STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { // parse args mp_arg_val_t vals[PYB_TIMER_INIT_NUM_ARGS]; mp_arg_parse_all(n_args, args, kw_args, PYB_TIMER_INIT_NUM_ARGS, pyb_timer_init_args, vals); // set the TIM configuration values TIM_Base_InitTypeDef *init = &self->tim.Init; if (vals[0].u_int != 0xffffffff) { // set prescaler and period from frequency if (vals[0].u_int == 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "can't have 0 frequency")); } // work out TIM's clock source uint tim_clock; if (self->tim_id == 1 || (8 <= self->tim_id && self->tim_id <= 11)) { // TIM{1,8,9,10,11} are on APB2 tim_clock = HAL_RCC_GetPCLK2Freq(); } else { // TIM{2,3,4,5,6,7,12,13,14} are on APB1 tim_clock = HAL_RCC_GetPCLK1Freq(); } // compute the prescaler value so TIM triggers at freq-Hz // dpgeorge: I don't understand why we need to multiply tim_clock by 2 uint32_t period = MAX(1, 2 * tim_clock / vals[0].u_int); uint32_t prescaler = 1; while (period > 0xffff) { period >>= 1; prescaler <<= 1; } init->Prescaler = prescaler - 1; init->Period = period - 1; } else if (vals[1].u_int != 0xffffffff && vals[2].u_int != 0xffffffff) {
// Factory function for I/O stream classes mp_obj_t mp_builtin_open(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { // TODO: analyze buffering args and instantiate appropriate type mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS]; mp_arg_parse_all(n_args, args, kwargs, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals); return fdfile_open((mp_obj_t)&mp_type_textio, arg_vals); }
STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bool success; // parse args mp_arg_val_t args[MP_ARRAY_SIZE(pyb_uart_init_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(pyb_uart_init_args), pyb_uart_init_args, args); // set the UART configuration values if (n_args > 1) { self->baudrate = args[0].u_int; switch (args[1].u_int) { case 5: self->config = UART_CONFIG_WLEN_5; break; case 6: self->config = UART_CONFIG_WLEN_6; break; case 7: self->config = UART_CONFIG_WLEN_7; break; case 8: self->config = UART_CONFIG_WLEN_8; break; default: nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); break; } // Parity if (args[2].u_obj == mp_const_none) { self->config |= UART_CONFIG_PAR_NONE; } else { self->config |= ((mp_obj_get_int(args[2].u_obj) & 1) ? UART_CONFIG_PAR_ODD : UART_CONFIG_PAR_EVEN); } // Stop bits self->config |= (args[3].u_int == 1 ? UART_CONFIG_STOP_ONE : UART_CONFIG_STOP_TWO); // Flow control self->flowcontrol = args[4].u_int; success = uart_init2(self); } else { success = uart_init(self, args[0].u_int); } // init UART (if it fails, something weird happened) if (!success) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); } // set timeouts self->timeout = args[5].u_int; self->timeout_char = args[6].u_int; // setup the read buffer m_del(byte, self->read_buf, self->read_buf_len); self->read_buf_head = 0; self->read_buf_tail = 0; if (args[7].u_int <= 0) { // no read buffer self->read_buf_len = 0; self->read_buf = NULL; MAP_UARTIntDisable(self->reg, UART_INT_RX | UART_INT_RT); } else { // read buffer using interrupts self->read_buf_len = args[7].u_int; self->read_buf = m_new(byte, args[7].u_int); } return mp_const_none; }
STATIC mp_obj_t network_server_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // parse args mp_arg_val_t args[MP_ARRAY_SIZE(network_server_args) - 1]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &network_server_args[1], args); return network_server_init_helper(pos_args[0], args); }
/// \method irq(trigger, priority, handler, wake) STATIC mp_obj_t pin_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); pin_obj_t *self = pos_args[0]; // convert the priority to the correct value uint priority = mp_irq_translate_priority (args[1].u_int); // verify and translate the interrupt mode uint mp_trigger = mp_obj_get_int(args[0].u_obj); uint trigger; if (mp_trigger == (PYB_PIN_FALLING_EDGE | PYB_PIN_RISING_EDGE)) { trigger = GPIO_BOTH_EDGES; } else { switch (mp_trigger) { case PYB_PIN_FALLING_EDGE: trigger = GPIO_FALLING_EDGE; break; case PYB_PIN_RISING_EDGE: trigger = GPIO_RISING_EDGE; break; case PYB_PIN_LOW_LEVEL: trigger = GPIO_LOW_LEVEL; break; case PYB_PIN_HIGH_LEVEL: trigger = GPIO_HIGH_LEVEL; break; default: goto invalid_args; } } uint8_t pwrmode = (args[3].u_obj == mp_const_none) ? PYB_PWR_MODE_ACTIVE : mp_obj_get_int(args[3].u_obj); if (pwrmode > (PYB_PWR_MODE_ACTIVE | PYB_PWR_MODE_LPDS | PYB_PWR_MODE_HIBERNATE)) { goto invalid_args; } // get the wake info from this pin uint hib_pin, idx; pin_get_hibernate_pin_and_idx ((const pin_obj_t *)self, &hib_pin, &idx); if (pwrmode & PYB_PWR_MODE_LPDS) { if (idx >= PYBPIN_NUM_WAKE_PINS) { goto invalid_args; } // wake modes are different in LDPS uint wake_mode; switch (trigger) { case GPIO_FALLING_EDGE: wake_mode = PRCM_LPDS_FALL_EDGE; break; case GPIO_RISING_EDGE: wake_mode = PRCM_LPDS_RISE_EDGE; break; case GPIO_LOW_LEVEL: wake_mode = PRCM_LPDS_LOW_LEVEL; break; case GPIO_HIGH_LEVEL: wake_mode = PRCM_LPDS_HIGH_LEVEL; break; default: goto invalid_args; break; } // first clear the lpds value from all wake-able pins for (uint i = 0; i < PYBPIN_NUM_WAKE_PINS; i++) { pybpin_wake_pin[i].lpds = PYBPIN_WAKES_NOT; } // enable this pin as a wake-up source during LPDS pybpin_wake_pin[idx].lpds = wake_mode; } else if (idx < PYBPIN_NUM_WAKE_PINS) { // this pin was the previous LPDS wake source, so disable it completely if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) { MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_GPIO); } pybpin_wake_pin[idx].lpds = PYBPIN_WAKES_NOT; } if (pwrmode & PYB_PWR_MODE_HIBERNATE) { if (idx >= PYBPIN_NUM_WAKE_PINS) { goto invalid_args; } // wake modes are different in hibernate uint wake_mode; switch (trigger) { case GPIO_FALLING_EDGE: wake_mode = PRCM_HIB_FALL_EDGE; break; case GPIO_RISING_EDGE: wake_mode = PRCM_HIB_RISE_EDGE; break; case GPIO_LOW_LEVEL: wake_mode = PRCM_HIB_LOW_LEVEL; break; case GPIO_HIGH_LEVEL: wake_mode = PRCM_HIB_HIGH_LEVEL; break; default: goto invalid_args; break; } // enable this pin as wake-up source during hibernate pybpin_wake_pin[idx].hib = wake_mode; } else if (idx < PYBPIN_NUM_WAKE_PINS) { pybpin_wake_pin[idx].hib = PYBPIN_WAKES_NOT; } // we need to update the callback atomically, so we disable the // interrupt before we update anything. pin_irq_disable(self); if (pwrmode & PYB_PWR_MODE_ACTIVE) { // register the interrupt pin_extint_register((pin_obj_t *)self, trigger, priority); if (idx < PYBPIN_NUM_WAKE_PINS) { pybpin_wake_pin[idx].active = true; } } else if (idx < PYBPIN_NUM_WAKE_PINS) { pybpin_wake_pin[idx].active = false; } // all checks have passed, we can create the irq object mp_obj_t _irq = mp_irq_new (self, args[2].u_obj, &pin_irq_methods); if (pwrmode & PYB_PWR_MODE_LPDS) { pyb_sleep_set_gpio_lpds_callback (_irq); } // save the mp_trigge for later self->irq_trigger = mp_trigger; // enable the interrupt just before leaving pin_irq_enable(self); return _irq; invalid_args: nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); }
STATIC mp_obj_t pyb_sd_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // parse args mp_arg_val_t args[MP_ARRAY_SIZE(pyb_sd_init_args) - 1]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_sd_init_args[1], args); return pyb_sd_init_helper(pos_args[0], args); }
mp_obj_t pyb_dac_write_timed(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { pyb_dac_obj_t *self = args[0]; // parse args mp_arg_val_t vals[PYB_DAC_WRITE_TIMED_NUM_ARGS]; mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_DAC_WRITE_TIMED_NUM_ARGS, pyb_dac_write_timed_args, vals); // get the data to write mp_buffer_info_t bufinfo; mp_get_buffer_raise(vals[0].u_obj, &bufinfo, MP_BUFFER_READ); // set TIM6 to trigger the DAC at the given frequency TIM6_Config(vals[1].u_int); __DMA1_CLK_ENABLE(); /* DMA_Cmd(self->dma_stream, DISABLE); while (DMA_GetCmdStatus(self->dma_stream) != DISABLE) { } DAC_Cmd(self->dac_channel, DISABLE); */ /* // DAC channel configuration DAC_InitTypeDef DAC_InitStructure; DAC_InitStructure.DAC_Trigger = DAC_Trigger_T7_TRGO; DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1; // unused, but need to set it to a valid value DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; DAC_Init(self->dac_channel, &DAC_InitStructure); */ // DMA1_Stream[67] channel7 configuration DMA_HandleTypeDef DMA_Handle; DMA_Handle.Instance = self->dma_stream; // Need to deinit DMA first DMA_Handle.State = HAL_DMA_STATE_READY; HAL_DMA_DeInit(&DMA_Handle); DMA_Handle.Init.Channel = DMA_CHANNEL_7; DMA_Handle.Init.Direction = DMA_MEMORY_TO_PERIPH; DMA_Handle.Init.PeriphInc = DMA_PINC_DISABLE; DMA_Handle.Init.MemInc = DMA_MINC_ENABLE; DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; DMA_Handle.Init.Mode = vals[2].u_int; DMA_Handle.Init.Priority = DMA_PRIORITY_HIGH; DMA_Handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; DMA_Handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL; DMA_Handle.Init.MemBurst = DMA_MBURST_SINGLE; DMA_Handle.Init.PeriphBurst = DMA_PBURST_SINGLE; HAL_DMA_Init(&DMA_Handle); if (self->dac_channel == DAC_CHANNEL_1) { __HAL_LINKDMA(&DAC_Handle, DMA_Handle1, DMA_Handle); } else { __HAL_LINKDMA(&DAC_Handle, DMA_Handle2, DMA_Handle); } DAC_Handle.Instance = DAC; DAC_Handle.State = HAL_DAC_STATE_RESET; HAL_DAC_Init(&DAC_Handle); if (self->state != 3) { DAC_ChannelConfTypeDef config; config.DAC_Trigger = DAC_TRIGGER_T6_TRGO; config.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel); self->state = 3; } HAL_DAC_Start_DMA(&DAC_Handle, self->dac_channel, (uint32_t*)bufinfo.buf, bufinfo.len, DAC_ALIGN_8B_R); /* // enable DMA stream DMA_Cmd(self->dma_stream, ENABLE); while (DMA_GetCmdStatus(self->dma_stream) == DISABLE) { } // enable DAC channel DAC_Cmd(self->dac_channel, ENABLE); // enable DMA for DAC channel DAC_DMACmd(self->dac_channel, ENABLE); */ //printf("DMA: %p %lu\n", bufinfo.buf, bufinfo.len); return mp_const_none; }
STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { // parse args mp_arg_val_t vals[PIN_INIT_NUM_ARGS]; mp_arg_parse_all(n_args, args, kw_args, PIN_INIT_NUM_ARGS, pin_init_args, vals); // get io mode uint mode = vals[0].u_int; if (!IS_GPIO_MODE(mode)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin mode: %d", mode)); } // get pull mode uint pull = vals[1].u_int; if (!IS_GPIO_PULL(pull)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin pull: %d", pull)); } // get af (alternate function) mp_int_t af = vals[2].u_int; if ((mode == GPIO_MODE_AF_PP || mode == GPIO_MODE_AF_OD) && !IS_GPIO_AF(af)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin af: %d", af)); } // enable the peripheral clock for the port of this pin switch (self->port) { #ifdef __GPIOA_CLK_ENABLE case PORT_A: __GPIOA_CLK_ENABLE(); break; #endif #ifdef __GPIOB_CLK_ENABLE case PORT_B: __GPIOB_CLK_ENABLE(); break; #endif #ifdef __GPIOC_CLK_ENABLE case PORT_C: __GPIOC_CLK_ENABLE(); break; #endif #ifdef __GPIOD_CLK_ENABLE case PORT_D: __GPIOD_CLK_ENABLE(); break; #endif #ifdef __GPIOE_CLK_ENABLE case PORT_E: __GPIOE_CLK_ENABLE(); break; #endif #ifdef __GPIOF_CLK_ENABLE case PORT_F: __GPIOF_CLK_ENABLE(); break; #endif #ifdef __GPIOG_CLK_ENABLE case PORT_G: __GPIOG_CLK_ENABLE(); break; #endif #ifdef __GPIOH_CLK_ENABLE case PORT_H: __GPIOH_CLK_ENABLE(); break; #endif #ifdef __GPIOI_CLK_ENABLE case PORT_I: __GPIOI_CLK_ENABLE(); break; #endif #ifdef __GPIOJ_CLK_ENABLE case PORT_J: __GPIOJ_CLK_ENABLE(); break; #endif } // configure the GPIO as requested GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Pin = self->pin_mask; GPIO_InitStructure.Mode = mode; GPIO_InitStructure.Pull = pull; GPIO_InitStructure.Speed = GPIO_SPEED_FAST; GPIO_InitStructure.Alternate = af; HAL_GPIO_Init(self->gpio, &GPIO_InitStructure); return mp_const_none; }
void mp_arg_parse_all_kw_array(uint n_pos, uint n_kw, const mp_obj_t *args, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals) { mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, args + n_pos); mp_arg_parse_all(n_pos, args, &kw_args, n_allowed, allowed, out_vals); }