kopia lustrzana https://github.com/micropython/micropython
Merge branch 'micropython:master' into master
commit
3cdb730f72
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
# These are binary so should never be modified by git.
|
# These are binary so should never be modified by git.
|
||||||
*.a binary
|
*.a binary
|
||||||
|
*.ico binary
|
||||||
*.png binary
|
*.png binary
|
||||||
*.jpg binary
|
*.jpg binary
|
||||||
*.dxf binary
|
*.dxf binary
|
||||||
|
|
|
@ -53,13 +53,16 @@ are then certifying and signing off against the following:
|
||||||
Code auto-formatting
|
Code auto-formatting
|
||||||
====================
|
====================
|
||||||
|
|
||||||
Both C and Python code are auto-formatted using the `tools/codeformat.py`
|
Both C and Python code formatting are controlled for consistency across the
|
||||||
script. This uses [uncrustify](https://github.com/uncrustify/uncrustify) to
|
MicroPython codebase. C code is formatted using the `tools/codeformat.py`
|
||||||
format C code and [black](https://github.com/psf/black) to format Python code.
|
script which uses [uncrustify](https://github.com/uncrustify/uncrustify).
|
||||||
After making changes, and before committing, run this tool to reformat your
|
Python code is linted and formatted using
|
||||||
changes to the correct style. Without arguments this tool will reformat all
|
[ruff & ruff format](https://github.com/astral-sh/ruff).
|
||||||
source code (and may take some time to run). Otherwise pass as arguments to
|
After making changes, and before committing, run `tools/codeformat.py` to
|
||||||
the tool the files that changed and it will only reformat those.
|
reformat your C code and `ruff format` for any Python code. Without
|
||||||
|
arguments this tool will reformat all source code (and may take some time
|
||||||
|
to run). Otherwise pass as arguments to the tool the files that changed,
|
||||||
|
and it will only reformat those.
|
||||||
|
|
||||||
uncrustify
|
uncrustify
|
||||||
==========
|
==========
|
||||||
|
@ -151,12 +154,22 @@ Tips:
|
||||||
* To ignore the pre-commit message format check temporarily, start the commit
|
* To ignore the pre-commit message format check temporarily, start the commit
|
||||||
message subject line with "WIP" (for "Work In Progress").
|
message subject line with "WIP" (for "Work In Progress").
|
||||||
|
|
||||||
|
Running pre-commit manually
|
||||||
|
===========================
|
||||||
|
|
||||||
|
Once pre-commit is installed as per the previous section it can be manually
|
||||||
|
run against the MicroPython python codebase to update file formatting on
|
||||||
|
demand, with either:
|
||||||
|
* `pre-commit run --all-files` to fix all files in the MicroPython codebase
|
||||||
|
* `pre-commit run --file ./path/to/my/file` to fix just one file
|
||||||
|
* `pre-commit run --file ./path/to/my/folder/*` to fix just one folder
|
||||||
|
|
||||||
Python code conventions
|
Python code conventions
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
Python code follows [PEP 8](https://legacy.python.org/dev/peps/pep-0008/) and
|
Python code follows [PEP 8](https://legacy.python.org/dev/peps/pep-0008/) and
|
||||||
is auto-formatted using [black](https://github.com/psf/black) with a line-length
|
is auto-formatted using [ruff format](https://docs.astral.sh/ruff/formatter)
|
||||||
of 99 characters.
|
with a line-length of 99 characters.
|
||||||
|
|
||||||
Naming conventions:
|
Naming conventions:
|
||||||
- Module names are short and all lowercase; eg pyb, stm.
|
- Module names are short and all lowercase; eg pyb, stm.
|
||||||
|
|
|
@ -193,7 +193,7 @@ numbers specified in ``write_pulses`` are multiplied by the resolution to
|
||||||
define the pulses.
|
define the pulses.
|
||||||
|
|
||||||
``clock_div`` is an 8-bit divider (0-255) and each pulse can be defined by
|
``clock_div`` is an 8-bit divider (0-255) and each pulse can be defined by
|
||||||
multiplying the resolution by a 15-bit (0-32,768) number. There are eight
|
multiplying the resolution by a 15-bit (1-``PULSE_MAX``) number. There are eight
|
||||||
channels (0-7) and each can have a different clock divider.
|
channels (0-7) and each can have a different clock divider.
|
||||||
|
|
||||||
So, in the example above, the 80MHz clock is divided by 8. Thus the
|
So, in the example above, the 80MHz clock is divided by 8. Thus the
|
||||||
|
@ -226,7 +226,7 @@ For more details see Espressif's `ESP-IDF RMT documentation.
|
||||||
``100``) and the output level to apply the carrier to (a boolean as per
|
``100``) and the output level to apply the carrier to (a boolean as per
|
||||||
*idle_level*).
|
*idle_level*).
|
||||||
|
|
||||||
.. method:: RMT.source_freq()
|
.. classmethod:: RMT.source_freq()
|
||||||
|
|
||||||
Returns the source clock frequency. Currently the source clock is not
|
Returns the source clock frequency. Currently the source clock is not
|
||||||
configurable so this will always return 80MHz.
|
configurable so this will always return 80MHz.
|
||||||
|
@ -264,10 +264,10 @@ For more details see Espressif's `ESP-IDF RMT documentation.
|
||||||
**Mode 3:** *duration* and *data* are lists or tuples of equal length,
|
**Mode 3:** *duration* and *data* are lists or tuples of equal length,
|
||||||
specifying individual durations and the output level for each.
|
specifying individual durations and the output level for each.
|
||||||
|
|
||||||
Durations are in integer units of the channel resolution (as described
|
Durations are in integer units of the channel resolution (as
|
||||||
above), between 1 and 32767 units. Output levels are any value that can
|
described above), between 1 and ``PULSE_MAX`` units. Output levels
|
||||||
be converted to a boolean, with ``True`` representing high voltage and
|
are any value that can be converted to a boolean, with ``True``
|
||||||
``False`` representing low.
|
representing high voltage and ``False`` representing low.
|
||||||
|
|
||||||
If transmission of an earlier sequence is in progress then this method will
|
If transmission of an earlier sequence is in progress then this method will
|
||||||
block until that transmission is complete before beginning the new sequence.
|
block until that transmission is complete before beginning the new sequence.
|
||||||
|
@ -290,6 +290,13 @@ For more details see Espressif's `ESP-IDF RMT documentation.
|
||||||
Passing in no argument will not change the channel. This function returns
|
Passing in no argument will not change the channel. This function returns
|
||||||
the current channel number.
|
the current channel number.
|
||||||
|
|
||||||
|
Constants
|
||||||
|
---------
|
||||||
|
|
||||||
|
.. data:: RMT.PULSE_MAX
|
||||||
|
|
||||||
|
Maximum integer that can be set for a pulse duration.
|
||||||
|
|
||||||
Ultra-Low-Power co-processor
|
Ultra-Low-Power co-processor
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,9 @@ Methods
|
||||||
Configure the ADC peripheral. *bits* will set the resolution of the
|
Configure the ADC peripheral. *bits* will set the resolution of the
|
||||||
conversion process.
|
conversion process.
|
||||||
|
|
||||||
.. method:: ADCBlock.connect(channel)
|
.. method:: ADCBlock.connect(channel, *, ...)
|
||||||
ADCBlock.connect(source)
|
ADCBlock.connect(source, *, ...)
|
||||||
ADCBlock.connect(channel, source)
|
ADCBlock.connect(channel, source, *, ...)
|
||||||
|
|
||||||
Connect up a channel on the ADC peripheral so it is ready for sampling,
|
Connect up a channel on the ADC peripheral so it is ready for sampling,
|
||||||
and return an :ref:`ADC <machine.ADC>` object that represents that connection.
|
and return an :ref:`ADC <machine.ADC>` object that represents that connection.
|
||||||
|
@ -56,3 +56,6 @@ Methods
|
||||||
|
|
||||||
If both *channel* and *source* are given then they are connected together
|
If both *channel* and *source* are given then they are connected together
|
||||||
and made ready for sampling.
|
and made ready for sampling.
|
||||||
|
|
||||||
|
Any additional keyword arguments are used to configure the returned ADC object,
|
||||||
|
via its :meth:`init <machine.ADC.init>` method.
|
||||||
|
|
|
@ -28,7 +28,7 @@ MIMXRT1060-EVK Debug USB D0/D1 D7/D6 D8/D9
|
||||||
MIMXRT1064-EVK Debug USB D0/D1 D7/D6 D8/D9
|
MIMXRT1064-EVK Debug USB D0/D1 D7/D6 D8/D9
|
||||||
MIMXRT1170-EVK Debug USB D0/D1 D12/D11 D10/D13
|
MIMXRT1170-EVK Debug USB D0/D1 D12/D11 D10/D13
|
||||||
Adafruit Metro M7 - D0/D1 D7/D3 A1/A0
|
Adafruit Metro M7 - D0/D1 D7/D3 A1/A0
|
||||||
Olimex RT1010Py - RxD/TxD D5/D6 -
|
Olimex RT1010Py - RxD/TxD D7/D8 D5/D6
|
||||||
Seeed ARCH MIX - J3_19/J3_20 J4_16/J4_17 J4_06/J4_07
|
Seeed ARCH MIX - J3_19/J3_20 J4_16/J4_17 J4_06/J4_07
|
||||||
================= =========== =========== =========== ===========
|
================= =========== =========== =========== ===========
|
||||||
|
|
||||||
|
|
|
@ -92,9 +92,7 @@ Use the :ref:`machine.Pin <machine.Pin>` class::
|
||||||
|
|
||||||
Available Pins follow the ranges and labelling of the respective board, like:
|
Available Pins follow the ranges and labelling of the respective board, like:
|
||||||
|
|
||||||
- 0-33 for Teensy 4.0,
|
- 'D0-Dxx', or 'A0-Ann' for Teensy 4.0, MIMXRT10xx-EVK ns Olimex board,
|
||||||
- 0-21 for the MIMXRT10xx-EVK board, or 'D0-Dxx', or 'A0-Ann',
|
|
||||||
- 0-14 for the Olimex RT1010Py board, or 'D0'-'Dxx' and 'A0'-'Ann'
|
|
||||||
- 'J3_xx', 'J4_xx', 'J5_xx' for the Seeed ARCH MIX board,
|
- 'J3_xx', 'J4_xx', 'J5_xx' for the Seeed ARCH MIX board,
|
||||||
|
|
||||||
or the pin names of the Pin.board or Pin.cpu classes.
|
or the pin names of the Pin.board or Pin.cpu classes.
|
||||||
|
@ -106,9 +104,9 @@ Notes:
|
||||||
* At the MIMXRT1010_EVK, pins D4, D5 and D9 of the Arduino connector are by
|
* At the MIMXRT1010_EVK, pins D4, D5 and D9 of the Arduino connector are by
|
||||||
default not connected to the MCU. For details refer to the schematics.
|
default not connected to the MCU. For details refer to the schematics.
|
||||||
* At the MIMXRT1170_EVK board, the inner rows of the Arduino connectors are assigned as follows:
|
* At the MIMXRT1170_EVK board, the inner rows of the Arduino connectors are assigned as follows:
|
||||||
- D16 - D23: J9, odd pin numbers; D17 is by default not connected.
|
- 'D16' - 'D23': J9, odd pin numbers; 'D17' is by default not connected.
|
||||||
- D24 - D27: J26, odd pin numbers; J63-J66 have to be closed to enable these pins.
|
- 'D24' - 'D27': J26, odd pin numbers; J63-J66 have to be closed to enable these pins.
|
||||||
- D29 - D36: J25, odd pin numbers; D29 and D30 are by default not connected.
|
- 'D29' - 'D36': J25, odd pin numbers; 'D29' and 'D30' are by default not connected.
|
||||||
|
|
||||||
There's a higher-level abstraction :ref:`machine.Signal <machine.Signal>`
|
There's a higher-level abstraction :ref:`machine.Signal <machine.Signal>`
|
||||||
which can be used to invert a pin. Useful for illuminating active-low LEDs
|
which can be used to invert a pin. Useful for illuminating active-low LEDs
|
||||||
|
@ -146,22 +144,22 @@ handling signal groups. ::
|
||||||
from machine import Pin, PWM
|
from machine import Pin, PWM
|
||||||
|
|
||||||
# create PWM object from a pin and set the frequency and duty cycle
|
# create PWM object from a pin and set the frequency and duty cycle
|
||||||
pwm2 = PWM(Pin(2), freq=2000, duty_u16=32768)
|
pwm2 = PWM(Pin('D2'), freq=2000, duty_u16=32768)
|
||||||
pwm2.freq() # get the current frequency
|
pwm2.freq() # get the current frequency
|
||||||
pwm2.freq(1000) # set/change the frequency
|
pwm2.freq(1000) # set/change the frequency
|
||||||
pwm2.duty_u16() # get the current duty cycle, range 0-65535
|
pwm2.duty_u16() # get the current duty cycle, range 0-65535
|
||||||
pwm2.duty_u16(200) # set the duty cycle, range 0-65535
|
pwm2.duty_u16(200) # set the duty cycle, range 0-65535
|
||||||
pwm2.deinit() # turn off PWM on the pin
|
pwm2.deinit() # turn off PWM on the pin
|
||||||
# create a complementary signal pair on Pin 2 and 3
|
# create a complementary signal pair on Pin 2 and 3
|
||||||
pwm2 = PWM((2, 3), freq=2000, duty_ns=20000)
|
pwm2 = PWM(('D2', 'D3'), freq=2000, duty_ns=20000)
|
||||||
|
|
||||||
# Create a group of four synchronized signals.
|
# Create a group of four synchronized signals.
|
||||||
# Start with Pin(4) at submodule 0, which creates the sync pulse.
|
# Start with Pin('D4') at submodule 0, which creates the sync pulse.
|
||||||
pwm4 = PWM(Pin(4), freq=1000, align=PWM.HEAD)
|
pwm4 = PWM(Pin('D4'), freq=1000, align=PWM.HEAD)
|
||||||
# Pins 5, 6, and 9 are pins at the same module
|
# Pins D5, D6, and D9 are pins at the same module
|
||||||
pwm5 = PWM(Pin(5), freq=1000, duty_u16=10000, align=PWM.HEAD, sync=True)
|
pwm5 = PWM(Pin('D5'), freq=1000, duty_u16=10000, align=PWM.HEAD, sync=True)
|
||||||
pwm6 = PWM(Pin(6), freq=1000, duty_u16=20000, align=PWM.HEAD, sync=True)
|
pwm6 = PWM(Pin('D6', freq=1000, duty_u16=20000, align=PWM.HEAD, sync=True)
|
||||||
pwm9 = PWM(Pin(9), freq=1000, duty_u16=30000, align=PWM.HEAD, sync=True)
|
pwm9 = PWM(Pin('D9'), freq=1000, duty_u16=30000, align=PWM.HEAD, sync=True)
|
||||||
|
|
||||||
pwm3 # show the PWM objects properties
|
pwm3 # show the PWM objects properties
|
||||||
|
|
||||||
|
@ -256,7 +254,7 @@ Use the :ref:`machine.ADC <machine.ADC>` class::
|
||||||
|
|
||||||
from machine import ADC
|
from machine import ADC
|
||||||
|
|
||||||
adc = ADC(Pin(32)) # create ADC object on ADC pin
|
adc = ADC(Pin('A2')) # create ADC object on ADC pin
|
||||||
adc.read_u16() # read value, 0-65536 across voltage range 0.0v - 3.3v
|
adc.read_u16() # read value, 0-65536 across voltage range 0.0v - 3.3v
|
||||||
|
|
||||||
The resolution of the ADC is 12 bit with 10 to 11 bit accuracy, irrespective of the
|
The resolution of the ADC is 12 bit with 10 to 11 bit accuracy, irrespective of the
|
||||||
|
@ -274,7 +272,7 @@ Software SPI (using bit-banging) works on all pins, and is accessed via the
|
||||||
# construct a SoftSPI bus on the given pins
|
# construct a SoftSPI bus on the given pins
|
||||||
# polarity is the idle state of SCK
|
# polarity is the idle state of SCK
|
||||||
# phase=0 means sample on the first edge of SCK, phase=1 means the second
|
# phase=0 means sample on the first edge of SCK, phase=1 means the second
|
||||||
spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
|
spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin('D0'), mosi=Pin('D2'), miso=Pin('D4'))
|
||||||
|
|
||||||
spi.init(baudrate=200000) # set the baudrate
|
spi.init(baudrate=200000) # set the baudrate
|
||||||
|
|
||||||
|
@ -303,7 +301,7 @@ rates (up to 30Mhz). Hardware SPI is accessed via the
|
||||||
from machine import SPI, Pin
|
from machine import SPI, Pin
|
||||||
|
|
||||||
spi = SPI(0, 10000000)
|
spi = SPI(0, 10000000)
|
||||||
cs_pin = Pin(6, Pin.OUT, value=1)
|
cs_pin = Pin('D6', Pin.OUT, value=1)
|
||||||
cs_pin(0)
|
cs_pin(0)
|
||||||
spi.write('Hello World')
|
spi.write('Hello World')
|
||||||
cs_pin(1)
|
cs_pin(1)
|
||||||
|
@ -331,7 +329,7 @@ accessed via the :ref:`machine.SoftI2C <machine.SoftI2C>` class::
|
||||||
|
|
||||||
from machine import Pin, SoftI2C
|
from machine import Pin, SoftI2C
|
||||||
|
|
||||||
i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=100000)
|
i2c = SoftI2C(scl=Pin('D5'), sda=Pin('D4'), freq=100000)
|
||||||
|
|
||||||
i2c.scan() # scan for devices
|
i2c.scan() # scan for devices
|
||||||
|
|
||||||
|
@ -365,7 +363,7 @@ See :ref:`machine.I2S <machine.I2S>`. Example using a Teensy 4.1 board with a si
|
||||||
external Codec like UDA1334.::
|
external Codec like UDA1334.::
|
||||||
|
|
||||||
from machine import I2S, Pin
|
from machine import I2S, Pin
|
||||||
i2s = I2S(2, sck=Pin(26), ws=Pin(27), sd=Pin(7),
|
i2s = I2S(2, sck=Pin('D26'), ws=Pin('D27'), sd=Pin('D7'),
|
||||||
mode=I2S.TX, bts=16,format=I2S.STEREO,
|
mode=I2S.TX, bts=16,format=I2S.STEREO,
|
||||||
rate=44100,ibuf=40000)
|
rate=44100,ibuf=40000)
|
||||||
i2s.write(buf) # write buffer of audio samples to I2S device
|
i2s.write(buf) # write buffer of audio samples to I2S device
|
||||||
|
@ -397,7 +395,7 @@ Example using the Teensy audio shield::
|
||||||
|
|
||||||
from machine import I2C, I2S, Pin
|
from machine import I2C, I2S, Pin
|
||||||
from sgtl5000 import CODEC
|
from sgtl5000 import CODEC
|
||||||
i2s = I2S(1, sck=Pin(21), ws=Pin(20), sd=Pin(7), mck=Pin(23),
|
i2s = I2S(1, sck=Pin('D21'), ws=Pin('D20'), sd=Pin('D7'), mck=Pin('D23'),
|
||||||
mode=I2S.TX, bits=16,rate=44100,format=I2S.STEREO,
|
mode=I2S.TX, bits=16,rate=44100,format=I2S.STEREO,
|
||||||
ibuf=40000,
|
ibuf=40000,
|
||||||
)
|
)
|
||||||
|
@ -475,7 +473,7 @@ The OneWire driver is implemented in software and works on all pins::
|
||||||
from machine import Pin
|
from machine import Pin
|
||||||
import onewire
|
import onewire
|
||||||
|
|
||||||
ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12
|
ow = onewire.OneWire(Pin('D12')) # create a OneWire bus on GPIO12
|
||||||
ow.scan() # return a list of devices on the bus
|
ow.scan() # return a list of devices on the bus
|
||||||
ow.reset() # reset the bus
|
ow.reset() # reset the bus
|
||||||
ow.readbyte() # read a byte
|
ow.readbyte() # read a byte
|
||||||
|
@ -505,12 +503,12 @@ The DHT driver is implemented in software and works on all pins::
|
||||||
import dht
|
import dht
|
||||||
import machine
|
import machine
|
||||||
|
|
||||||
d = dht.DHT11(machine.Pin(4))
|
d = dht.DHT11(machine.Pin('D4'))
|
||||||
d.measure()
|
d.measure()
|
||||||
d.temperature() # eg. 23 (°C)
|
d.temperature() # eg. 23 (°C)
|
||||||
d.humidity() # eg. 41 (% RH)
|
d.humidity() # eg. 41 (% RH)
|
||||||
|
|
||||||
d = dht.DHT22(machine.Pin(4))
|
d = dht.DHT22(machine.Pin('D4'))
|
||||||
d.measure()
|
d.measure()
|
||||||
d.temperature() # eg. 23.6 (°C)
|
d.temperature() # eg. 23.6 (°C)
|
||||||
d.humidity() # eg. 41.3 (% RH)
|
d.humidity() # eg. 41.3 (% RH)
|
||||||
|
|
|
@ -17,44 +17,53 @@ Adafruit ItsyBitsy M0 Express pin assignment table
|
||||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||||
Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
|
Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
|
||||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||||
0 PA11 D0 11 19 0/3 2/3 1/1 0/3
|
2 PA02 A0 2 0 - - - -
|
||||||
1 PA10 D1 10 18 0/2 2/2 1/0 0/2
|
40 PB08 A1 8 2 - 4/0 4/0 -
|
||||||
2 PA14 D2 14 - 2/2 4/2 3/0 0/4
|
41 PB09 A2 9 3 - 4/1 4/1 -
|
||||||
3 PA09 D3 9 17 0/1 2/1 0/1 1/3
|
4 PA04 A3 4 4 - 0/0 0/0 -
|
||||||
4 PA08 D4 - 16 0/0 2/0 0/0 1/2
|
5 PA05 A4 5 5 - 0/1 0/1 -
|
||||||
5 PA15 D5 15 - 2/3 4/3 3/1 0/5
|
34 PB02 A5 2 10 - 5/0 6/0 -
|
||||||
7 PA21 D7 5 - 5/3 3/3 7/1 0/7
|
11 PA11 D0 11 19 0/3 2/3 1/1 0/3
|
||||||
9 PA07 D9 7 7 - 0/3 1/1 -
|
10 PA10 D1 10 18 0/2 2/2 1/0 0/2
|
||||||
10 PA18 D10 2 - 1/2 3/2 3/0 0/2
|
14 PA14 D2 14 - 2/2 4/2 3/0 0/4
|
||||||
11 PA16 D11 0 - 1/0 3/0 2/0 0/6
|
9 PA09 D3 9 17 0/1 2/1 0/1 1/3
|
||||||
12 PA19 D12 3 - 1/3 3/3 3/1 0/3
|
8 PA08 D4 - 16 0/0 2/0 0/0 1/2
|
||||||
13 PA17 D13 1 - 1/1 3/1 2/1 0/7
|
15 PA15 D5 15 - 2/3 4/3 3/1 0/5
|
||||||
14 PA02 A0 2 0 - - - -
|
21 PA21 D7 5 - 5/3 3/3 7/1 0/7
|
||||||
15 PB08 A1 8 2 - 4/0 4/0 -
|
7 PA07 D9 7 7 - 0/3 1/1 -
|
||||||
16 PB09 A2 9 3 - 4/1 4/1 -
|
18 PA18 D10 2 - 1/2 3/2 3/0 0/2
|
||||||
17 PA04 A3 4 4 - 0/0 0/0 -
|
16 PA16 D11 0 - 1/0 3/0 2/0 0/6
|
||||||
18 PA05 A4 5 5 - 0/1 0/1 -
|
19 PA19 D12 3 - 1/3 3/3 3/1 0/3
|
||||||
19 PB02 A5 2 - - 5/0 6/0 -
|
17 PA17 D13 1 - 1/1 3/1 2/1 0/7
|
||||||
20 PA22 SDA 6 - 3/0 5/0 4/0 0/4
|
0 PA00 DOTSTAR_CLK 0 - - 1/0 2/0 -
|
||||||
21 PA23 SCL 7 - 3/1 5/1 4/1 0/5
|
1 PA01 DOTSTAR_DATA 1 - - 1/1 2/1 -
|
||||||
22 PB10 MOSI 10 - - 4/2 5/0 0/4
|
27 PA27 FLASH_CS 15 - - - - -
|
||||||
23 PA12 MISO 12 - 2/0 4/0 2/0 0/6
|
35 PB03 FLASH_MISO 3 11 - 5/1 6/1 -
|
||||||
24 PB11 SCK 11 - - 4/3 5/1 0/5
|
54 PB22 FLASH_MOSI 6 - - 5/2 7/0 -
|
||||||
25 PA00 DOTSTAR_CLK 0 - - 1/0 2/0 -
|
55 PB23 FLASH_SCK 7 - - 5/3 7/1 -
|
||||||
26 PA01 DOTSTAR_DATA 1 - - 1/1 2/1 -
|
12 PA12 MISO 12 - 2/0 4/0 2/0 0/6
|
||||||
27 PB22 FLASH_MOSI 6 - - 5/2 7/0 -
|
42 PB10 MOSI 10 - - 4/2 5/0 0/4
|
||||||
28 PB03 FLASH_MISO 3 - - 5/1 6/1 -
|
43 PB11 SCK 11 - - 4/3 5/1 0/5
|
||||||
29 PB23 FLASH_SCK 7 - - 5/3 7/1 -
|
23 PA23 SCL 7 - 3/1 5/1 4/1 0/5
|
||||||
|
22 PA22 SDA 6 - 3/0 5/0 4/0 0/4
|
||||||
|
30 PA30 SWCLK 10 - - 1/2 1/0 -
|
||||||
|
31 PA31 SWDIO 11 - - 1/3 1/1 -
|
||||||
|
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
|
||||||
|
25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3
|
||||||
|
3 PA03 3 1 - - - -
|
||||||
|
6 PA06 6 6 - 0/2 1/0 -
|
||||||
|
13 PA13 13 - 2/1 4/1 2/0 0/7
|
||||||
|
20 PA20 4 - 5/2 3/2 7/0 0/4
|
||||||
|
28 PA28 8 - - - - -
|
||||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||||
|
|
||||||
|
|
||||||
Description of the columns:
|
Description of the columns:
|
||||||
|
|
||||||
- *Pin* - The number that is expected at ``machine.Pin(n)``, if the pin is given
|
- *Pin* - The number that is expected at ``machine.Pin(n)``, if the pin is given
|
||||||
as a number. This is NOT the GPIO number, but the board pin number, as
|
as a number.
|
||||||
given in the board specific definition file.
|
- *GPIO* - The GPIO name, which can be used as argument to ``machine.Pin("name")``.
|
||||||
- *GPIO* - The GPIO number.
|
- *Pin Name* - The boards name, which can be used as argument to ``machine.Pin("name")``.
|
||||||
- *Pin Name* - The name of a Pin which is expected argument to ``machine.Pin("name")``.
|
|
||||||
- *IRQ* - The IRQ number assigned to that GPIO, used internally by ``Pin.irq()``. When
|
- *IRQ* - The IRQ number assigned to that GPIO, used internally by ``Pin.irq()``. When
|
||||||
using ``Pin.irq()``, different pins must use different IRQs
|
using ``Pin.irq()``, different pins must use different IRQs
|
||||||
- *ADC* - The ADC channel assigned to the pin. When using ADC, different pins must
|
- *ADC* - The ADC channel assigned to the pin. When using ADC, different pins must
|
||||||
|
@ -183,10 +192,9 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM
|
||||||
Description of the columns:
|
Description of the columns:
|
||||||
|
|
||||||
- *Pin* - The number that is expected at ``machine.Pin(n)``, if the pin is given
|
- *Pin* - The number that is expected at ``machine.Pin(n)``, if the pin is given
|
||||||
as a number. This is NOT the GPIO number, but the board pin number, as
|
as a number.
|
||||||
given in the board specific definition file.
|
- *GPIO* - The GPIO name, which can be used as argument to ``machine.Pin("name")``.
|
||||||
- *GPIO* - The GPIO number.
|
- *Pin Name* - The boards name, which can be used as argument to ``machine.Pin("name")``.
|
||||||
- *Pin Name* The name of a Pin which is expected argument to ``machine.Pin("name")``.
|
|
||||||
- *IRQ* - The IRQ number assigned to that GPIO, used internally by ``Pin.irq()``. When
|
- *IRQ* - The IRQ number assigned to that GPIO, used internally by ``Pin.irq()``. When
|
||||||
using ``Pin.irq()``, different pins must use different IRQs
|
using ``Pin.irq()``, different pins must use different IRQs
|
||||||
- *ADC* - The ADC0/1 channel assigned to the pin. When using ADC, different pins must
|
- *ADC* - The ADC0/1 channel assigned to the pin. When using ADC, different pins must
|
||||||
|
|
|
@ -8,6 +8,7 @@ set(MICROPY_SOURCE_EXTMOD
|
||||||
${MICROPY_DIR}/shared/libc/printf.c
|
${MICROPY_DIR}/shared/libc/printf.c
|
||||||
${MICROPY_EXTMOD_DIR}/btstack/modbluetooth_btstack.c
|
${MICROPY_EXTMOD_DIR}/btstack/modbluetooth_btstack.c
|
||||||
${MICROPY_EXTMOD_DIR}/machine_adc.c
|
${MICROPY_EXTMOD_DIR}/machine_adc.c
|
||||||
|
${MICROPY_EXTMOD_DIR}/machine_adc_block.c
|
||||||
${MICROPY_EXTMOD_DIR}/machine_bitstream.c
|
${MICROPY_EXTMOD_DIR}/machine_bitstream.c
|
||||||
${MICROPY_EXTMOD_DIR}/machine_i2c.c
|
${MICROPY_EXTMOD_DIR}/machine_i2c.c
|
||||||
${MICROPY_EXTMOD_DIR}/machine_i2s.c
|
${MICROPY_EXTMOD_DIR}/machine_i2s.c
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
SRC_EXTMOD_C += \
|
SRC_EXTMOD_C += \
|
||||||
extmod/machine_adc.c \
|
extmod/machine_adc.c \
|
||||||
|
extmod/machine_adc_block.c \
|
||||||
extmod/machine_bitstream.c \
|
extmod/machine_bitstream.c \
|
||||||
extmod/machine_i2c.c \
|
extmod/machine_i2c.c \
|
||||||
extmod/machine_i2s.c \
|
extmod/machine_i2s.c \
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Jonathan Hogg
|
||||||
|
* Copyright (c) 2023 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
#if MICROPY_PY_MACHINE_ADC_BLOCK
|
||||||
|
|
||||||
|
#include "py/mphal.h"
|
||||||
|
#include "extmod/modmachine.h"
|
||||||
|
|
||||||
|
// The port must provide implementations of these low-level ADCBlock functions.
|
||||||
|
STATIC void mp_machine_adc_block_print(const mp_print_t *print, machine_adc_block_obj_t *self);
|
||||||
|
STATIC machine_adc_block_obj_t *mp_machine_adc_block_get(mp_int_t unit);
|
||||||
|
STATIC void mp_machine_adc_block_bits_set(machine_adc_block_obj_t *self, mp_int_t bits);
|
||||||
|
STATIC machine_adc_obj_t *mp_machine_adc_block_connect(machine_adc_block_obj_t *self, mp_int_t channel_id, mp_hal_pin_obj_t pin, mp_map_t *kw_args);
|
||||||
|
|
||||||
|
// The port provides implementations of the above in this file.
|
||||||
|
#include MICROPY_PY_MACHINE_ADC_BLOCK_INCLUDEFILE
|
||||||
|
|
||||||
|
STATIC void machine_adc_block_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||||
|
machine_adc_block_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
mp_machine_adc_block_print(print, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void machine_adc_block_init_helper(machine_adc_block_obj_t *self, size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
enum {
|
||||||
|
ARG_bits,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
|
||||||
|
};
|
||||||
|
|
||||||
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all(n_pos_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
|
||||||
|
mp_int_t bits = args[ARG_bits].u_int;
|
||||||
|
mp_machine_adc_block_bits_set(self, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC mp_obj_t machine_adc_block_make_new(const mp_obj_type_t *type, size_t n_pos_args, size_t n_kw_args, const mp_obj_t *args) {
|
||||||
|
mp_arg_check_num(n_pos_args, n_kw_args, 1, MP_OBJ_FUN_ARGS_MAX, true);
|
||||||
|
mp_int_t unit = mp_obj_get_int(args[0]);
|
||||||
|
machine_adc_block_obj_t *self = mp_machine_adc_block_get(unit);
|
||||||
|
if (self == NULL) {
|
||||||
|
mp_raise_ValueError(MP_ERROR_TEXT("invalid block id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_map_t kw_args;
|
||||||
|
mp_map_init_fixed_table(&kw_args, n_kw_args, args + n_pos_args);
|
||||||
|
machine_adc_block_init_helper(self, n_pos_args - 1, args + 1, &kw_args);
|
||||||
|
|
||||||
|
return MP_OBJ_FROM_PTR(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC mp_obj_t machine_adc_block_init(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
machine_adc_block_obj_t *self = pos_args[0];
|
||||||
|
machine_adc_block_init_helper(self, n_pos_args - 1, pos_args + 1, kw_args);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_adc_block_init_obj, 1, machine_adc_block_init);
|
||||||
|
|
||||||
|
STATIC mp_obj_t machine_adc_block_connect(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
machine_adc_block_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
|
||||||
|
mp_int_t channel_id = -1;
|
||||||
|
mp_hal_pin_obj_t pin = -1;
|
||||||
|
if (n_pos_args == 2) {
|
||||||
|
if (mp_obj_is_int(pos_args[1])) {
|
||||||
|
channel_id = mp_obj_get_int(pos_args[1]);
|
||||||
|
} else {
|
||||||
|
pin = mp_hal_get_pin_obj(pos_args[1]);
|
||||||
|
}
|
||||||
|
} else if (n_pos_args == 3) {
|
||||||
|
channel_id = mp_obj_get_int(pos_args[1]);
|
||||||
|
pin = mp_hal_get_pin_obj(pos_args[2]);
|
||||||
|
} else {
|
||||||
|
mp_raise_TypeError(MP_ERROR_TEXT("too many positional args"));
|
||||||
|
}
|
||||||
|
|
||||||
|
machine_adc_obj_t *adc = mp_machine_adc_block_connect(self, channel_id, pin, kw_args);
|
||||||
|
if (adc == NULL) {
|
||||||
|
mp_raise_ValueError(MP_ERROR_TEXT("no matching ADC"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return MP_OBJ_FROM_PTR(adc);
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_adc_block_connect_obj, 2, machine_adc_block_connect);
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t machine_adc_block_locals_dict_table[] = {
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_adc_block_init_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&machine_adc_block_connect_obj) },
|
||||||
|
};
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(machine_adc_block_locals_dict, machine_adc_block_locals_dict_table);
|
||||||
|
|
||||||
|
MP_DEFINE_CONST_OBJ_TYPE(
|
||||||
|
machine_adc_block_type,
|
||||||
|
MP_QSTR_ADCBlock,
|
||||||
|
MP_TYPE_FLAG_NONE,
|
||||||
|
make_new, machine_adc_block_make_new,
|
||||||
|
print, machine_adc_block_print,
|
||||||
|
locals_dict, &machine_adc_block_locals_dict
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // MICROPY_PY_MACHINE_ADC_BLOCK
|
|
@ -328,7 +328,12 @@ STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) {
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr));
|
mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr));
|
||||||
}
|
}
|
||||||
#ifdef MICROPY_EVENT_POLL_HOOK
|
// This scan loop may run for some time, so process any pending events/exceptions,
|
||||||
|
// or allow the port to run any necessary background tasks. But do it as fast as
|
||||||
|
// possible, in particular we are not waiting on any events.
|
||||||
|
#if defined(MICROPY_EVENT_POLL_HOOK_FAST)
|
||||||
|
MICROPY_EVENT_POLL_HOOK_FAST;
|
||||||
|
#elif defined(MICROPY_EVENT_POLL_HOOK)
|
||||||
MICROPY_EVENT_POLL_HOOK
|
MICROPY_EVENT_POLL_HOOK
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1276,6 +1276,7 @@ STATIC mp_obj_t invoke_irq_handler(uint16_t event,
|
||||||
mp_stack_set_top(&ts + 1); // need to include ts in root-pointer scan
|
mp_stack_set_top(&ts + 1); // need to include ts in root-pointer scan
|
||||||
mp_stack_set_limit(MICROPY_PY_BLUETOOTH_SYNC_EVENT_STACK_SIZE - 1024);
|
mp_stack_set_limit(MICROPY_PY_BLUETOOTH_SYNC_EVENT_STACK_SIZE - 1024);
|
||||||
ts.gc_lock_depth = 0;
|
ts.gc_lock_depth = 0;
|
||||||
|
ts.nlr_jump_callback_top = NULL;
|
||||||
ts.mp_pending_exception = MP_OBJ_NULL;
|
ts.mp_pending_exception = MP_OBJ_NULL;
|
||||||
mp_locals_set(mp_state_ctx.thread.dict_locals); // set from the outer context
|
mp_locals_set(mp_state_ctx.thread.dict_locals); // set from the outer context
|
||||||
mp_globals_set(mp_state_ctx.thread.dict_globals); // set from the outer context
|
mp_globals_set(mp_state_ctx.thread.dict_globals); // set from the outer context
|
||||||
|
|
|
@ -128,6 +128,7 @@
|
||||||
|
|
||||||
// A port must provide these types, but they are otherwise opaque.
|
// A port must provide these types, but they are otherwise opaque.
|
||||||
typedef struct _machine_adc_obj_t machine_adc_obj_t;
|
typedef struct _machine_adc_obj_t machine_adc_obj_t;
|
||||||
|
typedef struct _machine_adc_block_obj_t machine_adc_block_obj_t;
|
||||||
typedef struct _machine_i2s_obj_t machine_i2s_obj_t;
|
typedef struct _machine_i2s_obj_t machine_i2s_obj_t;
|
||||||
typedef struct _machine_pwm_obj_t machine_pwm_obj_t;
|
typedef struct _machine_pwm_obj_t machine_pwm_obj_t;
|
||||||
typedef struct _machine_uart_obj_t machine_uart_obj_t;
|
typedef struct _machine_uart_obj_t machine_uart_obj_t;
|
||||||
|
@ -200,6 +201,7 @@ extern const machine_mem_obj_t machine_mem32_obj;
|
||||||
// Their Python bindings are implemented in extmod, and their implementation
|
// Their Python bindings are implemented in extmod, and their implementation
|
||||||
// is provided by a port.
|
// is provided by a port.
|
||||||
extern const mp_obj_type_t machine_adc_type;
|
extern const mp_obj_type_t machine_adc_type;
|
||||||
|
extern const mp_obj_type_t machine_adc_block_type;
|
||||||
extern const mp_obj_type_t machine_i2c_type;
|
extern const mp_obj_type_t machine_i2c_type;
|
||||||
extern const mp_obj_type_t machine_i2s_type;
|
extern const mp_obj_type_t machine_i2s_type;
|
||||||
extern const mp_obj_type_t machine_mem_type;
|
extern const mp_obj_type_t machine_mem_type;
|
||||||
|
|
|
@ -207,12 +207,12 @@ STATIC mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
|
||||||
subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len);
|
subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len);
|
||||||
subj.end = subj.begin + len;
|
subj.end = subj.begin + len;
|
||||||
int caps_num = (self->re.sub + 1) * 2;
|
int caps_num = (self->re.sub + 1) * 2;
|
||||||
mp_obj_match_t *match = m_new_obj_var(mp_obj_match_t, char *, caps_num);
|
mp_obj_match_t *match = m_new_obj_var(mp_obj_match_t, caps, char *, caps_num);
|
||||||
// cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char
|
// cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char
|
||||||
memset((char *)match->caps, 0, caps_num * sizeof(char *));
|
memset((char *)match->caps, 0, caps_num * sizeof(char *));
|
||||||
int res = re1_5_recursiveloopprog(&self->re, &subj, match->caps, caps_num, is_anchored);
|
int res = re1_5_recursiveloopprog(&self->re, &subj, match->caps, caps_num, is_anchored);
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
m_del_var(mp_obj_match_t, char *, caps_num, match);
|
m_del_var(mp_obj_match_t, caps, char *, caps_num, match);
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1701,7 +1701,7 @@ STATIC int create_l2cap_channel(uint16_t mtu, mp_bluetooth_nimble_l2cap_channel_
|
||||||
// multiply that by the "MTUs per channel" (set to 3 above).
|
// multiply that by the "MTUs per channel" (set to 3 above).
|
||||||
const size_t buf_blocks = MP_CEIL_DIVIDE(mtu, L2CAP_BUF_BLOCK_SIZE) * L2CAP_BUF_SIZE_MTUS_PER_CHANNEL;
|
const size_t buf_blocks = MP_CEIL_DIVIDE(mtu, L2CAP_BUF_BLOCK_SIZE) * L2CAP_BUF_SIZE_MTUS_PER_CHANNEL;
|
||||||
|
|
||||||
mp_bluetooth_nimble_l2cap_channel_t *chan = m_new_obj_var(mp_bluetooth_nimble_l2cap_channel_t, uint8_t, OS_MEMPOOL_SIZE(buf_blocks, L2CAP_BUF_BLOCK_SIZE) * sizeof(os_membuf_t));
|
mp_bluetooth_nimble_l2cap_channel_t *chan = m_new_obj_var(mp_bluetooth_nimble_l2cap_channel_t, sdu_mem, uint8_t, OS_MEMPOOL_SIZE(buf_blocks, L2CAP_BUF_BLOCK_SIZE) * sizeof(os_membuf_t));
|
||||||
MP_STATE_PORT(bluetooth_nimble_root_pointers)->l2cap_chan = chan;
|
MP_STATE_PORT(bluetooth_nimble_root_pointers)->l2cap_chan = chan;
|
||||||
|
|
||||||
// Will be set in BLE_L2CAP_EVENT_COC_CONNECTED or BLE_L2CAP_EVENT_COC_ACCEPT.
|
// Will be set in BLE_L2CAP_EVENT_COC_CONNECTED or BLE_L2CAP_EVENT_COC_ACCEPT.
|
||||||
|
|
|
@ -90,9 +90,9 @@ mp_obj_t MP_VFS_LFSx(file_open)(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mod
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LFS_BUILD_VERSION == 1
|
#if LFS_BUILD_VERSION == 1
|
||||||
MP_OBJ_VFS_LFSx_FILE *o = m_new_obj_var_with_finaliser(MP_OBJ_VFS_LFSx_FILE, uint8_t, self->lfs.cfg->prog_size);
|
MP_OBJ_VFS_LFSx_FILE *o = m_new_obj_var_with_finaliser(MP_OBJ_VFS_LFSx_FILE, file_buffer, uint8_t, self->lfs.cfg->prog_size);
|
||||||
#else
|
#else
|
||||||
MP_OBJ_VFS_LFSx_FILE *o = m_new_obj_var_with_finaliser(MP_OBJ_VFS_LFSx_FILE, uint8_t, self->lfs.cfg->cache_size);
|
MP_OBJ_VFS_LFSx_FILE *o = m_new_obj_var_with_finaliser(MP_OBJ_VFS_LFSx_FILE, file_buffer, uint8_t, self->lfs.cfg->cache_size);
|
||||||
#endif
|
#endif
|
||||||
o->base.type = type;
|
o->base.type = type;
|
||||||
o->vfs = self;
|
o->vfs = self;
|
||||||
|
|
|
@ -279,14 +279,14 @@ STATIC const mp_stream_p_t vfs_posix_textio_stream_p = {
|
||||||
|
|
||||||
#if MICROPY_PY_SYS_STDIO_BUFFER
|
#if MICROPY_PY_SYS_STDIO_BUFFER
|
||||||
|
|
||||||
const mp_obj_vfs_posix_file_t mp_sys_stdin_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDIN_FILENO};
|
mp_obj_vfs_posix_file_t mp_sys_stdin_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDIN_FILENO};
|
||||||
const mp_obj_vfs_posix_file_t mp_sys_stdout_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDOUT_FILENO};
|
mp_obj_vfs_posix_file_t mp_sys_stdout_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDOUT_FILENO};
|
||||||
const mp_obj_vfs_posix_file_t mp_sys_stderr_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDERR_FILENO};
|
mp_obj_vfs_posix_file_t mp_sys_stderr_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDERR_FILENO};
|
||||||
|
|
||||||
// Forward declarations.
|
// Forward declarations.
|
||||||
const mp_obj_vfs_posix_file_t mp_sys_stdin_obj;
|
mp_obj_vfs_posix_file_t mp_sys_stdin_obj;
|
||||||
const mp_obj_vfs_posix_file_t mp_sys_stdout_obj;
|
mp_obj_vfs_posix_file_t mp_sys_stdout_obj;
|
||||||
const mp_obj_vfs_posix_file_t mp_sys_stderr_obj;
|
mp_obj_vfs_posix_file_t mp_sys_stderr_obj;
|
||||||
|
|
||||||
STATIC void vfs_posix_textio_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
STATIC void vfs_posix_textio_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||||
if (dest[0] != MP_OBJ_NULL) {
|
if (dest[0] != MP_OBJ_NULL) {
|
||||||
|
@ -332,8 +332,8 @@ MP_DEFINE_CONST_OBJ_TYPE(
|
||||||
locals_dict, &vfs_posix_rawfile_locals_dict
|
locals_dict, &vfs_posix_rawfile_locals_dict
|
||||||
);
|
);
|
||||||
|
|
||||||
const mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_vfs_posix_textio}, STDIN_FILENO};
|
mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_vfs_posix_textio}, STDIN_FILENO};
|
||||||
const mp_obj_vfs_posix_file_t mp_sys_stdout_obj = {{&mp_type_vfs_posix_textio}, STDOUT_FILENO};
|
mp_obj_vfs_posix_file_t mp_sys_stdout_obj = {{&mp_type_vfs_posix_textio}, STDOUT_FILENO};
|
||||||
const mp_obj_vfs_posix_file_t mp_sys_stderr_obj = {{&mp_type_vfs_posix_textio}, STDERR_FILENO};
|
mp_obj_vfs_posix_file_t mp_sys_stderr_obj = {{&mp_type_vfs_posix_textio}, STDERR_FILENO};
|
||||||
|
|
||||||
#endif // MICROPY_VFS_POSIX
|
#endif // MICROPY_VFS_POSIX
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/stream.h"
|
#include "py/stream.h"
|
||||||
|
@ -34,33 +35,39 @@
|
||||||
|
|
||||||
#if MICROPY_READER_VFS
|
#if MICROPY_READER_VFS
|
||||||
|
|
||||||
|
#ifndef MICROPY_READER_VFS_DEFAULT_BUFFER_SIZE
|
||||||
|
#define MICROPY_READER_VFS_DEFAULT_BUFFER_SIZE (2 * MICROPY_BYTES_PER_GC_BLOCK - offsetof(mp_reader_vfs_t, buf))
|
||||||
|
#endif
|
||||||
|
#define MICROPY_READER_VFS_MIN_BUFFER_SIZE (MICROPY_BYTES_PER_GC_BLOCK - offsetof(mp_reader_vfs_t, buf))
|
||||||
|
#define MICROPY_READER_VFS_MAX_BUFFER_SIZE (255)
|
||||||
|
|
||||||
typedef struct _mp_reader_vfs_t {
|
typedef struct _mp_reader_vfs_t {
|
||||||
mp_obj_t file;
|
mp_obj_t file;
|
||||||
uint16_t len;
|
uint8_t bufpos;
|
||||||
uint16_t pos;
|
uint8_t buflen;
|
||||||
byte buf[24];
|
uint8_t bufsize;
|
||||||
|
byte buf[];
|
||||||
} mp_reader_vfs_t;
|
} mp_reader_vfs_t;
|
||||||
|
|
||||||
STATIC mp_uint_t mp_reader_vfs_readbyte(void *data) {
|
STATIC mp_uint_t mp_reader_vfs_readbyte(void *data) {
|
||||||
mp_reader_vfs_t *reader = (mp_reader_vfs_t *)data;
|
mp_reader_vfs_t *reader = (mp_reader_vfs_t *)data;
|
||||||
if (reader->pos >= reader->len) {
|
if (reader->bufpos >= reader->buflen) {
|
||||||
if (reader->len < sizeof(reader->buf)) {
|
if (reader->buflen < reader->bufsize) {
|
||||||
return MP_READER_EOF;
|
return MP_READER_EOF;
|
||||||
} else {
|
} else {
|
||||||
int errcode;
|
int errcode;
|
||||||
reader->len = mp_stream_rw(reader->file, reader->buf, sizeof(reader->buf),
|
reader->buflen = mp_stream_rw(reader->file, reader->buf, reader->bufsize, &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
|
||||||
&errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
|
|
||||||
if (errcode != 0) {
|
if (errcode != 0) {
|
||||||
// TODO handle errors properly
|
// TODO handle errors properly
|
||||||
return MP_READER_EOF;
|
return MP_READER_EOF;
|
||||||
}
|
}
|
||||||
if (reader->len == 0) {
|
if (reader->buflen == 0) {
|
||||||
return MP_READER_EOF;
|
return MP_READER_EOF;
|
||||||
}
|
}
|
||||||
reader->pos = 0;
|
reader->bufpos = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return reader->buf[reader->pos++];
|
return reader->buf[reader->bufpos++];
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void mp_reader_vfs_close(void *data) {
|
STATIC void mp_reader_vfs_close(void *data) {
|
||||||
|
@ -70,18 +77,31 @@ STATIC void mp_reader_vfs_close(void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_reader_new_file(mp_reader_t *reader, qstr filename) {
|
void mp_reader_new_file(mp_reader_t *reader, qstr filename) {
|
||||||
mp_reader_vfs_t *rf = m_new_obj(mp_reader_vfs_t);
|
|
||||||
mp_obj_t args[2] = {
|
mp_obj_t args[2] = {
|
||||||
MP_OBJ_NEW_QSTR(filename),
|
MP_OBJ_NEW_QSTR(filename),
|
||||||
MP_OBJ_NEW_QSTR(MP_QSTR_rb),
|
MP_OBJ_NEW_QSTR(MP_QSTR_rb),
|
||||||
};
|
};
|
||||||
rf->file = mp_vfs_open(MP_ARRAY_SIZE(args), &args[0], (mp_map_t *)&mp_const_empty_map);
|
mp_obj_t file = mp_vfs_open(MP_ARRAY_SIZE(args), &args[0], (mp_map_t *)&mp_const_empty_map);
|
||||||
int errcode;
|
|
||||||
rf->len = mp_stream_rw(rf->file, rf->buf, sizeof(rf->buf), &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
|
const mp_stream_p_t *stream_p = mp_get_stream(file);
|
||||||
|
int errcode = 0;
|
||||||
|
mp_uint_t bufsize = stream_p->ioctl(file, MP_STREAM_GET_BUFFER_SIZE, 0, &errcode);
|
||||||
|
if (bufsize == MP_STREAM_ERROR || bufsize == 0) {
|
||||||
|
// bufsize == 0 is included here to support mpremote v1.21 and older where mount file ioctl
|
||||||
|
// returned 0 by default.
|
||||||
|
bufsize = MICROPY_READER_VFS_DEFAULT_BUFFER_SIZE;
|
||||||
|
} else {
|
||||||
|
bufsize = MIN(MICROPY_READER_VFS_MAX_BUFFER_SIZE, MAX(MICROPY_READER_VFS_MIN_BUFFER_SIZE, bufsize));
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_reader_vfs_t *rf = m_new_obj_var(mp_reader_vfs_t, buf, byte, bufsize);
|
||||||
|
rf->file = file;
|
||||||
|
rf->bufsize = bufsize;
|
||||||
|
rf->buflen = mp_stream_rw(rf->file, rf->buf, rf->bufsize, &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
|
||||||
if (errcode != 0) {
|
if (errcode != 0) {
|
||||||
mp_raise_OSError(errcode);
|
mp_raise_OSError(errcode);
|
||||||
}
|
}
|
||||||
rf->pos = 0;
|
rf->bufpos = 0;
|
||||||
reader->data = rf;
|
reader->data = rf;
|
||||||
reader->readbyte = mp_reader_vfs_readbyte;
|
reader->readbyte = mp_reader_vfs_readbyte;
|
||||||
reader->close = mp_reader_vfs_close;
|
reader->close = mp_reader_vfs_close;
|
||||||
|
|
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 166 KiB |
|
@ -110,8 +110,9 @@ char *strchr(const char *s, int c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int strncmp(const char *s1, const char *s2, size_t n) {
|
int strncmp(const char *s1, const char *s2, size_t n) {
|
||||||
while (*s1 && *s2 && n-- > 0) {
|
while (n > 0 && *s1 && *s2) {
|
||||||
int c = *s1++ - *s2++;
|
int c = *s1++ - *s2++;
|
||||||
|
--n;
|
||||||
if (c) {
|
if (c) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 Nick Moore
|
||||||
|
* Copyright (c) 2021 Jonathan Hogg
|
||||||
|
*
|
||||||
|
* 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 "py/mphal.h"
|
||||||
|
#include "adc.h"
|
||||||
|
#include "driver/adc.h"
|
||||||
|
|
||||||
|
#define DEFAULT_VREF 1100
|
||||||
|
|
||||||
|
void madcblock_bits_helper(machine_adc_block_obj_t *self, mp_int_t bits) {
|
||||||
|
switch (bits) {
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
case 9:
|
||||||
|
self->width = ADC_WIDTH_BIT_9;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
self->width = ADC_WIDTH_BIT_10;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
self->width = ADC_WIDTH_BIT_11;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
case 12:
|
||||||
|
self->width = ADC_WIDTH_BIT_12;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2
|
||||||
|
case 13:
|
||||||
|
self->width = ADC_WIDTH_BIT_13;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
mp_raise_ValueError(MP_ERROR_TEXT("invalid bits"));
|
||||||
|
}
|
||||||
|
self->bits = bits;
|
||||||
|
|
||||||
|
if (self->unit_id == ADC_UNIT_1) {
|
||||||
|
adc1_config_width(self->width);
|
||||||
|
}
|
||||||
|
for (adc_atten_t atten = ADC_ATTEN_DB_0; atten < ADC_ATTEN_MAX; atten++) {
|
||||||
|
if (self->characteristics[atten] != NULL) {
|
||||||
|
esp_adc_cal_characterize(self->unit_id, atten, self->width, DEFAULT_VREF, self->characteristics[atten]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_int_t madcblock_read_helper(machine_adc_block_obj_t *self, adc_channel_t channel_id) {
|
||||||
|
int raw;
|
||||||
|
if (self->unit_id == ADC_UNIT_1) {
|
||||||
|
raw = adc1_get_raw(channel_id);
|
||||||
|
} else {
|
||||||
|
check_esp_err(adc2_get_raw(channel_id, self->width, &raw));
|
||||||
|
}
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_int_t madcblock_read_uv_helper(machine_adc_block_obj_t *self, adc_channel_t channel_id, adc_atten_t atten) {
|
||||||
|
int raw = madcblock_read_helper(self, channel_id);
|
||||||
|
esp_adc_cal_characteristics_t *adc_chars = self->characteristics[atten];
|
||||||
|
if (adc_chars == NULL) {
|
||||||
|
adc_chars = malloc(sizeof(esp_adc_cal_characteristics_t));
|
||||||
|
esp_adc_cal_characterize(self->unit_id, atten, self->width, DEFAULT_VREF, adc_chars);
|
||||||
|
self->characteristics[atten] = adc_chars;
|
||||||
|
}
|
||||||
|
mp_int_t uv = esp_adc_cal_raw_to_voltage(raw, adc_chars) * 1000;
|
||||||
|
return uv;
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* Development of the code in this file was sponsored by Microbric Pty Ltd
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef MICROPY_INCLUDED_ESP32_ADC_H
|
||||||
|
#define MICROPY_INCLUDED_ESP32_ADC_H
|
||||||
|
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "esp_adc_cal.h"
|
||||||
|
|
||||||
|
#define ADC_ATTEN_MAX SOC_ADC_ATTEN_NUM
|
||||||
|
|
||||||
|
typedef struct _machine_adc_block_obj_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
adc_unit_t unit_id;
|
||||||
|
mp_int_t bits;
|
||||||
|
adc_bits_width_t width;
|
||||||
|
esp_adc_cal_characteristics_t *characteristics[ADC_ATTEN_MAX];
|
||||||
|
} machine_adc_block_obj_t;
|
||||||
|
|
||||||
|
typedef struct _machine_adc_obj_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
machine_adc_block_obj_t *block;
|
||||||
|
adc_channel_t channel_id;
|
||||||
|
gpio_num_t gpio_id;
|
||||||
|
} machine_adc_obj_t;
|
||||||
|
|
||||||
|
extern machine_adc_block_obj_t madcblock_obj[];
|
||||||
|
|
||||||
|
void madcblock_bits_helper(machine_adc_block_obj_t *self, mp_int_t bits);
|
||||||
|
mp_int_t madcblock_read_helper(machine_adc_block_obj_t *self, adc_channel_t channel_id);
|
||||||
|
mp_int_t madcblock_read_uv_helper(machine_adc_block_obj_t *self, adc_channel_t channel_id, adc_atten_t atten);
|
||||||
|
|
||||||
|
const machine_adc_obj_t *madc_search_helper(machine_adc_block_obj_t *block, adc_channel_t channel_id, gpio_num_t gpio_id);
|
||||||
|
void madc_init_helper(const machine_adc_obj_t *self, size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_ESP32_ADC_H
|
|
@ -53,6 +53,7 @@ list(APPEND MICROPY_SOURCE_DRIVERS
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND MICROPY_SOURCE_PORT
|
list(APPEND MICROPY_SOURCE_PORT
|
||||||
|
adc.c
|
||||||
main.c
|
main.c
|
||||||
ppp_set_auth.c
|
ppp_set_auth.c
|
||||||
uart.c
|
uart.c
|
||||||
|
@ -66,7 +67,6 @@ list(APPEND MICROPY_SOURCE_PORT
|
||||||
machine_timer.c
|
machine_timer.c
|
||||||
machine_pin.c
|
machine_pin.c
|
||||||
machine_touchpad.c
|
machine_touchpad.c
|
||||||
machine_adcblock.c
|
|
||||||
machine_dac.c
|
machine_dac.c
|
||||||
machine_i2c.c
|
machine_i2c.c
|
||||||
modmachine.c
|
modmachine.c
|
||||||
|
|
|
@ -206,10 +206,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_rmt_deinit_obj, esp32_rmt_deinit);
|
||||||
// Return the source frequency.
|
// Return the source frequency.
|
||||||
// Currently only the APB clock (80MHz) can be used but it is possible other
|
// Currently only the APB clock (80MHz) can be used but it is possible other
|
||||||
// clock sources will added in the future.
|
// clock sources will added in the future.
|
||||||
STATIC mp_obj_t esp32_rmt_source_freq(mp_obj_t self_in) {
|
STATIC mp_obj_t esp32_rmt_source_freq() {
|
||||||
return mp_obj_new_int(APB_CLK_FREQ);
|
return mp_obj_new_int(APB_CLK_FREQ);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_rmt_source_freq_obj, esp32_rmt_source_freq);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp32_rmt_source_freq_obj, esp32_rmt_source_freq);
|
||||||
|
STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(esp32_rmt_source_obj, MP_ROM_PTR(&esp32_rmt_source_freq_obj));
|
||||||
|
|
||||||
// Return the clock divider.
|
// Return the clock divider.
|
||||||
STATIC mp_obj_t esp32_rmt_clock_div(mp_obj_t self_in) {
|
STATIC mp_obj_t esp32_rmt_clock_div(mp_obj_t self_in) {
|
||||||
|
@ -357,7 +358,6 @@ STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(esp32_rmt_bitstream_channel_obj, MP_ROM_
|
||||||
STATIC const mp_rom_map_elem_t esp32_rmt_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t esp32_rmt_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&esp32_rmt_deinit_obj) },
|
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&esp32_rmt_deinit_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&esp32_rmt_deinit_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&esp32_rmt_deinit_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_source_freq), MP_ROM_PTR(&esp32_rmt_source_freq_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_clock_div), MP_ROM_PTR(&esp32_rmt_clock_div_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_clock_div), MP_ROM_PTR(&esp32_rmt_clock_div_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_wait_done), MP_ROM_PTR(&esp32_rmt_wait_done_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_wait_done), MP_ROM_PTR(&esp32_rmt_wait_done_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_loop), MP_ROM_PTR(&esp32_rmt_loop_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_loop), MP_ROM_PTR(&esp32_rmt_loop_obj) },
|
||||||
|
@ -365,6 +365,12 @@ STATIC const mp_rom_map_elem_t esp32_rmt_locals_dict_table[] = {
|
||||||
|
|
||||||
// Static methods
|
// Static methods
|
||||||
{ MP_ROM_QSTR(MP_QSTR_bitstream_channel), MP_ROM_PTR(&esp32_rmt_bitstream_channel_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_bitstream_channel), MP_ROM_PTR(&esp32_rmt_bitstream_channel_obj) },
|
||||||
|
|
||||||
|
// Class methods
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_source_freq), MP_ROM_PTR(&esp32_rmt_source_obj) },
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_PULSE_MAX), MP_ROM_INT(32767) },
|
||||||
};
|
};
|
||||||
STATIC MP_DEFINE_CONST_DICT(esp32_rmt_locals_dict, esp32_rmt_locals_dict_table);
|
STATIC MP_DEFINE_CONST_DICT(esp32_rmt_locals_dict, esp32_rmt_locals_dict_table);
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,9 @@
|
||||||
// This file is never compiled standalone, it's included directly from
|
// This file is never compiled standalone, it's included directly from
|
||||||
// extmod/machine_adc.c via MICROPY_PY_MACHINE_ADC_INCLUDEFILE.
|
// extmod/machine_adc.c via MICROPY_PY_MACHINE_ADC_INCLUDEFILE.
|
||||||
|
|
||||||
#include "esp_log.h"
|
|
||||||
|
|
||||||
#include "driver/gpio.h"
|
|
||||||
#include "driver/adc.h"
|
|
||||||
|
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "machine_adc.h"
|
#include "adc.h"
|
||||||
|
#include "driver/adc.h"
|
||||||
|
|
||||||
#define ADCBLOCK1 (&madcblock_obj[0])
|
#define ADCBLOCK1 (&madcblock_obj[0])
|
||||||
#define ADCBLOCK2 (&madcblock_obj[1])
|
#define ADCBLOCK2 (&madcblock_obj[1])
|
||||||
|
@ -136,7 +132,7 @@ static inline void madc_atten_set(const machine_adc_obj_t *self, adc_atten_t att
|
||||||
madc_obj_atten[self - &madc_obj[0]] = atten + 1;
|
madc_obj_atten[self - &madc_obj[0]] = atten + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const machine_adc_obj_t *madc_search_helper(madcblock_obj_t *block, adc_channel_t channel_id, gpio_num_t gpio_id) {
|
const machine_adc_obj_t *madc_search_helper(machine_adc_block_obj_t *block, adc_channel_t channel_id, gpio_num_t gpio_id) {
|
||||||
for (int i = 0; i < MP_ARRAY_SIZE(madc_obj); i++) {
|
for (int i = 0; i < MP_ARRAY_SIZE(madc_obj); i++) {
|
||||||
const machine_adc_obj_t *adc = &madc_obj[i];
|
const machine_adc_obj_t *adc = &madc_obj[i];
|
||||||
if ((block == NULL || block == adc->block) && (channel_id == -1 || channel_id == adc->channel_id) && (gpio_id == -1 || gpio_id == adc->gpio_id)) {
|
if ((block == NULL || block == adc->block) && (channel_id == -1 || channel_id == adc->channel_id) && (gpio_id == -1 || gpio_id == adc->gpio_id)) {
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
#ifndef MICROPY_INCLUDED_MACHINE_ADC_H
|
|
||||||
#define MICROPY_INCLUDED_MACHINE_ADC_H
|
|
||||||
|
|
||||||
#include "machine_adcblock.h"
|
|
||||||
|
|
||||||
typedef struct _machine_adc_obj_t {
|
|
||||||
mp_obj_base_t base;
|
|
||||||
madcblock_obj_t *block;
|
|
||||||
adc_channel_t channel_id;
|
|
||||||
gpio_num_t gpio_id;
|
|
||||||
} machine_adc_obj_t;
|
|
||||||
|
|
||||||
const machine_adc_obj_t *madc_search_helper(madcblock_obj_t *block, adc_channel_t channel_id, gpio_num_t gpio_id);
|
|
||||||
void madc_init_helper(const machine_adc_obj_t *self, size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_MACHINE_ADC_H
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Jonathan Hogg
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This file is never compiled standalone, it's included directly from
|
||||||
|
// extmod/machine_adc_block.c via MICROPY_PY_MACHINE_ADC_BLOCK_INCLUDEFILE.
|
||||||
|
|
||||||
|
#include "py/mphal.h"
|
||||||
|
#include "adc.h"
|
||||||
|
#include "driver/adc.h"
|
||||||
|
|
||||||
|
machine_adc_block_obj_t madcblock_obj[] = {
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
{{&machine_adc_block_type}, ADC_UNIT_1, 12, -1, {0}},
|
||||||
|
{{&machine_adc_block_type}, ADC_UNIT_2, 12, -1, {0}},
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
|
{{&machine_adc_block_type}, ADC_UNIT_1, 13, -1, {0}},
|
||||||
|
{{&machine_adc_block_type}, ADC_UNIT_2, 13, -1, {0}},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC void mp_machine_adc_block_print(const mp_print_t *print, machine_adc_block_obj_t *self) {
|
||||||
|
mp_printf(print, "ADCBlock(%u, bits=%u)", self->unit_id, self->bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void mp_machine_adc_block_bits_set(machine_adc_block_obj_t *self, mp_int_t bits) {
|
||||||
|
if (bits != -1) {
|
||||||
|
madcblock_bits_helper(self, bits);
|
||||||
|
} else if (self->width == -1) {
|
||||||
|
madcblock_bits_helper(self, self->bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC machine_adc_block_obj_t *mp_machine_adc_block_get(mp_int_t unit) {
|
||||||
|
for (int i = 0; i < MP_ARRAY_SIZE(madcblock_obj); i++) {
|
||||||
|
if (unit == madcblock_obj[i].unit_id) {
|
||||||
|
return &madcblock_obj[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC machine_adc_obj_t *mp_machine_adc_block_connect(machine_adc_block_obj_t *self, mp_int_t channel_id, mp_hal_pin_obj_t gpio_id, mp_map_t *kw_args) {
|
||||||
|
const machine_adc_obj_t *adc = madc_search_helper(self, channel_id, gpio_id);
|
||||||
|
if (adc == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
madc_init_helper(adc, 0, NULL, kw_args);
|
||||||
|
return (machine_adc_obj_t *)adc;
|
||||||
|
}
|
|
@ -1,204 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021 Jonathan Hogg
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "esp_log.h"
|
|
||||||
|
|
||||||
#include "driver/gpio.h"
|
|
||||||
#include "driver/adc.h"
|
|
||||||
|
|
||||||
#include "py/runtime.h"
|
|
||||||
#include "py/mphal.h"
|
|
||||||
#include "modmachine.h"
|
|
||||||
#include "machine_adc.h"
|
|
||||||
#include "machine_adcblock.h"
|
|
||||||
|
|
||||||
#define DEFAULT_VREF 1100
|
|
||||||
|
|
||||||
madcblock_obj_t madcblock_obj[] = {
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
|
||||||
{{&machine_adcblock_type}, ADC_UNIT_1, 12, -1, {0}},
|
|
||||||
{{&machine_adcblock_type}, ADC_UNIT_2, 12, -1, {0}},
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
|
||||||
{{&machine_adcblock_type}, ADC_UNIT_1, 13, -1, {0}},
|
|
||||||
{{&machine_adcblock_type}, ADC_UNIT_2, 13, -1, {0}},
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC void madcblock_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
|
||||||
madcblock_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
mp_printf(print, "ADCBlock(%u, bits=%u)", self->unit_id, self->bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
void madcblock_bits_helper(madcblock_obj_t *self, mp_int_t bits) {
|
|
||||||
switch (bits) {
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
|
||||||
case 9:
|
|
||||||
self->width = ADC_WIDTH_BIT_9;
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
self->width = ADC_WIDTH_BIT_10;
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
self->width = ADC_WIDTH_BIT_11;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
|
||||||
case 12:
|
|
||||||
self->width = ADC_WIDTH_BIT_12;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2
|
|
||||||
case 13:
|
|
||||||
self->width = ADC_WIDTH_BIT_13;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("invalid bits"));
|
|
||||||
}
|
|
||||||
self->bits = bits;
|
|
||||||
|
|
||||||
if (self->unit_id == ADC_UNIT_1) {
|
|
||||||
adc1_config_width(self->width);
|
|
||||||
}
|
|
||||||
for (adc_atten_t atten = ADC_ATTEN_DB_0; atten < ADC_ATTEN_MAX; atten++) {
|
|
||||||
if (self->characteristics[atten] != NULL) {
|
|
||||||
esp_adc_cal_characterize(self->unit_id, atten, self->width, DEFAULT_VREF, self->characteristics[atten]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void madcblock_init_helper(madcblock_obj_t *self, size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
|
||||||
enum {
|
|
||||||
ARG_bits,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const mp_arg_t allowed_args[] = {
|
|
||||||
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
|
|
||||||
};
|
|
||||||
|
|
||||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
|
||||||
mp_arg_parse_all(n_pos_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
|
||||||
|
|
||||||
mp_int_t bits = args[ARG_bits].u_int;
|
|
||||||
if (bits != -1) {
|
|
||||||
madcblock_bits_helper(self, bits);
|
|
||||||
} else if (self->width == -1) {
|
|
||||||
madcblock_bits_helper(self, self->bits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t madcblock_make_new(const mp_obj_type_t *type, size_t n_pos_args, size_t n_kw_args, const mp_obj_t *args) {
|
|
||||||
mp_arg_check_num(n_pos_args, n_kw_args, 1, MP_OBJ_FUN_ARGS_MAX, true);
|
|
||||||
adc_unit_t unit = mp_obj_get_int(args[0]);
|
|
||||||
madcblock_obj_t *self = NULL;
|
|
||||||
for (int i = 0; i < MP_ARRAY_SIZE(madcblock_obj); i++) {
|
|
||||||
if (unit == madcblock_obj[i].unit_id) {
|
|
||||||
self = &madcblock_obj[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!self) {
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("invalid block id"));
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_map_t kw_args;
|
|
||||||
mp_map_init_fixed_table(&kw_args, n_kw_args, args + n_pos_args);
|
|
||||||
madcblock_init_helper(self, n_pos_args - 1, args + 1, &kw_args);
|
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t madcblock_init(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
|
||||||
madcblock_obj_t *self = pos_args[0];
|
|
||||||
madcblock_init_helper(self, n_pos_args - 1, pos_args + 1, kw_args);
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(madcblock_init_obj, 1, madcblock_init);
|
|
||||||
|
|
||||||
STATIC mp_obj_t madcblock_connect(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
|
||||||
madcblock_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
|
|
||||||
adc_channel_t channel_id = -1;
|
|
||||||
gpio_num_t gpio_id = -1;
|
|
||||||
if (n_pos_args == 2) {
|
|
||||||
if (mp_obj_is_int(pos_args[1])) {
|
|
||||||
channel_id = mp_obj_get_int(pos_args[1]);
|
|
||||||
} else {
|
|
||||||
gpio_id = machine_pin_get_id(pos_args[1]);
|
|
||||||
}
|
|
||||||
} else if (n_pos_args == 3) {
|
|
||||||
channel_id = mp_obj_get_int(pos_args[1]);
|
|
||||||
gpio_id = machine_pin_get_id(pos_args[2]);
|
|
||||||
} else {
|
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("too many positional args"));
|
|
||||||
}
|
|
||||||
|
|
||||||
const machine_adc_obj_t *adc = madc_search_helper(self, channel_id, gpio_id);
|
|
||||||
if (adc != NULL) {
|
|
||||||
madc_init_helper(adc, 0, pos_args + n_pos_args, kw_args);
|
|
||||||
return MP_OBJ_FROM_PTR(adc);
|
|
||||||
}
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("no matching ADC"));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(madcblock_connect_obj, 2, madcblock_connect);
|
|
||||||
|
|
||||||
mp_int_t madcblock_read_helper(madcblock_obj_t *self, adc_channel_t channel_id) {
|
|
||||||
int raw;
|
|
||||||
if (self->unit_id == ADC_UNIT_1) {
|
|
||||||
raw = adc1_get_raw(channel_id);
|
|
||||||
} else {
|
|
||||||
check_esp_err(adc2_get_raw(channel_id, self->width, &raw));
|
|
||||||
}
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_int_t madcblock_read_uv_helper(madcblock_obj_t *self, adc_channel_t channel_id, adc_atten_t atten) {
|
|
||||||
int raw = madcblock_read_helper(self, channel_id);
|
|
||||||
esp_adc_cal_characteristics_t *adc_chars = self->characteristics[atten];
|
|
||||||
if (adc_chars == NULL) {
|
|
||||||
adc_chars = malloc(sizeof(esp_adc_cal_characteristics_t));
|
|
||||||
esp_adc_cal_characterize(self->unit_id, atten, self->width, DEFAULT_VREF, adc_chars);
|
|
||||||
self->characteristics[atten] = adc_chars;
|
|
||||||
}
|
|
||||||
mp_int_t uv = esp_adc_cal_raw_to_voltage(raw, adc_chars) * 1000;
|
|
||||||
return uv;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t madcblock_locals_dict_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&madcblock_init_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&madcblock_connect_obj) },
|
|
||||||
};
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(madcblock_locals_dict, madcblock_locals_dict_table);
|
|
||||||
|
|
||||||
MP_DEFINE_CONST_OBJ_TYPE(
|
|
||||||
machine_adcblock_type,
|
|
||||||
MP_QSTR_ADCBlock,
|
|
||||||
MP_TYPE_FLAG_NONE,
|
|
||||||
make_new, madcblock_make_new,
|
|
||||||
print, madcblock_print,
|
|
||||||
locals_dict, &madcblock_locals_dict
|
|
||||||
);
|
|
|
@ -1,22 +0,0 @@
|
||||||
#ifndef MICROPY_INCLUDED_MACHINE_ADCBLOCK_H
|
|
||||||
#define MICROPY_INCLUDED_MACHINE_ADCBLOCK_H
|
|
||||||
|
|
||||||
#include "esp_adc_cal.h"
|
|
||||||
|
|
||||||
#define ADC_ATTEN_MAX SOC_ADC_ATTEN_NUM
|
|
||||||
|
|
||||||
typedef struct _madcblock_obj_t {
|
|
||||||
mp_obj_base_t base;
|
|
||||||
adc_unit_t unit_id;
|
|
||||||
mp_int_t bits;
|
|
||||||
adc_bits_width_t width;
|
|
||||||
esp_adc_cal_characteristics_t *characteristics[ADC_ATTEN_MAX];
|
|
||||||
} madcblock_obj_t;
|
|
||||||
|
|
||||||
extern madcblock_obj_t madcblock_obj[];
|
|
||||||
|
|
||||||
extern void madcblock_bits_helper(madcblock_obj_t *self, mp_int_t bits);
|
|
||||||
extern mp_int_t madcblock_read_helper(madcblock_obj_t *self, adc_channel_t channel_id);
|
|
||||||
extern mp_int_t madcblock_read_uv_helper(madcblock_obj_t *self, adc_channel_t channel_id, adc_atten_t atten);
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_MACHINE_ADCBLOCK_H
|
|
|
@ -312,7 +312,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
|
||||||
#if MICROPY_PY_MACHINE_ADC
|
#if MICROPY_PY_MACHINE_ADC
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) },
|
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) },
|
||||||
#endif
|
#endif
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ADCBlock), MP_ROM_PTR(&machine_adcblock_type) },
|
#if MICROPY_PY_MACHINE_ADC_BLOCK
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_ADCBlock), MP_ROM_PTR(&machine_adc_block_type) },
|
||||||
|
#endif
|
||||||
#if MICROPY_PY_MACHINE_DAC
|
#if MICROPY_PY_MACHINE_DAC
|
||||||
{ MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) },
|
{ MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) },
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,7 +10,6 @@ typedef enum {
|
||||||
} wake_type_t;
|
} wake_type_t;
|
||||||
|
|
||||||
extern const mp_obj_type_t machine_touchpad_type;
|
extern const mp_obj_type_t machine_touchpad_type;
|
||||||
extern const mp_obj_type_t machine_adcblock_type;
|
|
||||||
extern const mp_obj_type_t machine_dac_type;
|
extern const mp_obj_type_t machine_dac_type;
|
||||||
extern const mp_obj_type_t machine_sdcard_type;
|
extern const mp_obj_type_t machine_sdcard_type;
|
||||||
|
|
||||||
|
|
|
@ -99,10 +99,11 @@
|
||||||
#define MICROPY_PY_MACHINE_ADC (1)
|
#define MICROPY_PY_MACHINE_ADC (1)
|
||||||
#define MICROPY_PY_MACHINE_ADC_INCLUDEFILE "ports/esp32/machine_adc.c"
|
#define MICROPY_PY_MACHINE_ADC_INCLUDEFILE "ports/esp32/machine_adc.c"
|
||||||
#define MICROPY_PY_MACHINE_ADC_ATTEN_WIDTH (1)
|
#define MICROPY_PY_MACHINE_ADC_ATTEN_WIDTH (1)
|
||||||
#define MICROPY_PY_MACHINE_ADC_BLOCK (1)
|
|
||||||
#define MICROPY_PY_MACHINE_ADC_INIT (1)
|
#define MICROPY_PY_MACHINE_ADC_INIT (1)
|
||||||
#define MICROPY_PY_MACHINE_ADC_READ (1)
|
#define MICROPY_PY_MACHINE_ADC_READ (1)
|
||||||
#define MICROPY_PY_MACHINE_ADC_READ_UV (1)
|
#define MICROPY_PY_MACHINE_ADC_READ_UV (1)
|
||||||
|
#define MICROPY_PY_MACHINE_ADC_BLOCK (1)
|
||||||
|
#define MICROPY_PY_MACHINE_ADC_BLOCK_INCLUDEFILE "ports/esp32/machine_adc_block.c"
|
||||||
#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new
|
#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new
|
||||||
#define MICROPY_PY_MACHINE_BITSTREAM (1)
|
#define MICROPY_PY_MACHINE_BITSTREAM (1)
|
||||||
#define MICROPY_PY_MACHINE_PULSE (1)
|
#define MICROPY_PY_MACHINE_PULSE (1)
|
||||||
|
|
|
@ -18,18 +18,18 @@
|
||||||
// LPUART4 on D5/D6 -> 2
|
// LPUART4 on D5/D6 -> 2
|
||||||
|
|
||||||
#define MICROPY_HW_UART_NUM (sizeof(uart_index_table) / sizeof(uart_index_table)[0])
|
#define MICROPY_HW_UART_NUM (sizeof(uart_index_table) / sizeof(uart_index_table)[0])
|
||||||
#define MICROPY_HW_UART_INDEX { 0, 1, 4 }
|
#define MICROPY_HW_UART_INDEX { 0, 1, 3, 4 }
|
||||||
|
|
||||||
#define IOMUX_TABLE_UART \
|
#define IOMUX_TABLE_UART \
|
||||||
{ IOMUXC_GPIO_10_LPUART1_TXD }, { IOMUXC_GPIO_09_LPUART1_RXD }, \
|
{ IOMUXC_GPIO_10_LPUART1_TXD }, { IOMUXC_GPIO_09_LPUART1_RXD }, \
|
||||||
{ 0 }, { 0 }, \
|
{ 0 }, { 0 }, \
|
||||||
{ 0 }, { 0 }, \
|
{ IOMUXC_GPIO_08_LPUART3_TXD }, { IOMUXC_GPIO_07_LPUART3_RXD }, \
|
||||||
{ IOMUXC_GPIO_06_LPUART4_TXD }, { IOMUXC_GPIO_05_LPUART4_RXD },
|
{ IOMUXC_GPIO_06_LPUART4_TXD }, { IOMUXC_GPIO_05_LPUART4_RXD },
|
||||||
|
|
||||||
#define IOMUX_TABLE_UART_CTS_RTS \
|
#define IOMUX_TABLE_UART_CTS_RTS \
|
||||||
{ IOMUXC_GPIO_08_LPUART1_CTS_B }, { IOMUXC_GPIO_07_LPUART1_RTS_B }, \
|
{ IOMUXC_GPIO_08_LPUART1_CTS_B }, { IOMUXC_GPIO_07_LPUART1_RTS_B }, \
|
||||||
{ 0 }, { 0 }, \
|
{ 0 }, { 0 }, \
|
||||||
{ 0 }, { 0 }, \
|
{ IOMUXC_GPIO_AD_14_LPUART3_CTS_B }, { IOMUXC_GPIO_AD_13_LPUART3_RTS_B }, \
|
||||||
{ IOMUXC_GPIO_AD_14_LPUART4_CTS_B }, { IOMUXC_GPIO_AD_13_LPUART4_RTS_B },
|
{ IOMUXC_GPIO_AD_14_LPUART4_CTS_B }, { IOMUXC_GPIO_AD_13_LPUART4_RTS_B },
|
||||||
|
|
||||||
#define MICROPY_HW_SPI_INDEX { 0, 1, 2 }
|
#define MICROPY_HW_SPI_INDEX { 0, 1, 2 }
|
||||||
|
|
|
@ -121,10 +121,10 @@ STATIC mp_obj_t machine_deepsleep(size_t n_args, const mp_obj_t *args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MIMXRT117x_SERIES
|
#ifdef MIMXRT117x_SERIES
|
||||||
machine_pin_config(&pin_WAKEUP_DIG, PIN_MODE_IT_RISING, PIN_PULL_DISABLED, PIN_DRIVE_OFF, 0, PIN_AF_MODE_ALT5);
|
machine_pin_config(pin_WAKEUP_DIG, PIN_MODE_IT_RISING, PIN_PULL_DISABLED, PIN_DRIVE_OFF, 0, PIN_AF_MODE_ALT5);
|
||||||
GPC_CM_EnableIrqWakeup(GPC_CPU_MODE_CTRL_0, GPIO13_Combined_0_31_IRQn, true);
|
GPC_CM_EnableIrqWakeup(GPC_CPU_MODE_CTRL_0, GPIO13_Combined_0_31_IRQn, true);
|
||||||
#elif defined IOMUXC_SNVS_WAKEUP_GPIO5_IO00
|
#elif defined IOMUXC_SNVS_WAKEUP_GPIO5_IO00
|
||||||
machine_pin_config(&pin_WAKEUP, PIN_MODE_IT_RISING, PIN_PULL_DISABLED, PIN_DRIVE_OFF, 0, PIN_AF_MODE_ALT5);
|
machine_pin_config(pin_WAKEUP, PIN_MODE_IT_RISING, PIN_PULL_DISABLED, PIN_DRIVE_OFF, 0, PIN_AF_MODE_ALT5);
|
||||||
GPC_EnableIRQ(GPC, GPIO5_Combined_0_15_IRQn);
|
GPC_EnableIRQ(GPC, GPIO5_Combined_0_15_IRQn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,12 @@ CFLAGS += -DTEST
|
||||||
|
|
||||||
.PHONY: $(BUILD)/genhdr/tests.h
|
.PHONY: $(BUILD)/genhdr/tests.h
|
||||||
|
|
||||||
|
TESTS_PROFILE = $(dir $(abspath $(firstword $(MAKEFILE_LIST))))/tests_profile.txt
|
||||||
|
|
||||||
$(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h
|
$(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h
|
||||||
$(BUILD)/genhdr/tests.h:
|
$(BUILD)/genhdr/tests.h:
|
||||||
(cd $(TOP)/tests; ./run-tests.py --target=qemu-arm --write-exp)
|
(cd $(TOP)/tests; ./run-tests.py --target=qemu-arm --write-exp)
|
||||||
$(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py $(addprefix --exclude ,$(TESTS_EXCLUDE))) > $@
|
$(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py --profile $(TESTS_PROFILE) $(addprefix --exclude ,$(TESTS_EXCLUDE))) > $@
|
||||||
|
|
||||||
$(BUILD)/lib/tinytest/tinytest.o: CFLAGS += -DNO_FORKING
|
$(BUILD)/lib/tinytest/tinytest.o: CFLAGS += -DNO_FORKING
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Port-specific test directories.
|
||||||
|
|
||||||
|
test_dirs.add(("inlineasm", "qemu-arm"))
|
||||||
|
|
||||||
|
# Port-specific tests exclusion list.
|
||||||
|
|
||||||
|
exclude_tests.add(
|
||||||
|
(
|
||||||
|
# inline asm FP tests (require Cortex-M4)
|
||||||
|
"inlineasm/asmfpaddsub.py",
|
||||||
|
"inlineasm/asmfpcmp.py",
|
||||||
|
"inlineasm/asmfpldrstr.py",
|
||||||
|
"inlineasm/asmfpmuldiv.py",
|
||||||
|
"inlineasm/asmfpsqrt.py",
|
||||||
|
)
|
||||||
|
)
|
|
@ -30,7 +30,6 @@
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
|
|
||||||
extern const mp_obj_type_t machine_touchpad_type;
|
extern const mp_obj_type_t machine_touchpad_type;
|
||||||
extern const mp_obj_type_t machine_adcblock_type;
|
|
||||||
extern const mp_obj_type_t machine_dac_type;
|
extern const mp_obj_type_t machine_dac_type;
|
||||||
extern const mp_obj_type_t machine_sdcard_type;
|
extern const mp_obj_type_t machine_sdcard_type;
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ static inline mp_uint_t disable_irq(void) {
|
||||||
#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
|
#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
|
||||||
|
|
||||||
#if MICROPY_HW_ENABLE_USBDEV
|
#if MICROPY_HW_ENABLE_USBDEV
|
||||||
#define MICROPY_HW_USBDEV_TASK_HOOK extern void usbd_task(void); usbd_task();
|
#define MICROPY_HW_USBDEV_TASK_HOOK extern void mp_usbd_task(void); mp_usbd_task();
|
||||||
#define MICROPY_VM_HOOK_COUNT (10)
|
#define MICROPY_VM_HOOK_COUNT (10)
|
||||||
#define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT;
|
#define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT;
|
||||||
#define MICROPY_VM_HOOK_POLL if (--vm_hook_divisor == 0) { \
|
#define MICROPY_VM_HOOK_POLL if (--vm_hook_divisor == 0) { \
|
||||||
|
|
|
@ -406,6 +406,7 @@ target_compile_options(${MICROPY_TARGET} PRIVATE
|
||||||
|
|
||||||
target_link_options(${MICROPY_TARGET} PRIVATE
|
target_link_options(${MICROPY_TARGET} PRIVATE
|
||||||
-Wl,--defsym=__micropy_c_heap_size__=${MICROPY_C_HEAP_SIZE}
|
-Wl,--defsym=__micropy_c_heap_size__=${MICROPY_C_HEAP_SIZE}
|
||||||
|
-Wl,--wrap=dcd_event_handler
|
||||||
)
|
)
|
||||||
|
|
||||||
set_source_files_properties(
|
set_source_files_properties(
|
||||||
|
|
|
@ -69,21 +69,21 @@ STATIC mp_obj_t mp_machine_adc_make_new(const mp_obj_type_t *type, size_t n_args
|
||||||
|
|
||||||
mp_obj_t source = all_args[0];
|
mp_obj_t source = all_args[0];
|
||||||
|
|
||||||
uint32_t channel;
|
uint32_t channel = -1;
|
||||||
bool is_ext = false;
|
bool is_ext = false;
|
||||||
const machine_pin_obj_t *pin = NULL;
|
const machine_pin_obj_t *pin = NULL;
|
||||||
|
|
||||||
if (mp_obj_is_int(source)) {
|
if (mp_obj_is_int(source)) {
|
||||||
// Get and validate channel number.
|
// Get and validate channel number.
|
||||||
channel = mp_obj_get_int(source);
|
channel = mp_obj_get_int(source);
|
||||||
if (!((channel >= 0 && channel <= ADC_CHANNEL_TEMPSENSOR) || ADC_IS_VALID_GPIO(channel))) {
|
if (ADC_IS_VALID_GPIO(channel)) {
|
||||||
|
channel = ADC_CHANNEL_FROM_GPIO(channel);
|
||||||
|
} else if (!(channel >= 0 && channel <= ADC_CHANNEL_TEMPSENSOR)) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("invalid channel"));
|
mp_raise_ValueError(MP_ERROR_TEXT("invalid channel"));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Get GPIO and check it has ADC capabilities.
|
// Get GPIO and check it has ADC capabilities.
|
||||||
pin = machine_pin_find(source);
|
pin = machine_pin_find(source);
|
||||||
channel = pin->id;
|
|
||||||
bool valid_adc_pin = false;
|
bool valid_adc_pin = false;
|
||||||
#if MICROPY_HW_ADC_EXT_COUNT
|
#if MICROPY_HW_ADC_EXT_COUNT
|
||||||
is_ext = pin->is_ext;
|
is_ext = pin->is_ext;
|
||||||
|
@ -92,7 +92,7 @@ STATIC mp_obj_t mp_machine_adc_make_new(const mp_obj_type_t *type, size_t n_args
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
valid_adc_pin = ADC_IS_VALID_GPIO(channel);
|
valid_adc_pin = ADC_IS_VALID_GPIO(pin->id);
|
||||||
}
|
}
|
||||||
if (!valid_adc_pin) {
|
if (!valid_adc_pin) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("Pin doesn't have ADC capabilities"));
|
mp_raise_ValueError(MP_ERROR_TEXT("Pin doesn't have ADC capabilities"));
|
||||||
|
@ -104,16 +104,18 @@ STATIC mp_obj_t mp_machine_adc_make_new(const mp_obj_type_t *type, size_t n_args
|
||||||
adc_init();
|
adc_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pin) {
|
||||||
if (is_ext) {
|
if (is_ext) {
|
||||||
#if MICROPY_HW_ADC_EXT_COUNT
|
#if MICROPY_HW_ADC_EXT_COUNT
|
||||||
// Note external pins are mutable.
|
// Note external pins are mutable.
|
||||||
machine_pin_ext_config((machine_pin_obj_t *)pin, MACHINE_PIN_MODE_ANALOG, 0);
|
machine_pin_ext_config((machine_pin_obj_t *)pin, MACHINE_PIN_MODE_ANALOG, 0);
|
||||||
channel = machine_pin_ext_to_adc_channel(pin);
|
channel = machine_pin_ext_to_adc_channel(pin);
|
||||||
#endif
|
#endif
|
||||||
} else if (ADC_IS_VALID_GPIO(channel)) {
|
} else {
|
||||||
// Configure the GPIO pin in ADC mode.
|
// Configure the GPIO pin in ADC mode.
|
||||||
adc_gpio_init(channel);
|
adc_gpio_init(pin->id);
|
||||||
channel = ADC_CHANNEL_FROM_GPIO(channel);
|
channel = ADC_CHANNEL_FROM_GPIO(pin->id);
|
||||||
|
}
|
||||||
} else if (channel == ADC_CHANNEL_TEMPSENSOR) {
|
} else if (channel == ADC_CHANNEL_TEMPSENSOR) {
|
||||||
// Enable temperature sensor.
|
// Enable temperature sensor.
|
||||||
adc_set_temp_sensor_enabled(1);
|
adc_set_temp_sensor_enabled(1);
|
||||||
|
|
|
@ -140,8 +140,27 @@ static inline void read_mutex_unlock(machine_uart_obj_t *u) {
|
||||||
STATIC void uart_drain_rx_fifo(machine_uart_obj_t *self) {
|
STATIC void uart_drain_rx_fifo(machine_uart_obj_t *self) {
|
||||||
if (read_mutex_try_lock(self)) {
|
if (read_mutex_try_lock(self)) {
|
||||||
while (uart_is_readable(self->uart) && ringbuf_free(&self->read_buffer) > 0) {
|
while (uart_is_readable(self->uart) && ringbuf_free(&self->read_buffer) > 0) {
|
||||||
// get a byte from uart and put into the buffer
|
// Get a byte from uart and put into the buffer. Every entry from
|
||||||
ringbuf_put(&(self->read_buffer), uart_get_hw(self->uart)->dr);
|
// the FIFO is accompanied by 4 error bits, that may be used for
|
||||||
|
// error handling.
|
||||||
|
uint16_t c = uart_get_hw(self->uart)->dr;
|
||||||
|
if (c & UART_UARTDR_OE_BITS) {
|
||||||
|
// Overrun Error: We missed at least one byte. Not much we can do here.
|
||||||
|
}
|
||||||
|
if (c & UART_UARTDR_BE_BITS) {
|
||||||
|
// Break Error: RX was held low for longer than one character
|
||||||
|
// (11 bits). We did *not* read the zero byte that we seemed to
|
||||||
|
// read from dr.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c & UART_UARTDR_PE_BITS) {
|
||||||
|
// Parity Error: The byte we read is invalid.
|
||||||
|
}
|
||||||
|
if (c & UART_UARTDR_FE_BITS) {
|
||||||
|
// Framing Error: We did not receive a valid stop bit.
|
||||||
|
}
|
||||||
|
|
||||||
|
ringbuf_put(&(self->read_buffer), c);
|
||||||
}
|
}
|
||||||
read_mutex_unlock(self);
|
read_mutex_unlock(self);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, 1, machine_freq);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, 1, machine_freq);
|
||||||
|
|
||||||
STATIC mp_obj_t machine_idle(void) {
|
STATIC mp_obj_t machine_idle(void) {
|
||||||
best_effort_wfe_or_timeout(make_timeout_time_ms(1));
|
__wfe();
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_idle_obj, machine_idle);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_idle_obj, machine_idle);
|
||||||
|
|
|
@ -250,23 +250,8 @@ extern void mp_thread_end_atomic_section(uint32_t);
|
||||||
#define MICROPY_PY_LWIP_REENTER lwip_lock_acquire();
|
#define MICROPY_PY_LWIP_REENTER lwip_lock_acquire();
|
||||||
#define MICROPY_PY_LWIP_EXIT lwip_lock_release();
|
#define MICROPY_PY_LWIP_EXIT lwip_lock_release();
|
||||||
|
|
||||||
#if MICROPY_HW_ENABLE_USBDEV
|
|
||||||
#define MICROPY_HW_USBDEV_TASK_HOOK extern void usbd_task(void); usbd_task();
|
|
||||||
#define MICROPY_VM_HOOK_COUNT (10)
|
|
||||||
#define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT;
|
|
||||||
#define MICROPY_VM_HOOK_POLL if (get_core_num() == 0 && --vm_hook_divisor == 0) { \
|
|
||||||
vm_hook_divisor = MICROPY_VM_HOOK_COUNT; \
|
|
||||||
MICROPY_HW_USBDEV_TASK_HOOK \
|
|
||||||
}
|
|
||||||
#define MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_POLL
|
|
||||||
#define MICROPY_VM_HOOK_RETURN MICROPY_VM_HOOK_POLL
|
|
||||||
#else
|
|
||||||
#define MICROPY_HW_USBDEV_TASK_HOOK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MICROPY_EVENT_POLL_HOOK_FAST \
|
#define MICROPY_EVENT_POLL_HOOK_FAST \
|
||||||
do { \
|
do { \
|
||||||
if (get_core_num() == 0) { MICROPY_HW_USBDEV_TASK_HOOK } \
|
|
||||||
extern void mp_handle_pending(bool); \
|
extern void mp_handle_pending(bool); \
|
||||||
mp_handle_pending(true); \
|
mp_handle_pending(true); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -274,7 +259,7 @@ extern void mp_thread_end_atomic_section(uint32_t);
|
||||||
#define MICROPY_EVENT_POLL_HOOK \
|
#define MICROPY_EVENT_POLL_HOOK \
|
||||||
do { \
|
do { \
|
||||||
MICROPY_EVENT_POLL_HOOK_FAST; \
|
MICROPY_EVENT_POLL_HOOK_FAST; \
|
||||||
best_effort_wfe_or_timeout(make_timeout_time_ms(1)); \
|
__wfe(); \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1))
|
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1))
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "extmod/misc.h"
|
#include "extmod/misc.h"
|
||||||
#include "shared/runtime/interrupt_char.h"
|
#include "shared/runtime/interrupt_char.h"
|
||||||
#include "shared/timeutils/timeutils.h"
|
#include "shared/timeutils/timeutils.h"
|
||||||
|
#include "shared/tinyusb/mp_usbd.h"
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "hardware/rtc.h"
|
#include "hardware/rtc.h"
|
||||||
|
@ -54,6 +55,19 @@ ringbuf_t stdin_ringbuf = { stdin_ringbuf_array, sizeof(stdin_ringbuf_array) };
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_HW_USB_CDC
|
||||||
|
// Explicitly run the USB stack in case the scheduler is locked (eg we are in an
|
||||||
|
// interrupt handler) and there is in/out data pending on the USB CDC interface.
|
||||||
|
#define MICROPY_EVENT_POLL_HOOK_WITH_USB \
|
||||||
|
do { \
|
||||||
|
MICROPY_EVENT_POLL_HOOK; \
|
||||||
|
mp_usbd_task(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define MICROPY_EVENT_POLL_HOOK_WITH_USB MICROPY_EVENT_POLL_HOOK
|
||||||
|
#endif
|
||||||
|
|
||||||
#if MICROPY_HW_USB_CDC
|
#if MICROPY_HW_USB_CDC
|
||||||
|
|
||||||
uint8_t cdc_itf_pending; // keep track of cdc interfaces which need attention to poll
|
uint8_t cdc_itf_pending; // keep track of cdc interfaces which need attention to poll
|
||||||
|
@ -135,7 +149,7 @@ int mp_hal_stdin_rx_chr(void) {
|
||||||
return dupterm_c;
|
return dupterm_c;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
MICROPY_EVENT_POLL_HOOK
|
MICROPY_EVENT_POLL_HOOK_WITH_USB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +169,7 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
|
||||||
int timeout = 0;
|
int timeout = 0;
|
||||||
// Wait with a max of USC_CDC_TIMEOUT ms
|
// Wait with a max of USC_CDC_TIMEOUT ms
|
||||||
while (n > tud_cdc_write_available() && timeout++ < MICROPY_HW_USB_CDC_TX_TIMEOUT) {
|
while (n > tud_cdc_write_available() && timeout++ < MICROPY_HW_USB_CDC_TX_TIMEOUT) {
|
||||||
MICROPY_EVENT_POLL_HOOK
|
MICROPY_EVENT_POLL_HOOK_WITH_USB;
|
||||||
}
|
}
|
||||||
if (timeout >= MICROPY_HW_USB_CDC_TX_TIMEOUT) {
|
if (timeout >= MICROPY_HW_USB_CDC_TX_TIMEOUT) {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -93,6 +93,8 @@ LIBSTDCPP_FILE_NAME = "$(shell $(CXX) $(CXXFLAGS) -print-file-name=libstdc++.a)"
|
||||||
LDFLAGS += -L"$(shell dirname $(LIBSTDCPP_FILE_NAME))"
|
LDFLAGS += -L"$(shell dirname $(LIBSTDCPP_FILE_NAME))"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
LDFLAGS += --wrap=dcd_event_handler
|
||||||
|
|
||||||
MPY_CROSS_FLAGS += -march=$(MPY_CROSS_MCU_ARCH)
|
MPY_CROSS_FLAGS += -march=$(MPY_CROSS_MCU_ARCH)
|
||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
|
@ -131,6 +133,7 @@ SHARED_SRC_C += \
|
||||||
shared/runtime/sys_stdio_mphal.c \
|
shared/runtime/sys_stdio_mphal.c \
|
||||||
shared/timeutils/timeutils.c \
|
shared/timeutils/timeutils.c \
|
||||||
shared/tinyusb/mp_cdc_common.c \
|
shared/tinyusb/mp_cdc_common.c \
|
||||||
|
shared/tinyusb/mp_usbd.c
|
||||||
|
|
||||||
ASF4_SRC_C += $(addprefix lib/asf4/$(MCU_SERIES_LOWER)/,\
|
ASF4_SRC_C += $(addprefix lib/asf4/$(MCU_SERIES_LOWER)/,\
|
||||||
hal/src/hal_atomic.c \
|
hal/src/hal_atomic.c \
|
||||||
|
|
|
@ -49,6 +49,7 @@ typedef struct _machine_uart_obj_t {
|
||||||
uint8_t bits;
|
uint8_t bits;
|
||||||
uint8_t parity;
|
uint8_t parity;
|
||||||
uint8_t stop;
|
uint8_t stop;
|
||||||
|
uint8_t flow_control;
|
||||||
uint8_t tx;
|
uint8_t tx;
|
||||||
uint8_t rx;
|
uint8_t rx;
|
||||||
sercom_pad_config_t tx_pad_config;
|
sercom_pad_config_t tx_pad_config;
|
||||||
|
@ -112,6 +113,85 @@ void common_uart_irq_handler(int uart_id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Configure the Sercom device
|
||||||
|
STATIC void machine_sercom_configure(machine_uart_obj_t *self) {
|
||||||
|
Sercom *uart = sercom_instance[self->id];
|
||||||
|
|
||||||
|
// Reset (clear) the peripheral registers.
|
||||||
|
while (uart->USART.SYNCBUSY.bit.SWRST) {
|
||||||
|
}
|
||||||
|
uart->USART.CTRLA.bit.SWRST = 1; // Reset all Registers, disable peripheral
|
||||||
|
while (uart->USART.SYNCBUSY.bit.SWRST) {
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t txpo = self->tx_pad_config.pad_nr;
|
||||||
|
#if defined(MCU_SAMD21)
|
||||||
|
if (self->tx_pad_config.pad_nr == 2) { // Map pad 2 to TXPO = 1
|
||||||
|
txpo = 1;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
if (self->tx_pad_config.pad_nr != 0) {
|
||||||
|
mp_raise_ValueError(MP_ERROR_TEXT("invalid UART pin"));
|
||||||
|
}
|
||||||
|
#if MICROPY_HW_UART_RTSCTS
|
||||||
|
if ((self->flow_control & FLOW_CONTROL_RTS) && self->rts_pad_config.pad_nr == 2) {
|
||||||
|
txpo = 2;
|
||||||
|
mp_hal_set_pin_mux(self->rts, self->rts_pad_config.alt_fct);
|
||||||
|
}
|
||||||
|
if ((self->flow_control & FLOW_CONTROL_CTS) && self->cts_pad_config.pad_nr == 3) {
|
||||||
|
txpo = 2;
|
||||||
|
mp_hal_set_pin_mux(self->cts, self->cts_pad_config.alt_fct);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uart->USART.CTRLA.reg =
|
||||||
|
SERCOM_USART_CTRLA_DORD // Data order
|
||||||
|
| SERCOM_USART_CTRLA_FORM(self->parity != 0 ? 1 : 0) // Enable parity or not
|
||||||
|
| SERCOM_USART_CTRLA_RXPO(self->rx_pad_config.pad_nr) // Set Pad#
|
||||||
|
| SERCOM_USART_CTRLA_TXPO(txpo) // Set Pad#
|
||||||
|
| SERCOM_USART_CTRLA_MODE(1) // USART with internal clock
|
||||||
|
;
|
||||||
|
uart->USART.CTRLB.reg =
|
||||||
|
SERCOM_USART_CTRLB_RXEN // Enable Rx & Tx
|
||||||
|
| SERCOM_USART_CTRLB_TXEN
|
||||||
|
| ((self->parity & 1) << SERCOM_USART_CTRLB_PMODE_Pos)
|
||||||
|
| (self->stop << SERCOM_USART_CTRLB_SBMODE_Pos)
|
||||||
|
| SERCOM_USART_CTRLB_CHSIZE((self->bits & 7) | (self->bits & 1))
|
||||||
|
;
|
||||||
|
while (uart->USART.SYNCBUSY.bit.CTRLB) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// USART is driven by the clock of GCLK Generator 2, freq by get_peripheral_freq()
|
||||||
|
// baud rate; 65536 * (1 - 16 * 115200/bus_freq)
|
||||||
|
uint32_t baud = 65536 - ((uint64_t)(65536 * 16) * self->baudrate + get_peripheral_freq() / 2) / get_peripheral_freq();
|
||||||
|
uart->USART.BAUD.bit.BAUD = baud; // Set Baud
|
||||||
|
|
||||||
|
sercom_register_irq(self->id, &common_uart_irq_handler);
|
||||||
|
|
||||||
|
// Enable RXC interrupt
|
||||||
|
uart->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC;
|
||||||
|
#if defined(MCU_SAMD21)
|
||||||
|
NVIC_EnableIRQ(SERCOM0_IRQn + self->id);
|
||||||
|
#elif defined(MCU_SAMD51)
|
||||||
|
NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 2);
|
||||||
|
#endif
|
||||||
|
#if MICROPY_HW_UART_TXBUF
|
||||||
|
// Enable DRE interrupt
|
||||||
|
// SAMD21 has just 1 IRQ for all USART events, so no need for an additional NVIC enable
|
||||||
|
#if defined(MCU_SAMD51)
|
||||||
|
NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sercom_enable(uart, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void machine_uart_set_baudrate(mp_obj_t self_in, uint32_t baudrate) {
|
||||||
|
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
self->baudrate = baudrate;
|
||||||
|
machine_sercom_configure(self);
|
||||||
|
}
|
||||||
|
|
||||||
STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||||
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=%s, stop=%u, "
|
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=%s, stop=%u, "
|
||||||
|
@ -194,22 +274,22 @@ STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
|
||||||
if (args[ARG_rx].u_obj != mp_const_none) {
|
if (args[ARG_rx].u_obj != mp_const_none) {
|
||||||
self->rx = mp_hal_get_pin_obj(args[ARG_rx].u_obj);
|
self->rx = mp_hal_get_pin_obj(args[ARG_rx].u_obj);
|
||||||
}
|
}
|
||||||
|
self->flow_control = 0;
|
||||||
#if MICROPY_HW_UART_RTSCTS
|
#if MICROPY_HW_UART_RTSCTS
|
||||||
uint8_t flow_control = 0;
|
|
||||||
// Set RTS/CTS pins if configured.
|
// Set RTS/CTS pins if configured.
|
||||||
if (args[ARG_rts].u_obj != mp_const_none) {
|
if (args[ARG_rts].u_obj != mp_const_none) {
|
||||||
self->rts = mp_hal_get_pin_obj(args[ARG_rts].u_obj);
|
self->rts = mp_hal_get_pin_obj(args[ARG_rts].u_obj);
|
||||||
self->rts_pad_config = get_sercom_config(self->rts, self->id);
|
self->rts_pad_config = get_sercom_config(self->rts, self->id);
|
||||||
flow_control = FLOW_CONTROL_RTS;
|
self->flow_control = FLOW_CONTROL_RTS;
|
||||||
}
|
}
|
||||||
if (args[ARG_cts].u_obj != mp_const_none) {
|
if (args[ARG_cts].u_obj != mp_const_none) {
|
||||||
self->cts = mp_hal_get_pin_obj(args[ARG_cts].u_obj);
|
self->cts = mp_hal_get_pin_obj(args[ARG_cts].u_obj);
|
||||||
self->cts_pad_config = get_sercom_config(self->cts, self->id);
|
self->cts_pad_config = get_sercom_config(self->cts, self->id);
|
||||||
flow_control |= FLOW_CONTROL_CTS;
|
self->flow_control |= FLOW_CONTROL_CTS;
|
||||||
}
|
}
|
||||||
// rts only flow control is not allowed. Otherwise the state of the
|
// rts only flow control is not allowed. Otherwise the state of the
|
||||||
// cts pin is undefined.
|
// cts pin is undefined.
|
||||||
if (flow_control == FLOW_CONTROL_RTS) {
|
if (self->flow_control == FLOW_CONTROL_RTS) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("cts missing for flow control"));
|
mp_raise_ValueError(MP_ERROR_TEXT("cts missing for flow control"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -278,75 +358,8 @@ STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
|
||||||
// Next: Set up the clocks
|
// Next: Set up the clocks
|
||||||
enable_sercom_clock(self->id);
|
enable_sercom_clock(self->id);
|
||||||
|
|
||||||
// Next: Configure the USART
|
// Configure the sercom module
|
||||||
Sercom *uart = sercom_instance[self->id];
|
machine_sercom_configure(self);
|
||||||
// Reset (clear) the peripheral registers.
|
|
||||||
while (uart->USART.SYNCBUSY.bit.SWRST) {
|
|
||||||
}
|
|
||||||
uart->USART.CTRLA.bit.SWRST = 1; // Reset all Registers, disable peripheral
|
|
||||||
while (uart->USART.SYNCBUSY.bit.SWRST) {
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t txpo = self->tx_pad_config.pad_nr;
|
|
||||||
#if defined(MCU_SAMD21)
|
|
||||||
if (self->tx_pad_config.pad_nr == 2) { // Map pad 2 to TXPO = 1
|
|
||||||
txpo = 1;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
if (self->tx_pad_config.pad_nr != 0) {
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("invalid UART pin"));
|
|
||||||
}
|
|
||||||
#if MICROPY_HW_UART_RTSCTS
|
|
||||||
if ((flow_control & FLOW_CONTROL_RTS) && self->rts_pad_config.pad_nr == 2) {
|
|
||||||
txpo = 2;
|
|
||||||
mp_hal_set_pin_mux(self->rts, self->rts_pad_config.alt_fct);
|
|
||||||
}
|
|
||||||
if ((flow_control & FLOW_CONTROL_CTS) && self->cts_pad_config.pad_nr == 3) {
|
|
||||||
txpo = 2;
|
|
||||||
mp_hal_set_pin_mux(self->cts, self->cts_pad_config.alt_fct);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uart->USART.CTRLA.reg =
|
|
||||||
SERCOM_USART_CTRLA_DORD // Data order
|
|
||||||
| SERCOM_USART_CTRLA_FORM(self->parity != 0 ? 1 : 0) // Enable parity or not
|
|
||||||
| SERCOM_USART_CTRLA_RXPO(self->rx_pad_config.pad_nr) // Set Pad#
|
|
||||||
| SERCOM_USART_CTRLA_TXPO(txpo) // Set Pad#
|
|
||||||
| SERCOM_USART_CTRLA_MODE(1) // USART with internal clock
|
|
||||||
;
|
|
||||||
uart->USART.CTRLB.reg =
|
|
||||||
SERCOM_USART_CTRLB_RXEN // Enable Rx & Tx
|
|
||||||
| SERCOM_USART_CTRLB_TXEN
|
|
||||||
| ((self->parity & 1) << SERCOM_USART_CTRLB_PMODE_Pos)
|
|
||||||
| (self->stop << SERCOM_USART_CTRLB_SBMODE_Pos)
|
|
||||||
| SERCOM_USART_CTRLB_CHSIZE((self->bits & 7) | (self->bits & 1))
|
|
||||||
;
|
|
||||||
while (uart->USART.SYNCBUSY.bit.CTRLB) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// USART is driven by the clock of GCLK Generator 2, freq by get_peripheral_freq()
|
|
||||||
// baud rate; 65536 * (1 - 16 * 115200/bus_freq)
|
|
||||||
uint32_t baud = 65536 - ((uint64_t)(65536 * 16) * self->baudrate + get_peripheral_freq() / 2) / get_peripheral_freq();
|
|
||||||
uart->USART.BAUD.bit.BAUD = baud; // Set Baud
|
|
||||||
|
|
||||||
sercom_register_irq(self->id, &common_uart_irq_handler);
|
|
||||||
|
|
||||||
// Enable RXC interrupt
|
|
||||||
uart->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC;
|
|
||||||
#if defined(MCU_SAMD21)
|
|
||||||
NVIC_EnableIRQ(SERCOM0_IRQn + self->id);
|
|
||||||
#elif defined(MCU_SAMD51)
|
|
||||||
NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 2);
|
|
||||||
#endif
|
|
||||||
#if MICROPY_HW_UART_TXBUF
|
|
||||||
// Enable DRE interrupt
|
|
||||||
// SAMD21 has just 1 IRQ for all USART events, so no need for an additional NVIC enable
|
|
||||||
#if defined(MCU_SAMD51)
|
|
||||||
NVIC_EnableIRQ(SERCOM0_0_IRQn + 4 * self->id + 0);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sercom_enable(uart, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#define MICROPY_PY_BUILTINS_HELP (1)
|
#define MICROPY_PY_BUILTINS_HELP (1)
|
||||||
#define MICROPY_PY_BUILTINS_HELP_TEXT samd_help_text
|
#define MICROPY_PY_BUILTINS_HELP_TEXT samd_help_text
|
||||||
#define MICROPY_PY_BUILTINS_HELP_MODULES (1)
|
#define MICROPY_PY_BUILTINS_HELP_MODULES (1)
|
||||||
|
#define MICROPY_USE_INTERNAL_ERRNO (1)
|
||||||
#define MICROPY_ENABLE_SCHEDULER (1)
|
#define MICROPY_ENABLE_SCHEDULER (1)
|
||||||
#define MICROPY_SCHEDULER_STATIC_NODES (1)
|
#define MICROPY_SCHEDULER_STATIC_NODES (1)
|
||||||
#define MICROPY_HW_ENABLE_USBDEV (1)
|
#define MICROPY_HW_ENABLE_USBDEV (1)
|
||||||
|
|
|
@ -112,7 +112,7 @@ adc_config_t get_adc_config(int pin_id, int32_t flag) {
|
||||||
const machine_pin_obj_t *pct_ptr = pin_find_by_id(pin_id);
|
const machine_pin_obj_t *pct_ptr = pin_find_by_id(pin_id);
|
||||||
if (pct_ptr->adc0 != 0xff && (flag & (1 << pct_ptr->adc0)) == 0) {
|
if (pct_ptr->adc0 != 0xff && (flag & (1 << pct_ptr->adc0)) == 0) {
|
||||||
return (adc_config_t) {0, pct_ptr->adc0};
|
return (adc_config_t) {0, pct_ptr->adc0};
|
||||||
#if defined(MUC_SAMD51)
|
#if defined(MCU_SAMD51)
|
||||||
} else if (pct_ptr->adc1 != 0xff && (flag & (1 << (pct_ptr->adc1 + 16))) == 0) {
|
} else if (pct_ptr->adc1 != 0xff && (flag & (1 << (pct_ptr->adc1 + 16))) == 0) {
|
||||||
return (adc_config_t) {1, pct_ptr->adc1};
|
return (adc_config_t) {1, pct_ptr->adc1};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -310,10 +310,10 @@ const ISR isr_vector[] __attribute__((section(".isr_vector"))) = {
|
||||||
&Sercom7_Handler, // 77 Serial Communication Interface 7 (SERCOM7): SERCOM7_3 - 6
|
&Sercom7_Handler, // 77 Serial Communication Interface 7 (SERCOM7): SERCOM7_3 - 6
|
||||||
0, // 78 Control Area Network 0 (CAN0)
|
0, // 78 Control Area Network 0 (CAN0)
|
||||||
0, // 79 Control Area Network 1 (CAN1)
|
0, // 79 Control Area Network 1 (CAN1)
|
||||||
&USB_0_Handler_wrapper, // 80 Universal Serial Bus (USB): USB_EORSM_DNRS, ...
|
&USB_Handler_wrapper, // 80 Universal Serial Bus (USB): USB_EORSM_DNRS, ...
|
||||||
&USB_1_Handler_wrapper, // 81 Universal Serial Bus (USB): USB_SOF_HSOF
|
&USB_Handler_wrapper, // 81 Universal Serial Bus (USB): USB_SOF_HSOF
|
||||||
&USB_2_Handler_wrapper, // 82 Universal Serial Bus (USB): USB_TRCPT0_0 - _7
|
&USB_Handler_wrapper, // 82 Universal Serial Bus (USB): USB_TRCPT0_0 - _7
|
||||||
&USB_3_Handler_wrapper, // 83 Universal Serial Bus (USB): USB_TRCPT1_0 - _7
|
&USB_Handler_wrapper, // 83 Universal Serial Bus (USB): USB_TRCPT1_0 - _7
|
||||||
0, // 84 Ethernet MAC (GMAC)
|
0, // 84 Ethernet MAC (GMAC)
|
||||||
0, // 85 Timer Counter Control 0 (TCC0): TCC0_CNT_A ...
|
0, // 85 Timer Counter Control 0 (TCC0): TCC0_CNT_A ...
|
||||||
0, // 86 Timer Counter Control 0 (TCC0): TCC0_MC_0
|
0, // 86 Timer Counter Control 0 (TCC0): TCC0_MC_0
|
||||||
|
|
|
@ -36,10 +36,6 @@ void samd_init(void);
|
||||||
void samd_main(void);
|
void samd_main(void);
|
||||||
|
|
||||||
void USB_Handler_wrapper(void);
|
void USB_Handler_wrapper(void);
|
||||||
void USB_0_Handler_wrapper(void);
|
|
||||||
void USB_1_Handler_wrapper(void);
|
|
||||||
void USB_2_Handler_wrapper(void);
|
|
||||||
void USB_3_Handler_wrapper(void);
|
|
||||||
|
|
||||||
void sercom_enable(Sercom *spi, int state);
|
void sercom_enable(Sercom *spi, int state);
|
||||||
void sercom_register_irq(int sercom_id, void (*sercom_irq_handler));
|
void sercom_register_irq(int sercom_id, void (*sercom_irq_handler));
|
||||||
|
|
|
@ -117,33 +117,6 @@ const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||||
return desc_str;
|
return desc_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MCU_SAMD21)
|
|
||||||
|
|
||||||
void USB_Handler_wrapper(void) {
|
void USB_Handler_wrapper(void) {
|
||||||
tud_int_handler(0);
|
tud_int_handler(0);
|
||||||
tud_task();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(MCU_SAMD51)
|
|
||||||
|
|
||||||
void USB_0_Handler_wrapper(void) {
|
|
||||||
tud_int_handler(0);
|
|
||||||
tud_task();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USB_1_Handler_wrapper(void) {
|
|
||||||
tud_int_handler(0);
|
|
||||||
tud_task();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USB_2_Handler_wrapper(void) {
|
|
||||||
tud_int_handler(0);
|
|
||||||
tud_task();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USB_3_Handler_wrapper(void) {
|
|
||||||
tud_int_handler(0);
|
|
||||||
tud_task();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -104,6 +104,12 @@ void GIGA_board_low_power(int mode);
|
||||||
// SMPS configuration
|
// SMPS configuration
|
||||||
#define MICROPY_HW_PWR_SMPS_CONFIG (PWR_LDO_SUPPLY)
|
#define MICROPY_HW_PWR_SMPS_CONFIG (PWR_LDO_SUPPLY)
|
||||||
|
|
||||||
|
// Configure the analog switches for dual-pad pins.
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PA0 (SYSCFG_SWITCH_PA0_OPEN)
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PA1 (SYSCFG_SWITCH_PA1_OPEN)
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PC2 (SYSCFG_SWITCH_PC2_OPEN)
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PC3 (SYSCFG_SWITCH_PC3_OPEN)
|
||||||
|
|
||||||
// There is an external 32kHz oscillator
|
// There is an external 32kHz oscillator
|
||||||
#define RTC_ASYNCH_PREDIV (0)
|
#define RTC_ASYNCH_PREDIV (0)
|
||||||
#define RTC_SYNCH_PREDIV (0x7fff)
|
#define RTC_SYNCH_PREDIV (0x7fff)
|
||||||
|
|
|
@ -65,11 +65,6 @@ void NICLAV_board_early_init(void) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Make sure PC2 and PC3 and PC2_C and PC3_C pads are connected
|
|
||||||
// through the analog switch for ULPI NXT and DIR pins.
|
|
||||||
HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC2, SYSCFG_SWITCH_PC2_CLOSE);
|
|
||||||
HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC3, SYSCFG_SWITCH_PC3_CLOSE);
|
|
||||||
|
|
||||||
#if MICROPY_HW_USB_HS_ULPI3320
|
#if MICROPY_HW_USB_HS_ULPI3320
|
||||||
// Make sure UPLI is Not in low-power mode.
|
// Make sure UPLI is Not in low-power mode.
|
||||||
ulpi_leave_low_power();
|
ulpi_leave_low_power();
|
||||||
|
|
|
@ -107,6 +107,13 @@ void NICLAV_board_osc_enable(int enable);
|
||||||
// SMPS configuration
|
// SMPS configuration
|
||||||
#define MICROPY_HW_PWR_SMPS_CONFIG (PWR_LDO_SUPPLY)
|
#define MICROPY_HW_PWR_SMPS_CONFIG (PWR_LDO_SUPPLY)
|
||||||
|
|
||||||
|
// Configure the analog switches for dual-pad pins.
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PA0 (SYSCFG_SWITCH_PA0_OPEN)
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PA1 (SYSCFG_SWITCH_PA1_OPEN)
|
||||||
|
// PC2_C and PC3_C, which are connected to ULPI NXT and DIR pins.
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PC2 (SYSCFG_SWITCH_PC2_CLOSE)
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PC3 (SYSCFG_SWITCH_PC3_CLOSE)
|
||||||
|
|
||||||
// There is an external 32kHz oscillator
|
// There is an external 32kHz oscillator
|
||||||
#define RTC_ASYNCH_PREDIV (0)
|
#define RTC_ASYNCH_PREDIV (0)
|
||||||
#define RTC_SYNCH_PREDIV (0x7fff)
|
#define RTC_SYNCH_PREDIV (0x7fff)
|
||||||
|
|
|
@ -109,6 +109,12 @@ void PORTENTA_board_osc_enable(int enable);
|
||||||
// SMPS configuration
|
// SMPS configuration
|
||||||
#define MICROPY_HW_PWR_SMPS_CONFIG (PWR_SMPS_1V8_SUPPLIES_LDO)
|
#define MICROPY_HW_PWR_SMPS_CONFIG (PWR_SMPS_1V8_SUPPLIES_LDO)
|
||||||
|
|
||||||
|
// Configure the analog switches for dual-pad pins.
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PA0 (SYSCFG_SWITCH_PA0_OPEN)
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PA1 (SYSCFG_SWITCH_PA1_OPEN)
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PC2 (SYSCFG_SWITCH_PC2_OPEN)
|
||||||
|
#define MICROPY_HW_ANALOG_SWITCH_PC3 (SYSCFG_SWITCH_PC3_OPEN)
|
||||||
|
|
||||||
// There is an external 32kHz oscillator
|
// There is an external 32kHz oscillator
|
||||||
#define RTC_ASYNCH_PREDIV (0)
|
#define RTC_ASYNCH_PREDIV (0)
|
||||||
#define RTC_SYNCH_PREDIV (0x7fff)
|
#define RTC_SYNCH_PREDIV (0x7fff)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
# Don't include default frozen modules because MCU is tight on flash space.
|
||||||
|
|
||||||
|
# Only install the sync version of the LoRa driver because this board doesn't
|
||||||
|
# have asyncio by default.
|
||||||
|
require("lora-sync")
|
||||||
|
require("lora-stm32wl5")
|
|
@ -9,5 +9,5 @@ TEXT0_ADDR = 0x08000000
|
||||||
MICROPY_VFS_FAT = 0
|
MICROPY_VFS_FAT = 0
|
||||||
MICROPY_VFS_LFS2 = 1
|
MICROPY_VFS_LFS2 = 1
|
||||||
|
|
||||||
# Don't include default frozen modules because MCU is tight on flash space
|
# Board-specific manifest (doesn't include default modules, adds LoRa driver).
|
||||||
FROZEN_MANIFEST ?=
|
FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py
|
||||||
|
|
|
@ -49,6 +49,11 @@ PinAf = namedtuple(
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Only support ADC1, ADC2, ADC3 for now (e.g. cannot support ADC4 & ADC5 on
|
||||||
|
# STM32G4).
|
||||||
|
MIN_ADC_UNIT = 1
|
||||||
|
MAX_ADC_UNIT = 3
|
||||||
|
|
||||||
|
|
||||||
class Stm32Pin(boardgen.Pin):
|
class Stm32Pin(boardgen.Pin):
|
||||||
def __init__(self, cpu_pin_name):
|
def __init__(self, cpu_pin_name):
|
||||||
|
@ -134,8 +139,12 @@ class Stm32Pin(boardgen.Pin):
|
||||||
raise boardgen.PinGeneratorError(
|
raise boardgen.PinGeneratorError(
|
||||||
"Invalid adc '{:s}' for pin '{:s}'".format(adc_name, self.name())
|
"Invalid adc '{:s}' for pin '{:s}'".format(adc_name, self.name())
|
||||||
)
|
)
|
||||||
adc_units = [int(x) for x in m.group(1)]
|
adc_units = [int(x) for x in m.group(1) if MIN_ADC_UNIT <= int(x) <= MAX_ADC_UNIT]
|
||||||
_adc_mode = m.group(2)
|
adc_mode = m.group(2)
|
||||||
|
if adc_mode == "INN":
|
||||||
|
# On H7 we have INN/INP, all other parts use IN only. Only use
|
||||||
|
# IN or INP channels.
|
||||||
|
continue
|
||||||
adc_channel = int(m.group(3))
|
adc_channel = int(m.group(3))
|
||||||
|
|
||||||
# Pick the entry with the most ADC units, e.g. "ADC1_INP16/ADC12_INN1/ADC12_INP0" --> "ADC12_INN1".
|
# Pick the entry with the most ADC units, e.g. "ADC1_INP16/ADC12_INN1/ADC12_INP0" --> "ADC12_INN1".
|
||||||
|
@ -247,6 +256,8 @@ class Stm32PinGenerator(boardgen.PinGenerator):
|
||||||
)
|
)
|
||||||
# Don't include pins that weren't in pins.csv.
|
# Don't include pins that weren't in pins.csv.
|
||||||
for pin in self.available_pins():
|
for pin in self.available_pins():
|
||||||
|
if pin._hidden:
|
||||||
|
continue
|
||||||
if adc_unit in pin._adc_units:
|
if adc_unit in pin._adc_units:
|
||||||
print(
|
print(
|
||||||
" [{:d}] = {:s},".format(pin._adc_channel, self._cpu_pin_pointer(pin)),
|
" [{:d}] = {:s},".format(pin._adc_channel, self._cpu_pin_pointer(pin)),
|
||||||
|
|
|
@ -6,7 +6,7 @@ PortA,PA2 , ,TIM2_CH3 ,TIM5_CH3,TIM9_CH1 , ,
|
||||||
PortA,PA3 , ,TIM2_CH4 ,TIM5_CH4,TIM9_CH2 , , , ,USART2_RX , , ,OTG_HS_ULPI_D0 ,ETH_MII_COL , , ,LCD_B5 ,EVENTOUT,ADC123_IN3
|
PortA,PA3 , ,TIM2_CH4 ,TIM5_CH4,TIM9_CH2 , , , ,USART2_RX , , ,OTG_HS_ULPI_D0 ,ETH_MII_COL , , ,LCD_B5 ,EVENTOUT,ADC123_IN3
|
||||||
PortA,PA4 , , , , , ,SPI1_NSS ,SPI3_NSS/I2S3_WS ,USART2_CK , , , , ,OTG_HS_SOF ,DCMI_HSYNC ,LCD_VSYNC,EVENTOUT,ADC12_IN4
|
PortA,PA4 , , , , , ,SPI1_NSS ,SPI3_NSS/I2S3_WS ,USART2_CK , , , , ,OTG_HS_SOF ,DCMI_HSYNC ,LCD_VSYNC,EVENTOUT,ADC12_IN4
|
||||||
PortA,PA5 , ,TIM2_CH1/TIM2_ETR, ,TIM8_CH1N , ,SPI1_SCK , , , , ,OTG_HS_ULPI_CK , , , , ,EVENTOUT,ADC12_IN5
|
PortA,PA5 , ,TIM2_CH1/TIM2_ETR, ,TIM8_CH1N , ,SPI1_SCK , , , , ,OTG_HS_ULPI_CK , , , , ,EVENTOUT,ADC12_IN5
|
||||||
PortA,PA6 , ,TIM1_BKIN ,TIM3_CH1,TIM8_BKIN , ,SPI1_MISO , , , ,TIM13_CH1 , , , ,DCMI_PIXCLK ,LCD_G2 ,EVENTOUT,ADC12_IN6
|
PortA,PA6 , ,TIM1_BKIN ,TIM3_CH1,TIM8_BKIN , ,SPI1_MISO , , , ,TIM13_CH1 , , , ,DCMI_PIXCLK,LCD_G2 ,EVENTOUT,ADC12_IN6
|
||||||
PortA,PA7 , ,TIM1_CH1N ,TIM3_CH2,TIM8_CH1N , ,SPI1_MOSI , , , ,TIM14_CH1 , ,ETH_MII_RX_DV/ETH_RMII_CRS_DV , , , ,EVENTOUT,ADC12_IN7
|
PortA,PA7 , ,TIM1_CH1N ,TIM3_CH2,TIM8_CH1N , ,SPI1_MOSI , , , ,TIM14_CH1 , ,ETH_MII_RX_DV/ETH_RMII_CRS_DV , , , ,EVENTOUT,ADC12_IN7
|
||||||
PortA,PA8 ,MCO1 ,TIM1_CH1 , , ,I2C3_SCL , , ,USART1_CK , , ,OTG_FS_SOF , , , ,LCD_R6 ,EVENTOUT,
|
PortA,PA8 ,MCO1 ,TIM1_CH1 , , ,I2C3_SCL , , ,USART1_CK , , ,OTG_FS_SOF , , , ,LCD_R6 ,EVENTOUT,
|
||||||
PortA,PA9 , ,TIM1_CH2 , , ,I2C3_SMBA, , ,USART1_TX , , , , , ,DCMI_D0 , ,EVENTOUT,
|
PortA,PA9 , ,TIM1_CH2 , , ,I2C3_SMBA, , ,USART1_TX , , , , , ,DCMI_D0 , ,EVENTOUT,
|
||||||
|
@ -105,7 +105,7 @@ PortG,PG5 , , , , , ,
|
||||||
PortG,PG6 , , , , , , , , , , , , ,FMC_INT2 ,DCMI_D12 ,LCD_R7 ,EVENTOUT,
|
PortG,PG6 , , , , , , , , , , , , ,FMC_INT2 ,DCMI_D12 ,LCD_R7 ,EVENTOUT,
|
||||||
PortG,PG7 , , , , , , , , ,USART6_CK , , , ,FMC_INT3 ,DCMI_D13 ,LCD_CLK ,EVENTOUT,
|
PortG,PG7 , , , , , , , , ,USART6_CK , , , ,FMC_INT3 ,DCMI_D13 ,LCD_CLK ,EVENTOUT,
|
||||||
PortG,PG8 , , , , , ,SPI6_NSS , , ,USART6_RTS , , ,ETH_PPS_OUT ,FMC_SDCLK , , ,EVENTOUT,
|
PortG,PG8 , , , , , ,SPI6_NSS , , ,USART6_RTS , , ,ETH_PPS_OUT ,FMC_SDCLK , , ,EVENTOUT,
|
||||||
PortG,PG9 , , , , , , , , ,USART6_RX , , , ,FMC_NE2/FMC_NCE3 ,DCMI_VSYNC(1), ,EVENTOUT,
|
PortG,PG9 , , , , , , , , ,USART6_RX , , , ,FMC_NE2/FMC_NCE3 ,DCMI_VSYNC , ,EVENTOUT,
|
||||||
PortG,PG10, , , , , , , , , ,LCD_G3 , , ,FMC_NCE4_1/FMC_NE3,DCMI_D2 ,LCD_B2 ,EVENTOUT,
|
PortG,PG10, , , , , , , , , ,LCD_G3 , , ,FMC_NCE4_1/FMC_NE3,DCMI_D2 ,LCD_B2 ,EVENTOUT,
|
||||||
PortG,PG11, , , , , , , , , , , ,ETH_MII_TX_EN/ETH_RMII_TX_EN ,FMC_NCE4_2 ,DCMI_D3 ,LCD_B3 ,EVENTOUT,
|
PortG,PG11, , , , , , , , , , , ,ETH_MII_TX_EN/ETH_RMII_TX_EN ,FMC_NCE4_2 ,DCMI_D3 ,LCD_B3 ,EVENTOUT,
|
||||||
PortG,PG12, , , , , ,SPI6_MISO , , ,USART6_RTS ,LCD_B4 , , ,FMC_NE4 , ,LCD_B1 ,EVENTOUT,
|
PortG,PG12, , , , , ,SPI6_MISO , , ,USART6_RTS ,LCD_B4 , , ,FMC_NE4 , ,LCD_B1 ,EVENTOUT,
|
||||||
|
|
|
|
@ -6,7 +6,7 @@ PortA,PA2 , ,TIM2_CH3 ,TIM5_CH3,TIM9_CH1 , ,
|
||||||
PortA,PA3 , ,TIM2_CH4 ,TIM5_CH4,TIM9_CH2 , , , ,USART2_RX , , ,OTG_HS_ULPI_D0 ,ETH_MII_COL , , ,LCD_B5 ,EVENTOUT,ADC123_IN3
|
PortA,PA3 , ,TIM2_CH4 ,TIM5_CH4,TIM9_CH2 , , , ,USART2_RX , , ,OTG_HS_ULPI_D0 ,ETH_MII_COL , , ,LCD_B5 ,EVENTOUT,ADC123_IN3
|
||||||
PortA,PA4 , , , , , ,SPI1_NSS ,SPI3_NSS/I2S3_WS ,USART2_CK , , , , ,OTG_HS_SOF ,DCMI_HSYNC ,LCD_VSYNC,EVENTOUT,ADC12_IN4
|
PortA,PA4 , , , , , ,SPI1_NSS ,SPI3_NSS/I2S3_WS ,USART2_CK , , , , ,OTG_HS_SOF ,DCMI_HSYNC ,LCD_VSYNC,EVENTOUT,ADC12_IN4
|
||||||
PortA,PA5 , ,TIM2_CH1/TIM2_ETR, ,TIM8_CH1N , ,SPI1_SCK , , , , ,OTG_HS_ULPI_CK , , , , ,EVENTOUT,ADC12_IN5
|
PortA,PA5 , ,TIM2_CH1/TIM2_ETR, ,TIM8_CH1N , ,SPI1_SCK , , , , ,OTG_HS_ULPI_CK , , , , ,EVENTOUT,ADC12_IN5
|
||||||
PortA,PA6 , ,TIM1_BKIN ,TIM3_CH1,TIM8_BKIN , ,SPI1_MISO , , , ,TIM13_CH1 , , , ,DCMI_PIXCLK ,LCD_G2 ,EVENTOUT,ADC12_IN6
|
PortA,PA6 , ,TIM1_BKIN ,TIM3_CH1,TIM8_BKIN , ,SPI1_MISO , , , ,TIM13_CH1 , , , ,DCMI_PIXCLK,LCD_G2 ,EVENTOUT,ADC12_IN6
|
||||||
PortA,PA7 , ,TIM1_CH1N ,TIM3_CH2,TIM8_CH1N , ,SPI1_MOSI , , , ,TIM14_CH1 , ,ETH_MII_RX_DV/ETH_RMII_CRS_DV , , , ,EVENTOUT,ADC12_IN7
|
PortA,PA7 , ,TIM1_CH1N ,TIM3_CH2,TIM8_CH1N , ,SPI1_MOSI , , , ,TIM14_CH1 , ,ETH_MII_RX_DV/ETH_RMII_CRS_DV , , , ,EVENTOUT,ADC12_IN7
|
||||||
PortA,PA8 ,MCO1 ,TIM1_CH1 , , ,I2C3_SCL , , ,USART1_CK , , ,OTG_FS_SOF , , , ,LCD_R6 ,EVENTOUT,
|
PortA,PA8 ,MCO1 ,TIM1_CH1 , , ,I2C3_SCL , , ,USART1_CK , , ,OTG_FS_SOF , , , ,LCD_R6 ,EVENTOUT,
|
||||||
PortA,PA9 , ,TIM1_CH2 , , ,I2C3_SMBA, , ,USART1_TX , , , , , ,DCMI_D0 , ,EVENTOUT,
|
PortA,PA9 , ,TIM1_CH2 , , ,I2C3_SMBA, , ,USART1_TX , , , , , ,DCMI_D0 , ,EVENTOUT,
|
||||||
|
@ -105,7 +105,7 @@ PortG,PG5 , , , , , ,
|
||||||
PortG,PG6 , , , , , , , , , , , , ,FMC_INT2 ,DCMI_D12 ,LCD_R7 ,EVENTOUT,
|
PortG,PG6 , , , , , , , , , , , , ,FMC_INT2 ,DCMI_D12 ,LCD_R7 ,EVENTOUT,
|
||||||
PortG,PG7 , , , , , , , , ,USART6_CK , , , ,FMC_INT3 ,DCMI_D13 ,LCD_CLK ,EVENTOUT,
|
PortG,PG7 , , , , , , , , ,USART6_CK , , , ,FMC_INT3 ,DCMI_D13 ,LCD_CLK ,EVENTOUT,
|
||||||
PortG,PG8 , , , , , ,SPI6_NSS , , ,USART6_RTS , , ,ETH_PPS_OUT ,FMC_SDCLK , , ,EVENTOUT,
|
PortG,PG8 , , , , , ,SPI6_NSS , , ,USART6_RTS , , ,ETH_PPS_OUT ,FMC_SDCLK , , ,EVENTOUT,
|
||||||
PortG,PG9 , , , , , , , , ,USART6_RX , , , ,FMC_NE2/FMC_NCE3 ,DCMI_VSYNC(1), ,EVENTOUT,
|
PortG,PG9 , , , , , , , , ,USART6_RX , , , ,FMC_NE2/FMC_NCE3 ,DCMI_VSYNC , ,EVENTOUT,
|
||||||
PortG,PG10, , , , , , , , , ,LCD_G3 , , ,FMC_NCE4_1/FMC_NE3,DCMI_D2 ,LCD_B2 ,EVENTOUT,
|
PortG,PG10, , , , , , , , , ,LCD_G3 , , ,FMC_NCE4_1/FMC_NE3,DCMI_D2 ,LCD_B2 ,EVENTOUT,
|
||||||
PortG,PG11, , , , , , , , , , , ,ETH_MII_TX_EN/ETH_RMII_TX_EN ,FMC_NCE4_2 ,DCMI_D3 ,LCD_B3 ,EVENTOUT,
|
PortG,PG11, , , , , , , , , , , ,ETH_MII_TX_EN/ETH_RMII_TX_EN ,FMC_NCE4_2 ,DCMI_D3 ,LCD_B3 ,EVENTOUT,
|
||||||
PortG,PG12, , , , , ,SPI6_MISO , , ,USART6_RTS ,LCD_B4 , , ,FMC_NE4 , ,LCD_B1 ,EVENTOUT,
|
PortG,PG12, , , , , ,SPI6_MISO , , ,USART6_RTS ,LCD_B4 , , ,FMC_NE4 , ,LCD_B1 ,EVENTOUT,
|
||||||
|
|
|
|
@ -106,4 +106,4 @@ PortG,PG6 , , ,TIM20_BKIN
|
||||||
PortG,PG7 , , , ,SAI1_CK1 ,I2C3_SCL , , , ,LPUART1_TX , , , ,FMC_INT ,SAI1_MCLK_A , ,EVENTOUT,
|
PortG,PG7 , , , ,SAI1_CK1 ,I2C3_SCL , , , ,LPUART1_TX , , , ,FMC_INT ,SAI1_MCLK_A , ,EVENTOUT,
|
||||||
PortG,PG8 , , , , ,I2C3_SDA , , , ,LPUART1_RX , , , ,FMC_NE3 , , ,EVENTOUT,
|
PortG,PG8 , , , , ,I2C3_SDA , , , ,LPUART1_RX , , , ,FMC_NE3 , , ,EVENTOUT,
|
||||||
PortG,PG9 , , , , , , ,SPI3_SCK ,USART1_TX , , , , ,FMC_NCE/FMC_NE2 , ,TIM15_CH1N ,EVENTOUT,
|
PortG,PG9 , , , , , , ,SPI3_SCK ,USART1_TX , , , , ,FMC_NCE/FMC_NE2 , ,TIM15_CH1N ,EVENTOUT,
|
||||||
PortG,PG10,MCO , , , , , , , , , , , , , , , ,EVENTOUT
|
PortG,PG10,MCO , , , , , , , , , , , , , , ,EVENTOUT,
|
||||||
|
|
|
|
@ -108,6 +108,12 @@ void machine_init(void) {
|
||||||
reset_cause = PYB_RESET_DEEPSLEEP;
|
reset_cause = PYB_RESET_DEEPSLEEP;
|
||||||
PWR->CR1 |= PWR_CR1_CSBF;
|
PWR->CR1 |= PWR_CR1_CSBF;
|
||||||
} else
|
} else
|
||||||
|
#elif defined(STM32H5)
|
||||||
|
if (PWR->PMSR & PWR_PMSR_STOPF || PWR->PMSR & PWR_PMSR_SBF) {
|
||||||
|
// came out of standby or stop mode
|
||||||
|
reset_cause = PYB_RESET_DEEPSLEEP;
|
||||||
|
PWR->PMCR |= PWR_PMCR_CSSF;
|
||||||
|
} else
|
||||||
#elif defined(STM32H7)
|
#elif defined(STM32H7)
|
||||||
if (PWR->CPUCR & PWR_CPUCR_SBF || PWR->CPUCR & PWR_CPUCR_STOPF) {
|
if (PWR->CPUCR & PWR_CPUCR_SBF || PWR->CPUCR & PWR_CPUCR_STOPF) {
|
||||||
// came out of standby or stop mode
|
// came out of standby or stop mode
|
||||||
|
|
|
@ -48,6 +48,8 @@
|
||||||
#define POWERCTRL_GET_VOLTAGE_SCALING() PWR_REGULATOR_VOLTAGE_SCALE0
|
#define POWERCTRL_GET_VOLTAGE_SCALING() PWR_REGULATOR_VOLTAGE_SCALE0
|
||||||
#elif defined(STM32H723xx)
|
#elif defined(STM32H723xx)
|
||||||
#define POWERCTRL_GET_VOLTAGE_SCALING() LL_PWR_GetRegulVoltageScaling()
|
#define POWERCTRL_GET_VOLTAGE_SCALING() LL_PWR_GetRegulVoltageScaling()
|
||||||
|
#elif defined(STM32H5)
|
||||||
|
#define POWERCTRL_GET_VOLTAGE_SCALING() LL_PWR_GetRegulVoltageScaling()
|
||||||
#else
|
#else
|
||||||
#define POWERCTRL_GET_VOLTAGE_SCALING() \
|
#define POWERCTRL_GET_VOLTAGE_SCALING() \
|
||||||
(((PWR->CSR1 & PWR_CSR1_ACTVOS) && (SYSCFG->PWRCR & SYSCFG_PWRCR_ODEN)) ? \
|
(((PWR->CSR1 & PWR_CSR1_ACTVOS) && (SYSCFG->PWRCR & SYSCFG_PWRCR_ODEN)) ? \
|
||||||
|
@ -797,6 +799,14 @@ void powerctrl_enter_stop_mode(void) {
|
||||||
HAL_PWREx_EnableFlashPowerDown();
|
HAL_PWREx_EnableFlashPowerDown();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(STM32H5)
|
||||||
|
// Save RCC CR to re-enable OSCs and PLLs after wake up from low power mode.
|
||||||
|
uint32_t rcc_cr = RCC->CR;
|
||||||
|
|
||||||
|
// Save the current voltage scaling level to restore after exiting low power mode.
|
||||||
|
uint32_t vscaling = POWERCTRL_GET_VOLTAGE_SCALING();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(STM32H7)
|
#if defined(STM32H7)
|
||||||
// Save RCC CR to re-enable OSCs and PLLs after wake up from low power mode.
|
// Save RCC CR to re-enable OSCs and PLLs after wake up from low power mode.
|
||||||
uint32_t rcc_cr = RCC->CR;
|
uint32_t rcc_cr = RCC->CR;
|
||||||
|
@ -837,9 +847,9 @@ void powerctrl_enter_stop_mode(void) {
|
||||||
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_HSI48) {
|
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_HSI48) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else // defined(STM32F0)
|
||||||
|
|
||||||
#if defined(STM32H7)
|
#if defined(STM32H5) || defined(STM32H7)
|
||||||
// When exiting from Stop or Standby modes, the Run mode voltage scaling is reset to
|
// When exiting from Stop or Standby modes, the Run mode voltage scaling is reset to
|
||||||
// the default VOS3 value. Restore the voltage scaling to the previous voltage scale.
|
// the default VOS3 value. Restore the voltage scaling to the previous voltage scale.
|
||||||
if (vscaling != POWERCTRL_GET_VOLTAGE_SCALING()) {
|
if (vscaling != POWERCTRL_GET_VOLTAGE_SCALING()) {
|
||||||
|
@ -879,7 +889,7 @@ void powerctrl_enter_stop_mode(void) {
|
||||||
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) {
|
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else // defined(STM32H5)
|
||||||
|
|
||||||
// enable PLL
|
// enable PLL
|
||||||
__HAL_RCC_PLL_ENABLE();
|
__HAL_RCC_PLL_ENABLE();
|
||||||
|
@ -899,7 +909,7 @@ void powerctrl_enter_stop_mode(void) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif // defined(STM32H5)
|
||||||
|
|
||||||
powerctrl_disable_hsi_if_unused();
|
powerctrl_disable_hsi_if_unused();
|
||||||
|
|
||||||
|
@ -912,6 +922,15 @@ void powerctrl_enter_stop_mode(void) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(STM32H5)
|
||||||
|
if (rcc_cr & RCC_CR_HSI48ON) {
|
||||||
|
// Enable HSI48.
|
||||||
|
LL_RCC_HSI48_Enable();
|
||||||
|
while (!LL_RCC_HSI48_IsReady()) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(STM32H7)
|
#if defined(STM32H7)
|
||||||
// Enable HSI
|
// Enable HSI
|
||||||
if (rcc_cr & RCC_CR_HSION) {
|
if (rcc_cr & RCC_CR_HSION) {
|
||||||
|
|
|
@ -298,6 +298,10 @@ void SystemClock_Config(void) {
|
||||||
LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLL3Q);
|
LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLL3Q);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
DBGMCU->CR = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(STM32L0)
|
#elif defined(STM32L0)
|
||||||
|
|
|
@ -756,9 +756,11 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
|
||||||
RTC->WPR = 0xff;
|
RTC->WPR = 0xff;
|
||||||
|
|
||||||
// enable external interrupts on line EXTI_RTC_WAKEUP
|
// enable external interrupts on line EXTI_RTC_WAKEUP
|
||||||
#if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
|
#if defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
|
||||||
EXTI->IMR1 |= 1 << EXTI_RTC_WAKEUP;
|
EXTI->IMR1 |= 1 << EXTI_RTC_WAKEUP;
|
||||||
EXTI->RTSR1 |= 1 << EXTI_RTC_WAKEUP;
|
EXTI->RTSR1 |= 1 << EXTI_RTC_WAKEUP;
|
||||||
|
#elif defined(STM32H5)
|
||||||
|
EXTI->IMR1 |= 1 << EXTI_RTC_WAKEUP;
|
||||||
#elif defined(STM32H7)
|
#elif defined(STM32H7)
|
||||||
EXTI_D1->IMR1 |= 1 << EXTI_RTC_WAKEUP;
|
EXTI_D1->IMR1 |= 1 << EXTI_RTC_WAKEUP;
|
||||||
EXTI->RTSR1 |= 1 << EXTI_RTC_WAKEUP;
|
EXTI->RTSR1 |= 1 << EXTI_RTC_WAKEUP;
|
||||||
|
@ -768,8 +770,10 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// clear interrupt flags
|
// clear interrupt flags
|
||||||
#if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32WL)
|
#if defined(STM32G0) || defined(STM32G4) || defined(STM32WL)
|
||||||
RTC->ICSR &= ~RTC_ICSR_WUTWF;
|
RTC->ICSR &= ~RTC_ICSR_WUTWF;
|
||||||
|
#elif defined(STM32H5)
|
||||||
|
RTC->SCR = RTC_SCR_CWUTF;
|
||||||
#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
|
#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
|
||||||
RTC->SR &= ~RTC_SR_WUTF;
|
RTC->SR &= ~RTC_SR_WUTF;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -587,6 +587,20 @@ MP_WEAK void SystemClock_Config(void) {
|
||||||
// Enable the Debug Module in low-power modes.
|
// Enable the Debug Module in low-power modes.
|
||||||
DBGMCU->CR |= (DBGMCU_CR_DBG_SLEEPD1 | DBGMCU_CR_DBG_STOPD1 | DBGMCU_CR_DBG_STANDBYD1);
|
DBGMCU->CR |= (DBGMCU_CR_DBG_SLEEPD1 | DBGMCU_CR_DBG_STOPD1 | DBGMCU_CR_DBG_STANDBYD1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Configure the analog switches
|
||||||
|
#ifdef MICROPY_HW_ANALOG_SWITCH_PA0
|
||||||
|
HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PA0, MICROPY_HW_ANALOG_SWITCH_PA0);
|
||||||
|
#endif
|
||||||
|
#ifdef MICROPY_HW_ANALOG_SWITCH_PA1
|
||||||
|
HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PA1, MICROPY_HW_ANALOG_SWITCH_PA1);
|
||||||
|
#endif
|
||||||
|
#ifdef MICROPY_HW_ANALOG_SWITCH_PC2
|
||||||
|
HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC2, MICROPY_HW_ANALOG_SWITCH_PC2);
|
||||||
|
#endif
|
||||||
|
#ifdef MICROPY_HW_ANALOG_SWITCH_PC3
|
||||||
|
HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC3, MICROPY_HW_ANALOG_SWITCH_PC3);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -545,7 +545,7 @@ STATIC mp_obj_t extra_coverage(void) {
|
||||||
fun_bc.context = &context;
|
fun_bc.context = &context;
|
||||||
fun_bc.child_table = NULL;
|
fun_bc.child_table = NULL;
|
||||||
fun_bc.bytecode = (const byte *)"\x01"; // just needed for n_state
|
fun_bc.bytecode = (const byte *)"\x01"; // just needed for n_state
|
||||||
mp_code_state_t *code_state = m_new_obj_var(mp_code_state_t, mp_obj_t, 1);
|
mp_code_state_t *code_state = m_new_obj_var(mp_code_state_t, state, mp_obj_t, 1);
|
||||||
code_state->fun_bc = &fun_bc;
|
code_state->fun_bc = &fun_bc;
|
||||||
code_state->ip = (const byte *)"\x00"; // just needed for an invalid opcode
|
code_state->ip = (const byte *)"\x00"; // just needed for an invalid opcode
|
||||||
code_state->sp = &code_state->state[0];
|
code_state->sp = &code_state->state[0];
|
||||||
|
|
|
@ -102,3 +102,9 @@ test: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py
|
||||||
test_full: test
|
test_full: test
|
||||||
$(eval DIRNAME=ports/$(notdir $(CURDIR)))
|
$(eval DIRNAME=ports/$(notdir $(CURDIR)))
|
||||||
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) $(PYTHON) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) $(RUN_TESTS_SKIP) -d basics float micropython
|
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) $(PYTHON) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) $(RUN_TESTS_SKIP) -d basics float micropython
|
||||||
|
|
||||||
|
$(BUILD)/$(PROG): $(BUILD)/micropython.res
|
||||||
|
|
||||||
|
$(BUILD)/%.res: %.rc
|
||||||
|
$(ECHO) "WINDRES $<"
|
||||||
|
$(Q)$(WINDRES) $< -O coff -o $@
|
||||||
|
|
|
@ -135,3 +135,13 @@ For more info, see https://www.winehq.org/docs/wineusr-guide/cui-programs .
|
||||||
If built without line editing and history capabilities
|
If built without line editing and history capabilities
|
||||||
(MICROPY_USE_READLINE=0), the resulting binary can be run using the standard
|
(MICROPY_USE_READLINE=0), the resulting binary can be run using the standard
|
||||||
`wine` tool.
|
`wine` tool.
|
||||||
|
|
||||||
|
|
||||||
|
Generating the icon file
|
||||||
|
------------------------
|
||||||
|
The windows builds use a .ico file for the executable logo.
|
||||||
|
To generate such file from a .png file use ImageMagick, as was done for the icons in the logo/ directory:
|
||||||
|
|
||||||
|
magick convert vector-logo-2.png -define icon:auto-resize="256,128,96,64,48,32,16" vector-logo-2.ico
|
||||||
|
|
||||||
|
Note that for versions prior to 7.0 the command is `convert` instead of `magick convert`.
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
app ICON "../../logo/vector-logo-2.ico"
|
|
@ -103,6 +103,9 @@
|
||||||
<ClInclude Include="$(PyBaseDir)ports\windows\*.h" />
|
<ClInclude Include="$(PyBaseDir)ports\windows\*.h" />
|
||||||
<ClInclude Include="$(PyBaseDir)ports\windows\msvc\*.h" />
|
<ClInclude Include="$(PyBaseDir)ports\windows\msvc\*.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="micropython.rc" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="msvc/genhdr.targets" />
|
<Import Project="msvc/genhdr.targets" />
|
||||||
<Import Project="$(CustomPropsFile)" Condition="exists('$(CustomPropsFile)')" />
|
<Import Project="$(CustomPropsFile)" Condition="exists('$(CustomPropsFile)')" />
|
||||||
<Target Name="GenerateMicroPythonSources" BeforeTargets="BuildGenerateSources" DependsOnTargets="GenerateHeaders;FreezeModules">
|
<Target Name="GenerateMicroPythonSources" BeforeTargets="BuildGenerateSources" DependsOnTargets="GenerateHeaders;FreezeModules">
|
||||||
|
|
31
py/lexer.c
31
py/lexer.c
|
@ -527,14 +527,14 @@ STATIC void parse_string_literal(mp_lexer_t *lex, bool is_raw, bool is_fstring)
|
||||||
vstr_cut_tail_bytes(&lex->vstr, n_closing);
|
vstr_cut_tail_bytes(&lex->vstr, n_closing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function returns whether it has crossed a newline or not.
|
||||||
|
// It therefore always return true if stop_at_newline is true
|
||||||
STATIC bool skip_whitespace(mp_lexer_t *lex, bool stop_at_newline) {
|
STATIC bool skip_whitespace(mp_lexer_t *lex, bool stop_at_newline) {
|
||||||
bool had_physical_newline = false;
|
|
||||||
while (!is_end(lex)) {
|
while (!is_end(lex)) {
|
||||||
if (is_physical_newline(lex)) {
|
if (is_physical_newline(lex)) {
|
||||||
if (stop_at_newline && lex->nested_bracket_level == 0) {
|
if (stop_at_newline && lex->nested_bracket_level == 0) {
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
had_physical_newline = true;
|
|
||||||
next_char(lex);
|
next_char(lex);
|
||||||
} else if (is_whitespace(lex)) {
|
} else if (is_whitespace(lex)) {
|
||||||
next_char(lex);
|
next_char(lex);
|
||||||
|
@ -543,16 +543,16 @@ STATIC bool skip_whitespace(mp_lexer_t *lex, bool stop_at_newline) {
|
||||||
while (!is_end(lex) && !is_physical_newline(lex)) {
|
while (!is_end(lex) && !is_physical_newline(lex)) {
|
||||||
next_char(lex);
|
next_char(lex);
|
||||||
}
|
}
|
||||||
// had_physical_newline will be set on next loop
|
// will return true on next loop
|
||||||
} else if (is_char_and(lex, '\\', '\n')) {
|
} else if (is_char_and(lex, '\\', '\n')) {
|
||||||
// line-continuation, so don't set had_physical_newline
|
// line-continuation, so don't return true
|
||||||
next_char(lex);
|
next_char(lex);
|
||||||
next_char(lex);
|
next_char(lex);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return had_physical_newline;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_lexer_to_next(mp_lexer_t *lex) {
|
void mp_lexer_to_next(mp_lexer_t *lex) {
|
||||||
|
@ -577,7 +577,10 @@ void mp_lexer_to_next(mp_lexer_t *lex) {
|
||||||
vstr_reset(&lex->vstr);
|
vstr_reset(&lex->vstr);
|
||||||
|
|
||||||
// skip white space and comments
|
// skip white space and comments
|
||||||
bool had_physical_newline = skip_whitespace(lex, false);
|
// set the newline tokens at the line and column of the preceding line:
|
||||||
|
// only advance on the pointer until a new line is crossed, save the
|
||||||
|
// line and column, and then readvance it
|
||||||
|
bool had_physical_newline = skip_whitespace(lex, true);
|
||||||
|
|
||||||
// set token source information
|
// set token source information
|
||||||
lex->tok_line = lex->line;
|
lex->tok_line = lex->line;
|
||||||
|
@ -591,7 +594,12 @@ void mp_lexer_to_next(mp_lexer_t *lex) {
|
||||||
lex->tok_kind = MP_TOKEN_INDENT;
|
lex->tok_kind = MP_TOKEN_INDENT;
|
||||||
lex->emit_dent -= 1;
|
lex->emit_dent -= 1;
|
||||||
|
|
||||||
} else if (had_physical_newline && lex->nested_bracket_level == 0) {
|
} else if (had_physical_newline) {
|
||||||
|
// The cursor is at the end of the previous line, pointing to a
|
||||||
|
// physical newline. Skip any remaining whitespace, comments, and
|
||||||
|
// newlines.
|
||||||
|
skip_whitespace(lex, false);
|
||||||
|
|
||||||
lex->tok_kind = MP_TOKEN_NEWLINE;
|
lex->tok_kind = MP_TOKEN_NEWLINE;
|
||||||
|
|
||||||
size_t num_spaces = lex->column - 1;
|
size_t num_spaces = lex->column - 1;
|
||||||
|
@ -862,9 +870,10 @@ mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader) {
|
||||||
// preload first token
|
// preload first token
|
||||||
mp_lexer_to_next(lex);
|
mp_lexer_to_next(lex);
|
||||||
|
|
||||||
// Check that the first token is in the first column. If it's not then we
|
// Check that the first token is in the first column unless it is a
|
||||||
// convert the token kind to INDENT so that the parser gives a syntax error.
|
// newline. Otherwise we convert the token kind to INDENT so that
|
||||||
if (lex->tok_column != 1) {
|
// the parser gives a syntax error.
|
||||||
|
if (lex->tok_column != 1 && lex->tok_kind != MP_TOKEN_NEWLINE) {
|
||||||
lex->tok_kind = MP_TOKEN_INDENT;
|
lex->tok_kind = MP_TOKEN_INDENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
py/misc.h
14
py/misc.h
|
@ -71,26 +71,26 @@ typedef unsigned int uint;
|
||||||
#define m_new0(type, num) ((type *)(m_malloc0(sizeof(type) * (num))))
|
#define m_new0(type, num) ((type *)(m_malloc0(sizeof(type) * (num))))
|
||||||
#define m_new_obj(type) (m_new(type, 1))
|
#define m_new_obj(type) (m_new(type, 1))
|
||||||
#define m_new_obj_maybe(type) (m_new_maybe(type, 1))
|
#define m_new_obj_maybe(type) (m_new_maybe(type, 1))
|
||||||
#define m_new_obj_var(obj_type, var_type, var_num) ((obj_type *)m_malloc(sizeof(obj_type) + sizeof(var_type) * (var_num)))
|
#define m_new_obj_var(obj_type, var_field, var_type, var_num) ((obj_type *)m_malloc(offsetof(obj_type, var_field) + sizeof(var_type) * (var_num)))
|
||||||
#define m_new_obj_var0(obj_type, var_type, var_num) ((obj_type *)m_malloc0(sizeof(obj_type) + sizeof(var_type) * (var_num)))
|
#define m_new_obj_var0(obj_type, var_field, var_type, var_num) ((obj_type *)m_malloc0(offsetof(obj_type, var_field) + sizeof(var_type) * (var_num)))
|
||||||
#define m_new_obj_var_maybe(obj_type, var_type, var_num) ((obj_type *)m_malloc_maybe(sizeof(obj_type) + sizeof(var_type) * (var_num)))
|
#define m_new_obj_var_maybe(obj_type, var_field, var_type, var_num) ((obj_type *)m_malloc_maybe(offsetof(obj_type, var_field) + sizeof(var_type) * (var_num)))
|
||||||
#if MICROPY_ENABLE_FINALISER
|
#if MICROPY_ENABLE_FINALISER
|
||||||
#define m_new_obj_with_finaliser(type) ((type *)(m_malloc_with_finaliser(sizeof(type))))
|
#define m_new_obj_with_finaliser(type) ((type *)(m_malloc_with_finaliser(sizeof(type))))
|
||||||
#define m_new_obj_var_with_finaliser(type, var_type, var_num) ((type *)m_malloc_with_finaliser(sizeof(type) + sizeof(var_type) * (var_num)))
|
#define m_new_obj_var_with_finaliser(type, var_field, var_type, var_num) ((type *)m_malloc_with_finaliser(offsetof(type, var_field) + sizeof(var_type) * (var_num)))
|
||||||
#else
|
#else
|
||||||
#define m_new_obj_with_finaliser(type) m_new_obj(type)
|
#define m_new_obj_with_finaliser(type) m_new_obj(type)
|
||||||
#define m_new_obj_var_with_finaliser(type, var_type, var_num) m_new_obj_var(type, var_type, var_num)
|
#define m_new_obj_var_with_finaliser(type, var_field, var_type, var_num) m_new_obj_var(type, var_field, var_type, var_num)
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
|
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
|
||||||
#define m_renew(type, ptr, old_num, new_num) ((type *)(m_realloc((ptr), sizeof(type) * (old_num), sizeof(type) * (new_num))))
|
#define m_renew(type, ptr, old_num, new_num) ((type *)(m_realloc((ptr), sizeof(type) * (old_num), sizeof(type) * (new_num))))
|
||||||
#define m_renew_maybe(type, ptr, old_num, new_num, allow_move) ((type *)(m_realloc_maybe((ptr), sizeof(type) * (old_num), sizeof(type) * (new_num), (allow_move))))
|
#define m_renew_maybe(type, ptr, old_num, new_num, allow_move) ((type *)(m_realloc_maybe((ptr), sizeof(type) * (old_num), sizeof(type) * (new_num), (allow_move))))
|
||||||
#define m_del(type, ptr, num) m_free(ptr, sizeof(type) * (num))
|
#define m_del(type, ptr, num) m_free(ptr, sizeof(type) * (num))
|
||||||
#define m_del_var(obj_type, var_type, var_num, ptr) (m_free(ptr, sizeof(obj_type) + sizeof(var_type) * (var_num)))
|
#define m_del_var(obj_type, var_field, var_type, var_num, ptr) (m_free(ptr, offsetof(obj_type, var_field) + sizeof(var_type) * (var_num)))
|
||||||
#else
|
#else
|
||||||
#define m_renew(type, ptr, old_num, new_num) ((type *)(m_realloc((ptr), sizeof(type) * (new_num))))
|
#define m_renew(type, ptr, old_num, new_num) ((type *)(m_realloc((ptr), sizeof(type) * (new_num))))
|
||||||
#define m_renew_maybe(type, ptr, old_num, new_num, allow_move) ((type *)(m_realloc_maybe((ptr), sizeof(type) * (new_num), (allow_move))))
|
#define m_renew_maybe(type, ptr, old_num, new_num, allow_move) ((type *)(m_realloc_maybe((ptr), sizeof(type) * (new_num), (allow_move))))
|
||||||
#define m_del(type, ptr, num) ((void)(num), m_free(ptr))
|
#define m_del(type, ptr, num) ((void)(num), m_free(ptr))
|
||||||
#define m_del_var(obj_type, var_type, var_num, ptr) ((void)(var_num), m_free(ptr))
|
#define m_del_var(obj_type, var_field, var_type, var_num, ptr) ((void)(var_num), m_free(ptr))
|
||||||
#endif
|
#endif
|
||||||
#define m_del_obj(type, ptr) (m_del(type, ptr, 1))
|
#define m_del_obj(type, ptr) (m_del(type, ptr, 1))
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||||
SIZE = $(CROSS_COMPILE)size
|
SIZE = $(CROSS_COMPILE)size
|
||||||
STRIP = $(CROSS_COMPILE)strip
|
STRIP = $(CROSS_COMPILE)strip
|
||||||
AR = $(CROSS_COMPILE)ar
|
AR = $(CROSS_COMPILE)ar
|
||||||
|
WINDRES = $(CROSS_COMPILE)windres
|
||||||
|
|
||||||
MAKE_MANIFEST = $(PYTHON) $(TOP)/tools/makemanifest.py
|
MAKE_MANIFEST = $(PYTHON) $(TOP)/tools/makemanifest.py
|
||||||
MAKE_FROZEN = $(PYTHON) $(TOP)/tools/make-frozen.py
|
MAKE_FROZEN = $(PYTHON) $(TOP)/tools/make-frozen.py
|
||||||
|
|
|
@ -235,7 +235,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args)
|
||||||
// check for keyword arguments
|
// check for keyword arguments
|
||||||
if (n_args == 2) {
|
if (n_args == 2) {
|
||||||
// just position arguments
|
// just position arguments
|
||||||
th_args = m_new_obj_var(thread_entry_args_t, mp_obj_t, pos_args_len);
|
th_args = m_new_obj_var(thread_entry_args_t, args, mp_obj_t, pos_args_len);
|
||||||
th_args->n_kw = 0;
|
th_args->n_kw = 0;
|
||||||
} else {
|
} else {
|
||||||
// positional and keyword arguments
|
// positional and keyword arguments
|
||||||
|
@ -243,7 +243,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args)
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("expecting a dict for keyword args"));
|
mp_raise_TypeError(MP_ERROR_TEXT("expecting a dict for keyword args"));
|
||||||
}
|
}
|
||||||
mp_map_t *map = &((mp_obj_dict_t *)MP_OBJ_TO_PTR(args[2]))->map;
|
mp_map_t *map = &((mp_obj_dict_t *)MP_OBJ_TO_PTR(args[2]))->map;
|
||||||
th_args = m_new_obj_var(thread_entry_args_t, mp_obj_t, pos_args_len + 2 * map->used);
|
th_args = m_new_obj_var(thread_entry_args_t, args, mp_obj_t, pos_args_len + 2 * map->used);
|
||||||
th_args->n_kw = map->used;
|
th_args->n_kw = map->used;
|
||||||
// copy across the keyword arguments
|
// copy across the keyword arguments
|
||||||
for (size_t i = 0, n = pos_args_len; i < map->alloc; ++i) {
|
for (size_t i = 0, n = pos_args_len; i < map->alloc; ++i) {
|
||||||
|
|
|
@ -221,7 +221,7 @@ mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, siz
|
||||||
o_tuple = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj;
|
o_tuple = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj;
|
||||||
} else {
|
} else {
|
||||||
// Try to allocate memory for the tuple containing the args
|
// Try to allocate memory for the tuple containing the args
|
||||||
o_tuple = m_new_obj_var_maybe(mp_obj_tuple_t, mp_obj_t, n_args);
|
o_tuple = m_new_obj_var_maybe(mp_obj_tuple_t, items, mp_obj_t, n_args);
|
||||||
|
|
||||||
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
||||||
// If we are called by mp_obj_new_exception_msg_varg then it will have
|
// If we are called by mp_obj_new_exception_msg_varg then it will have
|
||||||
|
|
10
py/objfun.c
10
py/objfun.c
|
@ -215,7 +215,7 @@ mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args
|
||||||
// RuntimeError should be raised instead. So, we use m_new_obj_var_maybe(),
|
// RuntimeError should be raised instead. So, we use m_new_obj_var_maybe(),
|
||||||
// return NULL, then vm.c takes the needed action (either raise
|
// return NULL, then vm.c takes the needed action (either raise
|
||||||
// RuntimeError or fallback to stack allocation).
|
// RuntimeError or fallback to stack allocation).
|
||||||
code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size);
|
code_state = m_new_obj_var_maybe(mp_code_state_t, state, byte, state_size);
|
||||||
if (!code_state) {
|
if (!code_state) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -247,10 +247,10 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
|
||||||
// allocate state for locals and stack
|
// allocate state for locals and stack
|
||||||
mp_code_state_t *code_state = NULL;
|
mp_code_state_t *code_state = NULL;
|
||||||
#if MICROPY_ENABLE_PYSTACK
|
#if MICROPY_ENABLE_PYSTACK
|
||||||
code_state = mp_pystack_alloc(sizeof(mp_code_state_t) + state_size);
|
code_state = mp_pystack_alloc(offsetof(mp_code_state_t, state) + state_size);
|
||||||
#else
|
#else
|
||||||
if (state_size > VM_MAX_STATE_ON_STACK) {
|
if (state_size > VM_MAX_STATE_ON_STACK) {
|
||||||
code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size);
|
code_state = m_new_obj_var_maybe(mp_code_state_t, state, byte, state_size);
|
||||||
#if MICROPY_DEBUG_VM_STACK_OVERFLOW
|
#if MICROPY_DEBUG_VM_STACK_OVERFLOW
|
||||||
if (code_state != NULL) {
|
if (code_state != NULL) {
|
||||||
memset(code_state->state, 0, state_size);
|
memset(code_state->state, 0, state_size);
|
||||||
|
@ -258,7 +258,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (code_state == NULL) {
|
if (code_state == NULL) {
|
||||||
code_state = alloca(sizeof(mp_code_state_t) + state_size);
|
code_state = alloca(offsetof(mp_code_state_t, state) + state_size);
|
||||||
#if MICROPY_DEBUG_VM_STACK_OVERFLOW
|
#if MICROPY_DEBUG_VM_STACK_OVERFLOW
|
||||||
memset(code_state->state, 0, state_size);
|
memset(code_state->state, 0, state_size);
|
||||||
#endif
|
#endif
|
||||||
|
@ -320,7 +320,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
|
||||||
#else
|
#else
|
||||||
// free the state if it was allocated on the heap
|
// free the state if it was allocated on the heap
|
||||||
if (state_size != 0) {
|
if (state_size != 0) {
|
||||||
m_del_var(mp_code_state_t, byte, state_size, code_state);
|
m_del_var(mp_code_state_t, state, byte, state_size, code_state);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args,
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_namedtuple_type_t *mp_obj_new_namedtuple_base(size_t n_fields, mp_obj_t *fields) {
|
mp_obj_namedtuple_type_t *mp_obj_new_namedtuple_base(size_t n_fields, mp_obj_t *fields) {
|
||||||
mp_obj_namedtuple_type_t *o = m_new_obj_var0(mp_obj_namedtuple_type_t, qstr, n_fields);
|
mp_obj_namedtuple_type_t *o = m_new_obj_var0(mp_obj_namedtuple_type_t, fields, qstr, n_fields);
|
||||||
o->n_fields = n_fields;
|
o->n_fields = n_fields;
|
||||||
for (size_t i = 0; i < n_fields; i++) {
|
for (size_t i = 0; i < n_fields; i++) {
|
||||||
o->fields[i] = mp_obj_str_get_qstr(fields[i]);
|
o->fields[i] = mp_obj_str_get_qstr(fields[i]);
|
||||||
|
|
|
@ -264,7 +264,7 @@ void mp_obj_tuple_get(mp_obj_t self_in, size_t *len, mp_obj_t **items) {
|
||||||
void mp_obj_tuple_del(mp_obj_t self_in) {
|
void mp_obj_tuple_del(mp_obj_t self_in) {
|
||||||
assert(mp_obj_is_type(self_in, &mp_type_tuple));
|
assert(mp_obj_is_type(self_in, &mp_type_tuple));
|
||||||
mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
m_del_var(mp_obj_tuple_t, mp_obj_t, self->len, self);
|
m_del_var(mp_obj_tuple_t, items, mp_obj_t, self->len, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -1155,7 +1155,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
|
||||||
// (currently 10, plus 1 for base, plus 1 for base-protocol).
|
// (currently 10, plus 1 for base, plus 1 for base-protocol).
|
||||||
// Note: mp_obj_type_t is (2 + 3 + #slots) words, so going from 11 to 12 slots
|
// Note: mp_obj_type_t is (2 + 3 + #slots) words, so going from 11 to 12 slots
|
||||||
// moves from 4 to 5 gc blocks.
|
// moves from 4 to 5 gc blocks.
|
||||||
mp_obj_type_t *o = m_new_obj_var0(mp_obj_type_t, void *, 10 + (bases_len ? 1 : 0) + (base_protocol ? 1 : 0));
|
mp_obj_type_t *o = m_new_obj_var0(mp_obj_type_t, slots, void *, 10 + (bases_len ? 1 : 0) + (base_protocol ? 1 : 0));
|
||||||
o->base.type = &mp_type_type;
|
o->base.type = &mp_type_type;
|
||||||
o->flags = base_flags;
|
o->flags = base_flags;
|
||||||
o->name = name;
|
o->name = name;
|
||||||
|
|
|
@ -233,6 +233,11 @@ STATIC qstr qstr_add(mp_uint_t hash, mp_uint_t len, const char *q_ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
qstr qstr_find_strn(const char *str, size_t str_len) {
|
qstr qstr_find_strn(const char *str, size_t str_len) {
|
||||||
|
if (str_len == 0) {
|
||||||
|
// strncmp behaviour is undefined for str==NULL.
|
||||||
|
return MP_QSTR_;
|
||||||
|
}
|
||||||
|
|
||||||
// work out hash of str
|
// work out hash of str
|
||||||
size_t str_hash = qstr_compute_hash((const byte *)str, str_len);
|
size_t str_hash = qstr_compute_hash((const byte *)str, str_len);
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#define MP_STREAM_GET_DATA_OPTS (8) // Get data/message options
|
#define MP_STREAM_GET_DATA_OPTS (8) // Get data/message options
|
||||||
#define MP_STREAM_SET_DATA_OPTS (9) // Set data/message options
|
#define MP_STREAM_SET_DATA_OPTS (9) // Set data/message options
|
||||||
#define MP_STREAM_GET_FILENO (10) // Get fileno of underlying file
|
#define MP_STREAM_GET_FILENO (10) // Get fileno of underlying file
|
||||||
|
#define MP_STREAM_GET_BUFFER_SIZE (11) // Get preferred buffer size for file
|
||||||
|
|
||||||
// These poll ioctl values are compatible with Linux
|
// These poll ioctl values are compatible with Linux
|
||||||
#define MP_STREAM_POLL_RD (0x0001)
|
#define MP_STREAM_POLL_RD (0x0001)
|
||||||
|
|
|
@ -154,7 +154,7 @@ int strcmp(const char *s1, const char *s2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int strncmp(const char *s1, const char *s2, size_t n) {
|
int strncmp(const char *s1, const char *s2, size_t n) {
|
||||||
while (*s1 && *s2 && n > 0) {
|
while (n > 0 && *s1 && *s2) {
|
||||||
char c1 = *s1++; // XXX UTF8 get char, next char
|
char c1 = *s1++; // XXX UTF8 get char, next char
|
||||||
char c2 = *s2++; // XXX UTF8 get char, next char
|
char c2 = *s2++; // XXX UTF8 get char, next char
|
||||||
n--;
|
n--;
|
||||||
|
|
|
@ -27,17 +27,39 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
#if MICROPY_HW_ENABLE_USBDEV
|
#if MICROPY_HW_ENABLE_USBDEV
|
||||||
|
|
||||||
#ifndef NO_QSTR
|
#ifndef NO_QSTR
|
||||||
#include "tusb.h" // TinyUSB is not available when running the string preprocessor
|
#include "tusb.h" // TinyUSB is not available when running the string preprocessor
|
||||||
|
#include "device/dcd.h"
|
||||||
#include "device/usbd.h"
|
#include "device/usbd.h"
|
||||||
#include "device/usbd_pvt.h"
|
#include "device/usbd_pvt.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void usbd_task(void) {
|
// TinyUSB task function wrapper, as scheduled from the USB IRQ
|
||||||
|
static void mp_usbd_task_callback(mp_sched_node_t *node);
|
||||||
|
|
||||||
|
extern void __real_dcd_event_handler(dcd_event_t const *event, bool in_isr);
|
||||||
|
|
||||||
|
void mp_usbd_task(void) {
|
||||||
tud_task_ext(0, false);
|
tud_task_ext(0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If -Wl,--wrap=dcd_event_handler is passed to the linker, then this wrapper
|
||||||
|
// will be called and allows MicroPython to schedule the TinyUSB task when
|
||||||
|
// dcd_event_handler() is called from an ISR.
|
||||||
|
TU_ATTR_FAST_FUNC void __wrap_dcd_event_handler(dcd_event_t const *event, bool in_isr) {
|
||||||
|
static mp_sched_node_t usbd_task_node;
|
||||||
|
|
||||||
|
__real_dcd_event_handler(event, in_isr);
|
||||||
|
mp_sched_schedule_node(&usbd_task_node, mp_usbd_task_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mp_usbd_task_callback(mp_sched_node_t *node) {
|
||||||
|
(void)node;
|
||||||
|
mp_usbd_task();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
|
|
||||||
// Call instead of tud_task()
|
// Call this to explicitly run the TinyUSB device task.
|
||||||
void mp_usbd_task(void);
|
void mp_usbd_task(void);
|
||||||
|
|
||||||
// Function to be implemented in port code.
|
// Function to be implemented in port code.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
----------------
|
----------------
|
||||||
[ 4] \(rule\|file_input_2\)(1) (n=10)
|
[ 1] file_input_2(1) (n=10)
|
||||||
tok(6)
|
tok(6)
|
||||||
[ 4] \(rule\|for_stmt\)(22) (n=4)
|
[ 4] \(rule\|for_stmt\)(22) (n=4)
|
||||||
id(i)
|
id(i)
|
||||||
|
|
|
@ -16,6 +16,8 @@ except (ImportError, AttributeError):
|
||||||
|
|
||||||
|
|
||||||
class UserFile(io.IOBase):
|
class UserFile(io.IOBase):
|
||||||
|
buffer_size = 16
|
||||||
|
|
||||||
def __init__(self, mode, data):
|
def __init__(self, mode, data):
|
||||||
assert isinstance(data, bytes)
|
assert isinstance(data, bytes)
|
||||||
self.is_text = mode.find("b") == -1
|
self.is_text = mode.find("b") == -1
|
||||||
|
@ -39,7 +41,11 @@ class UserFile(io.IOBase):
|
||||||
|
|
||||||
def ioctl(self, req, arg):
|
def ioctl(self, req, arg):
|
||||||
print("ioctl", req, arg)
|
print("ioctl", req, arg)
|
||||||
|
if req == 4: # MP_STREAM_CLOSE
|
||||||
return 0
|
return 0
|
||||||
|
if req == 11: # MP_STREAM_GET_BUFFER_SIZE
|
||||||
|
return UserFile.buffer_size
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
class UserFS:
|
class UserFS:
|
||||||
|
@ -70,6 +76,8 @@ user_files = {
|
||||||
"/usermod2.py": b"print('in usermod2')",
|
"/usermod2.py": b"print('in usermod2')",
|
||||||
"/usermod3.py": b"syntax error",
|
"/usermod3.py": b"syntax error",
|
||||||
"/usermod4.mpy": b"syntax error",
|
"/usermod4.mpy": b"syntax error",
|
||||||
|
"/usermod5.py": b"print('in usermod5')",
|
||||||
|
"/usermod6.py": b"print('in usermod6')",
|
||||||
}
|
}
|
||||||
os.mount(UserFS(user_files), "/userfs")
|
os.mount(UserFS(user_files), "/userfs")
|
||||||
|
|
||||||
|
@ -93,6 +101,14 @@ try:
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print("ValueError in usermod4")
|
print("ValueError in usermod4")
|
||||||
|
|
||||||
|
# Test an import with largest buffer size
|
||||||
|
UserFile.buffer_size = 255
|
||||||
|
import usermod5
|
||||||
|
|
||||||
|
# Test an import with over-size buffer size (should be safely limited internally)
|
||||||
|
UserFile.buffer_size = 1024
|
||||||
|
import usermod6
|
||||||
|
|
||||||
# unmount and undo path addition
|
# unmount and undo path addition
|
||||||
os.umount("/userfs")
|
os.umount("/userfs")
|
||||||
sys.path.pop()
|
sys.path.pop()
|
||||||
|
|
|
@ -3,21 +3,37 @@ some data in a text file
|
||||||
stat /usermod1
|
stat /usermod1
|
||||||
stat /usermod1.py
|
stat /usermod1.py
|
||||||
open /usermod1.py rb
|
open /usermod1.py rb
|
||||||
|
ioctl 11 0
|
||||||
ioctl 4 0
|
ioctl 4 0
|
||||||
in usermod1
|
in usermod1
|
||||||
stat /usermod2
|
stat /usermod2
|
||||||
stat /usermod2.py
|
stat /usermod2.py
|
||||||
open /usermod2.py rb
|
open /usermod2.py rb
|
||||||
|
ioctl 11 0
|
||||||
ioctl 4 0
|
ioctl 4 0
|
||||||
in usermod2
|
in usermod2
|
||||||
stat /usermod3
|
stat /usermod3
|
||||||
stat /usermod3.py
|
stat /usermod3.py
|
||||||
open /usermod3.py rb
|
open /usermod3.py rb
|
||||||
|
ioctl 11 0
|
||||||
ioctl 4 0
|
ioctl 4 0
|
||||||
SyntaxError in usermod3
|
SyntaxError in usermod3
|
||||||
stat /usermod4
|
stat /usermod4
|
||||||
stat /usermod4.py
|
stat /usermod4.py
|
||||||
stat /usermod4.mpy
|
stat /usermod4.mpy
|
||||||
open /usermod4.mpy rb
|
open /usermod4.mpy rb
|
||||||
|
ioctl 11 0
|
||||||
ioctl 4 0
|
ioctl 4 0
|
||||||
ValueError in usermod4
|
ValueError in usermod4
|
||||||
|
stat /usermod5
|
||||||
|
stat /usermod5.py
|
||||||
|
open /usermod5.py rb
|
||||||
|
ioctl 11 0
|
||||||
|
ioctl 4 0
|
||||||
|
in usermod5
|
||||||
|
stat /usermod6
|
||||||
|
stat /usermod6.py
|
||||||
|
open /usermod6.py rb
|
||||||
|
ioctl 11 0
|
||||||
|
ioctl 4 0
|
||||||
|
in usermod6
|
||||||
|
|
|
@ -753,6 +753,13 @@ class RemoteFile(io.IOBase):
|
||||||
machine.mem32[arg] = self.seek(machine.mem32[arg], machine.mem32[arg + 4])
|
machine.mem32[arg] = self.seek(machine.mem32[arg], machine.mem32[arg + 4])
|
||||||
elif request == 4: # CLOSE
|
elif request == 4: # CLOSE
|
||||||
self.close()
|
self.close()
|
||||||
|
elif request == 11: # BUFFER_SIZE
|
||||||
|
# This is used as the vfs_reader buffer. n + 4 should be less than 255 to
|
||||||
|
# fit in stdin ringbuffer on supported ports. n + 7 should be multiple of 16
|
||||||
|
# to efficiently use gc blocks in mp_reader_vfs_t.
|
||||||
|
return 249
|
||||||
|
else:
|
||||||
|
return -1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
|
|
|
@ -32,6 +32,12 @@ def script_to_map(test_file):
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def load_profile(profile_file, test_dirs, exclude_tests):
|
||||||
|
profile_globals = {"test_dirs": test_dirs, "exclude_tests": exclude_tests}
|
||||||
|
exec(profile_file.read(), profile_globals)
|
||||||
|
return profile_globals["test_dirs"], profile_globals["exclude_tests"]
|
||||||
|
|
||||||
|
|
||||||
test_function = (
|
test_function = (
|
||||||
"void {name}(void* data) {{\n"
|
"void {name}(void* data) {{\n"
|
||||||
" static const char pystr[] = {script};\n"
|
" static const char pystr[] = {script};\n"
|
||||||
|
@ -50,17 +56,19 @@ testgroup_struct = "struct testgroup_t groups[] = {{\n{body}\n END_OF_GROUPS\n}
|
||||||
testgroup_member = ' {{ "{name}", {name}_tests }},'
|
testgroup_member = ' {{ "{name}", {name}_tests }},'
|
||||||
|
|
||||||
## XXX: may be we could have `--without <groups>` argument...
|
## XXX: may be we could have `--without <groups>` argument...
|
||||||
# currently these tests are selected because they pass on qemu-arm
|
|
||||||
test_dirs = (
|
test_dirs = set(
|
||||||
|
(
|
||||||
"basics",
|
"basics",
|
||||||
"micropython",
|
|
||||||
"misc",
|
|
||||||
"extmod",
|
"extmod",
|
||||||
"float",
|
"float",
|
||||||
"inlineasm",
|
"micropython",
|
||||||
"qemu-arm",
|
"misc",
|
||||||
) # 'import', 'io',)
|
)
|
||||||
exclude_tests = (
|
)
|
||||||
|
|
||||||
|
exclude_tests = set(
|
||||||
|
(
|
||||||
# pattern matching in .exp
|
# pattern matching in .exp
|
||||||
"basics/bytes_compare3.py",
|
"basics/bytes_compare3.py",
|
||||||
"extmod/ticks_diff.py",
|
"extmod/ticks_diff.py",
|
||||||
|
@ -80,12 +88,6 @@ exclude_tests = (
|
||||||
"float/float2int_doubleprec_intbig.py",
|
"float/float2int_doubleprec_intbig.py",
|
||||||
"float/float_format_ints_doubleprec.py",
|
"float/float_format_ints_doubleprec.py",
|
||||||
"float/float_parse_doubleprec.py",
|
"float/float_parse_doubleprec.py",
|
||||||
# inline asm FP tests (require Cortex-M4)
|
|
||||||
"inlineasm/asmfpaddsub.py",
|
|
||||||
"inlineasm/asmfpcmp.py",
|
|
||||||
"inlineasm/asmfpldrstr.py",
|
|
||||||
"inlineasm/asmfpmuldiv.py",
|
|
||||||
"inlineasm/asmfpsqrt.py",
|
|
||||||
# different filename in output
|
# different filename in output
|
||||||
"micropython/emg_exc.py",
|
"micropython/emg_exc.py",
|
||||||
"micropython/heapalloc_traceback.py",
|
"micropython/heapalloc_traceback.py",
|
||||||
|
@ -102,6 +104,7 @@ exclude_tests = (
|
||||||
# don't have f-string
|
# don't have f-string
|
||||||
"basics/string_fstring.py",
|
"basics/string_fstring.py",
|
||||||
"basics/string_fstring_debug.py",
|
"basics/string_fstring_debug.py",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
output = []
|
output = []
|
||||||
|
@ -112,11 +115,18 @@ argparser = argparse.ArgumentParser(
|
||||||
)
|
)
|
||||||
argparser.add_argument("--stdin", action="store_true", help="read list of tests from stdin")
|
argparser.add_argument("--stdin", action="store_true", help="read list of tests from stdin")
|
||||||
argparser.add_argument("--exclude", action="append", help="exclude test by name")
|
argparser.add_argument("--exclude", action="append", help="exclude test by name")
|
||||||
|
argparser.add_argument(
|
||||||
|
"--profile",
|
||||||
|
type=argparse.FileType("rt", encoding="utf-8"),
|
||||||
|
help="optional profile file providing test directories and exclusion list",
|
||||||
|
)
|
||||||
args = argparser.parse_args()
|
args = argparser.parse_args()
|
||||||
|
|
||||||
if not args.stdin:
|
if not args.stdin:
|
||||||
|
if args.profile:
|
||||||
|
test_dirs, exclude_tests = load_profile(args.profile, test_dirs, exclude_tests)
|
||||||
if args.exclude:
|
if args.exclude:
|
||||||
exclude_tests += tuple(args.exclude)
|
exclude_tests = exclude_tests.union(args.exclude)
|
||||||
for group in test_dirs:
|
for group in test_dirs:
|
||||||
tests += [test for test in glob("{}/*.py".format(group)) if test not in exclude_tests]
|
tests += [test for test in glob("{}/*.py".format(group)) if test not in exclude_tests]
|
||||||
else:
|
else:
|
||||||
|
|
Ładowanie…
Reference in New Issue