Merge remote-tracking branch 'origin/main' into build-python3x

This commit is contained in:
Jeff Epler 2022-11-15 14:02:09 -06:00
commit 412df210ad
No known key found for this signature in database
GPG Key ID: D5BF15AB975AB4DE
15 changed files with 216 additions and 121 deletions

View File

@ -7,15 +7,15 @@ msgstr ""
"Project-Id-Version: circuitpython-cn\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
"PO-Revision-Date: 2022-08-20 14:09+0000\n"
"Last-Translator: hexthat <hexthat@gmail.com>\n"
"PO-Revision-Date: 2022-11-15 04:35+0000\n"
"Last-Translator: River Wang <urfdvw@gmail.com>\n"
"Language-Team: Chinese Hanyu Pinyin\n"
"Language: zh_Latn_pinyin\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 4.14-dev\n"
"X-Generator: Weblate 4.15-dev\n"
#: main.c
msgid ""
@ -127,7 +127,7 @@ msgstr "%q chūshǐhuà shībài"
#: shared-bindings/dualbank/__init__.c
msgid "%q is %q"
msgstr ""
msgstr "%q shì %q"
#: py/argcheck.c
msgid "%q length must be %d"
@ -173,6 +173,7 @@ msgstr "%q bìxū >= %d"
#: shared-bindings/audiocore/RawSample.c
msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'"
msgstr ""
"%q bì xū shì zì jié shù zǔ huò lèi xíng wéi 'h', 'H', 'b', huò 'B' de shù zǔ"
#: py/argcheck.c
msgid "%q must be a string"
@ -597,7 +598,7 @@ msgstr "RX hé TX dōu xū yào liúliàng kòngzhì"
#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h
#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h
msgid "Both buttons were pressed at start up.\n"
msgstr ""
msgstr "qǐ dòng shí àn xià le liǎng gè àn niǔ.\n"
#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
msgid "Both pins must support hardware interrupts"
@ -667,7 +668,7 @@ msgstr "Zǒngxiàn yǐnjiǎo %d yǐjīng zài shǐyòng zhōng"
#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h
#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h
msgid "Button A was pressed at start up.\n"
msgstr ""
msgstr "qǐ dòng shí àn xià àn niǔ A.\n"
#: shared-bindings/_bleio/UUID.c
msgid "Byte buffer must be 16 bytes."
@ -740,12 +741,13 @@ msgid "Cannot get temperature"
msgstr "Wúfǎ huòqǔ wēndù"
#: shared-bindings/_bleio/Adapter.c
#, fuzzy
msgid "Cannot have scan responses for extended, connectable advertisements."
msgstr "Nín wúfǎ sǎomiáo kuòzhǎn de, kě liánjiē de guǎnggào."
#: ports/espressif/common-hal/alarm/pin/PinAlarm.c
msgid "Cannot pull on input-only pin."
msgstr "wú fǎ lā dòng jǐn shū rù yǐn jiǎo."
msgstr "wúfǎ lādòng jǐn shūrù yǐnjiǎo."
#: shared-bindings/audiobusio/PDMIn.c
msgid "Cannot record to a file"
@ -753,7 +755,7 @@ msgstr "Wúfǎ jìlù dào wénjiàn"
#: shared-module/storage/__init__.c
msgid "Cannot remount '/' when visible via USB."
msgstr "tōng guò USB kě jiàn shí wú fǎ chóng xīn ān zhuāng '/'."
msgstr "tōngguò USB kějiàn shí wúfǎ chóngxīn ānzhuāng '/'."
#: ports/atmel-samd/common-hal/microcontroller/__init__.c
#: ports/cxd56/common-hal/microcontroller/__init__.c
@ -772,31 +774,31 @@ msgstr "Dāng fāngxiàng wéi shūrù shí, bùnéng shèzhì zhí."
#: ports/espressif/common-hal/busio/UART.c
#: ports/mimxrt10xx/common-hal/busio/UART.c
msgid "Cannot specify RTS or CTS in RS485 mode"
msgstr "wú fǎ zài RS485 mó shì xià zhǐ dìng RTS huò CTS"
msgstr "wúfǎ zài RS485 móshì xià zhǐdìng RTS huò CTS"
#: py/objslice.c
msgid "Cannot subclass slice"
msgstr "bùnéng zi lèi huà qiēpiàn"
msgstr "bùnéng zǐlèihuà qiēpiàn"
#: shared-module/bitbangio/SPI.c
msgid "Cannot transfer without MOSI and MISO pins"
msgstr "méiyǒu MOSI hé MISO yǐn jiǎo wúfǎ chuánshū"
msgstr "méiyǒu MOSI hé MISO yǐnjiǎo, wúfǎ chuánshū"
#: shared-bindings/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
msgstr "Wúfǎ gēnggǎi yǐ zài shǐyòng de jìshí qì shàng de pínlǜ"
msgstr "Wúfǎ zài shǐyòng zhōng de jìshí qì shàng gēnggǎi pínlǜ"
#: ports/nrf/common-hal/alarm/pin/PinAlarm.c
msgid "Cannot wake on pin edge, only level"
msgstr "wúfǎ zài yǐn jiǎo biānyuán huànxǐng, zhǐ néng diàn píng"
msgstr "wúfǎ shǐyòng biānyuán huànxǐng, zhǐnéng shǐyòng diànpíng"
#: ports/espressif/common-hal/alarm/pin/PinAlarm.c
msgid "Cannot wake on pin edge. Only level."
msgstr "wú fǎ zài yǐn jiǎo biān yuán huàn xǐng. jǐn jí bié."
msgstr "wúfǎ shǐyòng biānyuán huànxǐng. zhǐnéng shǐyòng diànpíng"
#: shared-bindings/_bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr "Wèi tígōng zìfú huǎncún xiě rù"
msgstr "Wèi tígōng zìfú huǎncún xiěrù"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython core code crashed hard. Whoops!\n"
@ -808,11 +810,11 @@ msgstr "CircuitPython wúfǎ fēnpèi duī."
#: shared-module/bitbangio/I2C.c
msgid "Clock stretch too long"
msgstr "Shízhōng shēnzhǎn tài zhǎng"
msgstr "shízhōng yánzhǎn guòcháng"
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Clock unit in use"
msgstr "Shǐyòng shízhōng dānwèi"
msgstr "shízhōng dānyuán zhèngzài shǐyòng zhōng"
#: shared-bindings/_bleio/Connection.c
msgid ""
@ -830,7 +832,7 @@ msgstr "wúfǎ jiǎnsuǒ shízhōng"
#: shared-bindings/_bleio/Adapter.c
msgid "Could not set address"
msgstr "wú fǎ shè zhì dì zhǐ"
msgstr "wúfǎ shèzhì dìzhǐ"
#: shared-bindings/pwmio/PWMOut.c
msgid "Could not start PWM"
@ -842,11 +844,11 @@ msgstr "Wúfǎ qǐdòng zhōngduàn,RX máng"
#: shared-module/audiomp3/MP3Decoder.c
msgid "Couldn't allocate decoder"
msgstr "Zhǎo bù dào jiěmǎ qì"
msgstr "wúfǎ fēnpèi jiěmǎ qì"
#: supervisor/shared/safe_mode.c
msgid "Crash into the HardFault_Handler."
msgstr "Zhuìhuǐ. Shūrù HardFault_Handler."
msgstr "gu4zhang4, jin4ru4 HardFault_Handler."
#: ports/stm/common-hal/analogio/AnalogOut.c
msgid "DAC Channel Init Error"
@ -858,10 +860,11 @@ msgstr "DAC shèbèi chūshǐhuà cuòwù"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "DAC already in use"
msgstr "Fā yuán huì yǐjīng shǐyòng"
msgstr "DAC zhèngzài bèi shǐyòng"
#: ports/atmel-samd/common-hal/paralleldisplay/ParallelBus.c
#: ports/nrf/common-hal/paralleldisplay/ParallelBus.c
#, fuzzy
msgid "Data 0 pin must be byte aligned"
msgstr "Shùjù 0 de yǐn jiǎo bìxū shì zì jié duìqí"
@ -871,6 +874,7 @@ msgstr "Shùjù kuài bìxū zūnxún fmt qū kuài"
#: ports/espressif/common-hal/_bleio/Adapter.c
#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy
msgid "Data not supported with directed advertising"
msgstr "bù zhī chí dìng xiàng guǎng gào de shù jù"
@ -946,15 +950,15 @@ msgstr "cuò wù: bǎng dìng shī bài"
#: shared-bindings/coproc/__init__.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
msgid "Expected a %q"
msgstr "Yùqí %q"
msgstr "Yù qí %q"
#: ports/raspberrypi/bindings/cyw43/__init__.c
msgid "Expected a %q or %q"
msgstr ""
msgstr "yù qī wéi %q huò %q"
#: shared-bindings/alarm/__init__.c
msgid "Expected an %q"
msgstr ""
msgstr "yù qī wéi %q"
#: ports/espressif/common-hal/_bleio/Adapter.c
#: ports/nrf/common-hal/_bleio/Adapter.c
@ -1036,16 +1040,16 @@ msgstr "guò lǜ qì tài fù zá"
#: ports/espressif/common-hal/dualbank/__init__.c
msgid "Firmware is duplicate"
msgstr ""
msgstr "gù jiàn chóng fù"
#: ports/espressif/common-hal/dualbank/__init__.c
msgid "Firmware is invalid"
msgstr ""
msgstr "gù jiàn wú xiào"
#: ports/espressif/common-hal/coproc/Coproc.c
#: ports/espressif/common-hal/dualbank/__init__.c
msgid "Firmware is too big"
msgstr ""
msgstr "gù jiàn tài dà"
#: shared-bindings/bitmaptools/__init__.c
msgid "For L8 colorspace, input bitmap must have 8 bits per pixel"
@ -1663,7 +1667,7 @@ msgstr ""
#: ports/espressif/common-hal/alarm/coproc/CoprocAlarm.c
#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c
msgid "Only one %q can be set in deep sleep."
msgstr ""
msgstr "zài shēn dù shuì mián zhōng zhǐ néng shè zhì yí gè %q."
#: ports/espressif/common-hal/i2ctarget/I2CTarget.c
#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c
@ -2024,7 +2028,7 @@ msgstr "Wēndù dòu qǔ chāoshí"
#: supervisor/shared/safe_mode.c
msgid "The BOOT button was pressed at start up.\n"
msgstr ""
msgstr "qǐ dòng shí àn xià le yǐn dǎo àn niǔ.\n"
#: supervisor/shared/safe_mode.c
msgid ""
@ -2036,11 +2040,11 @@ msgstr ""
#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h
msgid "The SW38 button was pressed at start up.\n"
msgstr ""
msgstr "qǐ dòng shí àn xià le SW38 àn niǔ .\n"
#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h
msgid "The VOLUME button was pressed at start up.\n"
msgstr ""
msgstr "qǐ dòng shí àn xià yīn liàng àn niǔ.\n"
#: supervisor/shared/safe_mode.c
msgid ""
@ -2052,11 +2056,11 @@ msgstr ""
#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h
msgid "The central button was pressed at start up.\n"
msgstr ""
msgstr "qǐ dòng shí àn xià zhōng yāng àn niǔ.\n"
#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h
msgid "The left button was pressed at start up.\n"
msgstr ""
msgstr "qǐ dòng shí àn xià zuǒ àn niǔ.\n"
#: shared-bindings/rgbmatrix/RGBMatrix.c
msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30"
@ -2125,6 +2129,8 @@ msgstr "Chāoshí shíjiān tài zhǎng: Zuìdà chāoshí shíjiān wèi%d miǎ
#: supervisor/shared/safe_mode.c
msgid "To exit, please reset the board without requesting safe mode."
msgstr ""
"yào tuì chū, qǐng zài bù qǐng qiú ān quán mó shì de qíng kuàng xià chóng zhì "
"zhǔ bǎn."
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Too many channels in sample"
@ -2245,7 +2251,7 @@ msgstr "wú fǎ qǐ dòng mDNS chá xún"
#: shared-bindings/coproc/CoprocMemory.c
msgid "Unable to write"
msgstr ""
msgstr "wú fǎ xiě rù"
#: shared-bindings/nvm/ByteArray.c
msgid "Unable to write to nvm."
@ -2312,7 +2318,7 @@ msgstr "wèi zhī de xì tǒng gù jiàn cuò wù: %d"
#: ports/raspberrypi/common-hal/wifi/__init__.c
#, c-format
msgid "Unkown error code %d"
msgstr ""
msgstr "wèi zhī cuò wù dài %d"
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
#, c-format
@ -2989,6 +2995,8 @@ msgid ""
"esp32_camera.Camera requires reserved PSRAM to be configured. See the "
"documentation for instructions."
msgstr ""
"esp32_camera. shè xiàng jī xū yào pèi zhì yù liú de PSRAM. yǒu guān shuō "
"míng, qǐng cān yuè wén dàng."
#: py/runtime.c
msgid "exceptions must derive from BaseException"
@ -3769,11 +3777,11 @@ msgstr "Jǐn zhīchí wèi shēndù = 16"
#: ports/stm/common-hal/audiobusio/PDMIn.c
msgid "only mono is supported"
msgstr ""
msgstr "jǐn zhī chí dān shēng dào"
#: ports/stm/common-hal/audiobusio/PDMIn.c
msgid "only oversample=64 is supported"
msgstr ""
msgstr "jǐn zhī chí guò cǎi yàng =64"
#: ports/nrf/common-hal/audiobusio/PDMIn.c
#: ports/stm/common-hal/audiobusio/PDMIn.c
@ -4244,7 +4252,7 @@ msgstr "wèizhī lèixíng '%q'"
#: py/objstr.c
#, c-format
msgid "unmatched '%c' in format"
msgstr ""
msgstr "gé shì bù pǐ pèi de '%c'"
#: py/objtype.c py/runtime.c
msgid "unreadable attribute"
@ -4325,7 +4333,7 @@ msgstr "wèi qǐ yòng WIFI"
#: ports/raspberrypi/common-hal/wifi/Monitor.c
msgid "wifi.Monitor not available"
msgstr ""
msgstr "wú xiàn wǎng luò xiǎn shì qì bù kě yòng"
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"

