Merge remote-tracking branch 'micropython/master'
This commit is contained in:
commit
c6c977070e
|
@ -32,6 +32,7 @@ tests/*.out
|
|||
# Python cache files
|
||||
######################
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Customized Makefile/project overrides
|
||||
######################
|
||||
|
|
|
@ -23,14 +23,14 @@ Tab-completion is useful to find out what methods an object has.
|
|||
Paste mode (ctrl-E) is useful to paste a large slab of Python code into
|
||||
the REPL.
|
||||
|
||||
The ``machine`` module::
|
||||
The :mod:`machine` module::
|
||||
|
||||
import machine
|
||||
|
||||
machine.freq() # get the current frequency of the CPU
|
||||
machine.freq(160000000) # set the CPU frequency to 160 MHz
|
||||
|
||||
The ``esp`` module::
|
||||
The :mod:`esp` module::
|
||||
|
||||
import esp
|
||||
|
||||
|
@ -40,7 +40,7 @@ The ``esp`` module::
|
|||
Networking
|
||||
----------
|
||||
|
||||
The ``network`` module::
|
||||
The :mod:`network` module::
|
||||
|
||||
import network
|
||||
|
||||
|
@ -69,13 +69,13 @@ A useful function for connecting to your local WiFi network is::
|
|||
pass
|
||||
print('network config:', wlan.ifconfig())
|
||||
|
||||
Once the network is established the ``socket`` module can be used
|
||||
Once the network is established the :mod:`socket <usocket>` module can be used
|
||||
to create and use TCP/UDP sockets as usual.
|
||||
|
||||
Delay and timing
|
||||
----------------
|
||||
|
||||
Use the ``time`` module::
|
||||
Use the :mod:`time <utime>` module::
|
||||
|
||||
import time
|
||||
|
||||
|
@ -165,14 +165,14 @@ Use the ``machine.ADC`` class::
|
|||
SPI bus
|
||||
-------
|
||||
|
||||
The SPI driver is implemented in software and works on all pins::
|
||||
There are two SPI drivers. One is implemented in software and works on all pins::
|
||||
|
||||
from machine import Pin, SPI
|
||||
|
||||
# construct an SPI bus on the given pins
|
||||
# polarity is the idle state of SCK
|
||||
# phase=0 means sample on the first edge of SCK, phase=1 means the second
|
||||
spi = SPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
|
||||
spi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
|
||||
|
||||
spi.init(baudrate=200000) # set the baudrate
|
||||
|
||||
|
@ -194,13 +194,13 @@ Hardware SPI
|
|||
------------
|
||||
|
||||
The hardware SPI is faster (up to 80Mhz), but only works on following pins:
|
||||
``MISO`` is gpio2, ``MOSI`` is gpio13, and ``SCK`` is gpio14. It has the same
|
||||
``MISO`` is gpio12, ``MOSI`` is gpio13, and ``SCK`` is gpio14. It has the same
|
||||
methods as SPI, except for the pin parameters for the constructor and init
|
||||
(as those are fixed).
|
||||
|
||||
from machine import Pin, HSPI
|
||||
from machine import Pin, SPI
|
||||
|
||||
hspi = HSPI(baudrate=800000000, polarity=0, phase=0)
|
||||
hspi = SPI(0, baudrate=80000000, polarity=0, phase=0)
|
||||
|
||||
|
||||
I2C bus
|
||||
|
@ -253,15 +253,14 @@ The OneWire driver is implemented in software and works on all pins::
|
|||
ow.scan() # return a list of devices on the bus
|
||||
ow.reset() # reset the bus
|
||||
ow.readbyte() # read a byte
|
||||
ow.read(5) # read 5 bytes
|
||||
ow.writebyte(0x12) # write a byte on the bus
|
||||
ow.write('123') # write bytes on the bus
|
||||
ow.select_rom(b'12345678') # select a specific device by its ROM code
|
||||
|
||||
There is a specific driver for DS18B20 devices::
|
||||
There is a specific driver for DS18S20 and DS18B20 devices::
|
||||
|
||||
import time
|
||||
ds = onewire.DS18B20(ow)
|
||||
import time, ds18x20
|
||||
ds = ds18x20.DS18X20(ow)
|
||||
roms = ds.scan()
|
||||
ds.convert_temp()
|
||||
time.sleep_ms(750)
|
||||
|
|
|
@ -6,19 +6,19 @@ The 1-wire bus is a serial bus that uses just a single wire for communication
|
|||
is a very popular 1-wire device, and here we show how to use the onewire module
|
||||
to read from such a device.
|
||||
|
||||
For the following code to work you need to have at least one DS18B20 temperature
|
||||
For the following code to work you need to have at least one DS18S20 or DS18B20 temperature
|
||||
sensor with its data line connected to GPIO12. You must also power the sensors
|
||||
and connect a 4.7k Ohm resistor between the data pin and the power pin. ::
|
||||
|
||||
import time
|
||||
import machine
|
||||
import onewire
|
||||
import onewire, ds18x20
|
||||
|
||||
# the device is on GPIO12
|
||||
dat = machine.Pin(12)
|
||||
|
||||
# create the onewire object
|
||||
ds = onewire.DS18B20(onewire.OneWire(dat))
|
||||
ds = ds18x20.DS18X20(onewire.OneWire(dat))
|
||||
|
||||
# scan for devices on the bus
|
||||
roms = ds.scan()
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
.. currentmodule:: pyb
|
||||
|
||||
class USB_HID -- USB Human Interface Device (HID)
|
||||
=================================================
|
||||
|
||||
The USB_HID class allows creation of an object representing the USB
|
||||
Human Interface Device (HID) interface. It can be used to emulate
|
||||
a peripheral such as a mouse or keyboard.
|
||||
|
||||
Before you can use this class, you need to use :meth:`pyb.usb_mode()` to set the USB mode to include the HID interface.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: pyb.USB_HID()
|
||||
|
||||
Create a new USB_HID object.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: USB_HID.send(data)
|
||||
|
||||
Send data over the USB HID interface:
|
||||
|
||||
- ``data`` is the data to send (a tuple/list of integers, or a
|
||||
bytearray).
|
|
@ -188,7 +188,7 @@ Miscellaneous functions
|
|||
Takes a 4-tuple (or list) and sends it to the USB host (the PC) to
|
||||
signal a HID mouse-motion event.
|
||||
|
||||
.. note:: This function is deprecated. Use pyb.USB_HID().send(...) instead.
|
||||
.. note:: This function is deprecated. Use :meth:`pyb.USB_HID.send()` instead.
|
||||
|
||||
.. function:: info([dump_alloc_table])
|
||||
|
||||
|
@ -254,6 +254,33 @@ Miscellaneous functions
|
|||
|
||||
Returns a string of 12 bytes (96 bits), which is the unique ID of the MCU.
|
||||
|
||||
.. function:: usb_mode([modestr], vid=0xf055, pid=0x9801, hid=pyb.hid_mouse)
|
||||
|
||||
If called with no arguments, return the current USB mode as a string.
|
||||
|
||||
If called with ``modestr`` provided, attempts to set USB mode.
|
||||
This can only be done when called from ``boot.py`` before
|
||||
:meth:`pyb.main()` has been called. The following values of
|
||||
``modestr`` are understood:
|
||||
|
||||
- ``None``: disables USB
|
||||
- ``'VCP'``: enable with VCP (Virtual COM Port) interface
|
||||
- ``'VCP+MSC'``: enable with VCP and MSC (mass storage device class)
|
||||
- ``'VCP+HID'``: enable with VCP and HID (human interface device)
|
||||
|
||||
For backwards compatibility, ``'CDC'`` is understood to mean
|
||||
``'VCP'`` (and similarly for ``'CDC+MSC'`` and ``'CDC+HID'``).
|
||||
|
||||
The ``vid`` and ``pid`` parameters allow you to specify the VID
|
||||
(vendor id) and PID (product id).
|
||||
|
||||
If enabling HID mode, you may also specify the HID details by
|
||||
passing the ``hid`` keyword parameter. It takes a tuple of
|
||||
(subclass, protocol, max packet length, polling interval, report
|
||||
descriptor). By default it will set appropriate values for a USB
|
||||
mouse. There is also a ``pyb.hid_keyboard`` constant, which is an
|
||||
appropriate tuple for a USB keyboard.
|
||||
|
||||
Classes
|
||||
-------
|
||||
|
||||
|
@ -277,4 +304,5 @@ Classes
|
|||
pyb.Switch.rst
|
||||
pyb.Timer.rst
|
||||
pyb.UART.rst
|
||||
pyb.USB_HID.rst
|
||||
pyb.USB_VCP.rst
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
Quick reference for the pyboard
|
||||
===============================
|
||||
|
||||
The below pinout is for PYBv1.0. You can also view pinouts for
|
||||
other versions of the pyboard:
|
||||
`PYBv1.1 <http://micropython.org/resources/pybv11-pinout.jpg>`__
|
||||
or `PYBLITEv1.0-AC <http://micropython.org/resources/pyblitev10ac-pinout.jpg>`__
|
||||
or `PYBLITEv1.0 <http://micropython.org/resources/pyblitev10-pinout.jpg>`__.
|
||||
|
||||
.. image:: http://micropython.org/resources/pybv10-pinout.jpg
|
||||
:alt: PYBv1.0 pinout
|
||||
:width: 700px
|
||||
|
@ -14,14 +20,25 @@ See :mod:`pyb`. ::
|
|||
|
||||
import pyb
|
||||
|
||||
pyb.delay(50) # wait 50 milliseconds
|
||||
pyb.millis() # number of milliseconds since bootup
|
||||
pyb.repl_uart(pyb.UART(1, 9600)) # duplicate REPL on UART(1)
|
||||
pyb.wfi() # pause CPU, waiting for interrupt
|
||||
pyb.freq() # get CPU and bus frequencies
|
||||
pyb.freq(60000000) # set CPU freq to 60MHz
|
||||
pyb.stop() # stop CPU, waiting for external interrupt
|
||||
|
||||
Delay and timing
|
||||
----------------
|
||||
|
||||
Use the :mod:`time <utime>` module::
|
||||
|
||||
import time
|
||||
|
||||
time.sleep(1) # sleep for 1 second
|
||||
time.sleep_ms(500) # sleep for 500 milliseconds
|
||||
time.sleep_us(10) # sleep for 10 microseconds
|
||||
start = time.ticks_ms() # get value of millisecond counter
|
||||
delta = time.ticks_diff(start, time.ticks_ms()) # compute time difference
|
||||
|
||||
LEDs
|
||||
----
|
||||
|
||||
|
|
|
@ -13,23 +13,23 @@ will look something like this::
|
|||
|
||||
import pyb
|
||||
#pyb.main('main.py') # main script to run after this one
|
||||
#pyb.usb_mode('CDC+MSC') # act as a serial and a storage device
|
||||
#pyb.usb_mode('CDC+HID') # act as a serial device and a mouse
|
||||
#pyb.usb_mode('VCP+MSC') # act as a serial and a storage device
|
||||
#pyb.usb_mode('VCP+HID') # act as a serial device and a mouse
|
||||
|
||||
To enable the mouse mode, uncomment the last line of the file, to
|
||||
make it look like::
|
||||
|
||||
pyb.usb_mode('CDC+HID') # act as a serial device and a mouse
|
||||
pyb.usb_mode('VCP+HID') # act as a serial device and a mouse
|
||||
|
||||
If you already changed your ``boot.py`` file, then the minimum code it
|
||||
needs to work is::
|
||||
|
||||
import pyb
|
||||
pyb.usb_mode('CDC+HID')
|
||||
pyb.usb_mode('VCP+HID')
|
||||
|
||||
This tells the pyboard to configure itself as a CDC (serial) and HID
|
||||
(human interface device, in our case a mouse) USB device when it boots
|
||||
up.
|
||||
This tells the pyboard to configure itself as a VCP (Virtual COM Port,
|
||||
ie serial port) and HID (human interface device, in our case a mouse)
|
||||
USB device when it boots up.
|
||||
|
||||
Eject/unmount the pyboard drive and reset it using the RST switch.
|
||||
Your PC should now detect the pyboard as a mouse!
|
||||
|
@ -41,7 +41,8 @@ To get the py-mouse to do anything we need to send mouse events to the PC.
|
|||
We will first do this manually using the REPL prompt. Connect to your
|
||||
pyboard using your serial program and type the following::
|
||||
|
||||
>>> pyb.hid((0, 10, 0, 0))
|
||||
>>> hid = pyb.USB_HID()
|
||||
>>> hid.send((0, 10, 0, 0))
|
||||
|
||||
Your mouse should move 10 pixels to the right! In the command above you
|
||||
are sending 4 pieces of information: button status, x, y and scroll. The
|
||||
|
@ -52,7 +53,7 @@ Let's make the mouse oscillate left and right::
|
|||
>>> import math
|
||||
>>> def osc(n, d):
|
||||
... for i in range(n):
|
||||
... pyb.hid((0, int(20 * math.sin(i / 10)), 0, 0))
|
||||
... hid.send((0, int(20 * math.sin(i / 10)), 0, 0))
|
||||
... pyb.delay(d)
|
||||
...
|
||||
>>> osc(100, 50)
|
||||
|
@ -100,9 +101,10 @@ In ``main.py`` put the following code::
|
|||
|
||||
switch = pyb.Switch()
|
||||
accel = pyb.Accel()
|
||||
hid = pyb.USB_HID()
|
||||
|
||||
while not switch():
|
||||
pyb.hid((0, accel.x(), accel.y(), 0))
|
||||
hid.send((0, accel.x(), accel.y(), 0))
|
||||
pyb.delay(20)
|
||||
|
||||
Save your file, eject/unmount your pyboard drive, and reset it using the RST
|
||||
|
@ -112,7 +114,7 @@ the mouse around. Try it out, and see if you can make the mouse stand still!
|
|||
Press the USR switch to stop the mouse motion.
|
||||
|
||||
You'll note that the y-axis is inverted. That's easy to fix: just put a
|
||||
minus sign in front of the y-coordinate in the ``pyb.hid()`` line above.
|
||||
minus sign in front of the y-coordinate in the ``hid.send()`` line above.
|
||||
|
||||
Restoring your pyboard to normal
|
||||
--------------------------------
|
||||
|
@ -121,9 +123,9 @@ If you leave your pyboard as-is, it'll behave as a mouse everytime you plug
|
|||
it in. You probably want to change it back to normal. To do this you need
|
||||
to first enter safe mode (see above), and then edit the ``boot.py`` file.
|
||||
In the ``boot.py`` file, comment out (put a # in front of) the line with the
|
||||
``CDC+HID`` setting, so it looks like::
|
||||
``VCP+HID`` setting, so it looks like::
|
||||
|
||||
#pyb.usb_mode('CDC+HID') # act as a serial device and a mouse
|
||||
#pyb.usb_mode('VCP+HID') # act as a serial device and a mouse
|
||||
|
||||
Save your file, eject/unmount the drive, and reset the pyboard. It is now
|
||||
back to normal operating mode.
|
||||
|
|
|
@ -4,31 +4,41 @@ Micro Python driver for SD cards using SPI bus.
|
|||
Requires an SPI bus and a CS pin. Provides readblocks and writeblocks
|
||||
methods so the device can be mounted as a filesystem.
|
||||
|
||||
Example usage:
|
||||
Example usage on pyboard:
|
||||
|
||||
import pyb, sdcard, os
|
||||
sd = sdcard.SDCard(pyb.SPI(1), pyb.Pin.board.X5)
|
||||
pyb.mount(sd, '/sd2')
|
||||
os.listdir('/')
|
||||
|
||||
Example usage on ESP8266:
|
||||
|
||||
import machine, sdcard, os
|
||||
sd = sdcard.SDCard(machine.SPI(0), machine.Pin(15))
|
||||
os.umount()
|
||||
os.VfsFat(sd, "")
|
||||
os.listdir()
|
||||
|
||||
"""
|
||||
|
||||
import pyb
|
||||
import time
|
||||
|
||||
|
||||
_CMD_TIMEOUT = const(100)
|
||||
|
||||
_R1_IDLE_STATE = const(1 << 0)
|
||||
#R1_ERASE_RESET = const(1 << 1)
|
||||
_R1_ILLEGAL_COMMAND = const(1 << 2)
|
||||
#R1_COM_CRC_ERROR = const(1 << 3)
|
||||
#R1_ERASE_SEQUENCE_ERROR = const(1 << 4)
|
||||
#R1_ADDRESS_ERROR = const(1 << 5)
|
||||
#R1_PARAMETER_ERROR = const(1 << 6)
|
||||
_TOKEN_CMD25 = const(0xfc)
|
||||
_TOKEN_STOP_TRAN = const(0xfd)
|
||||
_TOKEN_DATA = const(0xfe)
|
||||
|
||||
|
||||
class SDCard:
|
||||
CMD_TIMEOUT = const(100)
|
||||
|
||||
R1_IDLE_STATE = const(1 << 0)
|
||||
#R1_ERASE_RESET = const(1 << 1)
|
||||
R1_ILLEGAL_COMMAND = const(1 << 2)
|
||||
#R1_COM_CRC_ERROR = const(1 << 3)
|
||||
#R1_ERASE_SEQUENCE_ERROR = const(1 << 4)
|
||||
#R1_ADDRESS_ERROR = const(1 << 5)
|
||||
#R1_PARAMETER_ERROR = const(1 << 6)
|
||||
TOKEN_CMD25 = const(0xfc)
|
||||
TOKEN_STOP_TRAN = const(0xfd)
|
||||
TOKEN_DATA = const(0xfe)
|
||||
|
||||
def __init__(self, spi, cs):
|
||||
self.spi = spi
|
||||
self.cs = cs
|
||||
|
@ -42,30 +52,39 @@ class SDCard:
|
|||
# initialise the card
|
||||
self.init_card()
|
||||
|
||||
def init_spi(self, baudrate):
|
||||
try:
|
||||
master = self.spi.MASTER
|
||||
except AttributeError:
|
||||
# on ESP8266
|
||||
self.spi.init(baudrate=baudrate, phase=0, polarity=0)
|
||||
else:
|
||||
# on pyboard
|
||||
self.spi.init(master, baudrate=baudrate, phase=0, polarity=0)
|
||||
|
||||
def init_card(self):
|
||||
# init CS pin
|
||||
self.cs.high()
|
||||
self.cs.init(self.cs.OUT_PP)
|
||||
self.cs.init(self.cs.OUT, value=1)
|
||||
|
||||
# init SPI bus; use low data rate for initialisation
|
||||
self.spi.init(self.spi.MASTER, baudrate=100000, phase=0, polarity=0)
|
||||
self.init_spi(100000)
|
||||
|
||||
# clock card at least 100 cycles with cs high
|
||||
for i in range(16):
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
# CMD0: init card; should return R1_IDLE_STATE (allow 5 attempts)
|
||||
# CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts)
|
||||
for _ in range(5):
|
||||
if self.cmd(0, 0, 0x95) == R1_IDLE_STATE:
|
||||
if self.cmd(0, 0, 0x95) == _R1_IDLE_STATE:
|
||||
break
|
||||
else:
|
||||
raise OSError("no SD card")
|
||||
|
||||
# CMD8: determine card version
|
||||
r = self.cmd(8, 0x01aa, 0x87, 4)
|
||||
if r == R1_IDLE_STATE:
|
||||
if r == _R1_IDLE_STATE:
|
||||
self.init_card_v2()
|
||||
elif r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND):
|
||||
elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND):
|
||||
self.init_card_v1()
|
||||
else:
|
||||
raise OSError("couldn't determine SD card version")
|
||||
|
@ -86,10 +105,10 @@ class SDCard:
|
|||
raise OSError("can't set 512 block size")
|
||||
|
||||
# set to high data rate now that it's initialised
|
||||
self.spi.init(self.spi.MASTER, baudrate=1320000, phase=0, polarity=0)
|
||||
self.init_spi(1320000)
|
||||
|
||||
def init_card_v1(self):
|
||||
for i in range(CMD_TIMEOUT):
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
self.cmd(55, 0, 0)
|
||||
if self.cmd(41, 0, 0) == 0:
|
||||
self.cdv = 512
|
||||
|
@ -98,8 +117,8 @@ class SDCard:
|
|||
raise OSError("timeout waiting for v1 card")
|
||||
|
||||
def init_card_v2(self):
|
||||
for i in range(CMD_TIMEOUT):
|
||||
pyb.delay(50)
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
time.sleep_ms(50)
|
||||
self.cmd(58, 0, 0, 4)
|
||||
self.cmd(55, 0, 0)
|
||||
if self.cmd(41, 0x40000000, 0) == 0:
|
||||
|
@ -120,87 +139,87 @@ class SDCard:
|
|||
buf[3] = arg >> 8
|
||||
buf[4] = arg
|
||||
buf[5] = crc
|
||||
self.spi.send(buf)
|
||||
self.spi.write(buf)
|
||||
|
||||
# wait for the repsonse (response[7] == 0)
|
||||
for i in range(CMD_TIMEOUT):
|
||||
response = self.spi.send_recv(0xff)[0]
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
response = self.spi.read(1, 0xff)[0]
|
||||
if not (response & 0x80):
|
||||
# this could be a big-endian integer that we are getting here
|
||||
for j in range(final):
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
if release:
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
return response
|
||||
|
||||
# timeout
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
return -1
|
||||
|
||||
def cmd_nodata(self, cmd):
|
||||
self.spi.send(cmd)
|
||||
self.spi.send_recv(0xff) # ignore stuff byte
|
||||
for _ in range(CMD_TIMEOUT):
|
||||
if self.spi.send_recv(0xff)[0] == 0xff:
|
||||
self.spi.write(cmd)
|
||||
self.spi.read(1, 0xff) # ignore stuff byte
|
||||
for _ in range(_CMD_TIMEOUT):
|
||||
if self.spi.read(1, 0xff)[0] == 0xff:
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
return 0 # OK
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
return 1 # timeout
|
||||
|
||||
def readinto(self, buf):
|
||||
self.cs.low()
|
||||
|
||||
# read until start byte (0xff)
|
||||
while self.spi.send_recv(0xff)[0] != 0xfe:
|
||||
while self.spi.read(1, 0xff)[0] != 0xfe:
|
||||
pass
|
||||
|
||||
# read data
|
||||
mv = self.dummybuf_memoryview[:len(buf)]
|
||||
self.spi.send_recv(mv, recv=buf)
|
||||
self.spi.write_readinto(mv, buf)
|
||||
|
||||
# read checksum
|
||||
self.spi.send(0xff)
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
def write(self, token, buf):
|
||||
self.cs.low()
|
||||
|
||||
# send: start of block, data, checksum
|
||||
self.spi.send(token)
|
||||
self.spi.send(buf)
|
||||
self.spi.send(0xff)
|
||||
self.spi.send(0xff)
|
||||
self.spi.read(1, token)
|
||||
self.spi.write(buf)
|
||||
self.spi.write(b'\xff')
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
# check the response
|
||||
if (self.spi.send_recv(0xff)[0] & 0x1f) != 0x05:
|
||||
if (self.spi.read(1, 0xff)[0] & 0x1f) != 0x05:
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
return
|
||||
|
||||
# wait for write to finish
|
||||
while self.spi.send_recv(0xff)[0] == 0:
|
||||
while self.spi.read(1, 0xff)[0] == 0:
|
||||
pass
|
||||
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
def write_token(self, token):
|
||||
self.cs.low()
|
||||
self.spi.send(token)
|
||||
self.spi.send(0xff)
|
||||
self.spi.read(1, token)
|
||||
self.spi.write(b'\xff')
|
||||
# wait for write to finish
|
||||
while self.spi.send_recv(0xff)[0] == 0:
|
||||
while self.spi.read(1, 0xff)[0] == 0x00:
|
||||
pass
|
||||
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
def count(self):
|
||||
return self.sectors
|
||||
|
@ -224,7 +243,7 @@ class SDCard:
|
|||
self.readinto(mv[offset : offset + 512])
|
||||
offset += 512
|
||||
nblocks -= 1
|
||||
return self.cmd_nodata(12)
|
||||
return self.cmd_nodata(b'\x0c') # cmd 12
|
||||
return 0
|
||||
|
||||
def writeblocks(self, block_num, buf):
|
||||
|
@ -236,7 +255,7 @@ class SDCard:
|
|||
return 1
|
||||
|
||||
# send the data
|
||||
self.write(TOKEN_DATA, buf)
|
||||
self.write(_TOKEN_DATA, buf)
|
||||
else:
|
||||
# CMD25: set write address for first block
|
||||
if self.cmd(25, block_num * self.cdv, 0) != 0:
|
||||
|
@ -245,8 +264,8 @@ class SDCard:
|
|||
offset = 0
|
||||
mv = memoryview(buf)
|
||||
while nblocks:
|
||||
self.write(TOKEN_CMD25, mv[offset : offset + 512])
|
||||
self.write(_TOKEN_CMD25, mv[offset : offset + 512])
|
||||
offset += 512
|
||||
nblocks -= 1
|
||||
self.write_token(TOKEN_STOP_TRAN)
|
||||
self.write_token(_TOKEN_STOP_TRAN)
|
||||
return 0
|
||||
|
|
|
@ -78,6 +78,7 @@ SRC_C = \
|
|||
modpybrtc.c \
|
||||
modpybadc.c \
|
||||
modpybuart.c \
|
||||
modmachinewdt.c \
|
||||
modmachinespi.c \
|
||||
modpybspi.c \
|
||||
modpybhspi.c \
|
||||
|
@ -140,7 +141,7 @@ DRIVERS_SRC_C = $(addprefix drivers/,\
|
|||
SRC_S = \
|
||||
gchelper.s \
|
||||
|
||||
FROZEN_MPY_PY_FILES := $(shell find $(FROZEN_MPY_DIR)/ -type f -name '*.py')
|
||||
FROZEN_MPY_PY_FILES := $(shell find $(FROZEN_MPY_DIR) -type f -name '*.py')
|
||||
FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy))
|
||||
|
||||
OBJ =
|
||||
|
|
|
@ -199,7 +199,11 @@ uint32_t spi_transaction(uint8_t spi_no, uint8_t cmd_bits, uint16_t cmd_data,
|
|||
// This is rather inefficient but allows for a very generic function.
|
||||
// CMD ADDR and MOSI are set below to save on an extra if statement.
|
||||
if (din_bits) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO);
|
||||
if (dout_bits) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_DOUTDIN);
|
||||
} else {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO);
|
||||
}
|
||||
}
|
||||
if (dummy_bits) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_DUMMY);
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
//#define MACHINE_WAKE_SLEEP (0x02)
|
||||
#define MACHINE_WAKE_DEEPSLEEP (0x04)
|
||||
|
||||
extern const mp_obj_type_t esp_wdt_type;
|
||||
|
||||
STATIC mp_obj_t machine_freq(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
// get
|
||||
|
@ -246,6 +248,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
|
|||
|
||||
{ MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&pyb_rtc_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&esp_timer_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&esp_wdt_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pyb_pin_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&pyb_pwm_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) },
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Paul Sokolovsky
|
||||
*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
const mp_obj_type_t esp_wdt_type;
|
||||
|
||||
typedef struct _machine_wdt_obj_t {
|
||||
mp_obj_base_t base;
|
||||
} machine_wdt_obj_t;
|
||||
|
||||
STATIC machine_wdt_obj_t wdt_default = {{&esp_wdt_type}};
|
||||
|
||||
STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||
|
||||
mp_int_t id = 0;
|
||||
if (n_args > 0) {
|
||||
id = mp_obj_get_int(args[0]);
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case 0:
|
||||
return &wdt_default;
|
||||
default:
|
||||
mp_raise_ValueError("");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t machine_wdt_feed(mp_obj_t self_in) {
|
||||
(void)self_in;
|
||||
system_soft_wdt_feed();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_feed_obj, machine_wdt_feed);
|
||||
|
||||
STATIC const mp_map_elem_t machine_wdt_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_feed), (mp_obj_t)&machine_wdt_feed_obj }
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t esp_wdt_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_WDT,
|
||||
.make_new = machine_wdt_make_new,
|
||||
.locals_dict = (mp_obj_t)&machine_wdt_locals_dict,
|
||||
};
|
|
@ -35,6 +35,7 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/machine_spi.h"
|
||||
|
||||
#include "hspi.h"
|
||||
|
||||
|
@ -47,6 +48,58 @@ typedef struct _pyb_hspi_obj_t {
|
|||
} pyb_hspi_obj_t;
|
||||
|
||||
|
||||
STATIC void hspi_transfer(mp_obj_base_t *self_in, size_t src_len, const uint8_t *src_buf, size_t dest_len, uint8_t *dest_buf) {
|
||||
(void)self_in;
|
||||
|
||||
if (dest_len == 0) {
|
||||
// fast case when we only need to write data
|
||||
size_t chunk_size = 1024;
|
||||
size_t count = src_len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
spi_tx8fast(HSPI, src_buf[i]);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < src_len) {
|
||||
spi_tx8fast(HSPI, src_buf[i]);
|
||||
++i;
|
||||
}
|
||||
} else {
|
||||
// we need to read and write data
|
||||
|
||||
// Process data in chunks, let the pending tasks run in between
|
||||
size_t chunk_size = 1024; // TODO this should depend on baudrate
|
||||
size_t count = dest_len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
uint32_t data_out;
|
||||
if (src_len == 1) {
|
||||
data_out = src_buf[0];
|
||||
} else {
|
||||
data_out = src_buf[i];
|
||||
}
|
||||
dest_buf[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out, 8, 0);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < dest_len) {
|
||||
uint32_t data_out;
|
||||
if (src_len == 1) {
|
||||
data_out = src_buf[0];
|
||||
} else {
|
||||
data_out = src_buf[i];
|
||||
}
|
||||
dest_buf[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out, 8, 0);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// MicroPython bindings for HSPI
|
||||
|
||||
|
@ -126,133 +179,25 @@ STATIC mp_obj_t pyb_hspi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_
|
|||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_hspi_init_obj, 1, pyb_hspi_init);
|
||||
|
||||
|
||||
STATIC mp_obj_t pyb_hspi_read(size_t n_args, const mp_obj_t *args) {
|
||||
vstr_t dest_buf;
|
||||
vstr_init_len(&dest_buf, mp_obj_get_int(args[1]));
|
||||
uint8_t write_byte = 0;
|
||||
if (n_args == 3) {
|
||||
write_byte = mp_obj_get_int(args[2]);
|
||||
}
|
||||
// Process data in chunks, let the pending tasks run in between
|
||||
size_t chunk_size = 1024; // TODO this should depend on baudrate
|
||||
size_t count = dest_buf.len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8,
|
||||
(uint32_t)write_byte, 8, 0);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < dest_buf.len) {
|
||||
((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8,
|
||||
(uint32_t)write_byte, 8, 0);
|
||||
++i;
|
||||
}
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &dest_buf);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_hspi_read_obj, 2, 3, pyb_hspi_read);
|
||||
|
||||
|
||||
STATIC mp_obj_t pyb_hspi_readinto(size_t n_args, const mp_obj_t *args) {
|
||||
mp_buffer_info_t dest_buf;
|
||||
mp_get_buffer_raise(args[1], &dest_buf, MP_BUFFER_WRITE);
|
||||
uint8_t write_byte = 0;
|
||||
if (n_args == 3) {
|
||||
write_byte = mp_obj_get_int(args[2]);
|
||||
}
|
||||
|
||||
size_t chunk_size = 1024;
|
||||
size_t count = dest_buf.len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8,
|
||||
(uint32_t)write_byte, 8, 0);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < dest_buf.len) {
|
||||
((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8,
|
||||
(uint32_t)write_byte, 8, 0);
|
||||
++i;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_hspi_readinto_obj, 2, 3, pyb_hspi_readinto);
|
||||
|
||||
|
||||
STATIC mp_obj_t pyb_hspi_write(mp_obj_t self_in, mp_obj_t wr_buf_in) {
|
||||
mp_buffer_info_t src_buf;
|
||||
mp_get_buffer_raise(wr_buf_in, &src_buf, MP_BUFFER_READ);
|
||||
|
||||
size_t chunk_size = 1024;
|
||||
size_t count = src_buf.len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
spi_tx8fast(HSPI, ((const uint8_t*)src_buf.buf)[i]);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < src_buf.len) {
|
||||
spi_tx8fast(HSPI, ((const uint8_t*)src_buf.buf)[i]);
|
||||
++i;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(pyb_hspi_write_obj, pyb_hspi_write);
|
||||
|
||||
|
||||
STATIC mp_obj_t pyb_hspi_write_readinto(mp_obj_t self_in, mp_obj_t wr_buf_in, mp_obj_t rd_buf_in) {
|
||||
mp_buffer_info_t src_buf;
|
||||
mp_get_buffer_raise(wr_buf_in, &src_buf, MP_BUFFER_READ);
|
||||
mp_buffer_info_t dest_buf;
|
||||
mp_get_buffer_raise(rd_buf_in, &dest_buf, MP_BUFFER_WRITE);
|
||||
if (src_buf.len != dest_buf.len) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
||||
"buffers must be the same length"));
|
||||
}
|
||||
|
||||
size_t chunk_size = 1024;
|
||||
size_t count = src_buf.len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8,
|
||||
(uint32_t)(((const uint8_t*)src_buf.buf)[i]), 8, 0);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < src_buf.len) {
|
||||
((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8,
|
||||
(uint32_t)(((const uint8_t*)src_buf.buf)[i]), 8, 0);
|
||||
++i;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_3(pyb_hspi_write_readinto_obj, pyb_hspi_write_readinto);
|
||||
|
||||
|
||||
STATIC const mp_rom_map_elem_t pyb_hspi_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_hspi_init_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&pyb_hspi_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&pyb_hspi_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&pyb_hspi_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&pyb_hspi_write_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_machine_spi_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_machine_spi_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_machine_spi_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&mp_machine_spi_write_readinto_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_hspi_locals_dict, pyb_hspi_locals_dict_table);
|
||||
|
||||
STATIC const mp_machine_spi_p_t pyb_hspi_p = {
|
||||
.transfer = hspi_transfer,
|
||||
};
|
||||
|
||||
const mp_obj_type_t pyb_hspi_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_HSPI,
|
||||
.print = pyb_hspi_print,
|
||||
.make_new = pyb_hspi_make_new,
|
||||
.protocol = &pyb_hspi_p,
|
||||
.locals_dict = (mp_obj_dict_t*)&pyb_hspi_locals_dict,
|
||||
};
|
||||
|
|
|
@ -212,7 +212,7 @@ STATIC mp_obj_t pyb_rtc_alarm(mp_obj_t self_in, mp_obj_t alarm_id, mp_obj_t time
|
|||
}
|
||||
|
||||
// set expiry time (in microseconds)
|
||||
pyb_rtc_alarm0_expiry = pyb_rtc_get_us_since_2000() + mp_obj_get_int(time_in) * 1000;
|
||||
pyb_rtc_alarm0_expiry = pyb_rtc_get_us_since_2000() + (uint64_t)mp_obj_get_int(time_in) * 1000;
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/machine_spi.h"
|
||||
|
||||
typedef struct _pyb_spi_obj_t {
|
||||
mp_obj_base_t base;
|
||||
|
@ -46,7 +47,8 @@ typedef struct _pyb_spi_obj_t {
|
|||
mp_hal_pin_obj_t miso;
|
||||
} pyb_spi_obj_t;
|
||||
|
||||
STATIC void mp_hal_spi_transfer(pyb_spi_obj_t *self, size_t src_len, const uint8_t *src_buf, size_t dest_len, uint8_t *dest_buf) {
|
||||
STATIC void mp_hal_spi_transfer(mp_obj_base_t *self_in, size_t src_len, const uint8_t *src_buf, size_t dest_len, uint8_t *dest_buf) {
|
||||
pyb_spi_obj_t *self = (pyb_spi_obj_t*)self_in;
|
||||
// only MSB transfer is implemented
|
||||
uint32_t delay_half = 500000 / self->baudrate + 1;
|
||||
for (size_t i = 0; i < src_len || i < dest_len; ++i) {
|
||||
|
@ -154,69 +156,25 @@ STATIC mp_obj_t pyb_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_a
|
|||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_init_obj, 1, pyb_spi_init);
|
||||
|
||||
STATIC mp_obj_t pyb_spi_read(size_t n_args, const mp_obj_t *args) {
|
||||
pyb_spi_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
uint8_t write_byte = 0;
|
||||
if (n_args == 3) {
|
||||
write_byte = mp_obj_get_int(args[2]);
|
||||
}
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, mp_obj_get_int(args[1]));
|
||||
mp_hal_spi_transfer(self, 1, &write_byte, vstr.len, (uint8_t*)vstr.buf);
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_spi_read_obj, 2, 3, pyb_spi_read);
|
||||
|
||||
STATIC mp_obj_t pyb_spi_readinto(size_t n_args, const mp_obj_t *args) {
|
||||
pyb_spi_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
|
||||
uint8_t write_byte = 0;
|
||||
if (n_args == 3) {
|
||||
write_byte = mp_obj_get_int(args[2]);
|
||||
}
|
||||
mp_hal_spi_transfer(self, 1, &write_byte, bufinfo.len, (uint8_t*)bufinfo.buf);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_spi_readinto_obj, 2, 3, pyb_spi_readinto);
|
||||
|
||||
STATIC mp_obj_t pyb_spi_write(mp_obj_t self_in, mp_obj_t wr_buf_in) {
|
||||
pyb_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_buffer_info_t src_buf;
|
||||
mp_get_buffer_raise(wr_buf_in, &src_buf, MP_BUFFER_READ);
|
||||
mp_hal_spi_transfer(self, src_buf.len, (const uint8_t*)src_buf.buf, 0, NULL);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(pyb_spi_write_obj, pyb_spi_write);
|
||||
|
||||
STATIC mp_obj_t pyb_spi_write_readinto(mp_obj_t self_in, mp_obj_t wr_buf_in, mp_obj_t rd_buf_in) {
|
||||
pyb_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_buffer_info_t src_buf;
|
||||
mp_get_buffer_raise(wr_buf_in, &src_buf, MP_BUFFER_READ);
|
||||
mp_buffer_info_t dest_buf;
|
||||
mp_get_buffer_raise(rd_buf_in, &dest_buf, MP_BUFFER_WRITE);
|
||||
if (src_buf.len != dest_buf.len) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "buffers must be the same length"));
|
||||
}
|
||||
mp_hal_spi_transfer(self, src_buf.len, (const uint8_t*)src_buf.buf, dest_buf.len, (uint8_t*)dest_buf.buf);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_3(pyb_spi_write_readinto_obj, pyb_spi_write_readinto);
|
||||
|
||||
STATIC const mp_rom_map_elem_t pyb_spi_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_spi_init_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&pyb_spi_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&pyb_spi_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&pyb_spi_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&pyb_spi_write_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_machine_spi_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_machine_spi_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_machine_spi_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&mp_machine_spi_write_readinto_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_spi_locals_dict, pyb_spi_locals_dict_table);
|
||||
|
||||
STATIC const mp_machine_spi_p_t pyb_spi_p = {
|
||||
.transfer = mp_hal_spi_transfer,
|
||||
};
|
||||
|
||||
const mp_obj_type_t pyb_spi_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_SoftSPI,
|
||||
.print = pyb_spi_print,
|
||||
.make_new = pyb_spi_make_new,
|
||||
.protocol = &pyb_spi_p,
|
||||
.locals_dict = (mp_obj_dict_t*)&pyb_spi_locals_dict,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# DS18x20 temperature sensor driver for MicroPython.
|
||||
# MIT license; Copyright (c) 2016 Damien P. George
|
||||
|
||||
_CONVERT = const(0x44)
|
||||
_RD_SCRATCH = const(0xbe)
|
||||
_WR_SCRATCH = const(0x4e)
|
||||
|
||||
class DS18X20:
|
||||
def __init__(self, onewire):
|
||||
self.ow = onewire
|
||||
self.buf = bytearray(9)
|
||||
|
||||
def scan(self):
|
||||
return [rom for rom in self.ow.scan() if rom[0] == 0x10 or rom[0] == 0x28]
|
||||
|
||||
def convert_temp(self):
|
||||
self.ow.reset(True)
|
||||
self.ow.writebyte(self.ow.SKIP_ROM)
|
||||
self.ow.writebyte(_CONVERT)
|
||||
|
||||
def read_scratch(self, rom):
|
||||
self.ow.reset(True)
|
||||
self.ow.select_rom(rom)
|
||||
self.ow.writebyte(_RD_SCRATCH)
|
||||
self.ow.readinto(self.buf)
|
||||
if self.ow.crc8(self.buf):
|
||||
raise Exception('CRC error')
|
||||
return self.buf
|
||||
|
||||
def write_scratch(self, rom, buf):
|
||||
self.ow.reset(True)
|
||||
self.ow.select_rom(rom)
|
||||
self.ow.writebyte(_WR_SCRATCH)
|
||||
self.ow.write(buf)
|
||||
|
||||
def read_temp(self, rom):
|
||||
buf = self.read_scratch(rom)
|
||||
if rom[0] == 0x10:
|
||||
if buf[1]:
|
||||
t = buf[0] >> 1 | 0x80
|
||||
t = -((~t + 1) & 0xff)
|
||||
else:
|
||||
t = buf[0] >> 1
|
||||
return t - 0.25 + (buf[7] - buf[6]) / buf[7]
|
||||
else:
|
||||
return (buf[1] << 8 | buf[0]) / 16
|
|
@ -15,8 +15,11 @@ class OneWire:
|
|||
self.pin = pin
|
||||
self.pin.init(pin.OPEN_DRAIN)
|
||||
|
||||
def reset(self):
|
||||
return _ow.reset(self.pin)
|
||||
def reset(self, required=False):
|
||||
reset = _ow.reset(self.pin)
|
||||
if required and not reset:
|
||||
raise OneWireError
|
||||
return reset
|
||||
|
||||
def readbit(self):
|
||||
return _ow.readbit(self.pin)
|
||||
|
@ -24,11 +27,9 @@ class OneWire:
|
|||
def readbyte(self):
|
||||
return _ow.readbyte(self.pin)
|
||||
|
||||
def read(self, count):
|
||||
buf = bytearray(count)
|
||||
for i in range(count):
|
||||
def readinto(self, buf):
|
||||
for i in range(len(buf)):
|
||||
buf[i] = _ow.readbyte(self.pin)
|
||||
return buf
|
||||
|
||||
def writebit(self, value):
|
||||
return _ow.writebit(self.pin, value)
|
||||
|
@ -87,41 +88,3 @@ class OneWire:
|
|||
|
||||
def crc8(self, data):
|
||||
return _ow.crc8(data)
|
||||
|
||||
class DS18B20:
|
||||
CONVERT = const(0x44)
|
||||
RD_SCRATCH = const(0xbe)
|
||||
WR_SCRATCH = const(0x4e)
|
||||
|
||||
def __init__(self, onewire):
|
||||
self.ow = onewire
|
||||
|
||||
def scan(self):
|
||||
return [rom for rom in self.ow.scan() if rom[0] == 0x28]
|
||||
|
||||
def convert_temp(self):
|
||||
if not self.ow.reset():
|
||||
raise OneWireError
|
||||
self.ow.writebyte(SKIP_ROM)
|
||||
self.ow.writebyte(CONVERT)
|
||||
|
||||
def read_scratch(self, rom):
|
||||
if not self.ow.reset():
|
||||
raise OneWireError
|
||||
self.ow.select_rom(rom)
|
||||
self.ow.writebyte(RD_SCRATCH)
|
||||
buf = self.ow.read(9)
|
||||
if self.ow.crc8(buf):
|
||||
raise OneWireError
|
||||
return buf
|
||||
|
||||
def write_scratch(self, rom, buf):
|
||||
if not self.ow.reset():
|
||||
raise OneWireError
|
||||
self.ow.select_rom(rom)
|
||||
self.ow.writebyte(WR_SCRATCH)
|
||||
self.ow.write(buf)
|
||||
|
||||
def read_temp(self, rom):
|
||||
buf = self.read_scratch(rom)
|
||||
return (buf[1] << 8 | buf[0]) / 16
|
|
@ -123,6 +123,10 @@ STATIC mp_obj_t os_rename(mp_obj_t path_old, mp_obj_t path_new) {
|
|||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
|
||||
|
||||
STATIC mp_obj_t os_umount(void) {
|
||||
return vfs_proxy_call(MP_QSTR_umount, 0, NULL);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_umount_obj, os_umount);
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||
|
@ -166,6 +170,7 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&os_remove_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&os_rename_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&os_stat_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&os_umount_obj) },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#define MICROPY_PY_MACHINE (1)
|
||||
#define MICROPY_PY_MACHINE_PULSE (1)
|
||||
#define MICROPY_PY_MACHINE_I2C (1)
|
||||
#define MICROPY_PY_MACHINE_SPI (1)
|
||||
#define MICROPY_PY_WEBSOCKET (1)
|
||||
#define MICROPY_PY_WEBREPL (1)
|
||||
#define MICROPY_PY_WEBREPL_DELAY (20)
|
||||
|
|
|
@ -16,10 +16,10 @@ pyb.LED(3).off() # indicate that we finished waiting for the swit
|
|||
pyb.LED(4).on() # indicate that we are selecting the mode
|
||||
|
||||
if switch_value:
|
||||
pyb.usb_mode('CDC+MSC')
|
||||
pyb.usb_mode('VCP+MSC')
|
||||
pyb.main('cardreader.py') # if switch was pressed, run this
|
||||
else:
|
||||
pyb.usb_mode('CDC+HID')
|
||||
pyb.usb_mode('VCP+HID')
|
||||
pyb.main('datalogger.py') # if switch wasn't pressed, run this
|
||||
|
||||
pyb.LED(4).off() # indicate that we finished selecting the mode
|
||||
|
|
|
@ -162,7 +162,7 @@ STATIC mp_obj_t fatfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
|
|||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(fsuser_mount_obj, 2, fatfs_mount);
|
||||
|
||||
STATIC mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in) {
|
||||
mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in) {
|
||||
size_t i = 0;
|
||||
if (MP_OBJ_IS_STR(bdev_or_path_in)) {
|
||||
mp_uint_t mnt_len;
|
||||
|
|
|
@ -55,6 +55,7 @@ typedef struct _fs_user_mount_t {
|
|||
} fs_user_mount_t;
|
||||
|
||||
fs_user_mount_t *fatfs_mount_mkfs(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, bool mkfs);
|
||||
mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(fsuser_mount_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(fsuser_umount_obj);
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "extmod/machine_spi.h"
|
||||
|
||||
#if MICROPY_PY_MACHINE_SPI
|
||||
|
||||
STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t slen, const uint8_t *src, size_t dlen, uint8_t *dest) {
|
||||
mp_obj_base_t *s = (mp_obj_base_t*)MP_OBJ_TO_PTR(self);
|
||||
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)s->type->protocol;
|
||||
spi_p->transfer(s, slen, src, dlen, dest);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t mp_machine_spi_read(size_t n_args, const mp_obj_t *args) {
|
||||
uint8_t write_byte = 0;
|
||||
if (n_args == 3) {
|
||||
write_byte = mp_obj_get_int(args[2]);
|
||||
}
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, mp_obj_get_int(args[1]));
|
||||
mp_machine_spi_transfer(args[0], 1, &write_byte, vstr.len, (uint8_t*)vstr.buf);
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj, 2, 3, mp_machine_spi_read);
|
||||
|
||||
STATIC mp_obj_t mp_machine_spi_readinto(size_t n_args, const mp_obj_t *args) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
|
||||
uint8_t write_byte = 0;
|
||||
if (n_args == 3) {
|
||||
write_byte = mp_obj_get_int(args[2]);
|
||||
}
|
||||
mp_machine_spi_transfer(args[0], 1, &write_byte, bufinfo.len, (uint8_t*)bufinfo.buf);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_readinto_obj, 2, 3, mp_machine_spi_readinto);
|
||||
|
||||
STATIC mp_obj_t mp_machine_spi_write(mp_obj_t self, mp_obj_t wr_buf) {
|
||||
mp_buffer_info_t src;
|
||||
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
|
||||
mp_machine_spi_transfer(self, src.len, (const uint8_t*)src.buf, 0, NULL);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(mp_machine_spi_write_obj, mp_machine_spi_write);
|
||||
|
||||
STATIC mp_obj_t mp_machine_spi_write_readinto(mp_obj_t self, mp_obj_t wr_buf, mp_obj_t rd_buf) {
|
||||
mp_buffer_info_t src;
|
||||
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
|
||||
mp_buffer_info_t dest;
|
||||
mp_get_buffer_raise(rd_buf, &dest, MP_BUFFER_WRITE);
|
||||
if (src.len != dest.len) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "buffers must be the same length"));
|
||||
}
|
||||
mp_machine_spi_transfer(self, src.len, (const uint8_t*)src.buf, dest.len, (uint8_t*)dest.buf);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_3(mp_machine_spi_write_readinto_obj, mp_machine_spi_write_readinto);
|
||||
|
||||
#endif // MICROPY_PY_MACHINE_SPI
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
|
||||
#define MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
// SPI protocol
|
||||
typedef struct _mp_machine_spi_p_t {
|
||||
void (*transfer)(mp_obj_base_t *obj, size_t slen, const uint8_t *src, size_t dlen, uint8_t *dest);
|
||||
} mp_machine_spi_p_t;
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_read_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_readinto_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_write_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_write_readinto_obj);
|
||||
|
||||
#endif // MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
|
|
@ -68,7 +68,8 @@ STATIC mp_obj_t framebuf1_fill(mp_obj_t self_in, mp_obj_t col_in) {
|
|||
if (col) {
|
||||
col = 0xff;
|
||||
}
|
||||
for (int y = 0; y < self->height / 8; ++y) {
|
||||
int end = (self->height + 7) >> 3;
|
||||
for (int y = 0; y < end; ++y) {
|
||||
memset(self->buf + y * self->stride, col, self->width);
|
||||
}
|
||||
return mp_const_none;
|
||||
|
@ -83,7 +84,7 @@ STATIC mp_obj_t framebuf1_pixel(size_t n_args, const mp_obj_t *args) {
|
|||
int index = (y / 8) * self->stride + x;
|
||||
if (n_args == 3) {
|
||||
// get
|
||||
return MP_OBJ_NEW_SMALL_INT(self->buf[index] >> (y & 7));
|
||||
return MP_OBJ_NEW_SMALL_INT((self->buf[index] >> (y & 7)) & 1);
|
||||
} else {
|
||||
// set
|
||||
if (mp_obj_get_int(args[3])) {
|
||||
|
@ -101,8 +102,9 @@ STATIC mp_obj_t framebuf1_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t y
|
|||
mp_obj_framebuf1_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_int_t xstep = mp_obj_get_int(xstep_in);
|
||||
mp_int_t ystep = mp_obj_get_int(ystep_in);
|
||||
int end = (self->height + 7) >> 3;
|
||||
if (xstep == 0 && ystep > 0) {
|
||||
for (int y = self->height / 8; y > 0;) {
|
||||
for (int y = end; y > 0;) {
|
||||
--y;
|
||||
for (int x = 0; x < self->width; ++x) {
|
||||
int prev = 0;
|
||||
|
@ -113,10 +115,10 @@ STATIC mp_obj_t framebuf1_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t y
|
|||
}
|
||||
}
|
||||
} else if (xstep == 0 && ystep < 0) {
|
||||
for (int y = 0; y < self->height / 8; ++y) {
|
||||
for (int y = 0; y < end; ++y) {
|
||||
for (int x = 0; x < self->width; ++x) {
|
||||
int prev = 0;
|
||||
if (y + 1 < self->height / 8) {
|
||||
if (y + 1 < end) {
|
||||
prev = self->buf[(y + 1) * self->stride + x] << (8 + ystep);
|
||||
}
|
||||
self->buf[y * self->stride + x] = (self->buf[y * self->stride + x] >> -ystep) | prev;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "py/binary.h"
|
||||
#include "extmod/modubinascii.h"
|
||||
|
||||
#include "uzlib/tinf.h"
|
||||
|
||||
mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
|
||||
// Second argument is for an extension to allow a separator to be used
|
||||
|
@ -203,6 +204,17 @@ mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
|
|||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj, mod_binascii_b2a_base64);
|
||||
|
||||
#if MICROPY_PY_UBINASCII_CRC32
|
||||
mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
|
||||
uint32_t crc = (n_args > 1) ? mp_obj_get_int(args[1]) : 0;
|
||||
crc = uzlib_crc32(bufinfo.buf, bufinfo.len, crc ^ 0xffffffff);
|
||||
return MP_OBJ_NEW_SMALL_INT(crc ^ 0xffffffff);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_crc32_obj, 1, 2, mod_binascii_crc32);
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_UBINASCII
|
||||
|
||||
STATIC const mp_rom_map_elem_t mp_module_binascii_globals_table[] = {
|
||||
|
@ -211,6 +223,9 @@ STATIC const mp_rom_map_elem_t mp_module_binascii_globals_table[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR_unhexlify), MP_ROM_PTR(&mod_binascii_unhexlify_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_a2b_base64), MP_ROM_PTR(&mod_binascii_a2b_base64_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_b2a_base64), MP_ROM_PTR(&mod_binascii_b2a_base64_obj) },
|
||||
#if MICROPY_PY_UBINASCII_CRC32
|
||||
{ MP_ROM_QSTR(MP_QSTR_crc32), MP_ROM_PTR(&mod_binascii_crc32_obj) },
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_binascii_globals, mp_module_binascii_globals_table);
|
||||
|
|
|
@ -31,10 +31,12 @@ extern mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args);
|
|||
extern mp_obj_t mod_binascii_unhexlify(mp_obj_t data);
|
||||
extern mp_obj_t mod_binascii_a2b_base64(mp_obj_t data);
|
||||
extern mp_obj_t mod_binascii_b2a_base64(mp_obj_t data);
|
||||
extern mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_hexlify_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_unhexlify_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_a2b_base64_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_b2a_base64_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_crc32_obj);
|
||||
|
||||
#endif /* MICROPY_EXTMOD_MODUBINASCII */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Paul Sokolovsky
|
||||
* Copyright (c) 2014-2016 Paul Sokolovsky
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mperrno.h"
|
||||
|
||||
#if MICROPY_PY_UZLIB
|
||||
|
||||
|
@ -40,6 +42,85 @@
|
|||
#define DEBUG_printf(...) (void)0
|
||||
#endif
|
||||
|
||||
typedef struct _mp_obj_decompio_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t src_stream;
|
||||
TINF_DATA decomp;
|
||||
bool eof;
|
||||
} mp_obj_decompio_t;
|
||||
|
||||
STATIC unsigned char read_src_stream(TINF_DATA *data) {
|
||||
byte *p = (void*)data;
|
||||
p -= offsetof(mp_obj_decompio_t, decomp);
|
||||
mp_obj_decompio_t *self = (mp_obj_decompio_t*)p;
|
||||
|
||||
const mp_stream_p_t *stream = mp_get_stream_raise(self->src_stream, MP_STREAM_OP_READ);
|
||||
int err;
|
||||
byte c;
|
||||
mp_uint_t out_sz = stream->read(self->src_stream, &c, 1, &err);
|
||||
if (out_sz == MP_STREAM_ERROR) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(err)));
|
||||
}
|
||||
if (out_sz == 0) {
|
||||
nlr_raise(mp_obj_new_exception(&mp_type_EOFError));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
#define DICT_SIZE 32768
|
||||
|
||||
STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||
mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t);
|
||||
o->base.type = type;
|
||||
memset(&o->decomp, 0, sizeof(o->decomp));
|
||||
uzlib_uncompress_init(&o->decomp, m_new(byte, DICT_SIZE), DICT_SIZE);
|
||||
o->decomp.readSource = read_src_stream;
|
||||
o->src_stream = args[0];
|
||||
o->eof = false;
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
STATIC mp_uint_t decompio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
|
||||
mp_obj_decompio_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
if (o->eof) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
o->decomp.dest = buf;
|
||||
o->decomp.destSize = size;
|
||||
int st = uzlib_uncompress_chksum(&o->decomp);
|
||||
if (st == TINF_DONE) {
|
||||
o->eof = true;
|
||||
}
|
||||
if (st < 0) {
|
||||
*errcode = MP_EINVAL;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
return o->decomp.dest - (byte*)buf;
|
||||
}
|
||||
|
||||
STATIC const mp_rom_map_elem_t decompio_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readall), MP_ROM_PTR(&mp_stream_readall_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(decompio_locals_dict, decompio_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t decompio_stream_p = {
|
||||
.read = decompio_read,
|
||||
};
|
||||
|
||||
STATIC const mp_obj_type_t decompio_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_DecompIO,
|
||||
.make_new = decompio_make_new,
|
||||
.protocol = &decompio_stream_p,
|
||||
.locals_dict = (void*)&decompio_locals_dict,
|
||||
};
|
||||
|
||||
STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
mp_obj_t data = args[0];
|
||||
|
@ -102,6 +183,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_uzlib_decompress_obj, 1, 3, mod_u
|
|||
STATIC const mp_rom_map_elem_t mp_module_uzlib_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uzlib) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_decompress), MP_ROM_PTR(&mod_uzlib_decompress_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_DecompIO), MP_ROM_PTR(&decompio_type) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_uzlib_globals, mp_module_uzlib_globals_table);
|
||||
|
|
|
@ -250,6 +250,13 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
|
|||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_stat_obj, fat_vfs_stat);
|
||||
|
||||
// Unmount the filesystem
|
||||
STATIC mp_obj_t fat_vfs_umount(mp_obj_t vfs_in) {
|
||||
fatfs_umount(((fs_user_mount_t *)vfs_in)->readblocks[1]);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_umount_obj, fat_vfs_umount);
|
||||
|
||||
STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&fat_vfs_open_obj) },
|
||||
|
@ -261,6 +268,7 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&fat_vfs_remove_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&fat_vfs_rename_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&fat_vfs_stat_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&fat_vfs_umount_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 78a4787948bb80cbfafcfd7910f95f61a4dd0d4c
|
||||
Subproject commit dab957dacddcbf6cbc85d42df62e189e4877bb72
|
|
@ -112,7 +112,7 @@ STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind,
|
|||
printf("took " UINT_FMT " ms\n", ticks);
|
||||
// qstr info
|
||||
{
|
||||
mp_uint_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes;
|
||||
size_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes;
|
||||
qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes);
|
||||
printf("qstr:\n n_pool=" UINT_FMT "\n n_qstr=" UINT_FMT "\n n_str_data_bytes=" UINT_FMT "\n n_total_bytes=" UINT_FMT "\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
// Send "cooked" string of given length, where every occurance of
|
||||
// LF character is replaced with CR LF.
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) {
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
|
||||
while (len--) {
|
||||
if (*str == '\n') {
|
||||
mp_hal_stdout_tx_strn("\r", 1);
|
||||
|
|
2
py/bc.c
2
py/bc.c
|
@ -89,7 +89,7 @@ STATIC void dump_args(const mp_obj_t *a, size_t sz) {
|
|||
// - code_state->ip should contain the offset in bytes from the start of
|
||||
// the bytecode chunk to just after n_state and n_exc_stack
|
||||
// - code_state->n_state should be set to the state size (locals plus stack)
|
||||
void mp_setup_code_state(mp_code_state *code_state, mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
void mp_setup_code_state(mp_code_state_t *code_state, mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
// This function is pretty complicated. It's main aim is to be efficient in speed and RAM
|
||||
// usage for the common case of positional only args.
|
||||
size_t n_state = code_state->n_state;
|
||||
|
|
14
py/bc.h
14
py/bc.h
|
@ -60,7 +60,7 @@
|
|||
// constN : obj
|
||||
|
||||
// Exception stack entry
|
||||
typedef struct _mp_exc_stack {
|
||||
typedef struct _mp_exc_stack_t {
|
||||
const byte *handler;
|
||||
// bit 0 is saved currently_in_except_block value
|
||||
// bit 1 is whether the opcode was SETUP_WITH or SETUP_FINALLY
|
||||
|
@ -69,7 +69,7 @@ typedef struct _mp_exc_stack {
|
|||
mp_obj_base_t *prev_exc;
|
||||
} mp_exc_stack_t;
|
||||
|
||||
typedef struct _mp_code_state {
|
||||
typedef struct _mp_code_state_t {
|
||||
const byte *code_info;
|
||||
const byte *ip;
|
||||
const mp_uint_t *const_table;
|
||||
|
@ -78,21 +78,21 @@ typedef struct _mp_code_state {
|
|||
mp_exc_stack_t *exc_sp;
|
||||
mp_obj_dict_t *old_globals;
|
||||
#if MICROPY_STACKLESS
|
||||
struct _mp_code_state *prev;
|
||||
struct _mp_code_state_t *prev;
|
||||
#endif
|
||||
size_t n_state;
|
||||
// Variable-length
|
||||
mp_obj_t state[0];
|
||||
// Variable-length, never accessed by name, only as (void*)(state + n_state)
|
||||
//mp_exc_stack_t exc_state[0];
|
||||
} mp_code_state;
|
||||
} mp_code_state_t;
|
||||
|
||||
mp_uint_t mp_decode_uint(const byte **ptr);
|
||||
|
||||
mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_obj_t inject_exc);
|
||||
mp_code_state *mp_obj_fun_bc_prepare_codestate(mp_obj_t func, size_t n_args, size_t n_kw, const mp_obj_t *args);
|
||||
mp_vm_return_kind_t mp_execute_bytecode(mp_code_state_t *code_state, volatile mp_obj_t inject_exc);
|
||||
mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t func, size_t n_args, size_t n_kw, const mp_obj_t *args);
|
||||
struct _mp_obj_fun_bc_t;
|
||||
void mp_setup_code_state(mp_code_state *code_state, struct _mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args);
|
||||
void mp_setup_code_state(mp_code_state_t *code_state, struct _mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args);
|
||||
void mp_bytecode_print(const void *descr, const byte *code, mp_uint_t len, const mp_uint_t *const_table);
|
||||
void mp_bytecode_print2(const byte *code, mp_uint_t len);
|
||||
const byte *mp_bytecode_print_str(const byte *ip);
|
||||
|
|
|
@ -1200,6 +1200,11 @@ STATIC void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns)
|
|||
}
|
||||
|
||||
STATIC void compile_assert_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
||||
// with optimisations enabled we don't compile assertions
|
||||
if (MP_STATE_VM(mp_optimise_value) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint l_end = comp_next_label(comp);
|
||||
c_if_cond(comp, pns->nodes[0], true, l_end);
|
||||
EMIT_LOAD_GLOBAL(MP_QSTR_AssertionError); // we load_global instead of load_id, to be consistent with CPython
|
||||
|
|
|
@ -348,12 +348,10 @@ mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader) {
|
|||
byte header[4];
|
||||
read_bytes(reader, header, sizeof(header));
|
||||
if (strncmp((char*)header, "M\x00", 2) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
|
||||
"invalid .mpy file"));
|
||||
mp_raise_ValueError("invalid .mpy file");
|
||||
}
|
||||
if (header[2] != MPY_FEATURE_FLAGS || header[3] > mp_small_int_bits()) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
|
||||
"incompatible .mpy file"));
|
||||
mp_raise_ValueError("incompatible .mpy file");
|
||||
}
|
||||
return load_raw_code(reader);
|
||||
}
|
||||
|
@ -559,8 +557,7 @@ STATIC void save_bytecode_qstrs(mp_print_t *print, const byte *ip, const byte *i
|
|||
|
||||
STATIC void save_raw_code(mp_print_t *print, mp_raw_code_t *rc) {
|
||||
if (rc->kind != MP_CODE_BYTECODE) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
|
||||
"can only save bytecode"));
|
||||
mp_raise_ValueError("can only save bytecode");
|
||||
}
|
||||
|
||||
// save bytecode
|
||||
|
|
|
@ -628,7 +628,7 @@ STATIC void emit_post_push_reg(emit_t *emit, vtype_kind_t vtype, int reg);
|
|||
STATIC void emit_native_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num);
|
||||
STATIC void emit_native_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num);
|
||||
|
||||
#define STATE_START (sizeof(mp_code_state) / sizeof(mp_uint_t))
|
||||
#define STATE_START (sizeof(mp_code_state_t) / sizeof(mp_uint_t))
|
||||
|
||||
STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
|
||||
DEBUG_printf("start_pass(pass=%u, scope=%p)\n", pass, scope);
|
||||
|
@ -775,10 +775,10 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
|
|||
|
||||
// set code_state.ip (offset from start of this function to prelude info)
|
||||
// XXX this encoding may change size
|
||||
ASM_MOV_IMM_TO_LOCAL_USING(emit->as, emit->prelude_offset, offsetof(mp_code_state, ip) / sizeof(mp_uint_t), REG_ARG_1);
|
||||
ASM_MOV_IMM_TO_LOCAL_USING(emit->as, emit->prelude_offset, offsetof(mp_code_state_t, ip) / sizeof(mp_uint_t), REG_ARG_1);
|
||||
|
||||
// set code_state.n_state
|
||||
ASM_MOV_IMM_TO_LOCAL_USING(emit->as, emit->n_state, offsetof(mp_code_state, n_state) / sizeof(mp_uint_t), REG_ARG_1);
|
||||
ASM_MOV_IMM_TO_LOCAL_USING(emit->as, emit->n_state, offsetof(mp_code_state_t, n_state) / sizeof(mp_uint_t), REG_ARG_1);
|
||||
|
||||
// put address of code_state into first arg
|
||||
ASM_MOV_LOCAL_ADDR_TO_REG(emit->as, 0, REG_ARG_1);
|
||||
|
|
10
py/gc.c
10
py/gc.c
|
@ -480,12 +480,17 @@ found:
|
|||
|
||||
GC_EXIT();
|
||||
|
||||
#if MICROPY_GC_CONSERVATIVE_CLEAR
|
||||
// be conservative and zero out all the newly allocated blocks
|
||||
memset((byte*)ret_ptr, 0, (end_block - start_block + 1) * BYTES_PER_BLOCK);
|
||||
#else
|
||||
// zero out the additional bytes of the newly allocated blocks
|
||||
// This is needed because the blocks may have previously held pointers
|
||||
// to the heap and will not be set to something else if the caller
|
||||
// doesn't actually use the entire block. As such they will continue
|
||||
// to point to the heap and may prevent other blocks from being reclaimed.
|
||||
memset((byte*)ret_ptr + n_bytes, 0, (end_block - start_block + 1) * BYTES_PER_BLOCK - n_bytes);
|
||||
#endif
|
||||
|
||||
#if MICROPY_ENABLE_FINALISER
|
||||
if (has_finaliser) {
|
||||
|
@ -713,8 +718,13 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) {
|
|||
|
||||
GC_EXIT();
|
||||
|
||||
#if MICROPY_GC_CONSERVATIVE_CLEAR
|
||||
// be conservative and zero out all the newly allocated blocks
|
||||
memset((byte*)ptr_in + n_blocks * BYTES_PER_BLOCK, 0, (new_blocks - n_blocks) * BYTES_PER_BLOCK);
|
||||
#else
|
||||
// zero out the additional bytes of the newly allocated blocks (see comment above in gc_alloc)
|
||||
memset((byte*)ptr_in + n_bytes, 0, new_blocks * BYTES_PER_BLOCK - n_bytes);
|
||||
#endif
|
||||
|
||||
#if EXTENSIVE_HEAP_PROFILING
|
||||
gc_dump_alloc_table();
|
||||
|
|
|
@ -14,11 +14,13 @@ import sys
|
|||
# - codepoint2name lives in a different module
|
||||
import platform
|
||||
if platform.python_version_tuple()[0] == '2':
|
||||
ord_bytes = ord
|
||||
bytes_cons = lambda val, enc=None: bytearray(val)
|
||||
from htmlentitydefs import codepoint2name
|
||||
elif platform.python_version_tuple()[0] == '3':
|
||||
ord_bytes = lambda x:x
|
||||
bytes_cons = bytes
|
||||
from html.entities import codepoint2name
|
||||
# end compatibility code
|
||||
|
||||
codepoint2name[ord('-')] = 'hyphen';
|
||||
|
||||
# add some custom names to map characters that aren't in HTML
|
||||
|
@ -52,8 +54,8 @@ codepoint2name[ord('~')] = 'tilde'
|
|||
# this must match the equivalent function in qstr.c
|
||||
def compute_hash(qstr, bytes_hash):
|
||||
hash = 5381
|
||||
for char in qstr:
|
||||
hash = (hash * 33) ^ ord(char)
|
||||
for b in qstr:
|
||||
hash = (hash * 33) ^ b
|
||||
# Make sure that valid hash is never zero, zero means "hash not computed"
|
||||
return (hash & ((1 << (8 * bytes_hash)) - 1)) or 1
|
||||
|
||||
|
@ -115,16 +117,15 @@ def parse_input_headers(infiles):
|
|||
return qcfgs, qstrs
|
||||
|
||||
def make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr):
|
||||
qhash = compute_hash(qstr, cfg_bytes_hash)
|
||||
qbytes = bytes_cons(qstr, 'utf8')
|
||||
qlen = len(qbytes)
|
||||
qhash = compute_hash(qbytes, cfg_bytes_hash)
|
||||
if all(32 <= ord(c) <= 126 and c != '\\' and c != '"' for c in qstr):
|
||||
# qstr is all printable ASCII so render it as-is (for easier debugging)
|
||||
qlen = len(qstr)
|
||||
qdata = qstr
|
||||
else:
|
||||
# qstr contains non-printable codes so render entire thing as hex pairs
|
||||
qbytes = qstr.encode('utf8')
|
||||
qlen = len(qbytes)
|
||||
qdata = ''.join(('\\x%02x' % ord_bytes(b)) for b in qbytes)
|
||||
qdata = ''.join(('\\x%02x' % b) for b in qbytes)
|
||||
if qlen >= (1 << (8 * cfg_bytes_len)):
|
||||
print('qstr is too long:', qstr)
|
||||
assert False
|
||||
|
|
|
@ -117,7 +117,10 @@ void *m_malloc0(size_t num_bytes) {
|
|||
if (ptr == NULL && num_bytes != 0) {
|
||||
return m_malloc_fail(num_bytes);
|
||||
}
|
||||
// If this config is set then the GC clears all memory, so we don't need to.
|
||||
#if !MICROPY_GC_CONSERVATIVE_CLEAR
|
||||
memset(ptr, 0, num_bytes);
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,8 +123,9 @@ clean-prog:
|
|||
.PHONY: clean-prog
|
||||
endif
|
||||
|
||||
lib: $(OBJ)
|
||||
$(AR) rcs libmicropython.a $^
|
||||
LIBMICROPYTHON = libmicropython.a
|
||||
lib $(LIBMICROPYTHON): $(OBJ)
|
||||
$(AR) rcs $(LIBMICROPYTHON) $^
|
||||
|
||||
clean:
|
||||
$(RM) -rf $(BUILD) $(CLEAN_EXTRA)
|
||||
|
|
|
@ -114,7 +114,7 @@ STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
|
|||
mp_uint_t align;
|
||||
size_t sz = mp_binary_get_size(fmt_type, *fmt, &align);
|
||||
if (sz == 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "unsupported format"));
|
||||
mp_raise_ValueError("unsupported format");
|
||||
}
|
||||
while (cnt--) {
|
||||
// Apply alignment
|
||||
|
@ -149,7 +149,7 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) {
|
|||
// negative offsets are relative to the end of the buffer
|
||||
offset = bufinfo.len + offset;
|
||||
if (offset < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "buffer too small"));
|
||||
mp_raise_ValueError("buffer too small");
|
||||
}
|
||||
}
|
||||
p += offset;
|
||||
|
@ -164,7 +164,7 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) {
|
|||
sz = get_fmt_num(&fmt);
|
||||
}
|
||||
if (p + sz > end_p) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "buffer too small"));
|
||||
mp_raise_ValueError("buffer too small");
|
||||
}
|
||||
mp_obj_t item;
|
||||
if (*fmt == 's') {
|
||||
|
@ -197,7 +197,7 @@ STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, byte* end_p, siz
|
|||
sz = get_fmt_num(&fmt);
|
||||
}
|
||||
if (p + sz > end_p) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "buffer too small"));
|
||||
mp_raise_ValueError("buffer too small");
|
||||
}
|
||||
|
||||
if (*fmt == 's') {
|
||||
|
@ -240,7 +240,7 @@ STATIC mp_obj_t struct_pack_into(size_t n_args, const mp_obj_t *args) {
|
|||
// negative offsets are relative to the end of the buffer
|
||||
offset = (mp_int_t)bufinfo.len + offset;
|
||||
if (offset < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "buffer too small"));
|
||||
mp_raise_ValueError("buffer too small");
|
||||
}
|
||||
}
|
||||
byte *p = (byte *)bufinfo.buf;
|
||||
|
|
|
@ -107,6 +107,15 @@
|
|||
#define MICROPY_ALLOC_GC_STACK_SIZE (64)
|
||||
#endif
|
||||
|
||||
// Be conservative and always clear to zero newly (re)allocated memory in the GC.
|
||||
// This helps eliminate stray pointers that hold on to memory that's no longer
|
||||
// used. It decreases performance due to unnecessary memory clearing.
|
||||
// TODO Do analysis to understand why some memory is not properly cleared and
|
||||
// find a more efficient way to clear it.
|
||||
#ifndef MICROPY_GC_CONSERVATIVE_CLEAR
|
||||
#define MICROPY_GC_CONSERVATIVE_CLEAR (1)
|
||||
#endif
|
||||
|
||||
// Support automatic GC when reaching allocation threshold,
|
||||
// configurable by gc.threshold().
|
||||
#ifndef MICROPY_GC_ALLOC_THRESHOLD
|
||||
|
@ -887,6 +896,11 @@ typedef double mp_float_t;
|
|||
#define MICROPY_PY_UBINASCII (0)
|
||||
#endif
|
||||
|
||||
// Depends on MICROPY_PY_UZLIB
|
||||
#ifndef MICROPY_PY_UBINASCII_CRC32
|
||||
#define MICROPY_PY_UBINASCII_CRC32 (0)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_URANDOM
|
||||
#define MICROPY_PY_URANDOM (0)
|
||||
#endif
|
||||
|
@ -909,6 +923,10 @@ typedef double mp_float_t;
|
|||
#define MICROPY_PY_MACHINE_I2C (0)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_MACHINE_SPI
|
||||
#define MICROPY_PY_MACHINE_SPI (0)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_USSL
|
||||
#define MICROPY_PY_USSL (0)
|
||||
#endif
|
||||
|
|
|
@ -537,10 +537,12 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
|
|||
chrs += mp_print_int(print, arg_value, *fmt == 'd', 10, 'a', flags, fill, width);
|
||||
break;
|
||||
}
|
||||
// fall through to default case to print unknown format char
|
||||
assert(!"unsupported fmt char");
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
// if it's not %% then it's an unsupported format character
|
||||
assert(*fmt == '%' || !"unsupported fmt char");
|
||||
print->print_strn(print->data, fmt, 1);
|
||||
chrs += 1;
|
||||
break;
|
||||
|
|
14
py/objfun.c
14
py/objfun.c
|
@ -165,7 +165,7 @@ STATIC void dump_args(const mp_obj_t *a, mp_uint_t sz) {
|
|||
#define VM_DETECT_STACK_OVERFLOW (0)
|
||||
|
||||
#if MICROPY_STACKLESS
|
||||
mp_code_state *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
MP_STACK_CHECK();
|
||||
mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
|
@ -178,8 +178,8 @@ mp_code_state *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args,
|
|||
|
||||
// allocate state for locals and stack
|
||||
size_t state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t);
|
||||
mp_code_state *code_state;
|
||||
code_state = m_new_obj_var_maybe(mp_code_state, byte, state_size);
|
||||
mp_code_state_t *code_state;
|
||||
code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size);
|
||||
if (!code_state) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -220,12 +220,12 @@ 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
|
||||
mp_uint_t state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t);
|
||||
mp_code_state *code_state = NULL;
|
||||
mp_code_state_t *code_state = NULL;
|
||||
if (state_size > VM_MAX_STATE_ON_STACK) {
|
||||
code_state = m_new_obj_var_maybe(mp_code_state, byte, state_size);
|
||||
code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size);
|
||||
}
|
||||
if (code_state == NULL) {
|
||||
code_state = alloca(sizeof(mp_code_state) + state_size);
|
||||
code_state = alloca(sizeof(mp_code_state_t) + state_size);
|
||||
state_size = 0; // indicate that we allocated using alloca
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
|
|||
|
||||
// free the state if it was allocated on the heap
|
||||
if (state_size != 0) {
|
||||
m_del_var(mp_code_state, byte, state_size, code_state);
|
||||
m_del_var(mp_code_state_t, byte, state_size, code_state);
|
||||
}
|
||||
|
||||
if (vm_return_kind == MP_VM_RETURN_NORMAL) {
|
||||
|
|
|
@ -46,7 +46,7 @@ typedef struct _mp_obj_gen_wrap_t {
|
|||
typedef struct _mp_obj_gen_instance_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_dict_t *globals;
|
||||
mp_code_state code_state;
|
||||
mp_code_state_t code_state;
|
||||
} mp_obj_gen_instance_t;
|
||||
|
||||
STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
|
|
|
@ -158,6 +158,9 @@ mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
|
|||
if (MP_OBJ_IS_TYPE(args[0], &mp_type_bytes)) {
|
||||
GET_STR_DATA_LEN(args[0], str_data, str_len);
|
||||
GET_STR_HASH(args[0], str_hash);
|
||||
if (str_hash == 0) {
|
||||
str_hash = qstr_compute_hash(str_data, str_len);
|
||||
}
|
||||
mp_obj_str_t *o = MP_OBJ_TO_PTR(mp_obj_new_str_of_type(type, NULL, str_len));
|
||||
o->data = str_data;
|
||||
o->hash = str_hash;
|
||||
|
@ -191,6 +194,9 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size
|
|||
}
|
||||
GET_STR_DATA_LEN(args[0], str_data, str_len);
|
||||
GET_STR_HASH(args[0], str_hash);
|
||||
if (str_hash == 0) {
|
||||
str_hash = qstr_compute_hash(str_data, str_len);
|
||||
}
|
||||
mp_obj_str_t *o = MP_OBJ_TO_PTR(mp_obj_new_str_of_type(&mp_type_bytes, NULL, str_len));
|
||||
o->data = str_data;
|
||||
o->hash = str_hash;
|
||||
|
|
|
@ -39,6 +39,7 @@ typedef struct _mp_obj_str_t {
|
|||
#define MP_DEFINE_STR_OBJ(obj_name, str) mp_obj_str_t obj_name = {{&mp_type_str}, 0, sizeof(str) - 1, (const byte*)str}
|
||||
|
||||
// use this macro to extract the string hash
|
||||
// warning: the hash can be 0, meaning invalid, and must then be explicitly computed from the data
|
||||
#define GET_STR_HASH(str_obj_in, str_hash) \
|
||||
mp_uint_t str_hash; if (MP_OBJ_IS_QSTR(str_obj_in)) \
|
||||
{ str_hash = qstr_hash(MP_OBJ_QSTR_VALUE(str_obj_in)); } else { str_hash = ((mp_obj_str_t*)MP_OBJ_TO_PTR(str_obj_in))->hash; }
|
||||
|
|
1
py/py.mk
1
py/py.mk
|
@ -208,6 +208,7 @@ PY_O_BASENAME = \
|
|||
../extmod/machine_pinbase.o \
|
||||
../extmod/machine_pulse.o \
|
||||
../extmod/machine_i2c.o \
|
||||
../extmod/machine_spi.o \
|
||||
../extmod/modussl_axtls.o \
|
||||
../extmod/modurandom.o \
|
||||
../extmod/modwebsocket.o \
|
||||
|
|
|
@ -217,6 +217,10 @@ mp_obj_t mp_unary_op(mp_uint_t op, mp_obj_t arg) {
|
|||
} else if (op == MP_UNARY_OP_HASH && MP_OBJ_IS_STR_OR_BYTES(arg)) {
|
||||
// fast path for hashing str/bytes
|
||||
GET_STR_HASH(arg, h);
|
||||
if (h == 0) {
|
||||
GET_STR_DATA_LEN(arg, data, len);
|
||||
h = qstr_compute_hash(data, len);
|
||||
}
|
||||
return MP_OBJ_NEW_SMALL_INT(h);
|
||||
} else {
|
||||
mp_obj_type_t *type = mp_obj_get_type(arg);
|
||||
|
|
10
py/vm.c
10
py/vm.c
|
@ -127,7 +127,7 @@ typedef enum {
|
|||
// MP_VM_RETURN_NORMAL, sp valid, return value in *sp
|
||||
// MP_VM_RETURN_YIELD, ip, sp valid, yielded value in *sp
|
||||
// MP_VM_RETURN_EXCEPTION, exception in fastn[0]
|
||||
mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_obj_t inject_exc) {
|
||||
mp_vm_return_kind_t mp_execute_bytecode(mp_code_state_t *code_state, volatile mp_obj_t inject_exc) {
|
||||
#define SELECTIVE_EXC_IP (0)
|
||||
#if SELECTIVE_EXC_IP
|
||||
#define MARK_EXC_IP_SELECTIVE() { code_state->ip = ip; } /* stores ip 1 byte past last opcode */
|
||||
|
@ -904,7 +904,7 @@ unwind_jump:;
|
|||
code_state->ip = ip;
|
||||
code_state->sp = sp;
|
||||
code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block);
|
||||
mp_code_state *new_state = mp_obj_fun_bc_prepare_codestate(*sp, unum & 0xff, (unum >> 8) & 0xff, sp + 1);
|
||||
mp_code_state_t *new_state = mp_obj_fun_bc_prepare_codestate(*sp, unum & 0xff, (unum >> 8) & 0xff, sp + 1);
|
||||
if (new_state) {
|
||||
new_state->prev = code_state;
|
||||
code_state = new_state;
|
||||
|
@ -940,7 +940,7 @@ unwind_jump:;
|
|||
mp_call_args_t out_args;
|
||||
mp_call_prepare_args_n_kw_var(false, unum, sp, &out_args);
|
||||
|
||||
mp_code_state *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
|
||||
mp_code_state_t *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
|
||||
out_args.n_args, out_args.n_kw, out_args.args);
|
||||
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
|
||||
if (new_state) {
|
||||
|
@ -976,7 +976,7 @@ unwind_jump:;
|
|||
mp_uint_t n_kw = (unum >> 8) & 0xff;
|
||||
int adjust = (sp[1] == MP_OBJ_NULL) ? 0 : 1;
|
||||
|
||||
mp_code_state *new_state = mp_obj_fun_bc_prepare_codestate(*sp, n_args + adjust, n_kw, sp + 2 - adjust);
|
||||
mp_code_state_t *new_state = mp_obj_fun_bc_prepare_codestate(*sp, n_args + adjust, n_kw, sp + 2 - adjust);
|
||||
if (new_state) {
|
||||
new_state->prev = code_state;
|
||||
code_state = new_state;
|
||||
|
@ -1011,7 +1011,7 @@ unwind_jump:;
|
|||
mp_call_args_t out_args;
|
||||
mp_call_prepare_args_n_kw_var(true, unum, sp, &out_args);
|
||||
|
||||
mp_code_state *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
|
||||
mp_code_state_t *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
|
||||
out_args.n_args, out_args.n_kw, out_args.args);
|
||||
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
|
||||
if (new_state) {
|
||||
|
|
|
@ -284,7 +284,7 @@ endif
|
|||
ifneq ($(FROZEN_MPY_DIR),)
|
||||
# To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and
|
||||
# then invoke make with FROZEN_MPY_DIR=frozen (be sure to build from scratch).
|
||||
FROZEN_MPY_PY_FILES := $(shell find $(FROZEN_MPY_DIR)/ -type f -name '*.py')
|
||||
FROZEN_MPY_PY_FILES := $(shell find $(FROZEN_MPY_DIR) -type f -name '*.py')
|
||||
FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy))
|
||||
CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool
|
||||
CFLAGS += -DMICROPY_MODULE_FROZEN_MPY
|
||||
|
|
25
stmhal/adc.c
25
stmhal/adc.c
|
@ -54,7 +54,16 @@
|
|||
#define ADCx (ADC1)
|
||||
#define ADCx_CLK_ENABLE __ADC1_CLK_ENABLE
|
||||
#define ADC_NUM_CHANNELS (19)
|
||||
#define ADC_NUM_GPIO_CHANNELS (16)
|
||||
|
||||
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
|
||||
#define ADC_FIRST_GPIO_CHANNEL (0)
|
||||
#define ADC_LAST_GPIO_CHANNEL (15)
|
||||
#elif defined(MCU_SERIES_L4)
|
||||
#define ADC_FIRST_GPIO_CHANNEL (1)
|
||||
#define ADC_LAST_GPIO_CHANNEL (16)
|
||||
#else
|
||||
#error Unsupported processor
|
||||
#endif
|
||||
|
||||
#if defined(STM32F405xx) || defined(STM32F415xx) || \
|
||||
defined(STM32F407xx) || defined(STM32F417xx) || \
|
||||
|
@ -124,7 +133,7 @@ STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (adc_obj->channel < ADC_NUM_GPIO_CHANNELS) {
|
||||
if (ADC_FIRST_GPIO_CHANNEL <= adc_obj->channel && adc_obj->channel <= ADC_LAST_GPIO_CHANNEL) {
|
||||
// Channels 0-16 correspond to real pins. Configure the GPIO pin in
|
||||
// ADC mode.
|
||||
const pin_obj_t *pin = pin_adc1[adc_obj->channel];
|
||||
|
@ -253,8 +262,14 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uin
|
|||
if (!is_adcx_channel(channel)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "not a valid ADC Channel: %d", channel));
|
||||
}
|
||||
if (pin_adc1[channel] == NULL) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "channel %d not available on this board", channel));
|
||||
|
||||
|
||||
if (ADC_FIRST_GPIO_CHANNEL <= channel && channel <= ADC_LAST_GPIO_CHANNEL) {
|
||||
// these channels correspond to physical GPIO ports so make sure they exist
|
||||
if (pin_adc1[channel] == NULL) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
||||
"channel %d not available on this board", channel));
|
||||
}
|
||||
}
|
||||
|
||||
pyb_obj_adc_t *o = m_new_obj(pyb_obj_adc_t);
|
||||
|
@ -423,7 +438,7 @@ void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution) {
|
|||
"resolution %d not supported", resolution));
|
||||
}
|
||||
|
||||
for (uint32_t channel = 0; channel < ADC_NUM_GPIO_CHANNELS; channel++) {
|
||||
for (uint32_t channel = ADC_FIRST_GPIO_CHANNEL; channel <= ADC_LAST_GPIO_CHANNEL; ++channel) {
|
||||
// Channels 0-16 correspond to real pins. Configure the GPIO pin in
|
||||
// ADC mode.
|
||||
const pin_obj_t *pin = pin_adc1[channel];
|
||||
|
|
|
@ -303,7 +303,9 @@ class Pins(object):
|
|||
def print_adc(self, adc_num):
|
||||
print('');
|
||||
print('const pin_obj_t * const pin_adc{:d}[] = {{'.format(adc_num))
|
||||
for channel in range(16):
|
||||
for channel in range(17):
|
||||
if channel == 16:
|
||||
print('#if defined(MCU_SERIES_L4)')
|
||||
adc_found = False
|
||||
for named_pin in self.cpu_pins:
|
||||
pin = named_pin.pin()
|
||||
|
@ -314,6 +316,8 @@ class Pins(object):
|
|||
break
|
||||
if not adc_found:
|
||||
print(' NULL, // {:d}'.format(channel))
|
||||
if channel == 16:
|
||||
print('#endif')
|
||||
print('};')
|
||||
|
||||
|
||||
|
|
|
@ -137,8 +137,8 @@ static const char fresh_boot_py[] =
|
|||
"import machine\r\n"
|
||||
"import pyb\r\n"
|
||||
"#pyb.main('main.py') # main script to run after this one\r\n"
|
||||
"#pyb.usb_mode('CDC+MSC') # act as a serial and a storage device\r\n"
|
||||
"#pyb.usb_mode('CDC+HID') # act as a serial device and a mouse\r\n"
|
||||
"#pyb.usb_mode('VCP+MSC') # act as a serial and a storage device\r\n"
|
||||
"#pyb.usb_mode('VCP+HID') # act as a serial device and a mouse\r\n"
|
||||
;
|
||||
|
||||
static const char fresh_main_py[] =
|
||||
|
|
|
@ -83,6 +83,7 @@ STATIC mp_obj_t socket_close(mp_obj_t self_in) {
|
|||
mod_network_socket_obj_t *self = self_in;
|
||||
if (self->nic != MP_OBJ_NULL) {
|
||||
self->nic_type->close(self);
|
||||
self->nic = MP_OBJ_NULL;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
#define MICROPY_PY_UHASHLIB (1)
|
||||
#define MICROPY_PY_MACHINE (1)
|
||||
#define MICROPY_PY_MACHINE_I2C (1)
|
||||
#define MICROPY_PY_MACHINE_SPI (1)
|
||||
#define MICROPY_PY_FRAMEBUF (1)
|
||||
|
||||
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
|
||||
|
|
|
@ -199,15 +199,15 @@ STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
|
|||
if (mode == GPIO_MODE_INPUT) {
|
||||
mode_qst = MP_QSTR_IN;
|
||||
} else if (mode == GPIO_MODE_OUTPUT_PP) {
|
||||
mode_qst = MP_QSTR_OUT_PP;
|
||||
mode_qst = MP_QSTR_OUT;
|
||||
} else if (mode == GPIO_MODE_OUTPUT_OD) {
|
||||
mode_qst = MP_QSTR_OUT_OD;
|
||||
mode_qst = MP_QSTR_OPEN_DRAIN;
|
||||
} else {
|
||||
af = true;
|
||||
if (mode == GPIO_MODE_AF_PP) {
|
||||
mode_qst = MP_QSTR_AF_PP;
|
||||
mode_qst = MP_QSTR_ALT;
|
||||
} else {
|
||||
mode_qst = MP_QSTR_AF_OD;
|
||||
mode_qst = MP_QSTR_ALT_OPEN_DRAIN;
|
||||
}
|
||||
}
|
||||
mp_print_str(print, qstr_str(mode_qst));
|
||||
|
|
171
stmhal/spi.c
171
stmhal/spi.c
|
@ -30,6 +30,7 @@
|
|||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/machine_spi.h"
|
||||
#include "irq.h"
|
||||
#include "pin.h"
|
||||
#include "genhdr/pins.h"
|
||||
|
@ -327,6 +328,90 @@ STATIC HAL_StatusTypeDef spi_wait_dma_finished(SPI_HandleTypeDef *spi, uint32_t
|
|||
return HAL_OK;
|
||||
}
|
||||
|
||||
STATIC void spi_transfer(mp_obj_base_t *self_in, size_t src_len, const uint8_t *src_buf, size_t dest_len, uint8_t *dest_buf, uint32_t timeout) {
|
||||
// Note: there seems to be a problem sending 1 byte using DMA the first
|
||||
// time directly after the SPI/DMA is initialised. The cause of this is
|
||||
// unknown but we sidestep the issue by using polling for 1 byte transfer.
|
||||
|
||||
pyb_spi_obj_t *self = (pyb_spi_obj_t*)self_in;
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
if (dest_len == 0) {
|
||||
// send only
|
||||
if (src_len == 1 || query_irq() == IRQ_STATE_DISABLED) {
|
||||
status = HAL_SPI_Transmit(self->spi, (uint8_t*)src_buf, src_len, timeout);
|
||||
} else {
|
||||
DMA_HandleTypeDef tx_dma;
|
||||
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
|
||||
self->spi->hdmatx = &tx_dma;
|
||||
self->spi->hdmarx = NULL;
|
||||
status = HAL_SPI_Transmit_DMA(self->spi, (uint8_t*)src_buf, src_len);
|
||||
if (status == HAL_OK) {
|
||||
status = spi_wait_dma_finished(self->spi, timeout);
|
||||
}
|
||||
dma_deinit(self->tx_dma_descr);
|
||||
}
|
||||
} else if (src_len == 0) {
|
||||
// receive only
|
||||
if (dest_len == 1 || query_irq() == IRQ_STATE_DISABLED) {
|
||||
status = HAL_SPI_Receive(self->spi, dest_buf, dest_len, timeout);
|
||||
} else {
|
||||
DMA_HandleTypeDef tx_dma, rx_dma;
|
||||
if (self->spi->Init.Mode == SPI_MODE_MASTER) {
|
||||
// in master mode the HAL actually does a TransmitReceive call
|
||||
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
|
||||
self->spi->hdmatx = &tx_dma;
|
||||
} else {
|
||||
self->spi->hdmatx = NULL;
|
||||
}
|
||||
dma_init(&rx_dma, self->rx_dma_descr, self->spi);
|
||||
self->spi->hdmarx = &rx_dma;
|
||||
|
||||
status = HAL_SPI_Receive_DMA(self->spi, dest_buf, dest_len);
|
||||
if (status == HAL_OK) {
|
||||
status = spi_wait_dma_finished(self->spi, timeout);
|
||||
}
|
||||
if (self->spi->hdmatx != NULL) {
|
||||
dma_deinit(self->tx_dma_descr);
|
||||
}
|
||||
dma_deinit(self->rx_dma_descr);
|
||||
}
|
||||
} else {
|
||||
// send and receive
|
||||
// requires src_len==dest_len
|
||||
if (src_len == 1 || query_irq() == IRQ_STATE_DISABLED) {
|
||||
status = HAL_SPI_TransmitReceive(self->spi, (uint8_t*)src_buf, dest_buf, src_len, timeout);
|
||||
} else {
|
||||
DMA_HandleTypeDef tx_dma, rx_dma;
|
||||
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
|
||||
self->spi->hdmatx = &tx_dma;
|
||||
dma_init(&rx_dma, self->rx_dma_descr, self->spi);
|
||||
self->spi->hdmarx = &rx_dma;
|
||||
status = HAL_SPI_TransmitReceive_DMA(self->spi, (uint8_t*)src_buf, dest_buf, src_len);
|
||||
if (status == HAL_OK) {
|
||||
status = spi_wait_dma_finished(self->spi, timeout);
|
||||
}
|
||||
dma_deinit(self->tx_dma_descr);
|
||||
dma_deinit(self->rx_dma_descr);
|
||||
}
|
||||
}
|
||||
|
||||
if (status != HAL_OK) {
|
||||
mp_hal_raise(status);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void spi_transfer_machine(mp_obj_base_t *self_in, size_t src_len, const uint8_t *src_buf, size_t dest_len, uint8_t *dest_buf) {
|
||||
if (src_len == 1 && dest_len > 1) {
|
||||
// this catches read and readinto
|
||||
// copy the single output byte to the dest buffer and use that as source
|
||||
memset(dest_buf, src_buf[0], dest_len);
|
||||
src_len = dest_len;
|
||||
src_buf = dest_buf;
|
||||
}
|
||||
spi_transfer(self_in, src_len, src_buf, dest_len, dest_buf, 100);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
|
@ -556,27 +641,7 @@ STATIC mp_obj_t pyb_spi_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
|
|||
pyb_buf_get_for_send(args[0].u_obj, &bufinfo, data);
|
||||
|
||||
// send the data
|
||||
// Note: there seems to be a problem sending 1 byte using DMA the first
|
||||
// time directly after the SPI/DMA is initialised. The cause of this is
|
||||
// unknown but we sidestep the issue by using polling for 1 byte transfer.
|
||||
HAL_StatusTypeDef status;
|
||||
if (bufinfo.len == 1 || query_irq() == IRQ_STATE_DISABLED) {
|
||||
status = HAL_SPI_Transmit(self->spi, bufinfo.buf, bufinfo.len, args[1].u_int);
|
||||
} else {
|
||||
DMA_HandleTypeDef tx_dma;
|
||||
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
|
||||
self->spi->hdmatx = &tx_dma;
|
||||
self->spi->hdmarx = NULL;
|
||||
status = HAL_SPI_Transmit_DMA(self->spi, bufinfo.buf, bufinfo.len);
|
||||
if (status == HAL_OK) {
|
||||
status = spi_wait_dma_finished(self->spi, args[1].u_int);
|
||||
}
|
||||
dma_deinit(self->tx_dma_descr);
|
||||
}
|
||||
|
||||
if (status != HAL_OK) {
|
||||
mp_hal_raise(status);
|
||||
}
|
||||
spi_transfer((mp_obj_base_t*)self, bufinfo.len, bufinfo.buf, 0, NULL, args[1].u_int);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
@ -610,34 +675,7 @@ STATIC mp_obj_t pyb_spi_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
|
|||
mp_obj_t o_ret = pyb_buf_get_for_recv(args[0].u_obj, &vstr);
|
||||
|
||||
// receive the data
|
||||
HAL_StatusTypeDef status;
|
||||
if (vstr.len == 1 || query_irq() == IRQ_STATE_DISABLED) {
|
||||
status = HAL_SPI_Receive(self->spi, (uint8_t*)vstr.buf, vstr.len, args[1].u_int);
|
||||
} else {
|
||||
DMA_HandleTypeDef tx_dma, rx_dma;
|
||||
if (self->spi->Init.Mode == SPI_MODE_MASTER) {
|
||||
// in master mode the HAL actually does a TransmitReceive call
|
||||
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
|
||||
self->spi->hdmatx = &tx_dma;
|
||||
} else {
|
||||
self->spi->hdmatx = NULL;
|
||||
}
|
||||
dma_init(&rx_dma, self->rx_dma_descr, self->spi);
|
||||
self->spi->hdmarx = &rx_dma;
|
||||
|
||||
status = HAL_SPI_Receive_DMA(self->spi, (uint8_t*)vstr.buf, vstr.len);
|
||||
if (status == HAL_OK) {
|
||||
status = spi_wait_dma_finished(self->spi, args[1].u_int);
|
||||
}
|
||||
if (self->spi->hdmatx != NULL) {
|
||||
dma_deinit(self->tx_dma_descr);
|
||||
}
|
||||
dma_deinit(self->rx_dma_descr);
|
||||
}
|
||||
|
||||
if (status != HAL_OK) {
|
||||
mp_hal_raise(status);
|
||||
}
|
||||
spi_transfer((mp_obj_base_t*)self, 0, NULL, vstr.len, (uint8_t*)vstr.buf, args[1].u_int);
|
||||
|
||||
// return the received data
|
||||
if (o_ret != MP_OBJ_NULL) {
|
||||
|
@ -706,27 +744,8 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp
|
|||
}
|
||||
}
|
||||
|
||||
// send and receive the data
|
||||
HAL_StatusTypeDef status;
|
||||
if (bufinfo_send.len == 1 || query_irq() == IRQ_STATE_DISABLED) {
|
||||
status = HAL_SPI_TransmitReceive(self->spi, bufinfo_send.buf, bufinfo_recv.buf, bufinfo_send.len, args[2].u_int);
|
||||
} else {
|
||||
DMA_HandleTypeDef tx_dma, rx_dma;
|
||||
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
|
||||
self->spi->hdmatx = &tx_dma;
|
||||
dma_init(&rx_dma, self->rx_dma_descr, self->spi);
|
||||
self->spi->hdmarx = &rx_dma;
|
||||
status = HAL_SPI_TransmitReceive_DMA(self->spi, bufinfo_send.buf, bufinfo_recv.buf, bufinfo_send.len);
|
||||
if (status == HAL_OK) {
|
||||
status = spi_wait_dma_finished(self->spi, args[2].u_int);
|
||||
}
|
||||
dma_deinit(self->tx_dma_descr);
|
||||
dma_deinit(self->rx_dma_descr);
|
||||
}
|
||||
|
||||
if (status != HAL_OK) {
|
||||
mp_hal_raise(status);
|
||||
}
|
||||
// do the transfer
|
||||
spi_transfer((mp_obj_base_t*)self, bufinfo_send.len, bufinfo_send.buf, bufinfo_recv.len, bufinfo_recv.buf, args[2].u_int);
|
||||
|
||||
// return the received data
|
||||
if (o_ret != MP_OBJ_NULL) {
|
||||
|
@ -741,6 +760,13 @@ STATIC const mp_map_elem_t pyb_spi_locals_dict_table[] = {
|
|||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_spi_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_spi_deinit_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_machine_spi_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_machine_spi_readinto_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_machine_spi_write_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write_readinto), (mp_obj_t)&mp_machine_spi_write_readinto_obj },
|
||||
|
||||
// legacy methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_spi_send_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_spi_recv_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_send_recv), (mp_obj_t)&pyb_spi_send_recv_obj },
|
||||
|
@ -766,10 +792,15 @@ STATIC const mp_map_elem_t pyb_spi_locals_dict_table[] = {
|
|||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_spi_locals_dict, pyb_spi_locals_dict_table);
|
||||
|
||||
STATIC const mp_machine_spi_p_t pyb_spi_p = {
|
||||
.transfer = spi_transfer_machine,
|
||||
};
|
||||
|
||||
const mp_obj_type_t pyb_spi_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_SPI,
|
||||
.print = pyb_spi_print,
|
||||
.make_new = pyb_spi_make_new,
|
||||
.protocol = &pyb_spi_p,
|
||||
.locals_dict = (mp_obj_t)&pyb_spi_locals_dict,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# cmdline: -O
|
||||
# test optimisation output
|
||||
print(__debug__)
|
||||
assert 0
|
|
@ -0,0 +1 @@
|
|||
False
|
|
@ -0,0 +1,20 @@
|
|||
try:
|
||||
import ubinascii as binascii
|
||||
except ImportError:
|
||||
import binascii
|
||||
try:
|
||||
binascii.crc32
|
||||
except AttributeError:
|
||||
print("SKIP")
|
||||
import sys
|
||||
sys.exit()
|
||||
|
||||
print(hex(binascii.crc32(b'The quick brown fox jumps over the lazy dog')))
|
||||
print(hex(binascii.crc32(b'\x00' * 32)))
|
||||
print(hex(binascii.crc32(b'\xff' * 32)))
|
||||
print(hex(binascii.crc32(bytes(range(32)))))
|
||||
|
||||
print(hex(binascii.crc32(b' over the lazy dog', binascii.crc32(b'The quick brown fox jumps'))))
|
||||
print(hex(binascii.crc32(b'\x00' * 16, binascii.crc32(b'\x00' * 16))))
|
||||
print(hex(binascii.crc32(b'\xff' * 16, binascii.crc32(b'\xff' * 16))))
|
||||
print(hex(binascii.crc32(bytes(range(16, 32)), binascii.crc32(bytes(range(16))))))
|
|
@ -0,0 +1,19 @@
|
|||
try:
|
||||
import zlib
|
||||
except ImportError:
|
||||
import uzlib as zlib
|
||||
import uio as io
|
||||
|
||||
|
||||
# Raw DEFLATE bitstream
|
||||
buf = io.BytesIO(b'\xcbH\xcd\xc9\xc9\x07\x00')
|
||||
inp = zlib.DecompIO(buf)
|
||||
print(buf.seek(0, 1))
|
||||
print(inp.read(1))
|
||||
print(buf.seek(0, 1))
|
||||
print(inp.read(2))
|
||||
print(inp.read())
|
||||
print(buf.seek(0, 1))
|
||||
print(inp.read(1))
|
||||
print(inp.read())
|
||||
print(buf.seek(0, 1))
|
|
@ -0,0 +1,9 @@
|
|||
0
|
||||
b'h'
|
||||
2
|
||||
b'el'
|
||||
b'lo'
|
||||
7
|
||||
b''
|
||||
b''
|
||||
7
|
|
@ -1,5 +1,6 @@
|
|||
import sys
|
||||
import uos
|
||||
import uerrno
|
||||
try:
|
||||
uos.VfsFat
|
||||
except AttributeError:
|
||||
|
@ -84,3 +85,15 @@ assert vfs.listdir() == ["sub_file.txt"]
|
|||
|
||||
vfs.chdir("..")
|
||||
print("getcwd:", vfs.getcwd())
|
||||
|
||||
|
||||
vfs.umount()
|
||||
try:
|
||||
vfs.listdir()
|
||||
except OSError as e:
|
||||
assert e.args[0] == uerrno.ENODEV
|
||||
else:
|
||||
raise AssertionError("expected OSError not thrown")
|
||||
|
||||
vfs = uos.VfsFat(bdev, "/ramdisk")
|
||||
assert vfs.listdir() == ['foo_dir', 'moved-to-root.txt']
|
||||
|
|
|
@ -200,7 +200,9 @@ def run_tests(pyb, tests, args):
|
|||
# Some tests shouldn't be run under Travis CI
|
||||
if os.getenv('TRAVIS') == 'true':
|
||||
skip_tests.add('basics/memoryerror.py')
|
||||
skip_tests.add('thread/thread_gc1.py') # has reliability issues
|
||||
skip_tests.add('thread/thread_lock4.py') # has reliability issues
|
||||
skip_tests.add('thread/stress_heap.py') # has reliability issues
|
||||
|
||||
if not has_complex:
|
||||
skip_tests.add('float/complex1.py')
|
||||
|
|
|
@ -5,4 +5,11 @@ except NameError:
|
|||
import sys
|
||||
sys.exit()
|
||||
|
||||
extra_coverage()
|
||||
data = extra_coverage()
|
||||
|
||||
# test hashing of str/bytes that have an invalid hash
|
||||
print(data)
|
||||
print(hash(data[0]))
|
||||
print(hash(data[1]))
|
||||
print(hash(bytes(data[0], 'utf8')))
|
||||
print(hash(str(data[1], 'utf8')))
|
||||
|
|
|
@ -7,7 +7,6 @@ ab abc
|
|||
|
||||
false true
|
||||
(null)
|
||||
t
|
||||
-2147483648
|
||||
2147483648
|
||||
80000000
|
||||
|
@ -36,3 +35,8 @@ ementation
|
|||
12345678
|
||||
0
|
||||
0
|
||||
('0123456789', b'0123456789')
|
||||
7300
|
||||
7300
|
||||
7300
|
||||
7300
|
||||
|
|
|
@ -283,15 +283,15 @@ class RawCode:
|
|||
# generate constant objects
|
||||
for i, obj in enumerate(self.objs):
|
||||
obj_name = 'const_obj_%s_%u' % (self.escaped_name, i)
|
||||
if is_str_type(obj):
|
||||
obj = bytes_cons(obj, 'utf8')
|
||||
print('STATIC const mp_obj_str_t %s = '
|
||||
'{{&mp_type_str}, 0, %u, (const byte*)"%s"};'
|
||||
% (obj_name, len(obj), ''.join(('\\x%02x' % b) for b in obj)))
|
||||
elif is_bytes_type(obj):
|
||||
print('STATIC const mp_obj_str_t %s = '
|
||||
'{{&mp_type_bytes}, 0, %u, (const byte*)"%s"};'
|
||||
% (obj_name, len(obj), ''.join(('\\x%02x' % b) for b in obj)))
|
||||
if is_str_type(obj) or is_bytes_type(obj):
|
||||
if is_str_type(obj):
|
||||
obj = bytes_cons(obj, 'utf8')
|
||||
obj_type = 'mp_type_str'
|
||||
else:
|
||||
obj_type = 'mp_type_bytes'
|
||||
print('STATIC const mp_obj_str_t %s = {{&%s}, %u, %u, (const byte*)"%s"};'
|
||||
% (obj_name, obj_type, qstrutil.compute_hash(obj, config.MICROPY_QSTR_BYTES_IN_HASH),
|
||||
len(obj), ''.join(('\\x%02x' % b) for b in obj)))
|
||||
elif is_int_type(obj):
|
||||
if config.MICROPY_LONGINT_IMPL == config.MICROPY_LONGINT_IMPL_NONE:
|
||||
# TODO check if we can actually fit this long-int into a small-int
|
||||
|
@ -320,6 +320,9 @@ class RawCode:
|
|||
print('STATIC const mp_obj_float_t %s = {{&mp_type_float}, %.16g};'
|
||||
% (obj_name, obj))
|
||||
print('#endif')
|
||||
elif type(obj) is complex:
|
||||
print('STATIC const mp_obj_complex_t %s = {{&mp_type_complex}, %.16g, %.16g};'
|
||||
% (obj_name, obj.real, obj.imag))
|
||||
else:
|
||||
# TODO
|
||||
raise FreezeError(self, 'freezing of object %r is not implemented' % (obj,))
|
||||
|
@ -444,10 +447,7 @@ def dump_mpy(raw_codes):
|
|||
for rc in raw_codes:
|
||||
rc.dump()
|
||||
|
||||
def freeze_mpy(qcfgs, base_qstrs, raw_codes):
|
||||
cfg_bytes_len = int(qcfgs['BYTES_IN_LEN'])
|
||||
cfg_bytes_hash = int(qcfgs['BYTES_IN_HASH'])
|
||||
|
||||
def freeze_mpy(base_qstrs, raw_codes):
|
||||
# add to qstrs
|
||||
new = {}
|
||||
for q in global_qstrs:
|
||||
|
@ -488,6 +488,15 @@ def freeze_mpy(qcfgs, base_qstrs, raw_codes):
|
|||
print('#endif')
|
||||
print()
|
||||
|
||||
print('#if MICROPY_PY_BUILTINS_COMPLEX')
|
||||
print('typedef struct _mp_obj_complex_t {')
|
||||
print(' mp_obj_base_t base;')
|
||||
print(' mp_float_t real;')
|
||||
print(' mp_float_t imag;')
|
||||
print('} mp_obj_complex_t;')
|
||||
print('#endif')
|
||||
print()
|
||||
|
||||
print('enum {')
|
||||
for i in range(len(new)):
|
||||
if i == 0:
|
||||
|
@ -505,7 +514,8 @@ def freeze_mpy(qcfgs, base_qstrs, raw_codes):
|
|||
print(' %u, // used entries' % len(new))
|
||||
print(' {')
|
||||
for _, _, qstr in new:
|
||||
print(' %s,' % qstrutil.make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr))
|
||||
print(' %s,'
|
||||
% qstrutil.make_bytes(config.MICROPY_QSTR_BYTES_IN_LEN, config.MICROPY_QSTR_BYTES_IN_HASH, qstr))
|
||||
print(' },')
|
||||
print('};')
|
||||
|
||||
|
@ -549,10 +559,15 @@ def main():
|
|||
}[args.mlongint_impl]
|
||||
config.MPZ_DIG_SIZE = args.mmpz_dig_size
|
||||
|
||||
# set config values for qstrs, and get the existing base set of qstrs
|
||||
if args.qstr_header:
|
||||
qcfgs, base_qstrs = qstrutil.parse_input_headers([args.qstr_header])
|
||||
config.MICROPY_QSTR_BYTES_IN_LEN = int(qcfgs['BYTES_IN_LEN'])
|
||||
config.MICROPY_QSTR_BYTES_IN_HASH = int(qcfgs['BYTES_IN_HASH'])
|
||||
else:
|
||||
qcfgs, base_qstrs = {'BYTES_IN_LEN':1, 'BYTES_IN_HASH':1}, {}
|
||||
config.MICROPY_QSTR_BYTES_IN_LEN = 1
|
||||
config.MICROPY_QSTR_BYTES_IN_HASH = 1
|
||||
base_qstrs = {}
|
||||
|
||||
raw_codes = [read_mpy(file) for file in args.files]
|
||||
|
||||
|
@ -560,7 +575,7 @@ def main():
|
|||
dump_mpy(raw_codes)
|
||||
elif args.freeze:
|
||||
try:
|
||||
freeze_mpy(qcfgs, base_qstrs, raw_codes)
|
||||
freeze_mpy(base_qstrs, raw_codes)
|
||||
except FreezeError as er:
|
||||
print(er, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
|
|
@ -183,7 +183,7 @@ ifneq ($(FROZEN_MPY_DIR),)
|
|||
# then invoke make with FROZEN_MPY_DIR=frozen (be sure to build from scratch).
|
||||
MPY_CROSS = ../mpy-cross/mpy-cross
|
||||
MPY_TOOL = ../tools/mpy-tool.py
|
||||
FROZEN_MPY_PY_FILES := $(shell find $(FROZEN_MPY_DIR)/ -type f -name '*.py')
|
||||
FROZEN_MPY_PY_FILES := $(shell find $(FROZEN_MPY_DIR) -type f -name '*.py')
|
||||
FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy))
|
||||
CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool
|
||||
CFLAGS += -DMICROPY_MODULE_FROZEN_MPY
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/mpz.h"
|
||||
|
||||
#if defined(MICROPY_UNIX_COVERAGE)
|
||||
|
||||
// str/bytes objects without a valid hash
|
||||
STATIC const mp_obj_str_t str_no_hash_obj = {{&mp_type_str}, 0, 10, (const byte*)"0123456789"};
|
||||
STATIC const mp_obj_str_t bytes_no_hash_obj = {{&mp_type_bytes}, 0, 10, (const byte*)"0123456789"};
|
||||
|
||||
// function to run extra tests for things that can't be checked by scripts
|
||||
STATIC mp_obj_t extra_coverage(void) {
|
||||
// mp_printf (used by ports that don't have a native printf)
|
||||
{
|
||||
mp_printf(&mp_plat_print, "# mp_printf\n");
|
||||
mp_printf(&mp_plat_print, "%"); // nothing after percent
|
||||
mp_printf(&mp_plat_print, "%d %+d % d\n", -123, 123, 123); // sign
|
||||
mp_printf(&mp_plat_print, "%05d\n", -123); // negative number with zero padding
|
||||
mp_printf(&mp_plat_print, "%ld\n", 123); // long
|
||||
|
@ -21,7 +25,6 @@ STATIC mp_obj_t extra_coverage(void) {
|
|||
mp_printf(&mp_plat_print, "%.*s\n", -1, "abc"); // negative string precision
|
||||
mp_printf(&mp_plat_print, "%b %b\n", 0, 1); // bools
|
||||
mp_printf(&mp_plat_print, "%s\n", NULL); // null string
|
||||
mp_printf(&mp_plat_print, "%t\n"); // non-format char
|
||||
mp_printf(&mp_plat_print, "%d\n", 0x80000000); // should print signed
|
||||
mp_printf(&mp_plat_print, "%u\n", 0x80000000); // should print unsigned
|
||||
mp_printf(&mp_plat_print, "%x\n", 0x80000000); // should print unsigned
|
||||
|
@ -111,7 +114,9 @@ STATIC mp_obj_t extra_coverage(void) {
|
|||
mp_printf(&mp_plat_print, "%d\n", mpz_as_uint_checked(&mpz, &value));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
// return a tuple of data for testing on the Python side
|
||||
mp_obj_t items[] = {(mp_obj_t)&str_no_hash_obj, (mp_obj_t)&bytes_no_hash_obj};
|
||||
return mp_obj_new_tuple(MP_ARRAY_SIZE(items), items);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(extra_coverage_obj, extra_coverage);
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@
|
|||
#define MICROPY_PY_UHASHLIB_SHA1 (1)
|
||||
#endif
|
||||
#define MICROPY_PY_UBINASCII (1)
|
||||
#define MICROPY_PY_UBINASCII_CRC32 (1)
|
||||
#define MICROPY_PY_URANDOM (1)
|
||||
#ifndef MICROPY_PY_USELECT
|
||||
#define MICROPY_PY_USELECT (1)
|
||||
|
|
Loading…
Reference in New Issue