diff options
| author | Dan Halbert <halbert@halwitz.org> | 2019-01-10 21:12:17 -0500 |
|---|---|---|
| committer | Dan Halbert <halbert@halwitz.org> | 2019-01-10 21:12:17 -0500 |
| commit | 50ee5ef24cf9830328d349e83364b462d552b715 (patch) | |
| tree | a0c95d9a81a19c92c3d5261bbc91966491b88c5a | |
| parent | c80b5f4f4c2df7ca5175792ccbf0572c4d937b7e (diff) | |
| parent | 516d7da64173055422230e46173f7d19273a5107 (diff) | |
merge translations; add bleio comments; fix minor sphinx issues in midi
43 files changed, 3852 insertions, 188 deletions
diff --git a/.travis.yml b/.travis.yml index 6c141385b..06231a594 100755 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ env: - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero" TRAVIS_SDK=arm - - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick pyportal" TRAVIS_SDK=arm + - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick pyportal sparkfun_samd21_mini" TRAVIS_SDK=arm addons: artifacts: diff --git a/lib/tinyusb b/lib/tinyusb -Subproject 3bb53273cd3770328f55ba317af3df0cce4333c +Subproject 5804e56e3c2ab4480bf72d94d997f769a645af4 diff --git a/locale/ID.po b/locale/ID.po new file mode 100644 index 000000000..405b3a0e3 --- /dev/null +++ b/locale/ID.po @@ -0,0 +1,2587 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-01-10 11:05-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: extmod/machine_i2c.c:299 +msgid "invalid I2C peripheral" +msgstr "perangkat I2C tidak valid" + +#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 +#: extmod/machine_i2c.c:392 +msgid "I2C operation not supported" +msgstr "operasi I2C tidak didukung" + +#: extmod/machine_mem.c:45 ports/unix/modmachine.c:53 +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "alamat %08x tidak selaras dengan %d bytes" + +#: extmod/machine_spi.c:57 +msgid "invalid SPI peripheral" +msgstr "perangkat SPI tidak valid" + +#: extmod/machine_spi.c:124 +msgid "buffers must be the same length" +msgstr "buffers harus mempunyai panjang yang sama" + +#: extmod/machine_spi.c:207 +msgid "bits must be 8" +msgstr "bits harus memilki nilai 8" + +#: extmod/machine_spi.c:210 +msgid "firstbit must be MSB" +msgstr "bit pertama(firstbit) harus berupa MSB" + +#: extmod/machine_spi.c:215 +msgid "must specify all of sck/mosi/miso" +msgstr "harus menentukan semua pin sck/mosi/miso" + +#: extmod/modframebuf.c:299 +msgid "invalid format" +msgstr "format tidak valid" + +#: extmod/modubinascii.c:38 extmod/moduhashlib.c:102 +msgid "a bytes-like object is required" +msgstr "sebuah objek menyerupai byte (bytes-like) dibutuhkan" + +#: extmod/modubinascii.c:90 +msgid "odd-length string" +msgstr "panjang data string memiliki keganjilan (odd-length)" + +#: extmod/modubinascii.c:101 +msgid "non-hex digit found" +msgstr "digit non-hex ditemukan" + +#: extmod/modubinascii.c:169 +msgid "incorrect padding" +msgstr "lapisan (padding) tidak benar" + +#: extmod/moductypes.c:122 +msgid "syntax error in uctypes descriptor" +msgstr "sintaksis error pada pendeskripsi uctypes" + +#: extmod/moductypes.c:219 +msgid "Cannot unambiguously get sizeof scalar" +msgstr "tidak dapat mendapatkan ukuran scalar secara tidak ambigu" + +#: extmod/moductypes.c:397 +msgid "struct: no fields" +msgstr "struct: tidak ada fields" + +#: extmod/moductypes.c:530 +msgid "struct: cannot index" +msgstr "struct: tidak bisa melakukan index" + +#: extmod/moductypes.c:544 +msgid "struct: index out of range" +msgstr "struct: index keluar dari jangkauan" + +#: extmod/moduheapq.c:38 +msgid "heap must be a list" +msgstr "heap harus berupa sebuah list" + +#: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172 +msgid "empty heap" +msgstr "heap kosong" + +#: extmod/modujson.c:281 +msgid "syntax error in JSON" +msgstr "sintaksis error pada JSON" + +#: extmod/modure.c:161 +msgid "Splitting with sub-captures" +msgstr "Memisahkan dengan menggunakan sub-captures" + +#: extmod/modure.c:207 +msgid "Error in regex" +msgstr "Error pada regex" + +#: extmod/modussl_axtls.c:81 +msgid "invalid key" +msgstr "key tidak valid" + +#: extmod/modussl_axtls.c:87 +msgid "invalid cert" +msgstr "cert tidak valid" + +#: extmod/modutimeq.c:131 +msgid "queue overflow" +msgstr "antrian meluap (overflow)" + +#: extmod/moduzlib.c:98 +msgid "compression header" +msgstr "kompresi header" + +#: extmod/uos_dupterm.c:120 +msgid "invalid dupterm index" +msgstr "indeks dupterm tidak valid" + +#: extmod/vfs_fat.c:426 py/moduerrno.c:154 +msgid "Read-only filesystem" +msgstr "sistem file (filesystem) bersifat Read-only" + +#: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43 +msgid "I/O operation on closed file" +msgstr "operasi I/O pada file tertutup" + +#: lib/embed/abort_.c:8 +msgid "abort() called" +msgstr "abort() dipanggil" + +#: lib/netutils/netutils.c:83 +msgid "invalid arguments" +msgstr "argumen-argumen tidak valid" + +#: lib/utils/pyexec.c:97 py/builtinimport.c:251 +msgid "script compilation not supported" +msgstr "kompilasi script tidak didukung" + +#: main.c:150 +msgid " output:\n" +msgstr "output:\n" + +#: main.c:164 main.c:237 +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"Auto-reload aktif. Silahkan simpan data-data (files) melalui USB untuk " +"menjalankannya atau masuk ke REPL untukmenonaktifkan.\n" + +#: main.c:166 +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Berjalan di mode aman(safe mode)! Auto-reload tidak aktif.\n" + +#: main.c:168 main.c:239 +msgid "Auto-reload is off.\n" +msgstr "Auto-reload tidak aktif.\n" + +#: main.c:182 +msgid "Running in safe mode! Not running saved code.\n" +msgstr "" +"Berjalan di mode aman(safe mode)! tidak menjalankan kode yang tersimpan.\n" + +#: main.c:198 +msgid "WARNING: Your code filename has two extensions\n" +msgstr "PERINGATAN: Nama file kode anda mempunyai dua ekstensi\n" + +#: main.c:244 +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" +"Tekan tombol apa saja untuk masuk ke dalam REPL. Gunakan CTRL+D untuk reset " +"(Reload)" + +#: main.c:407 +msgid "soft reboot\n" +msgstr "memulai ulang software(soft reboot)\n" + +#: ports/atmel-samd/audio_dma.c:209 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 +msgid "All sync event channels in use" +msgstr "Semua channel event yang disinkronisasi sedang digunakan" + +#: ports/atmel-samd/bindings/samd/Clock.c:135 +msgid "calibration is read only" +msgstr "kalibrasi adalah read only" + +#: ports/atmel-samd/bindings/samd/Clock.c:137 +msgid "calibration is out of range" +msgstr "kalibrasi keluar dari jangkauan" + +#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 +msgid "No default I2C bus" +msgstr "Tidak ada standar bus I2C" + +#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 +msgid "No default SPI bus" +msgstr "Tidak ada standar bus SPI" + +#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 +msgid "No default UART bus" +msgstr "Tidak ada standar bus UART" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 +#: ports/nrf/common-hal/analogio/AnalogIn.c:39 +msgid "Pin does not have ADC capabilities" +msgstr "Pin tidak mempunya kemampuan untuk ADC (Analog Digital Converter)" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49 +msgid "No DAC on chip" +msgstr "Tidak ada DAC (Digital Analog Converter) di dalam chip" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56 +msgid "AnalogOut not supported on given pin" +msgstr "pin yang dipakai tidak mendukung AnalogOut" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:147 +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:150 +msgid "Invalid bit clock pin" +msgstr "Bit clock pada pin tidak valid" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:153 +msgid "Bit clock and word select must share a clock unit" +msgstr "Bit clock dan word harus memiliki kesamaan pada clock unit" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:156 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:130 +msgid "Invalid data pin" +msgstr "data pin tidak valid" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:169 +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:174 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:145 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:150 +msgid "Serializer in use" +msgstr "Serializer sedang digunakan" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:230 +msgid "Clock unit in use" +msgstr "Clock unit sedang digunakan" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:240 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:172 +msgid "Unable to find free GCLK" +msgstr "Tidak dapat menemukan GCLK yang kosong" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:254 +msgid "Too many channels in sample." +msgstr "Terlalu banyak channel dalam sampel" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 +msgid "No DMA channel found" +msgstr "tidak ada channel DMA ditemukan" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 +msgid "Unable to allocate buffers for signed conversion" +msgstr "Tidak dapat mengalokasikan buffer untuk signed conversion" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:109 +msgid "Invalid clock pin" +msgstr "Clock pada pin tidak valid" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:134 +msgid "Only 8 or 16 bit mono with " +msgstr "Hanya 8 atau 16 bit mono dengan " + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:167 +msgid "sampling rate out of range" +msgstr "nilai sampling keluar dari jangkauan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 +msgid "DAC already in use" +msgstr "DAC sudah digunakan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 +msgid "Right channel unsupported" +msgstr "Channel Kanan tidak didukung" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 +#: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 +msgid "Invalid pin" +msgstr "Pin tidak valid" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 +msgid "Invalid pin for left channel" +msgstr "Pin untuk channel kiri tidak valid" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 +msgid "Invalid pin for right channel" +msgstr "Pin untuk channel kanan tidak valid" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 +msgid "Cannot output both channels on the same pin" +msgstr "" +"Tidak dapat menggunakan output di kedua channel dengan menggunakan pin yang " +"sama" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +#: ports/nrf/common-hal/pulseio/PulseOut.c:107 +msgid "All timers in use" +msgstr "Semua timer sedang digunakan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 +msgid "All event channels in use" +msgstr "Semua channel event sedang digunakan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "Nilai sampel terlalu tinggi. Nilai harus kurang dari %d" + +#: ports/atmel-samd/common-hal/busio/I2C.c:71 +msgid "Not enough pins available" +msgstr "Pin yang tersedia tidak cukup" + +#: ports/atmel-samd/common-hal/busio/I2C.c:78 +#: ports/atmel-samd/common-hal/busio/SPI.c:171 +#: ports/atmel-samd/common-hal/busio/UART.c:120 +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 +#: ports/nrf/common-hal/busio/I2C.c:84 +msgid "Invalid pins" +msgstr "Pin-pin tidak valid" + +#: ports/atmel-samd/common-hal/busio/I2C.c:101 +msgid "SDA or SCL needs a pull up" +msgstr "SDA atau SCL membutuhkan pull up" + +#: ports/atmel-samd/common-hal/busio/I2C.c:121 +msgid "Unsupported baudrate" +msgstr "Baudrate tidak didukung" + +#: ports/atmel-samd/common-hal/busio/UART.c:67 +msgid "bytes > 8 bits not supported" +msgstr "byte > 8 bit tidak didukung" + +#: ports/atmel-samd/common-hal/busio/UART.c:73 +#: ports/nrf/common-hal/busio/UART.c:118 +msgid "tx and rx cannot both be None" +msgstr "tx dan rx keduanya tidak boleh kosong" + +#: ports/atmel-samd/common-hal/busio/UART.c:146 +#: ports/nrf/common-hal/busio/UART.c:152 +msgid "Failed to allocate RX buffer" +msgstr "Gagal untuk mengalokasikan buffer RX" + +#: ports/atmel-samd/common-hal/busio/UART.c:154 +msgid "Could not initialize UART" +msgstr "Tidak dapat menginisialisasi UART" + +#: ports/atmel-samd/common-hal/busio/UART.c:241 +#: ports/nrf/common-hal/busio/UART.c:197 +msgid "No RX pin" +msgstr "Tidak pin RX" + +#: ports/atmel-samd/common-hal/busio/UART.c:300 +#: ports/nrf/common-hal/busio/UART.c:232 +msgid "No TX pin" +msgstr "Tidak ada pin TX" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 +msgid "Cannot get pull while in output mode" +msgstr "Tidak bisa mendapatkan pull pada saat mode output" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 +#: ports/esp8266/common-hal/microcontroller/__init__.c:64 +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "" +"Tidak dapat melakukan reset ke bootloader karena tidak ada bootloader yang " +"terisi" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 +#: ports/nrf/common-hal/pulseio/PWMOut.c:119 +#: ports/nrf/common-hal/pulseio/PWMOut.c:233 +msgid "Invalid PWM frequency" +msgstr "Frekuensi PWM tidak valid" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:187 +msgid "All timers for this pin are in use" +msgstr "Semua timer untuk pin ini sedang digunakan" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:110 +msgid "No hardware support on pin" +msgstr "Tidak ada dukungan hardware untuk pin" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:113 +msgid "EXTINT channel already in use" +msgstr "Channel EXTINT sedang digunakan" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Gagal untuk megalokasikan buffer RX dari %d byte" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +msgid "pop from an empty PulseIn" +msgstr "Muncul dari PulseIn yang kosong" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:422 +msgid "index out of range" +msgstr "index keluar dari jangkauan" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:178 +msgid "Another send is already active" +msgstr "Send yang lain sudah aktif" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:38 +msgid "Both pins must support hardware interrupts" +msgstr "Kedua pin harus mendukung hardware interrut" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:46 +msgid "A hardware interrupt channel is already in use" +msgstr "Sebuah channel hardware interrupt sedang digunakan" + +#: ports/atmel-samd/common-hal/rtc/RTC.c:101 +msgid "calibration value out of range +/-127" +msgstr "nilai kalibrasi keluar dari jangkauan +/-127" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 +msgid "No free GCLKs" +msgstr "Tidak ada GCLK yang kosong" + +#: ports/esp8266/common-hal/analogio/AnalogIn.c:43 +msgid "Pin %q does not have ADC capabilities" +msgstr "Pin %q tidak memiliki kemampuan ADC" + +#: ports/esp8266/common-hal/analogio/AnalogOut.c:39 +msgid "No hardware support for analog out." +msgstr "Tidak dukungan hardware untuk analog out." + +#: ports/esp8266/common-hal/busio/SPI.c:72 +msgid "Pins not valid for SPI" +msgstr "Pin-pin tidak valid untuk SPI" + +#: ports/esp8266/common-hal/busio/UART.c:45 +msgid "Only tx supported on UART1 (GPIO2)." +msgstr "Hanya tx yang mendukung pada UART1 (GPIO2)." + +#: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108 +msgid "invalid data bits" +msgstr "bit data tidak valid" + +#: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144 +msgid "invalid stop bits" +msgstr "stop bit tidak valid" + +#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200 +msgid "ESP8266 does not support pull down." +msgstr "ESP866 tidak mendukung pull down" + +#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210 +msgid "GPIO16 does not support pull up." +msgstr "GPIO16 tidak mendukung pull up" + +#: ports/esp8266/common-hal/microcontroller/__init__.c:66 +msgid "ESP8226 does not support safe mode." +msgstr "ESP8266 tidak mendukung safe mode" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:54 +#: ports/esp8266/common-hal/pulseio/PWMOut.c:113 +#, c-format +msgid "Maximum PWM frequency is %dhz." +msgstr "Nilai maksimum frekuensi PWM adalah %dhz" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:57 +#: ports/esp8266/common-hal/pulseio/PWMOut.c:116 +msgid "Minimum PWM frequency is 1hz." +msgstr "Nilai minimum frekuensi PWM is 1hz" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:68 +#, c-format +msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +msgstr "Nilai Frekuensi PWM ganda tidak didukung. PWM sudah diatur pada %dhz" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70 +#, c-format +msgid "PWM not supported on pin %d" +msgstr "PWM tidak didukung pada pin %d" + +#: ports/esp8266/common-hal/pulseio/PulseIn.c:78 +msgid "No PulseIn support for %q" +msgstr "Tidak ada dukungan PulseIn untuk %q" + +#: ports/esp8266/common-hal/storage/__init__.c:34 +msgid "Unable to remount filesystem" +msgstr "Tidak dapat memasang filesystem kembali" + +#: ports/esp8266/common-hal/storage/__init__.c:38 +msgid "Use esptool to erase flash and re-upload Python instead" +msgstr "" +"Gunakan esptool untuk menghapus flash dan upload ulang Python sebagai " +"gantinya" + +#: ports/esp8266/esp_mphal.c:154 +msgid "C-level assert" +msgstr "Dukungan C-level" + +#: ports/esp8266/machine_adc.c:57 +#, c-format +msgid "not a valid ADC Channel: %d" +msgstr "tidak valid channel ADC: %d" + +#: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137 +msgid "impossible baudrate" +msgstr "baudrate tidak memungkinkan" + +#: ports/esp8266/machine_pin.c:129 +msgid "expecting a pin" +msgstr "mengharapkan sebuah pin" + +#: ports/esp8266/machine_pin.c:284 +msgid "Pin(16) doesn't support pull" +msgstr "Pin(16) tidak mendukung pull" + +#: ports/esp8266/machine_pin.c:323 +msgid "invalid pin" +msgstr "pin tidak valid" + +#: ports/esp8266/machine_pin.c:389 +msgid "pin does not have IRQ capabilities" +msgstr "pin tidak memiliki kemampuan IRQ" + +#: ports/esp8266/machine_rtc.c:185 +msgid "buffer too long" +msgstr "buffer terlalu panjang" + +#: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223 +#: ports/esp8266/machine_rtc.c:246 +msgid "invalid alarm" +msgstr "alarm tidak valid" + +#: ports/esp8266/machine_uart.c:169 +#, c-format +msgid "UART(%d) does not exist" +msgstr "UART(%d) tidak ada" + +#: ports/esp8266/machine_uart.c:219 +msgid "UART(1) can't read" +msgstr "UART(1) tidak dapat dibaca" + +#: ports/esp8266/modesp.c:119 +msgid "len must be multiple of 4" +msgstr "len harus kelipatan dari 4" + +#: ports/esp8266/modesp.c:274 +#, c-format +msgid "memory allocation failed, allocating %u bytes for native code" +msgstr "alokasi memori gagal, mengalokasikan %u byte untuk kode native" + +#: ports/esp8266/modesp.c:317 +msgid "flash location must be below 1MByte" +msgstr "alokasi flash harus dibawah 1MByte" + +#: ports/esp8266/modmachine.c:63 +msgid "frequency can only be either 80Mhz or 160MHz" +msgstr "frekuensi hanya bisa didefinisikan 80Mhz atau 160Mhz" + +#: ports/esp8266/modnetwork.c:61 +msgid "AP required" +msgstr "AP dibutuhkan" + +#: ports/esp8266/modnetwork.c:61 +msgid "STA required" +msgstr "STA dibutuhkan" + +#: ports/esp8266/modnetwork.c:87 +msgid "Cannot update i/f status" +msgstr "Tidak dapat memperbarui status i/f" + +#: ports/esp8266/modnetwork.c:142 +msgid "Cannot set STA config" +msgstr "Tidak dapat mengatur konfigurasi STA" + +#: ports/esp8266/modnetwork.c:144 +msgid "Cannot connect to AP" +msgstr "Tidak dapat menyambungkan ke AP" + +#: ports/esp8266/modnetwork.c:152 +msgid "Cannot disconnect from AP" +msgstr "Tidak dapat memutuskna dari AP" + +#: ports/esp8266/modnetwork.c:173 +msgid "unknown status param" +msgstr "status param tidak diketahui" + +#: ports/esp8266/modnetwork.c:222 +msgid "STA must be active" +msgstr "STA harus aktif" + +#: ports/esp8266/modnetwork.c:239 +msgid "scan failed" +msgstr "scan gagal" + +#: ports/esp8266/modnetwork.c:306 +msgid "wifi_set_ip_info() failed" +msgstr "wifi_set_ip_info() gagal" + +#: ports/esp8266/modnetwork.c:319 +msgid "either pos or kw args are allowed" +msgstr "hanya antar pos atau kw args yang diperbolehkan" + +#: ports/esp8266/modnetwork.c:329 +msgid "can't get STA config" +msgstr "tidak bisa mendapatkan konfigurasi STA" + +#: ports/esp8266/modnetwork.c:331 +msgid "can't get AP config" +msgstr "tidak bisa mendapatkan konfigurasi AP" + +#: ports/esp8266/modnetwork.c:346 +msgid "invalid buffer length" +msgstr "panjang buffer tidak valid" + +#: ports/esp8266/modnetwork.c:405 +msgid "can't set STA config" +msgstr "tidak bisa mendapatkan konfigurasi STA" + +#: ports/esp8266/modnetwork.c:407 +msgid "can't set AP config" +msgstr "tidak bisa mendapatkan konfigurasi AP" + +#: ports/esp8266/modnetwork.c:416 +msgid "can query only one param" +msgstr "hanya bisa melakukan query satu param" + +#: ports/esp8266/modnetwork.c:469 +msgid "unknown config param" +msgstr "konfigurasi param tidak diketahui" + +#: ports/nrf/common-hal/analogio/AnalogOut.c:37 +msgid "AnalogOut functionality not supported" +msgstr "fungsionalitas AnalogOut tidak didukung" + +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "Dukungan soft device, id: 0x%08lX, pc: 0x%08l" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "Gagal untuk merubah status softdevice, error: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "Gagal untuk mendapatkan status softdevice, error: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "Gagal untuk mendapatkan alamat lokal, error: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Gagal untuk melaporkan nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +msgid "Can not fit data into the advertisment packet" +msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, fuzzy, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "Gagal untuk menemukan layanan, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "Gagal untuk menyambungkan, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Gagal untuk memulai advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Gagal untuk melakukan scanning, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Gagal untuk membuat mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "Gagal untuk menambahkan karakteristik, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Gagal untuk menambahkan Vendor Spesific UUID, status: 0x%08lX" + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Panjang string UUID tidak valid" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Parameter UUID tidak valid" + +#: ports/nrf/common-hal/busio/I2C.c:98 +msgid "All I2C peripherals are in use" +msgstr "Semua perangkat I2C sedang digunakan" + +#: ports/nrf/common-hal/busio/SPI.c:133 +msgid "All SPI peripherals are in use" +msgstr "Semua perangkat SPI sedang digunakan" + +#: ports/nrf/common-hal/busio/UART.c:49 +#, c-format +msgid "error = 0x%08lX" +msgstr "error = 0x%08lX" + +#: ports/nrf/common-hal/busio/UART.c:122 +msgid "Invalid buffer size" +msgstr "Ukuran buffer tidak valid" + +#: ports/nrf/common-hal/busio/UART.c:126 +msgid "Odd parity is not supported" +msgstr "Parity ganjil tidak didukung" + +#: ports/nrf/common-hal/busio/UART.c:358 ports/nrf/common-hal/busio/UART.c:362 +#: ports/nrf/common-hal/busio/UART.c:367 ports/nrf/common-hal/busio/UART.c:372 +#: ports/nrf/common-hal/busio/UART.c:378 ports/nrf/common-hal/busio/UART.c:383 +#: ports/nrf/common-hal/busio/UART.c:388 ports/nrf/common-hal/busio/UART.c:392 +#: ports/nrf/common-hal/busio/UART.c:400 +msgid "busio.UART not available" +msgstr "busio.UART tidak tersedia" + +#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#, c-format +msgid "Can not get temperature. status: 0x%02x" +msgstr "Tidak bisa mendapatkan temperatur. status: 0x%02x" + +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 +msgid "All PWM peripherals are in use" +msgstr "Semua perangkat PWM sedang digunakan" + +#: ports/unix/modffi.c:138 +msgid "Unknown type" +msgstr "Tipe tidak diketahui" + +#: ports/unix/modffi.c:207 ports/unix/modffi.c:265 +msgid "Error in ffi_prep_cif" +msgstr "Errod pada ffi_prep_cif" + +#: ports/unix/modffi.c:270 +msgid "ffi_prep_closure_loc" +msgstr "ffi_prep_closure_loc" + +#: ports/unix/modffi.c:413 +msgid "Don't know how to pass object to native function" +msgstr "Tidak tahu cara meloloskan objek ke fungsi native" + +#: ports/unix/modusocket.c:474 +#, c-format +msgid "[addrinfo error %d]" +msgstr "[addrinfo error %d]" + +#: py/argcheck.c:44 +msgid "function does not take keyword arguments" +msgstr "fungsi tidak dapat mengambil argumen keyword" + +#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "fungsi mengambil posisi argumen %d tapi %d yang diberikan" + +#: py/argcheck.c:64 +#, c-format +msgid "function missing %d required positional arguments" +msgstr "fungsi kehilangan %d argumen posisi yang dibutuhkan" + +#: py/argcheck.c:72 +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "fungsi diharapkan setidaknya %d argumen, hanya mendapatkan %d" + +#: py/argcheck.c:97 +msgid "'%q' argument required" +msgstr "'%q' argumen dibutuhkan" + +#: py/argcheck.c:122 +msgid "extra positional arguments given" +msgstr "argumen posisi ekstra telah diberikan" + +#: py/argcheck.c:130 +msgid "extra keyword arguments given" +msgstr "argumen keyword ekstra telah diberikan" + +#: py/argcheck.c:142 +msgid "argument num/types mismatch" +msgstr "argumen num/types tidak cocok" + +#: py/argcheck.c:147 +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "argumen keyword belum diimplementasi - gunakan args normal" + +#: py/bc.c:88 py/objnamedtuple.c:108 +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() mengambil posisi argumen %d tapi %d yang diberikan" + +#: py/bc.c:197 py/bc.c:215 +msgid "unexpected keyword argument" +msgstr "argumen keyword tidak diharapkan" + +#: py/bc.c:199 +msgid "keywords must be strings" +msgstr "keyword harus berupa string" + +#: py/bc.c:206 py/objnamedtuple.c:138 +msgid "function got multiple values for argument '%q'" +msgstr "fungsi mendapatkan nilai ganda untuk argumen '%q'" + +#: py/bc.c:218 py/objnamedtuple.c:130 +msgid "unexpected keyword argument '%q'" +msgstr "keyword argumen '%q' tidak diharapkan" + +#: py/bc.c:244 +#, c-format +msgid "function missing required positional argument #%d" +msgstr "fungsi kehilangan argumen posisi #%d yang dibutuhkan" + +#: py/bc.c:260 +msgid "function missing required keyword argument '%q'" +msgstr "fungsi kehilangan argumen keyword '%q' yang dibutuhkan" + +#: py/bc.c:269 +msgid "function missing keyword-only argument" +msgstr "fungsi kehilangan argumen keyword-only" + +#: py/binary.c:112 +msgid "bad typecode" +msgstr "typecode buruk" + +#: py/builtinevex.c:99 +msgid "bad compile mode" +msgstr "mode compile buruk" + +#: py/builtinhelp.c:137 +msgid "Plus any modules on the filesystem\n" +msgstr "Tambahkan module apapun pada filesystem\n" + +#: py/builtinhelp.c:183 +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" +"Selamat datang ke Adafruit CircuitPython %s!\n" +"\n" +"Silahkan kunjungi learn.adafruit.com/category/circuitpython untuk panduan " +"project.\n" +"\n" +"Untuk menampilkan modul built-in silahkan ketik `help(\"modules\")`.\n" + +#: py/builtinimport.c:336 +msgid "cannot perform relative import" +msgstr "tidak dapat melakukan relative import" + +#: py/builtinimport.c:420 py/builtinimport.c:532 +msgid "module not found" +msgstr "modul tidak ditemukan" + +#: py/builtinimport.c:423 py/builtinimport.c:535 +msgid "no module named '%q'" +msgstr "tidak ada modul yang bernama '%q'" + +#: py/builtinimport.c:510 +msgid "relative import" +msgstr "relative import" + +#: py/compile.c:397 py/compile.c:542 +msgid "can't assign to expression" +msgstr "tidak dapat menetapkan ke ekspresi" + +#: py/compile.c:416 +msgid "multiple *x in assignment" +msgstr "perkalian *x dalam assignment" + +#: py/compile.c:642 +msgid "non-default argument follows default argument" +msgstr "argumen non-default mengikuti argumen standar(default)" + +#: py/compile.c:771 py/compile.c:789 +msgid "invalid micropython decorator" +msgstr "micropython decorator tidak valid" + +#: py/compile.c:943 +msgid "can't delete expression" +msgstr "tidak bisa menghapus ekspresi" + +#: py/compile.c:955 +msgid "'break' outside loop" +msgstr "'break' diluar loop" + +#: py/compile.c:958 +msgid "'continue' outside loop" +msgstr "'continue' diluar loop" + +#: py/compile.c:969 +msgid "'return' outside function" +msgstr "'return' diluar fungsi" + +#: py/compile.c:1169 +msgid "identifier redefined as global" +msgstr "identifier didefinisi ulang sebagai global" + +#: py/compile.c:1185 +msgid "no binding for nonlocal found" +msgstr "tidak ada ikatan/bind pada temuan nonlocal" + +#: py/compile.c:1188 +msgid "identifier redefined as nonlocal" +msgstr "identifier didefinisi ulang sebagai nonlocal" + +#: py/compile.c:1197 +msgid "can't declare nonlocal in outer code" +msgstr "tidak dapat mendeklarasikan nonlocal diluar jangkauan kode" + +#: py/compile.c:1542 +msgid "default 'except' must be last" +msgstr "'except' standar harus terakhir" + +#: py/compile.c:2095 +msgid "*x must be assignment target" +msgstr "*x harus menjadi target assignment" + +#: py/compile.c:2193 +msgid "super() can't find self" +msgstr "super() tidak dapat menemukan dirinya sendiri" + +#: py/compile.c:2256 +msgid "can't have multiple *x" +msgstr "tidak bisa memiliki *x ganda" + +#: py/compile.c:2263 +msgid "can't have multiple **x" +msgstr "tidak bisa memiliki **x ganda" + +#: py/compile.c:2271 +msgid "LHS of keyword arg must be an id" +msgstr "LHS dari keyword arg harus menjadi sebuah id" + +#: py/compile.c:2287 +msgid "non-keyword arg after */**" +msgstr "non-keyword arg setelah */**" + +#: py/compile.c:2291 +msgid "non-keyword arg after keyword arg" +msgstr "non-keyword arg setelah keyword arg" + +#: py/compile.c:2463 py/compile.c:2473 py/compile.c:2712 py/compile.c:2742 +#: py/parse.c:1176 +msgid "invalid syntax" +msgstr "syntax tidak valid" + +#: py/compile.c:2465 +msgid "expecting key:value for dict" +msgstr "key:value diharapkan untuk dict" + +#: py/compile.c:2475 +msgid "expecting just a value for set" +msgstr "hanya mengharapkan sebuah nilai (value) untuk set" + +#: py/compile.c:2600 +msgid "'yield' outside function" +msgstr "'yield' diluar fungsi" + +#: py/compile.c:2619 +msgid "'await' outside function" +msgstr "'await' diluar fungsi" + +#: py/compile.c:2774 +msgid "name reused for argument" +msgstr "nama digunakan kembali untuk argumen" + +#: py/compile.c:2827 +msgid "parameter annotation must be an identifier" +msgstr "anotasi parameter haruse sebuah identifier" + +#: py/compile.c:2969 py/compile.c:3137 +msgid "return annotation must be an identifier" +msgstr "anotasi return harus sebuah identifier" + +#: py/compile.c:3097 +msgid "inline assembler must be a function" +msgstr "inline assembler harus sebuah fungsi" + +#: py/compile.c:3134 +msgid "unknown type" +msgstr "tipe tidak diketahui" + +#: py/compile.c:3154 +msgid "expecting an assembler instruction" +msgstr "sebuah instruksi assembler diharapkan" + +#: py/compile.c:3184 +msgid "'label' requires 1 argument" +msgstr "'label' membutuhkan 1 argumen" + +#: py/compile.c:3190 +msgid "label redefined" +msgstr "label didefinis ulang" + +#: py/compile.c:3196 +msgid "'align' requires 1 argument" +msgstr "'align' membutuhkan 1 argumen" + +#: py/compile.c:3205 +msgid "'data' requires at least 2 arguments" +msgstr "'data' membutuhkan setidaknya 2 argumen" + +#: py/compile.c:3212 +msgid "'data' requires integer arguments" +msgstr "'data' membutuhkan argumen integer" + +#: py/emitinlinethumb.c:102 +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "hanya mampu memiliki hingga 4 parameter untuk Thumb assembly" + +#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 +msgid "parameters must be registers in sequence r0 to r3" +msgstr "parameter harus menjadi register dalam urutan r0 sampai r3" + +#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' mengharapkan setidaknya r%d" + +#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' mengharapkan sebuah register" + +#: py/emitinlinethumb.c:211 +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' mengharapkan sebuah register spesial" + +#: py/emitinlinethumb.c:239 +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' mengharapkan sebuah FPU register" + +#: py/emitinlinethumb.c:292 +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' mengharapkan {r0, r1, ...}" + +#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' mengharapkan integer" + +#: py/emitinlinethumb.c:304 +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "'%s' integer 0x%x tidak cukup didalam mask 0x%x" + +#: py/emitinlinethumb.c:328 +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' mengharapkan sebuah alamat dengan bentuk [a, b]" + +#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 +#, c-format +msgid "'%s' expects a label" +msgstr "" + +#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 +msgid "label '%q' not defined" +msgstr "" + +#: py/emitinlinethumb.c:806 +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinethumb.c:810 +msgid "branch not in range" +msgstr "" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + +#: py/emitinlinextensa.c:327 +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "" + +#: py/emitnative.c:183 +msgid "unknown type '%q'" +msgstr "" + +#: py/emitnative.c:260 +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "" + +#: py/emitnative.c:742 +msgid "conversion to object" +msgstr "" + +#: py/emitnative.c:921 +msgid "local '%q' used before type known" +msgstr "" + +#: py/emitnative.c:1118 py/emitnative.c:1156 +msgid "can't load from '%q'" +msgstr "" + +#: py/emitnative.c:1128 +msgid "can't load with '%q' index" +msgstr "" + +#: py/emitnative.c:1188 +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "" + +#: py/emitnative.c:1289 py/emitnative.c:1379 +msgid "can't store '%q'" +msgstr "" + +#: py/emitnative.c:1358 py/emitnative.c:1419 +msgid "can't store to '%q'" +msgstr "" + +#: py/emitnative.c:1369 +msgid "can't store with '%q' index" +msgstr "" + +#: py/emitnative.c:1540 +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "" + +#: py/emitnative.c:1774 +msgid "unary op %q not implemented" +msgstr "" + +#: py/emitnative.c:1930 +msgid "binary op %q not implemented" +msgstr "" + +#: py/emitnative.c:1951 +msgid "can't do binary op between '%q' and '%q'" +msgstr "" + +#: py/emitnative.c:2126 +msgid "casting" +msgstr "" + +#: py/emitnative.c:2173 +msgid "return expected '%q' but got '%q'" +msgstr "" + +#: py/emitnative.c:2191 +msgid "must raise an object" +msgstr "" + +#: py/emitnative.c:2201 +msgid "native yield" +msgstr "" + +#: py/lexer.c:345 +msgid "unicode name escapes" +msgstr "" + +#: py/modbuiltins.c:162 +msgid "chr() arg not in range(0x110000)" +msgstr "" + +#: py/modbuiltins.c:171 +msgid "chr() arg not in range(256)" +msgstr "" + +#: py/modbuiltins.c:285 +msgid "arg is an empty sequence" +msgstr "" + +#: py/modbuiltins.c:350 +msgid "ord expects a character" +msgstr "" + +#: py/modbuiltins.c:353 +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" + +#: py/modbuiltins.c:363 +msgid "3-arg pow() not supported" +msgstr "" + +#: py/modbuiltins.c:517 +msgid "must use keyword argument for key function" +msgstr "" + +#: py/modmath.c:41 shared-bindings/math/__init__.c:53 +msgid "math domain error" +msgstr "" + +#: py/modmath.c:196 py/objfloat.c:270 py/objint_longlong.c:222 +#: py/objint_mpz.c:230 py/runtime.c:619 shared-bindings/math/__init__.c:346 +msgid "division by zero" +msgstr "" + +#: py/modmicropython.c:155 +msgid "schedule stack full" +msgstr "" + +#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 +#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 +#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +msgid "buffer too small" +msgstr "" + +#: py/modthread.c:240 +msgid "expecting a dict for keyword args" +msgstr "" + +#: py/moduerrno.c:147 py/moduerrno.c:150 +msgid "Permission denied" +msgstr "" + +#: py/moduerrno.c:148 +msgid "No such file/directory" +msgstr "" + +#: py/moduerrno.c:149 +msgid "Input/output error" +msgstr "" + +#: py/moduerrno.c:151 +msgid "File exists" +msgstr "" + +#: py/moduerrno.c:152 +msgid "Unsupported operation" +msgstr "" + +#: py/moduerrno.c:153 +msgid "Invalid argument" +msgstr "" + +#: py/obj.c:92 +msgid "Traceback (most recent call last):\n" +msgstr "" + +#: py/obj.c:96 +msgid " File \"%q\", line %d" +msgstr "" + +#: py/obj.c:98 +msgid " File \"%q\"" +msgstr "" + +#: py/obj.c:102 +msgid ", in %q\n" +msgstr "" + +#: py/obj.c:259 +msgid "can't convert to int" +msgstr "" + +#: py/obj.c:262 +#, c-format +msgid "can't convert %s to int" +msgstr "" + +#: py/obj.c:322 +msgid "can't convert to float" +msgstr "" + +#: py/obj.c:325 +#, c-format +msgid "can't convert %s to float" +msgstr "" + +#: py/obj.c:355 +msgid "can't convert to complex" +msgstr "" + +#: py/obj.c:358 +#, c-format +msgid "can't convert %s to complex" +msgstr "" + +#: py/obj.c:373 +msgid "expected tuple/list" +msgstr "" + +#: py/obj.c:376 +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "" + +#: py/obj.c:387 +msgid "tuple/list has wrong length" +msgstr "" + +#: py/obj.c:389 +#, c-format +msgid "requested length %d but object has length %d" +msgstr "" + +#: py/obj.c:402 +msgid "indices must be integers" +msgstr "" + +#: py/obj.c:405 +msgid "%q indices must be integers, not %s" +msgstr "" + +#: py/obj.c:425 +msgid "%q index out of range" +msgstr "" + +#: py/obj.c:457 +msgid "object has no len" +msgstr "" + +#: py/obj.c:460 +#, c-format +msgid "object of type '%s' has no len()" +msgstr "" + +#: py/obj.c:500 +msgid "object does not support item deletion" +msgstr "" + +#: py/obj.c:503 +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "" + +#: py/obj.c:507 +msgid "object is not subscriptable" +msgstr "" + +#: py/obj.c:510 +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "" + +#: py/obj.c:514 +msgid "object does not support item assignment" +msgstr "" + +#: py/obj.c:517 +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "" + +#: py/obj.c:548 +msgid "object with buffer protocol required" +msgstr "" + +#: py/objarray.c:413 py/objstr.c:427 py/objstrunicode.c:191 py/objtuple.c:187 +#: shared-bindings/nvm/ByteArray.c:85 +msgid "only slices with step=1 (aka None) are supported" +msgstr "" + +#: py/objarray.c:426 +msgid "lhs and rhs should be compatible" +msgstr "" + +#: py/objarray.c:444 shared-bindings/nvm/ByteArray.c:107 +msgid "array/bytes required on right side" +msgstr "" + +#: py/objcomplex.c:203 +msgid "can't do truncated division of a complex number" +msgstr "" + +#: py/objcomplex.c:209 +msgid "complex division by zero" +msgstr "" + +#: py/objcomplex.c:237 +msgid "0.0 to a complex power" +msgstr "" + +#: py/objdeque.c:107 +msgid "full" +msgstr "" + +#: py/objdeque.c:127 +msgid "empty" +msgstr "" + +#: py/objdict.c:314 +msgid "popitem(): dictionary is empty" +msgstr "" + +#: py/objdict.c:357 +msgid "dict update sequence has wrong length" +msgstr "" + +#: py/objfloat.c:308 py/parsenum.c:331 +msgid "complex values not supported" +msgstr "" + +#: py/objgenerator.c:108 +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objgenerator.c:126 +msgid "generator already executing" +msgstr "" + +#: py/objgenerator.c:229 +msgid "generator ignored GeneratorExit" +msgstr "" + +#: py/objgenerator.c:251 +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objint.c:144 +msgid "can't convert inf to int" +msgstr "" + +#: py/objint.c:146 +msgid "can't convert NaN to int" +msgstr "" + +#: py/objint.c:163 +msgid "float too big" +msgstr "" + +#: py/objint.c:328 +msgid "long int not supported in this build" +msgstr "" + +#: py/objint.c:334 py/objint.c:340 py/objint.c:350 py/objint.c:358 +msgid "small int overflow" +msgstr "" + +#: py/objint_longlong.c:189 py/objint_mpz.c:283 py/runtime.c:486 +msgid "negative power with no float support" +msgstr "" + +#: py/objint_longlong.c:251 +msgid "ulonglong too large" +msgstr "" + +#: py/objint_mpz.c:267 py/runtime.c:396 py/runtime.c:411 +msgid "negative shift count" +msgstr "" + +#: py/objint_mpz.c:336 +msgid "pow() with 3 arguments requires integers" +msgstr "" + +#: py/objint_mpz.c:347 +msgid "pow() 3rd argument cannot be 0" +msgstr "" + +#: py/objint_mpz.c:415 +msgid "overflow converting long int to machine word" +msgstr "" + +#: py/objlist.c:273 +msgid "pop from empty list" +msgstr "" + +#: py/objnamedtuple.c:92 +msgid "can't set attribute" +msgstr "" + +#: py/objobject.c:55 +msgid "__new__ arg must be a user-type" +msgstr "" + +#: py/objrange.c:110 +msgid "zero step" +msgstr "" + +#: py/objset.c:371 +msgid "pop from an empty set" +msgstr "" + +#: py/objslice.c:66 +msgid "Length must be an int" +msgstr "" + +#: py/objslice.c:71 +msgid "Length must be non-negative" +msgstr "" + +#: py/objslice.c:86 py/sequence.c:57 +msgid "slice step cannot be zero" +msgstr "" + +#: py/objslice.c:159 +msgid "Cannot subclass slice" +msgstr "" + +#: py/objstr.c:261 +msgid "bytes value out of range" +msgstr "" + +#: py/objstr.c:270 +msgid "wrong number of arguments" +msgstr "" + +#: py/objstr.c:467 +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" + +#: py/objstr.c:542 py/objstr.c:647 py/objstr.c:1744 +msgid "empty separator" +msgstr "" + +#: py/objstr.c:641 +msgid "rsplit(None,n)" +msgstr "" + +#: py/objstr.c:713 +msgid "substring not found" +msgstr "" + +#: py/objstr.c:770 +msgid "start/end indices" +msgstr "" + +#: py/objstr.c:931 +msgid "bad format string" +msgstr "" + +#: py/objstr.c:953 +msgid "single '}' encountered in format string" +msgstr "" + +#: py/objstr.c:992 +msgid "bad conversion specifier" +msgstr "" + +#: py/objstr.c:996 +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: py/objstr.c:998 +#, c-format +msgid "unknown conversion specifier %c" +msgstr "" + +#: py/objstr.c:1029 +msgid "unmatched '{' in format" +msgstr "" + +#: py/objstr.c:1036 +msgid "expected ':' after format specifier" +msgstr "" + +#: py/objstr.c:1050 +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c:1055 py/objstr.c:1083 +msgid "tuple index out of range" +msgstr "" + +#: py/objstr.c:1071 +msgid "attributes not supported yet" +msgstr "" + +#: py/objstr.c:1079 +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objstr.c:1171 +msgid "invalid format specifier" +msgstr "" + +#: py/objstr.c:1192 +msgid "sign not allowed in string format specifier" +msgstr "" + +#: py/objstr.c:1200 +msgid "sign not allowed with integer format specifier 'c'" +msgstr "" + +#: py/objstr.c:1259 +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "" + +#: py/objstr.c:1331 +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "" + +#: py/objstr.c:1343 +msgid "'=' alignment not allowed in string format specifier" +msgstr "" + +#: py/objstr.c:1367 +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "" + +#: py/objstr.c:1415 +msgid "format requires a dict" +msgstr "" + +#: py/objstr.c:1424 +msgid "incomplete format key" +msgstr "" + +#: py/objstr.c:1482 +msgid "incomplete format" +msgstr "" + +#: py/objstr.c:1490 +msgid "not enough arguments for format string" +msgstr "" + +#: py/objstr.c:1500 +#, c-format +msgid "%%c requires int or char" +msgstr "" + +#: py/objstr.c:1507 +msgid "integer required" +msgstr "" + +#: py/objstr.c:1570 +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "" + +#: py/objstr.c:1577 +msgid "not all arguments converted during string formatting" +msgstr "" + +#: py/objstr.c:2102 +msgid "can't convert to str implicitly" +msgstr "" + +#: py/objstr.c:2106 +msgid "can't convert '%q' object to %q implicitly" +msgstr "" + +#: py/objstrunicode.c:134 +#, c-format +msgid "string indices must be integers, not %s" +msgstr "" + +#: py/objstrunicode.c:145 py/objstrunicode.c:164 +msgid "string index out of range" +msgstr "" + +#: py/objtype.c:358 +msgid "__init__() should return None" +msgstr "" + +#: py/objtype.c:360 +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "" + +#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +msgid "unreadable attribute" +msgstr "" + +#: py/objtype.c:868 py/runtime.c:653 +msgid "object not callable" +msgstr "" + +#: py/objtype.c:870 py/runtime.c:655 +#, c-format +msgid "'%s' object is not callable" +msgstr "" + +#: py/objtype.c:978 +msgid "type takes 1 or 3 arguments" +msgstr "" + +#: py/objtype.c:989 +msgid "cannot create instance" +msgstr "" + +#: py/objtype.c:991 +msgid "cannot create '%q' instances" +msgstr "" + +#: py/objtype.c:1047 +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/objtype.c:1091 py/objtype.c:1097 +msgid "type is not an acceptable base type" +msgstr "" + +#: py/objtype.c:1100 +msgid "type '%q' is not an acceptable base type" +msgstr "" + +#: py/objtype.c:1137 +msgid "multiple inheritance not supported" +msgstr "" + +#: py/objtype.c:1164 +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c:1205 +msgid "first argument to super() must be type" +msgstr "" + +#: py/objtype.c:1370 +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" + +#: py/objtype.c:1384 +msgid "issubclass() arg 1 must be a class" +msgstr "" + +#: py/parse.c:726 +msgid "constant must be an integer" +msgstr "" + +#: py/parse.c:868 +msgid "Unable to init parser" +msgstr "" + +#: py/parse.c:1170 +msgid "unexpected indent" +msgstr "" + +#: py/parse.c:1173 +msgid "unindent does not match any outer indentation level" +msgstr "" + +#: py/parsenum.c:60 +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "" + +#: py/parsenum.c:151 +msgid "invalid syntax for integer" +msgstr "" + +#: py/parsenum.c:155 +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "" + +#: py/parsenum.c:339 +msgid "invalid syntax for number" +msgstr "" + +#: py/parsenum.c:342 +msgid "decimal numbers not supported" +msgstr "" + +#: py/persistentcode.c:223 +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" + +#: py/persistentcode.c:326 +msgid "can only save bytecode" +msgstr "" + +#: py/runtime.c:206 +msgid "name not defined" +msgstr "" + +#: py/runtime.c:209 +msgid "name '%q' is not defined" +msgstr "" + +#: py/runtime.c:304 py/runtime.c:611 +msgid "unsupported type for operator" +msgstr "" + +#: py/runtime.c:307 +msgid "unsupported type for %q: '%s'" +msgstr "" + +#: py/runtime.c:614 +msgid "unsupported types for %q: '%s', '%s'" +msgstr "" + +#: py/runtime.c:881 py/runtime.c:888 py/runtime.c:945 +msgid "wrong number of values to unpack" +msgstr "" + +#: py/runtime.c:883 py/runtime.c:947 +#, c-format +msgid "need more than %d values to unpack" +msgstr "" + +#: py/runtime.c:890 +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "" + +#: py/runtime.c:984 +msgid "argument has wrong type" +msgstr "" + +#: py/runtime.c:986 +msgid "argument should be a '%q' not a '%q'" +msgstr "" + +#: py/runtime.c:1123 py/runtime.c:1197 +msgid "no such attribute" +msgstr "" + +#: py/runtime.c:1128 +msgid "type object '%q' has no attribute '%q'" +msgstr "" + +#: py/runtime.c:1132 py/runtime.c:1200 +msgid "'%s' object has no attribute '%q'" +msgstr "" + +#: py/runtime.c:1238 +msgid "object not iterable" +msgstr "" + +#: py/runtime.c:1241 +#, c-format +msgid "'%s' object is not iterable" +msgstr "" + +#: py/runtime.c:1260 py/runtime.c:1296 +msgid "object not an iterator" +msgstr "" + +#: py/runtime.c:1262 py/runtime.c:1298 +#, c-format +msgid "'%s' object is not an iterator" +msgstr "" + +#: py/runtime.c:1401 +msgid "exceptions must derive from BaseException" +msgstr "" + +#: py/runtime.c:1430 +msgid "cannot import name %q" +msgstr "" + +#: py/runtime.c:1535 +msgid "memory allocation failed, heap is locked" +msgstr "" + +#: py/runtime.c:1539 +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "" + +#: py/runtime.c:1609 +msgid "maximum recursion depth exceeded" +msgstr "" + +#: py/sequence.c:264 +msgid "object not in sequence" +msgstr "" + +#: py/stream.c:96 +msgid "stream operation not supported" +msgstr "" + +#: py/stream.c:254 +msgid "string not supported; use bytes or bytearray" +msgstr "" + +#: py/stream.c:289 +msgid "length argument not allowed for this type" +msgstr "" + +#: py/vm.c:255 +msgid "local variable referenced before assignment" +msgstr "" + +#: py/vm.c:1142 +msgid "no active exception to reraise" +msgstr "" + +#: py/vm.c:1284 +msgid "byte code not implemented" +msgstr "" + +#: shared-bindings/_stage/Layer.c:71 +msgid "graphic must be 2048 bytes long" +msgstr "" + +#: shared-bindings/_stage/Layer.c:77 shared-bindings/_stage/Text.c:75 +msgid "palette must be 32 bytes long" +msgstr "" + +#: shared-bindings/_stage/Layer.c:84 +msgid "map buffer too small" +msgstr "" + +#: shared-bindings/_stage/Text.c:69 +msgid "font must be 2048 bytes long" +msgstr "" + +#: shared-bindings/_stage/Text.c:81 +msgid "chars buffer too small" +msgstr "" + +#: shared-bindings/analogio/AnalogOut.c:118 +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "" + +#: shared-bindings/audiobusio/I2SOut.c:225 +#: shared-bindings/audioio/AudioOut.c:226 +msgid "Not playing" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:124 +msgid "Bit depth must be multiple of 8." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:128 +msgid "Oversample must be multiple of 8." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:136 +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:193 +msgid "destination_length must be an int >= 0" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:199 +msgid "Cannot record to a file" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:202 +msgid "Destination capacity is smaller than destination_length." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:206 +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:208 +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:94 +msgid "Invalid voice count" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:99 +msgid "Invalid channel count" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:103 +msgid "Sample rate must be positive" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:107 +msgid "bits_per_sample must be 8 or 16" +msgstr "" + +#: shared-bindings/audioio/RawSample.c:98 +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" + +#: shared-bindings/audioio/RawSample.c:104 +msgid "buffer must be a bytes-like object" +msgstr "" + +#: shared-bindings/audioio/WaveFile.c:78 +#: shared-bindings/displayio/OnDiskBitmap.c:85 +msgid "file must be a file opened in byte mode" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 +#: shared-bindings/busio/SPI.c:133 +msgid "Function requires lock" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +msgid "Buffer must be at least length 1" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +msgid "Invalid polarity" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +msgid "Invalid phase" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +msgid "Invalid number of bits" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +msgid "buffer slices must be of equal length" +msgstr "" + +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + +#: shared-bindings/busio/I2C.c:120 +msgid "Function requires lock." +msgstr "" + +#: shared-bindings/busio/UART.c:106 +msgid "bits must be 7, 8 or 9" +msgstr "" + +#: shared-bindings/busio/UART.c:118 +msgid "stop must be 1 or 2" +msgstr "" + +#: shared-bindings/busio/UART.c:123 +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:211 +msgid "Invalid direction." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:240 +msgid "Cannot set value when direction is input." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:266 +#: shared-bindings/digitalio/DigitalInOut.c:281 +msgid "Drive mode not used when direction is input." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:314 +#: shared-bindings/digitalio/DigitalInOut.c:331 +msgid "Pull not used when direction is output." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:340 +msgid "Unsupported pull value." +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:84 +msgid "y should be an int" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:89 +msgid "row buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:94 +msgid "row data must be a buffer" +msgstr "" + +#: shared-bindings/displayio/ColorConverter.c:72 +msgid "color should be an int" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:55 +#: shared-bindings/displayio/FourWire.c:64 +msgid "displayio is a work in progress" +msgstr "" + +#: shared-bindings/displayio/Group.c:65 +msgid "Group must have size at least 1" +msgstr "" + +#: shared-bindings/displayio/Palette.c:96 +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Palette.c:102 +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" + +#: shared-bindings/displayio/Palette.c:106 +msgid "color must be between 0x000000 and 0xffffff" +msgstr "" + +#: shared-bindings/displayio/Palette.c:110 +msgid "color buffer must be a buffer or int" +msgstr "" + +#: shared-bindings/displayio/Palette.c:123 +#: shared-bindings/displayio/Palette.c:137 +msgid "palette_index should be an int" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:48 +msgid "position must be 2-tuple" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:97 +msgid "unsupported bitmap type" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:162 +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "" + +#: shared-bindings/gamepad/GamePad.c:100 +msgid "too many arguments" +msgstr "" + +#: shared-bindings/gamepad/GamePad.c:104 +msgid "expected a DigitalInOut" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:98 +msgid "can't convert address to int" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:101 +msgid "address out of bounds" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:107 +msgid "addresses is empty" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c:89 +#: shared-bindings/neopixel_write/__init__.c:67 +#: shared-bindings/pulseio/PulseOut.c:76 +msgid "Expected a %q" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c:100 +msgid "%q in use" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c:126 +msgid "Invalid run mode." +msgstr "" + +#: shared-bindings/multiterminal/__init__.c:68 +msgid "Stream missing readinto() or write() method." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:99 +msgid "Slice and value different lengths." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:104 +msgid "Array values should be single bytes." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:111 shared-bindings/nvm/ByteArray.c:141 +msgid "Unable to write to nvm." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:137 +msgid "Bytes must be between 0 and 255." +msgstr "" + +#: shared-bindings/os/__init__.c:200 +msgid "No hardware random available" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c:164 +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c:195 +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:275 +msgid "Cannot delete values" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:281 +msgid "Slices not supported" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:287 +msgid "index must be int" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:293 +msgid "Read-only" +msgstr "" + +#: shared-bindings/pulseio/PulseOut.c:135 +msgid "Array must contain halfwords (type 'H')" +msgstr "" + +#: shared-bindings/random/__init__.c:92 shared-bindings/random/__init__.c:100 +msgid "stop not reachable from start" +msgstr "" + +#: shared-bindings/random/__init__.c:111 +msgid "step must be non-zero" +msgstr "" + +#: shared-bindings/random/__init__.c:114 +msgid "invalid step" +msgstr "" + +#: shared-bindings/random/__init__.c:146 +msgid "empty sequence" +msgstr "" + +#: shared-bindings/rtc/RTC.c:40 shared-bindings/rtc/RTC.c:44 +#: shared-bindings/time/__init__.c:190 +msgid "RTC is not supported on this board" +msgstr "" + +#: shared-bindings/rtc/RTC.c:52 +msgid "RTC calibration is not supported on this board" +msgstr "" + +#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:81 +msgid "no available NIC" +msgstr "" + +#: shared-bindings/storage/__init__.c:77 +msgid "filesystem must provide mount method" +msgstr "" + +#: shared-bindings/supervisor/__init__.c:93 +msgid "Brightness must be between 0 and 255" +msgstr "" + +#: shared-bindings/supervisor/__init__.c:119 +msgid "Stack size must be at least 256" +msgstr "" + +#: shared-bindings/time/__init__.c:78 +msgid "sleep length must be non-negative" +msgstr "" + +#: shared-bindings/time/__init__.c:88 +msgid "time.struct_time() takes exactly 1 argument" +msgstr "" + +#: shared-bindings/time/__init__.c:91 +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c:169 shared-bindings/time/__init__.c:263 +msgid "Tuple or struct_time argument required" +msgstr "" + +#: shared-bindings/time/__init__.c:174 shared-bindings/time/__init__.c:268 +msgid "function takes exactly 9 arguments" +msgstr "" + +#: shared-bindings/time/__init__.c:239 shared-bindings/time/__init__.c:272 +msgid "timestamp out of range for platform time_t" +msgstr "" + +#: shared-bindings/touchio/TouchIn.c:173 +msgid "threshold must be in the range 0-65536" +msgstr "" + +#: shared-bindings/util.c:38 +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" + +#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:82 +msgid "Voice index too high" +msgstr "" + +#: shared-module/audioio/Mixer.c:85 +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:88 +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:91 +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:100 +msgid "The sample's signedness does not match the mixer's" +msgstr "" + +#: shared-module/audioio/WaveFile.c:61 +msgid "Invalid wave file" +msgstr "" + +#: shared-module/audioio/WaveFile.c:69 +msgid "Invalid format chunk size" +msgstr "" + +#: shared-module/audioio/WaveFile.c:83 +msgid "Unsupported format" +msgstr "" + +#: shared-module/audioio/WaveFile.c:99 +msgid "Data chunk must follow fmt chunk" +msgstr "" + +#: shared-module/audioio/WaveFile.c:107 +msgid "Invalid file" +msgstr "" + +#: shared-module/bitbangio/I2C.c:58 +msgid "Clock stretch too long" +msgstr "" + +#: shared-module/bitbangio/SPI.c:44 +msgid "Clock pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:50 +msgid "MOSI pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:61 +msgid "MISO pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:121 +msgid "Cannot write without MOSI pin." +msgstr "" + +#: shared-module/bitbangio/SPI.c:176 +msgid "Cannot read without MISO pin." +msgstr "" + +#: shared-module/bitbangio/SPI.c:240 +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "" + +#: shared-module/displayio/Bitmap.c:49 +msgid "Only bit maps of 8 bit color or less are supported" +msgstr "" + +#: shared-module/displayio/Bitmap.c:69 +msgid "row must be packed and word aligned" +msgstr "" + +#: shared-module/displayio/Group.c:39 +msgid "Group full" +msgstr "" + +#: shared-module/displayio/Group.c:48 +msgid "Group empty" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:49 +msgid "Invalid BMP file" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:59 +#, c-format +msgid "Only Windows format, uncompressed BMP supported %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:64 +#, c-format +msgid "Only true color (24 bpp or higher) BMP supported %x" +msgstr "" + +#: shared-module/storage/__init__.c:155 +msgid "Cannot remount '/' when USB is active." +msgstr "" + +#: shared-module/struct/__init__.c:39 +msgid "'S' and 'O' are not supported format types" +msgstr "" + +#: shared-module/struct/__init__.c:83 +msgid "too many arguments provided with the given format" +msgstr "" + +#: shared-module/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "" + +#: shared-module/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "" + +#: shared-module/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "" + +#: supervisor/shared/safe_mode.c:97 +msgid "You requested starting safe mode by " +msgstr "Anda mengajukan untuk memulai mode aman pada (safe mode) pada " + +#: supervisor/shared/safe_mode.c:100 +msgid "To exit, please reset the board without " +msgstr "Untuk keluar, silahkan reset board tanpa " + +#: supervisor/shared/safe_mode.c:107 +#, fuzzy +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" +"Anda sedang menjalankan mode aman (safe mode) yang berarti sesuatu yang " +"sangat buruk telah terjadi.\n" + +#: supervisor/shared/safe_mode.c:109 +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" + +#: supervisor/shared/safe_mode.c:111 +msgid "Crash into the HardFault_Handler.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c:113 +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c:115 +msgid "MicroPython fatal error.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c:118 +#, fuzzy +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"Tegangan dari mikrokontroler turun atau mati. Pastikan sumber tegangan " +"memberikan daya\n" + +#: supervisor/shared/safe_mode.c:120 +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" + +#: supervisor/shared/safe_mode.c:123 +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Sepertinya inti kode CircuitPython kita crash dengan sangat keras. Ups!\n" + +#~ msgid "" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY).\n" +#~ msgstr "" +#~ "tegangan cukup untuk semua sirkuit dan tekan reset (setelah mencabut " +#~ "CIRCUITPY).\n" + +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Silahkan taruh masalah disini dengan isi dari CIRCUITPY drive: anda \n" diff --git a/locale/de_DE.po b/locale/de_DE.po index 691d83762..88471e090 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -2694,12 +2694,23 @@ msgstr "" #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Kann das Merkmal nicht hinzufügen." + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" + #~ msgid "Cannot apply GAP parameters." #~ msgstr "Kann GAP Parameter nicht anwenden." -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." - #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " #~ "CIRCUITPY).\n" @@ -2707,22 +2718,14 @@ msgstr "" #~ "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " #~ "sicheren Auswerfen von CIRCUITPY.)\n" -#~ msgid "Can not query for the device address." -#~ msgstr "Kann nicht nach der Geräteadresse suchen." - -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." - #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Kann UUID in das advertisement packet kodieren." +#~ msgid "Can not query for the device address." +#~ msgstr "Kann nicht nach der Geräteadresse suchen." + #~ msgid "Can not add Service." #~ msgstr "Kann den Dienst nicht hinzufügen." -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "CircuitPython ist abgestürzt. Ups!\n" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." diff --git a/locale/es.po b/locale/es.po index f9debc7f4..be9f47c9d 100644 --- a/locale/es.po +++ b/locale/es.po @@ -2710,15 +2710,33 @@ msgstr "" #~ msgid "Wrong number of bytes provided" #~ msgstr "Numero erroneo de bytes dados" + #~ msgid "Cannot apply GAP parameters." #~ msgstr "No se pueden aplicar los parámetros GAP." #~ msgid "Can not apply device name in the stack." #~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" + +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Baud rate demasiado alto para este periférico SPI" + #~ msgid "Can not encode UUID, to check length." #~ msgstr "No se puede codificar el UUID, para revisar la longitud." +#~ msgid "Can not query for the device address." +#~ msgstr "No se puede consultar la dirección del dispositivo." + +#, fuzzy +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " +#~ "unidad de almacenamiento CIRCUITPY:\n" + #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Se puede codificar el UUID en el paquete de anuncio." @@ -2728,12 +2746,6 @@ msgstr "" #~ msgid "Can not add Service." #~ msgstr "No se puede agregar el Servicio." -#~ msgid "Can not query for the device address." -#~ msgstr "No se puede consultar la dirección del dispositivo." - -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Baud rate demasiado alto para este periférico SPI" - #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" @@ -2746,14 +2758,3 @@ msgstr "" #~ msgstr "" #~ "suficiente poder para todo el circuito y presiona reset (después de " #~ "expulsar CIRCUITPY).\n" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" - -#, fuzzy -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Por favor registra un issue en la siguiente URL con el contenidos de tu " -#~ "unidad de almacenamiento CIRCUITPY:\n" diff --git a/locale/fil.po b/locale/fil.po index ffcdef1dc..a25f6dfb0 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -2727,15 +2727,33 @@ msgstr "" #~ msgid "Wrong number of bytes provided" #~ msgstr "Mali ang bilang ng bytes" + #~ msgid "Cannot apply GAP parameters." #~ msgstr "Hindi ma-apply ang GAP parameters." #~ msgid "Can not apply device name in the stack." #~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" + +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "ang palette ay dapat 32 bytes ang haba" + #~ msgid "Can not encode UUID, to check length." #~ msgstr "Hindi ma-encode UUID, para suriin ang haba." +#~ msgid "Can not query for the device address." +#~ msgstr "Hindi maaaring mag-query para sa address ng device." + +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " +#~ "drive:\n" + #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Maaring i-encode ang UUID sa advertisement packet." @@ -2745,13 +2763,6 @@ msgstr "" #~ msgid "Can not add Service." #~ msgstr "Hindi maidaragdag ang serbisyo." -#~ msgid "Can not query for the device address." -#~ msgstr "Hindi maaaring mag-query para sa address ng device." - -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "ang palette ay dapat 32 bytes ang haba" - #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" @@ -2764,13 +2775,3 @@ msgstr "" #~ msgstr "" #~ "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang " #~ "reset (pagkatapos i-eject ang CIRCUITPY).\n" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" - -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " -#~ "drive:\n" diff --git a/locale/fr.po b/locale/fr.po index 4cca9d8d4..af90c6f6f 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -2766,17 +2766,12 @@ msgstr "" #~ msgstr "" #~ "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" -#~ msgid "Can not add Service." -#~ msgstr "Impossible d'ajouter le Service" - -#~ msgid "Invalid Service type" -#~ msgstr "Type de service invalide" - -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "value_size doit être une puissance de 2" -#~ msgid "Can not query for the device address." -#~ msgstr "Impossible d'obtenir l'adresse du périphérique" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " @@ -2785,19 +2780,27 @@ msgstr "" #~ "assez de puissance pour l'ensemble du circuit et appuyez sur " #~ "'reset' (après avoir éjecter CIRCUITPY).\n" -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossible d'appliquer les paramètres PPCP" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être une displayio.Palette" + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." + +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" + +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." #~ msgid "Can not apply device name in the stack." #~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" +#~ msgid "Can not query for the device address." +#~ msgstr "Impossible d'obtenir l'adresse du périphérique" + #~ msgid "Cannot apply GAP parameters." #~ msgstr "Impossible d'appliquer les paramètres GAP" -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "value_size doit être une puissance de 2" - -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être une displayio.Palette" +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" diff --git a/locale/it_IT.po b/locale/it_IT.po index d08d2d356..cbb497e57 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -2729,15 +2729,29 @@ msgstr "" #~ msgid "Can not apply advertisement data. status: 0x%02x" #~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossibile applicare i parametri GAP." +#~ msgid "" +#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" +#~ msgstr "" +#~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " +#~ "CIRCUITPY:\n" -#~ msgid "Can not apply device name in the stack." -#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Non è possibile aggiungere Characteristic." + +#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +#~ msgstr "" +#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " +#~ "Whoops!\n" #~ msgid "Cannot set PPCP parameters." #~ msgstr "Impossibile impostare i parametri PPCP." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossibile applicare i parametri GAP." + #~ msgid "" #~ "enough power for the whole circuit and press reset (after ejecting " #~ "CIRCUITPY).\n" @@ -2745,25 +2759,14 @@ msgstr "" #~ "abbastanza potenza per l'intero circuito e premere reset (dopo aver " #~ "espulso CIRCUITPY).\n" -#~ msgid "Can not query for the device address." -#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." - -#~ msgid "Can not encode UUID, to check length." -#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." - #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." + #~ msgid "Can not add Service." #~ msgstr "Non è possibile aggiungere Service." -#~ msgid "" -#~ "Please file an issue here with the contents of your CIRCUITPY drive:\n" -#~ msgstr "" -#~ "Ti preghiamo di compilare una issue con il contenuto del tuo drie " -#~ "CIRCUITPY:\n" - -#~ msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" -#~ msgstr "" -#~ "Sembra che il codice del core di CircuitPython sia crashato malamente. " -#~ "Whoops!\n" +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 955a8e198..974bdb41b 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -2670,17 +2670,23 @@ msgstr "" #~ msgid "Invalid UUID parameter" #~ msgstr "Parâmetro UUID inválido" +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possÃvel aplicar dados de anúncio. status: 0x%02x" + #~ msgid "Can not apply device name in the stack." #~ msgstr "Não é possÃvel aplicar o nome do dispositivo na pilha." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Pode codificar o UUID no pacote de anúncios." +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Não é possÃvel aplicar parâmetros GAP." #~ msgid "Invalid Service type" #~ msgstr "Tipo de serviço inválido" -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Não é possÃvel aplicar parâmetros GAP." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Pode codificar o UUID no pacote de anúncios." #~ msgid "Cannot set PPCP parameters." #~ msgstr "Não é possÃvel definir parâmetros PPCP." @@ -2688,11 +2694,8 @@ msgstr "" #~ msgid "Can not query for the device address." #~ msgstr "Não é possÃvel consultar o endereço do dispositivo." -#~ msgid "Baud rate too high for this SPI peripheral" -#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" - -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possÃvel aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Can not add Characteristic." +#~ msgstr "Não é possÃvel adicionar CaracterÃstica." -#~ msgid "Can not add Service." -#~ msgstr "Não é possÃvel adicionar o serviço." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possÃvel definir parâmetros PPCP." diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 91795ab01..852de75f3 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -90,13 +90,13 @@ BASE_CFLAGS = \ ifeq ($(CHIP_FAMILY), samd21) CFLAGS += -Os -DNDEBUG # TinyUSB defines -CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUD_CDC_RX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=128 -DCFG_TUD_MSC_BUFSIZE=512 +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=128 -DCFG_TUD_MSC_BUFSIZE=512 endif ifeq ($(CHIP_FAMILY), samd51) CFLAGS += -Os -DNDEBUG # TinyUSB defines -CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD51 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024 +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD51 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024 endif #Debugging/Optimization @@ -104,9 +104,9 @@ ifeq ($(DEBUG), 1) # Turn on Python modules useful for debugging (e.g. uheap, ustack). CFLAGS += -ggdb # You may want to disable -flto if it interferes with debugging. - CFLAGS += -flto + # CFLAGS += -flto # You may want to enable these flags to make setting breakpoints easier. - # CFLAGS += -fno-inline -fno-ipa-sra + CFLAGS += -fno-inline -fno-ipa-sra ifeq ($(CHIP_FAMILY), samd21) CFLAGS += -DENABLE_MICRO_TRACE_BUFFER endif @@ -267,7 +267,6 @@ SRC_C = \ lib/oofatfs/option/ccsbcs.c \ lib/timeutils/timeutils.c \ lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c \ - lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c \ lib/utils/buffer_helper.c \ lib/utils/context_manager_helpers.c \ lib/utils/interrupt_char.c \ diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst index 6037c7d3b..b0b3bb40e 100644 --- a/ports/atmel-samd/README.rst +++ b/ports/atmel-samd/README.rst @@ -22,51 +22,51 @@ different names. The table below matches the pin order in and omits the pins only available on the largest package because all supported boards use smaller version. -===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================ +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================================ ================ `microcontroller.pin` `board` ---------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -Datasheet arduino_mkrzero arduino_zero circuitplayground_express feather_m0_adalogger feather_m0_basic feather_m0_express gemma_m0 metro_m0_express trinket_m0 -===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================ -PA00 ``ACCELEROMETER_SDA`` ``APA102_MOSI`` ``APA102_MOSI`` -PA01 ``ACCELEROMETER_SCL`` ``APA102_SCK`` ``APA102_SCK`` -PA02 ``A0`` ``A0`` ``A0`` / ``SPEAKER`` ``A0`` ``A0`` ``A0`` ``A0`` / ``D1`` ``A0`` ``D1`` / ``A0`` +--------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Datasheet arduino_mkrzero arduino_zero circuitplayground_express feather_m0_adalogger feather_m0_basic feather_m0_express gemma_m0 metro_m0_express sparkfun_samd21_mini trinket_m0 +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================================ ================ +PA00 ``ACCELEROMETER_SDA`` ``APA102_MOSI`` ``APA102_MOSI`` +PA01 ``ACCELEROMETER_SCL`` ``APA102_SCK`` ``APA102_SCK`` +PA02 ``A0`` ``A0`` ``A0`` / ``SPEAKER`` ``A0`` ``A0`` ``A0`` ``A0`` / ``D1`` ``A0`` ``A0`` ``D1`` / ``A0`` PA03 -PB08 ``L`` ``A1`` ``A7`` / ``TX`` ``A1`` ``A1`` ``A1`` ``A1`` -PB09 ``BATTERY`` ``A2`` ``A6`` / ``RX`` ``A2`` ``A2`` ``A2`` ``A2`` -PA04 ``A3`` ``A3`` ``IR_PROXIMITY`` ``A3`` ``A3`` ``A3`` ``D0`` / ``TX`` / ``SDA`` ``A3`` +PB08 ``L`` ``A1`` ``A7`` / ``TX`` ``A1`` ``A1`` ``A1`` ``A1`` ``A1`` +PB09 ``BATTERY`` ``A2`` ``A6`` / ``RX`` ``A2`` ``A2`` ``A2`` ``A2`` ``A2`` +PA04 ``A3`` ``A3`` ``IR_PROXIMITY`` ``A3`` ``A3`` ``A3`` ``D0`` / ``TX`` / ``SDA`` ``A3`` ``A3`` PA05 ``A4`` ``A4`` ``A1`` ``A4`` ``A4`` ``A4`` ``D2`` / ``RX`` / ``SCL`` ``A4`` -PA06 ``A5`` ``D8`` ``A2`` ``D8`` / ``GREEN_LED`` ``NEOPIXEL`` ``D8`` ``D4`` / ``TX`` -PA07 ``A6`` ``D9`` ``A3`` ``D9`` ``D9`` ``D9`` ``D9`` ``D3`` / ``RX`` -PA08 ``D11`` / ``SDA`` ``D4`` ``MICROPHONE_DO`` ``D4`` / ``SD_CS`` ``D4`` ``D0`` / ``SDA`` -PA09 ``D12`` / ``SCL`` ``D3`` ``TEMPERATURE`` / ``A9`` ``D3`` ``D2`` / ``SCL`` -PA10 ``D2`` ``D1`` / ``TX`` ``MICROPHONE_SCK`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D13`` -PA11 ``D3`` ``D0`` / ``RX`` ``LIGHT`` / ``A8`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` +PA06 ``A5`` ``D8`` ``A2`` ``D8`` / ``GREEN_LED`` ``NEOPIXEL`` ``D8`` ``D8`` ``D4`` / ``TX`` +PA07 ``A6`` ``D9`` ``A3`` ``D9`` ``D9`` ``D9`` ``D9`` ``D9`` ``D3`` / ``RX`` +PA08 ``D11`` / ``SDA`` ``D4`` ``MICROPHONE_DO`` ``D4`` / ``SD_CS`` ``D4`` ``D4`` ``D0`` / ``SDA`` +PA09 ``D12`` / ``SCL`` ``D3`` ``TEMPERATURE`` / ``A9`` ``D3`` ``D3`` ``D2`` / ``SCL`` +PA10 ``D2`` ``D1`` / ``TX`` ``MICROPHONE_SCK`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D13`` +PA11 ``D3`` ``D0`` / ``RX`` ``LIGHT`` / ``A8`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` PB10 ``D4`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` PB11 ``D5`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` PA12 ``SD_MOSI`` ``MISO`` ``REMOTEIN`` / ``IR_RX`` ``MISO`` ``MISO`` ``MISO`` ``MISO`` PA13 ``SD_SCK`` ``ACCELEROMETER_INTERRUPT`` ``FLASH_CS`` -PA14 ``SD_CS`` ``D2`` ``BUTTON_B`` / ``D5`` ``D2`` -PA15 ``SD_MISO`` ``D5`` ``SLIDE_SWITCH`` / ``D7`` ``D5`` ``D5`` ``D5`` ``D5`` -PA16 ``D8`` / ``MOSI`` ``D11`` ``MISO`` ``D11`` ``D11`` ``D11`` ``D11`` -PA17 ``D9`` / ``SCK`` ``D13`` ``D13`` ``D13`` / ``RED_LED`` ``D13`` ``D13`` ``D13`` -PA18 ``D10`` ``D10`` ``D10`` ``D10`` ``D10`` -PA19 ``D10`` / ``MISO`` ``D12`` ``D12`` ``D12`` ``D12`` ``D12`` -PA20 ``D6`` ``D6`` ``MOSI`` ``D6`` ``D6`` ``D6`` ``D6`` -PA21 ``D7`` ``D7`` ``SCK`` ``D7`` / ``SD_CD`` ``D7`` -PA22 ``D0`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` -PA23 ``D1`` ``SCL`` ``REMOTEOUT`` / ``IR_TX`` ``SCL`` ``SCL`` ``SCL`` ``L`` / ``D13`` ``SCL`` +PA14 ``SD_CS`` ``D2`` ``BUTTON_B`` / ``D5`` ``D2`` ``D2`` +PA15 ``SD_MISO`` ``D5`` ``SLIDE_SWITCH`` / ``D7`` ``D5`` ``D5`` ``D5`` ``D5`` ``D5`` +PA16 ``D8`` / ``MOSI`` ``D11`` ``MISO`` ``D11`` ``D11`` ``D11`` ``D11`` ``D11`` / ``MOSI`` +PA17 ``D9`` / ``SCK`` ``D13`` ``D13`` ``D13`` / ``RED_LED`` ``D13`` ``D13`` ``D13`` ``D13`` / ``SCK`` / ``BLUE_LED`` +PA18 ``D10`` ``D10`` ``D10`` ``D10`` ``D10`` ``D10`` +PA19 ``D10`` / ``MISO`` ``D12`` ``D12`` ``D12`` ``D12`` ``D12`` ``D12`` / ``MISO`` +PA20 ``D6`` ``D6`` ``MOSI`` ``D6`` ``D6`` ``D6`` ``D6`` ``D6`` +PA21 ``D7`` ``D7`` ``SCK`` ``D7`` / ``SD_CD`` ``D7`` ``D7`` +PA22 ``D0`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` +PA23 ``D1`` ``SCL`` ``REMOTEOUT`` / ``IR_TX`` ``SCL`` ``SCL`` ``SCL`` ``L`` / ``D13`` ``SCL`` ``SCL`` PA24 PA25 PB22 ``D14`` / ``TX`` ``FLASH_CS`` PB23 ``D13`` / ``RX`` ``NEOPIXEL`` / ``D8`` -PA27 ``SD_CD`` +PA27 ``SD_CD`` ``GREEN_LED`` PA28 ``BUTTON_A`` / ``D4`` PA29 PA30 ``SPEAKER_ENABLE`` ``NEOPIXEL`` PA31 PB02 ``A1`` ``A5`` ``A5`` / ``SDA`` ``A5`` ``A5`` ``A5`` ``A5`` -PB03 ``A2`` ``A4`` / ``SCL`` -===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================ +PB03 ``A2`` ``A4`` / ``SCL`` ``YELLOW_LED`` +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================================ ================ Here is a table about which pins can do what in CircuitPython terms. However, just because something is listed, doesn't mean it will always work. Existing use diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c b/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c new file mode 100644 index 000000000..0f60736a2 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.h b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.h new file mode 100644 index 000000000..aec54ddfb --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.h @@ -0,0 +1,24 @@ +#define MICROPY_HW_BOARD_NAME "SparkFun SAMD21 Mini Breakout" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 0 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA16) +#define DEFAULT_SPI_BUS_MISO (&pin_PA19) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk new file mode 100644 index 000000000..0cba15d70 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk @@ -0,0 +1,11 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x1B4F +USB_PID = 0x8D22 +USB_PRODUCT = "SparkFun SAMD21 Mini Breakout" +USB_MANUFACTURER = "SparkFun" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c b/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c new file mode 100644 index 000000000..abe63d064 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c @@ -0,0 +1,53 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + + // Analog pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + + // Digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + + // UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + + // SPI pins + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA19) }, + + // I2C pins + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + + // LED pins + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_YELLOW_LED), MP_ROM_PTR(&pin_PB03) }, + + // Comm objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index d0ebbfa39..65b8c94c5 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -237,6 +237,7 @@ extern const struct _mp_obj_module_t gamepad_module; extern const struct _mp_obj_module_t stage_module; extern const struct _mp_obj_module_t touchio_module; extern const struct _mp_obj_module_t usb_hid_module; +extern const struct _mp_obj_module_t usb_midi_module; extern const struct _mp_obj_module_t network_module; extern const struct _mp_obj_module_t socket_module; extern const struct _mp_obj_module_t wiznet_module; @@ -382,6 +383,7 @@ extern const struct _mp_obj_module_t wiznet_module; { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR__time), (mp_obj_t)&time_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_usb_midi),(mp_obj_t)&usb_midi_module }, \ TOUCHIO_MODULE \ EXTRA_BUILTIN_MODULES @@ -410,6 +412,7 @@ extern const struct _mp_obj_module_t wiznet_module; { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_usb_midi),(mp_obj_t)&usb_midi_module }, \ TOUCHIO_MODULE \ EXTRA_BUILTIN_MODULES #endif diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 2e345b9c7..2bc508475 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -75,7 +75,7 @@ LDFLAGS += -mthumb -mabi=aapcs -T $(LD_FILE) -L boards/ LDFLAGS += -Wl,--gc-sections # TinyUSB defines -CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128 #Debugging/Optimization ifeq ($(DEBUG), 1) @@ -103,6 +103,7 @@ SRC_NRFX = $(addprefix nrfx/,\ drivers/src/nrfx_timer.c \ drivers/src/nrfx_twim.c \ drivers/src/nrfx_uarte.c \ + drivers/src/nrfx_gpiote.c \ ) ifdef EXTERNAL_FLASH_DEVICES diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c index 85f3b6b6c..710825960 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/bleio/Peripheral.c @@ -100,6 +100,10 @@ STATIC uint32_t add_services_to_advertisement(bleio_peripheral_obj_t *self, size +// if raw_data is a zero-length buffer, generate an advertising packet that advertises the +// services passed in when this Peripheral was created. +// If raw_data contains some bytes, use those bytes as the advertising packet. +// TODO: Generate the advertising packet in Python, not here. STATIC uint32_t set_advertisement_data(bleio_peripheral_obj_t *self, bool connectable, mp_buffer_info_t *raw_data) { common_hal_bleio_adapter_set_enabled(true); diff --git a/ports/nrf/common-hal/neopixel_write/__init__.c b/ports/nrf/common-hal/neopixel_write/__init__.c index 76bc170e8..f47188ea2 100644 --- a/ports/nrf/common-hal/neopixel_write/__init__.c +++ b/ports/nrf/common-hal/neopixel_write/__init__.c @@ -141,7 +141,7 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout for ( uint16_t n = 0; n < numBytes; n++ ) { uint8_t pix = pixels[n]; - for ( uint8_t mask = 0x80, i = 0; mask > 0; mask >>= 1, i++ ) { + for ( uint8_t mask = 0x80; mask > 0; mask >>= 1 ) { pixels_pattern[pos] = (pix & mask) ? MAGIC_T1H : MAGIC_T0H; pos++; } diff --git a/ports/nrf/common-hal/pulseio/PulseIn.c b/ports/nrf/common-hal/pulseio/PulseIn.c index 3d6d266af..6e5825af6 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.c +++ b/ports/nrf/common-hal/pulseio/PulseIn.c @@ -27,6 +27,7 @@ #include "common-hal/pulseio/PulseIn.h" #include <stdint.h> +#include <string.h> #include "py/mpconfig.h" #include "py/gc.h" @@ -35,50 +36,247 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/pulseio/PulseIn.h" +#include "tick.h" +#include "nrfx_gpiote.h" + +// obj array to map pin -> self since nrfx hide the mapping +static pulseio_pulsein_obj_t* _objs[GPIOTE_CH_NUM]; + +// return index of the object in array +static int _find_pulsein_obj(pulseio_pulsein_obj_t* obj) { + for(int i = 0; i < NRFX_ARRAY_SIZE(_objs); i++ ) { + if ( _objs[i] == obj) { + return i; + } + } + + return -1; +} + +static void _pulsein_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { + // Grab the current time first. + uint32_t current_us; + uint64_t current_ms; + current_tick(¤t_ms, ¤t_us); + + // current_tick gives us the remaining us until the next tick but we want the number since the last ms. + current_us = 1000 - current_us; + + pulseio_pulsein_obj_t* self = NULL; + for(int i = 0; i < NRFX_ARRAY_SIZE(_objs); i++ ) { + if ( _objs[i] && _objs[i]->pin == pin ) { + self = _objs[i]; + break; + } + } + if ( !self ) return; + + if (self->first_edge) { + // first pulse is opposite state from idle + bool state = nrf_gpio_pin_read(self->pin); + if ( self->idle_state != state ) { + self->first_edge = false; + } + }else { + uint32_t ms_diff = current_ms - self->last_ms; + uint16_t us_diff = current_us - self->last_us; + uint32_t total_diff = us_diff; + + if (self->last_us > current_us) { + total_diff = 1000 + current_us - self->last_us; + if (ms_diff > 1) { + total_diff += (ms_diff - 1) * 1000; + } + } else { + total_diff += ms_diff * 1000; + } + uint16_t duration = 0xffff; + if (total_diff < duration) { + duration = total_diff; + } + + uint16_t i = (self->start + self->len) % self->maxlen; + self->buffer[i] = duration; + if (self->len < self->maxlen) { + self->len++; + } else { + self->start++; + } + } + + self->last_ms = current_ms; + self->last_us = current_us; +} + void pulsein_reset(void) { + if ( nrfx_gpiote_is_init() ) { + nrfx_gpiote_uninit(); + } + nrfx_gpiote_init(); + memset(_objs, 0, sizeof(_objs)); } void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) { - mp_raise_NotImplementedError(NULL); + int idx = _find_pulsein_obj(NULL); + if ( idx < 0 ) { + mp_raise_NotImplementedError(NULL); + } + _objs[idx] = self; + + self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false); + if (self->buffer == NULL) { + mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), maxlen * sizeof(uint16_t)); + } + + self->pin = pin->number; + self->maxlen = maxlen; + self->idle_state = idle_state; + self->start = 0; + self->len = 0; + self->first_edge = true; + self->paused = false; + self->last_us = 0; + self->last_ms = 0; + + claim_pin(pin); + + nrfx_gpiote_in_config_t cfg = { + .sense = NRF_GPIOTE_POLARITY_TOGGLE, + .pull = NRF_GPIO_PIN_NOPULL, // idle_state ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_PULLUP, + .is_watcher = false, // nrf_gpio_cfg_watcher vs nrf_gpio_cfg_input + .hi_accuracy = true, + .skip_gpio_setup = false + }; + nrfx_gpiote_in_init(self->pin, &cfg, _pulsein_handler); + nrfx_gpiote_in_event_enable(self->pin, true); } bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) { - return 1; + return self->pin == NO_PIN; } void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { + if (common_hal_pulseio_pulsein_deinited(self)) { + return; + } + + nrfx_gpiote_in_event_disable(self->pin); + nrfx_gpiote_in_uninit(self->pin); + + // mark local array as invalid + int idx = _find_pulsein_obj(self); + if ( idx < 0 ) { + mp_raise_NotImplementedError(NULL); + } + _objs[idx] = NULL; + reset_pin_number(self->pin); + self->pin = NO_PIN; } void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) { - + nrfx_gpiote_in_event_disable(self->pin); + self->paused = true; } void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t trigger_duration) { + // Make sure we're paused. + if ( !self->paused ) { + common_hal_pulseio_pulsein_pause(self); + } + + // Send the trigger pulse. + if (trigger_duration > 0) { + nrfx_gpiote_in_uninit(self->pin); + + nrf_gpio_cfg_output(self->pin); + nrf_gpio_pin_write(self->pin, !self->idle_state); + common_hal_mcu_delay_us((uint32_t)trigger_duration); + nrf_gpio_pin_write(self->pin, self->idle_state); + + nrfx_gpiote_in_config_t cfg = { + .sense = NRF_GPIOTE_POLARITY_TOGGLE, + .pull = NRF_GPIO_PIN_NOPULL, // idle_state ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_PULLUP, + .is_watcher = false, // nrf_gpio_cfg_watcher vs nrf_gpio_cfg_input + .hi_accuracy = true, + .skip_gpio_setup = false + }; + nrfx_gpiote_in_init(self->pin, &cfg, _pulsein_handler); + } + + self->first_edge = true; + self->paused = false; + self->last_ms = 0; + self->last_us = 0; + nrfx_gpiote_in_event_enable(self->pin, true); } void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) { + if ( !self->paused ) { + nrfx_gpiote_in_event_disable(self->pin); + } + self->start = 0; + self->len = 0; + + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } +} + +uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) { + if ( !self->paused ) { + nrfx_gpiote_in_event_disable(self->pin); + } + + if (index < 0) { + index += self->len; + } + if (index < 0 || index >= self->len) { + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } + mp_raise_IndexError(translate("index out of range")); + } + uint16_t value = self->buffer[(self->start + index) % self->maxlen]; + + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } + + return value; } uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) { - return 0; + if (self->len == 0) { + mp_raise_IndexError(translate("pop from an empty PulseIn")); + } + + if ( !self->paused ) { + nrfx_gpiote_in_event_disable(self->pin); + } + + uint16_t value = self->buffer[self->start]; + self->start = (self->start + 1) % self->maxlen; + self->len--; + + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } + + return value; } uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) { - return 0xadaf; + return self->maxlen; } bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) { - return false; + return self->paused; } uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) { - return 0xadaf; -} - -uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) { - return 0xadaf; + return self->len; } diff --git a/ports/nrf/common-hal/pulseio/PulseIn.h b/ports/nrf/common-hal/pulseio/PulseIn.h index 666f5a164..4b2c6eee3 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.h +++ b/ports/nrf/common-hal/pulseio/PulseIn.h @@ -33,15 +33,19 @@ typedef struct { mp_obj_base_t base; - uint8_t channel; + uint8_t pin; + bool idle_state; + bool paused; + volatile bool first_edge; + uint16_t* buffer; uint16_t maxlen; - bool idle_state; + volatile uint16_t start; volatile uint16_t len; - volatile bool first_edge; - uint16_t ticks_per_ms; + volatile uint16_t last_us; + volatile uint64_t last_ms; } pulseio_pulsein_obj_t; void pulsein_reset(void); diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 25710cea2..d38b14578 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -175,6 +175,7 @@ extern const struct _mp_obj_module_t supervisor_module; extern const struct _mp_obj_module_t gamepad_module; extern const struct _mp_obj_module_t neopixel_write_module; extern const struct _mp_obj_module_t usb_hid_module; +extern const struct _mp_obj_module_t usb_midi_module; extern const struct _mp_obj_module_t bleio_module; #if MICROPY_PY_BLEIO @@ -207,6 +208,7 @@ extern const struct _mp_obj_module_t bleio_module; { MP_OBJ_NEW_QSTR (MP_QSTR_time ), (mp_obj_t)&time_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_json ), (mp_obj_t)&mp_module_ujson }, \ USBHID_MODULE \ + { MP_OBJ_NEW_QSTR(MP_QSTR_usb_midi),(mp_obj_t)&usb_midi_module }, \ BLEIO_MODULE // extra built in names to add to the global namespace diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h index 1d3085e2b..8676bd7f8 100644 --- a/ports/nrf/nrfx_config.h +++ b/ports/nrf/nrfx_config.h @@ -84,4 +84,9 @@ #define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 7 +// GPIO interrupt +#define NRFX_GPIOTE_ENABLED 1 +#define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1 +#define NRFX_GPIOTE_CONFIG_IRQ_PRIORITY 7 + #endif // NRFX_CONFIG_H__ diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index cf0434793..b2e98fd5b 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -43,6 +43,7 @@ #include "common-hal/busio/SPI.h" #include "common-hal/pulseio/PWMOut.h" #include "common-hal/pulseio/PulseOut.h" +#include "common-hal/pulseio/PulseIn.h" #include "tick.h" static void power_warning_handler(void) { @@ -85,6 +86,7 @@ void reset_port(void) { spi_reset(); pwmout_reset(); pulseout_reset(); + pulsein_reset(); timers_reset(); bleio_reset(); diff --git a/shared-bindings/bleio/Peripheral.c b/shared-bindings/bleio/Peripheral.c index 1027bbb1f..cea44486f 100644 --- a/shared-bindings/bleio/Peripheral.c +++ b/shared-bindings/bleio/Peripheral.c @@ -192,7 +192,8 @@ const mp_obj_property_t bleio_peripheral_name_obj = { //| services are included in the advertisement packets. //| //| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral. -//| :param buf data: If not None, then send data bytes in advertising packets. +//| :param buf data: If `None`, advertise the services passed to this Peripheral when it was created. +//| If not `None`, then send the bytes in ``data`` as the advertising packet. //| STATIC mp_obj_t bleio_peripheral_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); diff --git a/shared-bindings/usb_midi/PortIn.c b/shared-bindings/usb_midi/PortIn.c new file mode 100644 index 000000000..e1e6eabcc --- /dev/null +++ b/shared-bindings/usb_midi/PortIn.c @@ -0,0 +1,128 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 <stdint.h> + +#include "shared-bindings/usb_midi/PortIn.h" +#include "shared-bindings/util.h" + +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: usb_midi +//| +//| :class:`PortIn` -- receives midi commands over USB +//| =================================================== +//| +//| .. class:: PortIn() +//| +//| Not currently dynamically supported. +//| +//| PortIn objects are constructed for every corresponding entry in the USB descriptor and added +//| to the ``usb_midi.ports`` tuple. +//| + +STATIC mp_obj_t usb_midi_portin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + return mp_const_none; +} + +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: read(nbytes=None) +//| +//| Read characters. If ``nbytes`` is specified then read at most that many +//| bytes. Otherwise, read everything that arrives until the connection +//| times out. Providing the number of bytes expected is highly recommended +//| because it will be faster. +//| +//| :return: Data read +//| :rtype: bytes or None +//| +//| .. method:: readinto(buf, nbytes=None) +//| +//| Read bytes into the ``buf``. If ``nbytes`` is specified then read at most +//| that many bytes. Otherwise, read at most ``len(buf)`` bytes. +//| +//| :return: number of bytes read and stored into ``buf`` +//| :rtype: bytes or None +//| + +// These three methods are used by the shared stream methods. +STATIC mp_uint_t usb_midi_portin_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + usb_midi_portin_obj_t *self = MP_OBJ_TO_PTR(self_in); + byte *buf = buf_in; + + // make sure we want at least 1 char + if (size == 0) { + return 0; + } + + return common_hal_usb_midi_portin_read(self, buf, size, errcode); +} + +STATIC mp_uint_t usb_midi_portin_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + usb_midi_portin_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_midi_portin_bytes_available(self) > 0) { + ret |= MP_IOCTL_POLL_RD; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +STATIC const mp_rom_map_elem_t usb_midi_portin_locals_dict_table[] = { + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(usb_midi_portin_locals_dict, usb_midi_portin_locals_dict_table); + +STATIC const mp_stream_p_t usb_midi_portin_stream_p = { + .read = usb_midi_portin_read, + .write = NULL, + .ioctl = usb_midi_portin_ioctl, + .is_text = false, +}; + +const mp_obj_type_t usb_midi_portin_type = { + { &mp_type_type }, + .name = MP_QSTR_PortIn, + .make_new = usb_midi_portin_make_new, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &usb_midi_portin_stream_p, + .locals_dict = (mp_obj_dict_t*)&usb_midi_portin_locals_dict, +}; diff --git a/shared-bindings/usb_midi/PortIn.h b/shared-bindings/usb_midi/PortIn.h new file mode 100644 index 000000000..89bb59b71 --- /dev/null +++ b/shared-bindings/usb_midi/PortIn.h @@ -0,0 +1,44 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTIN_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTIN_H + +#include "shared-module/usb_midi/PortIn.h" + +extern const mp_obj_type_t usb_midi_portin_type; + +// Construct an underlying UART object. +extern void common_hal_usb_midi_portin_construct(usb_midi_portin_obj_t *self, + uint8_t receiver_buffer_size); +// Read characters. +extern size_t common_hal_usb_midi_portin_read(usb_midi_portin_obj_t *self, + uint8_t *data, size_t len, int *errcode); + +extern uint32_t common_hal_usb_midi_portin_bytes_available(usb_midi_portin_obj_t *self); +extern void common_hal_usb_midi_portin_clear_buffer(usb_midi_portin_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTIN_H diff --git a/shared-bindings/usb_midi/PortOut.c b/shared-bindings/usb_midi/PortOut.c new file mode 100644 index 000000000..0588eed90 --- /dev/null +++ b/shared-bindings/usb_midi/PortOut.c @@ -0,0 +1,110 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 <stdint.h> + +#include "shared-bindings/usb_midi/PortOut.h" +#include "shared-bindings/util.h" + +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: usb_midi +//| +//| :class:`PortOut` -- sends midi messages to a computer over USB +//| ============================================================== +//| +//| .. class:: PortOut() +//| +//| Not currently dynamically supported. +//| +//| PortOut objects are constructed for every corresponding entry in the USB descriptor and added +//| to the ``usb_midi.ports`` tuple. +//| + +STATIC mp_obj_t usb_midi_portout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + return mp_const_none; +} + +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: write(buf) +//| +//| Write the buffer of bytes to the bus. +//| +//| :return: the number of bytes written +//| :rtype: int or None +//| + +STATIC mp_uint_t usb_midi_portout_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in); + const byte *buf = buf_in; + + return common_hal_usb_midi_portout_write(self, buf, size, errcode); +} + +STATIC mp_uint_t usb_midi_portout_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_midi_portout_ready_to_tx(self)) { + ret |= MP_IOCTL_POLL_WR; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +STATIC const mp_rom_map_elem_t usb_midi_portout_locals_dict_table[] = { + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(usb_midi_portout_locals_dict, usb_midi_portout_locals_dict_table); + +STATIC const mp_stream_p_t usb_midi_portout_stream_p = { + .read = NULL, + .write = usb_midi_portout_write, + .ioctl = usb_midi_portout_ioctl, + .is_text = false, +}; + +const mp_obj_type_t usb_midi_portout_type = { + { &mp_type_type }, + .name = MP_QSTR_PortOut, + .make_new = usb_midi_portout_make_new, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &usb_midi_portout_stream_p, + .locals_dict = (mp_obj_dict_t*)&usb_midi_portout_locals_dict, +}; diff --git a/shared-bindings/usb_midi/PortOut.h b/shared-bindings/usb_midi/PortOut.h new file mode 100644 index 000000000..dd42d7cdb --- /dev/null +++ b/shared-bindings/usb_midi/PortOut.h @@ -0,0 +1,44 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTOUT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTOUT_H + +#include "shared-module/usb_midi/PortOut.h" + +extern const mp_obj_type_t usb_midi_portout_type; + +// Construct an underlying UART object. +extern void common_hal_usb_midi_portout_construct(usb_midi_portout_obj_t *self, + uint8_t receiver_buffer_size); + +// Write characters. len is in characters NOT bytes! +extern size_t common_hal_usb_midi_portout_write(usb_midi_portout_obj_t *self, + const uint8_t *data, size_t len, int *errcode); + +extern bool common_hal_usb_midi_portout_ready_to_tx(usb_midi_portout_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTOUT_H diff --git a/shared-bindings/usb_midi/__init__.c b/shared-bindings/usb_midi/__init__.c new file mode 100644 index 000000000..f57d3631b --- /dev/null +++ b/shared-bindings/usb_midi/__init__.c @@ -0,0 +1,78 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 <stdint.h> + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/usb_midi/__init__.h" +#include "shared-bindings/usb_midi/PortIn.h" +#include "shared-bindings/usb_midi/PortOut.h" + +#include "py/runtime.h" + +//| :mod:`usb_midi` --- MIDI over USB +//| ================================================= +//| +//| .. module:: usb_midi +//| :synopsis: MIDI over USB +//| +//| The `usb_midi` module contains classes to transmit and receive MIDI messages over USB +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| PortIn +//| PortOut +//| +//| +mp_map_elem_t usb_midi_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usb_midi) }, + { MP_ROM_QSTR(MP_QSTR_ports), mp_const_empty_tuple }, + { MP_ROM_QSTR(MP_QSTR_PortIn), MP_OBJ_FROM_PTR(&usb_midi_portin_type) }, + { MP_ROM_QSTR(MP_QSTR_PortOut), MP_OBJ_FROM_PTR(&usb_midi_portout_type) }, +}; + +// This isn't const so we can set ports dynamically. +mp_obj_dict_t usb_midi_module_globals = { + .base = {&mp_type_dict}, + .map = { + .all_keys_are_qstrs = 1, + .is_fixed = 1, + .is_ordered = 1, + .used = MP_ARRAY_SIZE(usb_midi_module_globals_table), + .alloc = MP_ARRAY_SIZE(usb_midi_module_globals_table), + .table = usb_midi_module_globals_table, + }, +}; + +const mp_obj_module_t usb_midi_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&usb_midi_module_globals, +}; diff --git a/shared-bindings/usb_midi/__init__.h b/shared-bindings/usb_midi/__init__.h new file mode 100644 index 000000000..e81818e04 --- /dev/null +++ b/shared-bindings/usb_midi/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H + +#include "py/obj.h" + +extern mp_obj_dict_t usb_midi_module_globals; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H diff --git a/shared-module/usb_midi/PortIn.c b/shared-module/usb_midi/PortIn.c new file mode 100644 index 000000000..b256c5937 --- /dev/null +++ b/shared-module/usb_midi/PortIn.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-module/usb_midi/PortIn.h" +#include "supervisor/shared/translate.h" +#include "tusb.h" + +void common_hal_usb_midi_portin_construct(usb_midi_portin_obj_t *self, uint8_t receiver_buffer_size) { +} + +size_t common_hal_usb_midi_portin_read(usb_midi_portin_obj_t *self, uint8_t *data, size_t len, int *errcode) { + return tud_midi_read(data, len); +} + +uint32_t common_hal_usb_midi_portin_bytes_available(usb_midi_portin_obj_t *self) { + return tud_midi_available(); +} diff --git a/shared-module/usb_midi/PortIn.h b/shared-module/usb_midi/PortIn.h new file mode 100644 index 000000000..2f72aa4c2 --- /dev/null +++ b/shared-module/usb_midi/PortIn.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_MODULE_USB_MIDI_PORTIN_H +#define SHARED_MODULE_USB_MIDI_PORTIN_H + +#include <stdint.h> +#include <stdbool.h> + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} usb_midi_portin_obj_t; + +#endif /* SHARED_MODULE_USB_MIDI_PORTIN_H */ diff --git a/shared-module/usb_midi/PortOut.c b/shared-module/usb_midi/PortOut.c new file mode 100644 index 000000000..3b9998c73 --- /dev/null +++ b/shared-module/usb_midi/PortOut.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-module/usb_midi/PortOut.h" +#include "supervisor/shared/translate.h" +#include "tusb.h" + +void common_hal_usb_midi_portout_construct(usb_midi_portout_obj_t *self) { +} + +size_t common_hal_usb_midi_portout_write(usb_midi_portout_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + return tud_midi_write(0, data, len); +} + +bool common_hal_usb_midi_portout_ready_to_tx(usb_midi_portout_obj_t *self) { + return tud_midi_connected(); +} diff --git a/shared-module/usb_midi/PortOut.h b/shared-module/usb_midi/PortOut.h new file mode 100644 index 000000000..6b1b88464 --- /dev/null +++ b/shared-module/usb_midi/PortOut.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_MODULE_USB_MIDI_PORTOUT_H +#define SHARED_MODULE_USB_MIDI_PORTOUT_H + +#include <stdint.h> +#include <stdbool.h> + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} usb_midi_portout_obj_t; + +#endif /* SHARED_MODULE_USB_MIDI_PORTOUT_H */ diff --git a/shared-module/usb_midi/__init__.c b/shared-module/usb_midi/__init__.c new file mode 100644 index 000000000..73a314b99 --- /dev/null +++ b/shared-module/usb_midi/__init__.c @@ -0,0 +1,63 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "shared-bindings/usb_midi/__init__.h" + +#include "genhdr/autogen_usb_descriptor.h" +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/objtuple.h" +#include "shared-bindings/usb_midi/PortIn.h" +#include "shared-bindings/usb_midi/PortOut.h" +#include "supervisor/memory.h" +#include "tusb.h" + +supervisor_allocation* usb_midi_allocation; + +void usb_midi_init(void) { + // TODO(tannewt): Make this dynamic. + uint16_t tuple_size = align32_size(sizeof(mp_obj_tuple_t) + sizeof(mp_obj_t*) * 2); + uint16_t portin_size = align32_size(sizeof(usb_midi_portin_obj_t)); + uint16_t portout_size = align32_size(sizeof(usb_midi_portout_obj_t)); + + // For each embedded MIDI Jack in the descriptor we create a Port + usb_midi_allocation = allocate_memory(tuple_size + portin_size + portout_size, false); + + mp_obj_tuple_t *ports = (mp_obj_tuple_t *) usb_midi_allocation->ptr; + ports->base.type = &mp_type_tuple; + ports->len = 2; + + usb_midi_portin_obj_t* in = (usb_midi_portin_obj_t *) (usb_midi_allocation->ptr + tuple_size / 4); + in->base.type = &usb_midi_portin_type; + ports->items[0] = MP_OBJ_FROM_PTR(in); + + usb_midi_portout_obj_t* out = (usb_midi_portout_obj_t *) (usb_midi_allocation->ptr + tuple_size / 4 + portin_size / 4); + out->base.type = &usb_midi_portout_type; + ports->items[1] = MP_OBJ_FROM_PTR(out); + + mp_map_lookup(&usb_midi_module_globals.map, MP_ROM_QSTR(MP_QSTR_ports), MP_MAP_LOOKUP)->value = MP_OBJ_FROM_PTR(ports); +} diff --git a/shared-module/usb_midi/__init__.h b/shared-module/usb_midi/__init__.h new file mode 100644 index 000000000..e1ad1fbaf --- /dev/null +++ b/shared-module/usb_midi/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_MODULE_USB_MIDI___INIT___H +#define SHARED_MODULE_USB_MIDI___INIT___H + +void usb_midi_init(void); + +#endif /* SHARED_MODULE_USB_MIDI___INIT___H */ diff --git a/supervisor/memory.h b/supervisor/memory.h index 4f8317a2d..c89f14bd9 100755 --- a/supervisor/memory.h +++ b/supervisor/memory.h @@ -39,6 +39,8 @@ typedef struct { uint32_t length; // in bytes } supervisor_allocation; + + void memory_init(void); void free_memory(supervisor_allocation* allocation); supervisor_allocation* allocate_remaining_memory(void); @@ -48,4 +50,11 @@ supervisor_allocation* allocate_remaining_memory(void); // statically allocated memory. supervisor_allocation* allocate_memory(uint32_t length, bool high_address); +static inline uint16_t align32_size(uint16_t size) { + if (size % 4 != 0) { + return (size & 0xfffc) + 0x4; + } + return size; +} + #endif // MICROPY_INCLUDED_SUPERVISOR_MEMORY_H diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h index 649c390ac..301805275 100644 --- a/supervisor/shared/usb/tusb_config.h +++ b/supervisor/shared/usb/tusb_config.h @@ -75,6 +75,7 @@ #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 1 #define CFG_TUD_HID 1 +#define CFG_TUD_MIDI 1 #define CFG_TUD_CUSTOM_CLASS 0 /*------------------------------------------------------------------*/ diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 1aa34e9e6..5898323e8 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -26,6 +26,7 @@ #include "tick.h" #include "shared-bindings/microcontroller/Processor.h" +#include "shared-module/usb_midi/__init__.h" #include "supervisor/port.h" #include "supervisor/usb.h" #include "lib/utils/interrupt_char.h" @@ -71,11 +72,13 @@ void usb_init(void) { // This callback always got invoked regardless of mp_interrupt_char value since we only set it once here tud_cdc_set_wanted_char(CHAR_CTRL_C); #endif + + usb_midi_init(); } void usb_background(void) { if (usb_enabled()) { - tusb_task(); + tud_task(); tud_cdc_write_flush(); } } diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 56ad8a3ba..191af7b25 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -49,6 +49,7 @@ else lib/tinyusb/src/class/msc/msc_device.c \ lib/tinyusb/src/class/cdc/cdc_device.c \ lib/tinyusb/src/class/hid/hid_device.c \ + lib/tinyusb/src/class/midi/midi_device.c \ lib/tinyusb/src/tusb.c \ supervisor/shared/serial.c \ supervisor/usb.c \ @@ -57,8 +58,14 @@ else supervisor/shared/usb/usb_msc_flash.c \ shared-bindings/usb_hid/__init__.c \ shared-bindings/usb_hid/Device.c \ + shared-bindings/usb_midi/__init__.c \ + shared-bindings/usb_midi/PortIn.c \ + shared-bindings/usb_midi/PortOut.c \ shared-module/usb_hid/__init__.c \ shared-module/usb_hid/Device.c \ + shared-module/usb_midi/__init__.c \ + shared-module/usb_midi/PortIn.c \ + shared-module/usb_midi/PortOut.c \ $(BUILD)/autogen_usb_descriptor.c CFLAGS += -DUSB_AVAILABLE endif diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py index 2cb06ec2f..10bbf5066 100644 --- a/tools/gen_usb_descriptor.py +++ b/tools/gen_usb_descriptor.py @@ -176,16 +176,33 @@ hid_interfaces = [ ] # Audio! -midi_in_jack = midi.InJackDescriptor( - description="MIDI PC <- CircuitPython internals", +# In and out here are relative to CircuitPython + +# USB OUT -> midi_in_jack_emb -> midi_out_jack_ext -> CircuitPython +midi_in_jack_emb = midi.InJackDescriptor( + description="MIDI PC -> CircuitPython", bJackType=midi.JACK_TYPE_EMBEDDED, - iJack=0) -midi_out_jack = midi.OutJackDescriptor( - description="MIDI PC -> CircuitPython internals", + iJack=StringIndex.index("CircuitPython usb_midi.ports[0]")) +midi_out_jack_ext = midi.OutJackDescriptor( + description="MIDI data out to user code.", + bJackType=midi.JACK_TYPE_EXTERNAL, + input_pins=[(midi_in_jack_emb, 1)], + iJack=0) + +# USB IN <- midi_out_jack_emb <- midi_in_jack_ext <- CircuitPython +midi_in_jack_ext = midi.InJackDescriptor( + description="MIDI data in from user code.", + bJackType=midi.JACK_TYPE_EXTERNAL, + iJack=0) +midi_out_jack_emb = midi.OutJackDescriptor( + description="MIDI PC <- CircuitPython", bJackType=midi.JACK_TYPE_EMBEDDED, - iJack=0) + input_pins=[(midi_in_jack_ext, 1)], + iJack=StringIndex.index("CircuitPython usb_midi.ports[1]")) + + audio_midi_interface = standard.InterfaceDescriptor( - description="All the audio", + description="Midi goodness", bInterfaceClass=audio.AUDIO_CLASS_DEVICE, bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING, bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1, @@ -193,26 +210,23 @@ audio_midi_interface = standard.InterfaceDescriptor( subdescriptors=[ midi.Header( jacks_and_elements=[ - midi_in_jack, - midi.InJackDescriptor( - description="MIDI data in from user code.", - bJackType=midi.JACK_TYPE_EXTERNAL, iJack=0), - midi_out_jack, - midi.OutJackDescriptor( - description="MIDI data out to user code.", - bJackType=midi.JACK_TYPE_EXTERNAL, iJack=0), - ] + midi_in_jack_emb, + midi_in_jack_ext, + midi_out_jack_emb, + midi_out_jack_ext + ], ), standard.EndpointDescriptor( - description="MIDI data out", + description="MIDI data out to CircuitPython", bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT, bmAttributes=standard.EndpointDescriptor.TYPE_BULK), - midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack]), + midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack_emb]), standard.EndpointDescriptor( - description="MIDI data in", + description="MIDI data in from CircuitPython", bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK), - midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack]), + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval = 0x0), + midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack_emb]), ]) cs_ac_interface = audio10.AudioControlInterface( @@ -234,12 +248,12 @@ audio_control_interface = standard.InterfaceDescriptor( ]) # Audio streaming interfaces must occur before MIDI ones. -# audio_interfaces = [audio_control_interface] + cs_ac_interface.audio_streaming_interfaces + cs_ac_interface.midi_streaming_interfaces +audio_interfaces = [audio_control_interface] + cs_ac_interface.audio_streaming_interfaces + cs_ac_interface.midi_streaming_interfaces # This will renumber the endpoints to make them unique across descriptors, # and renumber the interfaces in order. But we still need to fix up certain # interface cross-references. -interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces, hid_interfaces) +interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces, hid_interfaces, audio_interfaces) # Now adjust the CDC interface cross-references. @@ -256,21 +270,13 @@ cdc_iad = standard.InterfaceAssociationDescriptor( bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model bFunctionProtocol=cdc.CDC_PROTOCOL_NONE) -# audio_iad = standard.InterfaceAssociationDescriptor( -# description="Audio IAD", -# bFirstInterface=audio_control_interface.bInterfaceNumber, -# bInterfaceCount=len(audio_interfaces), -# bFunctionClass=audio.AUDIO_CLASS_DEVICE, -# bFunctionSubClass=audio.AUDIO_SUBCLASS_UNKNOWN, -# bFunctionProtocol=audio.AUDIO_PROTOCOL_V1) - - descriptor_list = [] descriptor_list.append(cdc_iad) -# descriptor_list.append(audio_iad) descriptor_list.extend(cdc_interfaces) descriptor_list.extend(msc_interfaces) -# descriptor_list.append(audio_control_interface) +# Only add the control interface because other audio interfaces are managed by it to ensure the +# correct ordering. +descriptor_list.append(audio_control_interface) # Put the CDC IAD just before the CDC interfaces. # There appears to be a bug in the Windows composite USB driver that requests the # HID report descriptor with the wrong interface number if the HID interface is not given diff --git a/tools/usb_descriptor b/tools/usb_descriptor -Subproject 57bf602dac9cba8c4226f764c286cbc60103d67 +Subproject e2e79566a807b7230dddbc53a103c19b2f65e2c |