View File

@ -1,5 +1,5 @@
# idf.py menuconfig
./sdkconfig*
/sdkconfig*
# lock files for examples and components
dependencies.lock

View File

@ -123,6 +123,14 @@ const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj) {
return MP_OBJ_TO_PTR(obj);
}
const mcu_pin_obj_t *validate_obj_is_free_pin_or_gpio29(mp_obj_t obj) {
const mcu_pin_obj_t *pin = validate_obj_is_pin(obj);
if (obj != &pin_GPIO29) {
assert_pin_free(pin);
}
return pin;
}
const mcu_pin_obj_t *validate_obj_is_free_pin_including_cyw43(mp_obj_t obj) {
const mcu_pin_obj_t *pin = validate_obj_is_pin_including_cyw43(obj);
assert_pin_free(pin);

View File

@ -32,6 +32,7 @@
extern const mp_obj_type_t cyw43_pin_type;
const mcu_pin_obj_t *validate_obj_is_free_pin_including_cyw43(mp_obj_t obj);
const mcu_pin_obj_t *validate_obj_is_free_pin_or_gpio29(mp_obj_t obj);
const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj);
#define CONSTANT_CYW43_PM_VALUE(pm_mode, pm2_sleep_ret_ms, li_beacon_period, li_dtim_period, li_assoc) \

View File

@ -45,6 +45,10 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) },
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) },
{ MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) },
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) },
{ MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);

View File

@ -26,6 +26,7 @@
#include "common-hal/analogio/AnalogIn.h"
#include "shared-bindings/analogio/AnalogIn.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "py/runtime.h"
#include "supervisor/shared/translate/translate.h"
@ -35,16 +36,31 @@
#define ADC_FIRST_PIN_NUMBER 26
#define ADC_PIN_COUNT 4
// Voltage monitor is special on Pico W, because this pin is shared between the
// voltage monitor function and the wifi function. Special handling is required
// to read the analog voltage.
#if CIRCUITPY_CYW43
#include "bindings/cyw43/__init__.h"
#define SPECIAL_PIN(pin) (pin->number == 29)
const mcu_pin_obj_t *common_hal_analogio_analogin_validate_pin(mp_obj_t obj) {
return validate_obj_is_free_pin_or_gpio29(obj);
}
#else
#define SPECIAL_PIN(pin) false
#endif
void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const mcu_pin_obj_t *pin) {
if (pin->number < ADC_FIRST_PIN_NUMBER || pin->number > ADC_FIRST_PIN_NUMBER + ADC_PIN_COUNT) {
raise_ValueError_invalid_pin();
}
adc_init();
if (!SPECIAL_PIN(pin)) {
adc_gpio_init(pin->number);
claim_pin(pin);
}
adc_gpio_init(pin->number);
claim_pin(pin);
self->pin = pin;
}
@ -57,14 +73,30 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) {
return;
}
reset_pin_number(self->pin->number);
if (!SPECIAL_PIN(self->pin)) {
reset_pin_number(self->pin->number);
}
self->pin = NULL;
}
uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) {
adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER);
uint16_t value = adc_read();
uint16_t value;
if (SPECIAL_PIN(self->pin)) {
common_hal_mcu_disable_interrupts();
uint32_t old_pad = padsbank0_hw->io[self->pin->number];
uint32_t old_ctrl = iobank0_hw->io[self->pin->number].ctrl;
adc_gpio_init(self->pin->number);
adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER);
common_hal_mcu_delay_us(100);
value = adc_read();
gpio_init(self->pin->number);
padsbank0_hw->io[self->pin->number] = old_pad;
iobank0_hw->io[self->pin->number].ctrl = old_ctrl;
common_hal_mcu_enable_interrupts();
} else {
adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER);
value = adc_read();
}
// Stretch 12-bit ADC reading to 16-bit range
return (value << 4) | (value >> 8);
}

View File

@ -41,6 +41,10 @@
#include "pico/cyw43_arch.h"
#include "bindings/cyw43/__init__.h"
#define IS_CYW(self) ((self)->pin->base.type == &cyw43_pin_type)
const mcu_pin_obj_t *common_hal_digitalio_validate_pin(mp_obj_t obj) {
return validate_obj_is_free_pin_including_cyw43(obj);
}
#endif
digitalinout_result_t common_hal_digitalio_digitalinout_construct(

View File

@ -106,7 +106,8 @@ void pulsein_reset(void) {
memset(callback_obj_ref, 0, sizeof(callback_obj_ref));
HAL_TIM_Base_DeInit(&tim_handle);
tim_clock_disable(stm_peripherals_timer_get_index(tim_handle.Instance));
// tim_clock_disable() takes a bitmask of timers.
tim_clock_disable(1 << stm_peripherals_timer_get_index(tim_handle.Instance));
memset(&tim_handle, 0, sizeof(tim_handle));
refcount = 0;
}

View File

@ -36,23 +36,24 @@
#include "timers.h"
#define ALL_CLOCKS 0xFFFF
STATIC uint8_t reserved_tim[TIM_BANK_ARRAY_LEN];
// Bitmask of channels taken.
STATIC uint8_t tim_channels_taken[TIM_BANK_ARRAY_LEN];
// Initial frequency timer is set to.
STATIC uint32_t tim_frequencies[TIM_BANK_ARRAY_LEN];
STATIC bool never_reset_tim[TIM_BANK_ARRAY_LEN];
STATIC uint32_t timer_get_internal_duty(uint16_t duty, uint32_t period) {
// duty cycle is duty/0xFFFF fraction x (number of pulses per period)
return (duty * period) / ((1 << 16) - 1);
return (duty * period) / 0xffff;
}
STATIC bool timer_get_optimal_divisors(uint32_t *period, uint32_t *prescaler,
uint32_t frequency, uint32_t source_freq) {
// Find the largest possible period supported by this frequency
for (int i = 0; i < (1 << 16); i++) {
*prescaler = 0;
for (uint32_t i = 1; i <= 0xffff; i++) {
*period = source_freq / (i * frequency);
if (*period < (1 << 16) && *period >= 2) {
if (*period <= 0xffff && *period >= 2) {
*prescaler = i;
break;
}
@ -62,13 +63,10 @@ STATIC bool timer_get_optimal_divisors(uint32_t *period, uint32_t *prescaler,
}
void pwmout_reset(void) {
uint16_t never_reset_mask = 0x00;
for (int i = 0; i < TIM_BANK_ARRAY_LEN; i++) {
if (!never_reset_tim[i]) {
reserved_tim[i] = 0x00;
tim_frequencies[i] = 0x00;
} else {
never_reset_mask |= 1 << i;
tim_channels_taken[i] = 0x00;
tim_frequencies[i] = 0;
}
}
}
@ -78,73 +76,69 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
uint16_t duty,
uint32_t frequency,
bool variable_frequency) {
TIM_TypeDef *TIMx;
uint8_t tim_num = MP_ARRAY_SIZE(mcu_tim_pin_list);
bool tim_taken_internal = false;
bool tim_chan_taken = false;
bool tim_taken_f_mismatch = false;
bool var_freq_mismatch = false;
// Default error is no timer at all on pin.
pwmout_result_t last_failure = PWMOUT_INVALID_PIN;
bool first_time_setup = true;
for (uint i = 0; i < tim_num; i++) {
const mcu_tim_pin_obj_t *l_tim = &mcu_tim_pin_list[i];
uint8_t l_tim_index = l_tim->tim_index;
uint8_t l_tim_channel = l_tim->channel_index;
uint8_t tim_index;
uint8_t tim_channel_index;
self->tim = NULL;
for (uint i = 0; i < MP_ARRAY_SIZE(mcu_tim_pin_list); i++) {
const mcu_tim_pin_obj_t *tim = &mcu_tim_pin_list[i];
tim_index = tim->tim_index;
tim_channel_index = tim->channel_index;
// if pin is same
if (l_tim->pin == pin) {
if (tim->pin == pin) {
// check if the timer has a channel active, or is reserved by main timer system
if (l_tim_index < TIM_BANK_ARRAY_LEN && reserved_tim[l_tim_index] != 0) {
if (tim_index < TIM_BANK_ARRAY_LEN && tim_channels_taken[tim_index] != 0) {
// Timer has already been reserved by an internal module
if (stm_peripherals_timer_is_reserved(mcu_tim_banks[l_tim_index])) {
tim_taken_internal = true;
if (stm_peripherals_timer_is_reserved(mcu_tim_banks[tim_index])) {
last_failure = PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
continue; // keep looking
}
// is it the same channel? (or all channels reserved by a var-freq)
if (reserved_tim[l_tim_index] & 1 << (l_tim_channel)) {
tim_chan_taken = true;
if (tim_channels_taken[tim_index] & (1 << tim_channel_index)) {
last_failure = PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
continue; // keep looking, might be another viable option
}
// If the frequencies are the same it's ok
if (tim_frequencies[l_tim_index] != frequency) {
tim_taken_f_mismatch = true;
if (tim_frequencies[tim_index] != frequency) {
last_failure = PWMOUT_INVALID_FREQUENCY_ON_PIN;
continue; // keep looking
}
// you can't put a variable frequency on a partially reserved timer
if (variable_frequency) {
var_freq_mismatch = true;
last_failure = PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE;
continue; // keep looking
}
first_time_setup = false; // skip setting up the timer
}
// No problems taken, so set it up
self->tim = l_tim;
self->tim = tim;
break;
}
}
TIM_TypeDef *TIMx;
// handle valid/invalid timer instance
if (self->tim != NULL) {
// create instance
TIMx = mcu_tim_banks[self->tim->tim_index];
TIMx = mcu_tim_banks[tim_index];
// reserve timer/channel
if (variable_frequency) {
reserved_tim[self->tim->tim_index] = 0x0F;
// Take all the channels.
tim_channels_taken[tim_index] = 0x0F;
} else {
reserved_tim[self->tim->tim_index] |= 1 << self->tim->channel_index;
tim_channels_taken[tim_index] |= 1 << tim_channel_index;
}
tim_frequencies[self->tim->tim_index] = frequency;
tim_frequencies[tim_index] = frequency;
stm_peripherals_timer_reserve(TIMx);
} else { // no match found
if (tim_chan_taken || tim_taken_internal) {
return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
} else if (tim_taken_f_mismatch) {
return PWMOUT_INVALID_FREQUENCY_ON_PIN;
} else if (var_freq_mismatch) {
return PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE;
} else {
return PWMOUT_INVALID_PIN;
}
} else {
// no match found
return last_failure;
}
uint32_t prescaler = 0; // prescaler is 15 bit
@ -163,10 +157,10 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
HAL_GPIO_Init(pin_port(pin->port), &GPIO_InitStruct);
self->pin = pin;
tim_clock_enable(1 << (self->tim->tim_index));
tim_clock_enable(1 << tim_index);
// translate channel into handle value
self->channel = 4 * self->tim->channel_index;
// translate channel into handle value: TIM_CHANNEL_1, _2, _3, _4.
self->channel = 4 * tim_channel_index;
// Timer init
self->handle.Instance = TIMx;
@ -175,6 +169,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
self->handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
self->handle.Init.CounterMode = TIM_COUNTERMODE_UP;
self->handle.Init.RepetitionCounter = 0;
self->handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
// only run init if this is the first instance of this timer
if (first_time_setup) {
@ -232,15 +227,15 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) {
}
// var freq shuts down entire timer, others just their channel
if (self->variable_frequency) {
reserved_tim[self->tim->tim_index] = 0x00;
tim_channels_taken[self->tim->tim_index] = 0x00;
} else {
reserved_tim[self->tim->tim_index] &= ~(1 << self->tim->channel_index);
tim_channels_taken[self->tim->tim_index] &= ~(1 << self->tim->channel_index);
HAL_TIM_PWM_Stop(&self->handle, self->channel);
}
common_hal_reset_pin(self->pin);
// if reserved timer has no active channels, we can disable it
if (reserved_tim[self->tim->tim_index] == 0) {
if (tim_channels_taken[self->tim->tim_index] == 0) {
tim_frequencies[self->tim->tim_index] = 0x00;
stm_peripherals_timer_free(self->handle.Instance);
}

View File

@ -39,12 +39,12 @@ typedef struct {
TIM_HandleTypeDef handle;
TIM_OC_InitTypeDef chan_handle;
const mcu_tim_pin_obj_t *tim;
uint8_t channel : 7;
bool variable_frequency : 1;
uint16_t duty_cycle;
uint32_t frequency;
uint32_t period;
const mcu_pin_obj_t *pin;
uint16_t duty_cycle;
uint8_t channel;
bool variable_frequency;
} pwmio_pwmout_obj_t;
void pwmout_reset(void);

View File

@ -150,26 +150,65 @@ static size_t irq_map[] = {
};
// Get the frequency (in Hz) of the source clock for the given timer.
// 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.
//
// From STM ref manual: DM00031020 Rev 19, section 7.2, page 217:
//
// The timer clock frequencies for STM32F405xx/07xx and STM32F415xx/17xx are
// automatically set by hardware. There are two cases:
// 1. If the APB prescaler is 1, the timer clock frequencies are set to the same frequency as
// that of the APB domain to which the timers are connected.
// 2. Otherwise, they are set to twice (×2) the frequency of the APB domain to which the
// timers are connected.
// From STM ref manual: DM00031020 Rev 19, section 6.2, page 153:
//
// The timer clock frequencies for STM32F42xxx and STM32F43xxx are automatically set by
// hardware. There are two cases depending on the value of TIMPRE bit in RCC_CFGR [sic - should be RCC_DKCFGR]
// register:
// * If TIMPRE bit in RCC_DKCFGR register is reset:
// If the APB prescaler is configured to a division factor of 1, the timer clock frequencies
// (TIMxCLK) are set to PCLKx. Otherwise, the timer clock frequencies are twice the
// frequency of the APB domain to which the timers are connected: TIMxCLK = 2xPCLKx.
// * If TIMPRE bit in RCC_DKCFGR register is set:
// If the APB prescaler is configured to a division factor of 1, 2 or 4, the timer clock
// frequencies (TIMxCLK) are set to HCLK. Otherwise, the timer clock frequencies is four
// times the frequency of the APB domain to which the timers are connected: TIMxCLK = 4xPCLKx.
uint32_t stm_peripherals_timer_get_source_freq(TIM_TypeDef *timer) {
size_t tim_id = stm_peripherals_timer_get_index(timer);
// The timer index starts at 0, but the timer numbers start at TIM1.
size_t tim_id = stm_peripherals_timer_get_index(timer) + 1;
uint32_t source, clk_div;
if (tim_id == 1 || (8 <= tim_id && tim_id <= 11)) {
// TIM{1,8,9,10,11} are on APB2
source = HAL_RCC_GetPCLK2Freq();
clk_div = RCC->CFGR & RCC_CFGR_PPRE2;
// 0b0xx means not divided; 0b100 is divide by 2; 0b101 by 4; 0b110 by 8; 0b111 by 16.
clk_div = (RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos;
} else {
// TIM{2,3,4,5,6,7,12,13,14} are on APB1
source = HAL_RCC_GetPCLK1Freq();
clk_div = RCC->CFGR & RCC_CFGR_PPRE1;
// 0b0xx means not divided; 0b100 is divide by 2; 0b101 by 4; 0b110 by 8; 0b111 by 16.
clk_div = (RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos;
}
if (clk_div != 0) {
// APB prescaler for this timer is > 1
// Only some STM32's have TIMPRE.
#if defined(RCC_CFGR_TIMPRE)
uint32_t timpre = RCC->DCKCFGR & RCC_CFGR_TIMPRE;
if (timpre == 0) {
if (clk_div >= 0b100) {
source *= 2;
}
} else {
if (clk_div > 0b101) {
source *= 4;
} else {
source = HAL_RCC_GetHCLKFreq();
}
}
#else
if (clk_div >= 0b100) {
source *= 2;
}
#endif
return source;
}
@ -271,6 +310,7 @@ bool stm_peripherals_timer_is_reserved(TIM_TypeDef *instance) {
return stm_timer_reserved[tim_idx];
}
// Note this returns a timer index starting at zero, corresponding to TIM1.
size_t stm_peripherals_timer_get_index(TIM_TypeDef *instance) {
for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_tim_banks); i++) {
if (instance == mcu_tim_banks[i]) {

View File

@ -36,6 +36,10 @@
#include "shared-bindings/analogio/AnalogIn.h"
#include "shared-bindings/util.h"
MP_WEAK const mcu_pin_obj_t *common_hal_analogio_analogin_validate_pin(mp_obj_t obj) {
return validate_obj_is_free_pin(obj);
}
//| class AnalogIn:
//| """Read analog voltage levels
//|
@ -60,8 +64,7 @@ STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type,
mp_arg_check_num(n_args, n_kw, 1, 1, false);
// 1st argument is the pin
const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0]);
const mcu_pin_obj_t *pin = common_hal_analogio_analogin_validate_pin(args[0]);
analogio_analogin_obj_t *self = m_new_obj(analogio_analogin_obj_t);
self->base.type = &analogio_analogin_type;
common_hal_analogio_analogin_construct(self, pin);

View File

@ -32,6 +32,7 @@
extern const mp_obj_type_t analogio_analogin_type;
const mcu_pin_obj_t *common_hal_analogio_analogin_validate_pin(mp_obj_t obj);
void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const mcu_pin_obj_t *pin);
void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self);
bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self);

View File

@ -66,6 +66,10 @@ STATIC void check_result(digitalinout_result_t result) {
}
}
MP_WEAK const mcu_pin_obj_t *common_hal_digitalio_validate_pin(mp_obj_t obj) {
return validate_obj_is_free_pin(obj);
}
//| class DigitalInOut:
//| """Digital input and output
//|
@ -87,14 +91,7 @@ STATIC mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type,
digitalio_digitalinout_obj_t *self = m_new_obj(digitalio_digitalinout_obj_t);
self->base.type = &digitalio_digitalinout_type;
#if CIRCUITPY_CYW43
// The GPIO pin attached to the CYW43 co-processor can only be used for
// DigitalInOut, not for other purposes like PWM. That's why this check
// is here, and it's not rolled into validate_obj_is_free_pin.
const mcu_pin_obj_t *pin = validate_obj_is_free_pin_including_cyw43(args[0]);
#else
const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0]);
#endif
const mcu_pin_obj_t *pin = common_hal_digitalio_validate_pin(args[0]);
common_hal_digitalio_digitalinout_construct(self, pin);
return MP_OBJ_FROM_PTR(self);

View File

@ -55,6 +55,7 @@ typedef enum {
DIGITALINOUT_REG_TOGGLE,
} digitalinout_reg_op_t;
const mcu_pin_obj_t *common_hal_digitalio_validate_pin(mp_obj_t obj);
digitalinout_result_t common_hal_digitalio_digitalinout_construct(digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin);
void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self);
bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self);