Unverified Commit bbac9d4b authored by Earle F. Philhower, III's avatar Earle F. Philhower, III Committed by GitHub

Add full-fledged documentation, update I2S API (#80)

Last step before 1.0. Docs for readthedocs.io.

Update the I2S API to mimic others where `setXXX` is called before
`begin()` to set the GPIO pins used.
parent 84a9273b
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = Arduino-Pico
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
Analog I/O
==========
Analog Input
------------
For analog inputs, the RP2040 device has a 12-bit, 4-channel ADC +
temperature sensor available on a fixed set of pins (A0...A3).
The standard Arduino calls can be used to read their values (with
3.3V nominally reading as 4095).
int analogRead(pin_size_t pin = A0..A3)
---------------------------------------
Returns a value from 0...4095 correspionding to the ADC reading
of the specific pin.
float analogReadTemp()
----------------------
Returns the temperature, in Celsius, of the onboard thermal sensor.
This reading is not exceedingly accurate and of relatively low
resolution, so it is not a replacement for an external temperature
sensor in many cases.
Analog Outputs
--------------
The RP2040 does not have any onboard DACs, so analog outputs are
simulated using the standard method of using pulse width modulation
(PWM) using the RP20400's hardware PWM units.
While up to 16 PWM channels can be generated, they are not independent
and there are significant restrictions as to allowed pins in parallel.
See the [RP2040 datasheet](https://datasheets.raspberrypi.org/rp2040/rp2040-datasheet.pdf)
for full details.
void analogWriteFreq(uint32_t freq)
-----------------------------------
Sets the master PWM frequency used (i.e. how often the PWM output cycles).
From 100Hz to 60KHz are supported.
}
void analogWriteRange(uint32_t range) and analogWriteResolution(int res)
------------------------------------------------------------------------
These calls set the maximum PWM value (i.e. writing this value will result in
a PWM duty cycle of 100%)/ either explicitly (range) or as a power-of-two
(res). A range of 16 to 65535 is supported.
void analogWrite(pin_size_t pin, int val)
-----------------------------------------
Writes a PWM value to a specific pin. The PWM machine is enabled and set to
the requested frequency and scale, and the output is generated. This will
continue until a `digitalWrite` or other digital output is performed.
# -*- coding: utf-8 -*-
#
# Arduino-Pico documentation build configuration file, created by
# sphinx-quickstart on Sat Apr 3 15:02:21 2021.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Arduino-Pico'
copyright = u'2021, Earle F. Philhower, III'
author = u'Earle F. Philhower, III'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = u'1.0.0'
# The full version, including alpha/beta/rc tags.
release = u'1.0.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# This is required for the alabaster theme
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
html_sidebars = {
'**': [
'relations.html', # needs 'show_related': True theme option to display
'searchbox.html',
]
}
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'Arduino-Picodoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'Arduino-Pico.tex', u'Arduino-Pico Documentation',
u'Earle F. Philhower, III', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'arduino-pico', u'Arduino-Pico Documentation',
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'Arduino-Pico', u'Arduino-Pico Documentation',
author, 'Arduino-Pico', 'One line description of project.',
'Miscellaneous'),
]
Digital I/O
===========
The Raspberry Pi Pico RP2040 chip supports up to 30 digital I/O pins,
however not all boards provide access to all pins.
EEPROM Library
==============
While the Raspberry Pi Pico RP2040 does not come with an EEPROM onboard, we
simulate one by using a single 4K chunk of flash at the end of flash space.
**Note that this is a simulated EEPROM and will only support the numeber of
writes as the onboard flash chip, not the 100,000 or so of a real EEPROM.**
Therefore, do not frequently update the EEPROM or you may prematurely wear
out the flash.
EEPROM.begin(size=256...4096)
-----------------------------
Call before the first use of the EEPROM data for read or write. It makes a
copy of the emulated EEPROM sector in RAM to allow random update and access.
EEPROM.read(addr), EEPROM[addr]
-------------------------------
Returns the data at a specific offset in the EEPROM. See `EEPROM.get` later
for a more
EEPROM.write(addr, data), EEPROM[addr] = data
---------------------------------------------
Writes a byte of data at the offset specified. Not persisted to flash until
`EEPROM.commit()` is called.
EEPROM.commit()
---------------
Writes the updated data to flash, so next reboot it will be readable.
EEPROM.end()
------------
`EEPROM.commit()` and frees all memory used. Need to call `EEPROM.begin()`
before the EEPROM can be used again.
EEPROM.get(addr, val)
---------------------
Copies the (potentially multi-byte) data in EEPROM at the specific byte
offset into the returned value. Useful for reading structures from EEPROM.
EEPROM.put(addr, val)
---------------------
Copies the (potentially multi-byte) value into EEPROM a the byte offset
supplied. Useful for storing `struct` in EEPROM. Note that any pointers
inside a written structure will not be valid, and that most C++ objects
like `String` cannot be written to EEPROM this way because of it.
EEPROM.length()
---------------
Returns the length of the EEPROM (i.e. the value specified in
`EEPROM.begin()` ).
EEPROM Examples
---------------
Three EEPROM [examples](https://github.com/earlephilhower/arduino-pico/tree/master/libraries/EEPROM) are included.
This diff is collapsed.
Getting Help and Contributing
=============================
This is a community supported project and has multiple ways to get assistance.
Posting complete details, in a polite and organized way will get the best
response.
For bugs in the Core, or to submit patches, please use the
[GitHub Issues](https://github.com/earlephilhower/arduino-pico/issues) or
[GitHub Pull Requests](https://github.com/earlephilhower/arduino-pico/pulls)
For general questions/discussions use either [GitHub Discussions](https://github.com/earlephilhower/arduino-pico/discussions)
or live-chat with [gitter](https://gitter.im/arduino-pico/community)
I2S (Digital Audio) Output Library
==================================
While the RP2040 chip on the Raspberry Pi Pico does not include a hardware
I2S device, it is possible to use the PIO (Programmable I/O) state machines
to implement one dynamically.
This I2S library uses the `pico-extras` I2S audio library and wraps it in
an Arduino I2S library. It supports 16 bits/sample and frequencies of up
to 48kHZ, with configurable BCLK, LRCLK(always pin "BCLK + 1"), and DOUT pins.
**Note:** This I2S device takes over the entire PIO1 (second) unit and adjusts
its clock frequency to meet the I2S needs. That means when only 4 Tones
or only 4 Servos may be used when the I2S device is used.
bool setBCLK(pin_size_t pin)
----------------------------
Sets the BCLK pin of the I2S device. The LRCLK/word clock will be `pin + 1`
due to limitations of the PIO state machines. Call this before `I2S.begin()`
Default BCLK = 26, LRCLK = 27
bool setDOUT(pin_size_t pin)
----------------------------
Sets the DOUT pin of the I2S device. Any pin may be used. Default DOUT = 28
Call before `I2S.begin()`
bool begin(long sampleRate)
---------------------------
Start the I2S device up with the given sample rate. The pins selected above
will be turned to output and the I2S will begin to drive silence frames (all
zero) out.
void end()
----------
Stops the I2S device. **Note, at present the memory allocated for I2S buffers
is not freed leading to a memory leak when `end()` is called. This is due
to the state of the `pico-extras` release from thich this device came.**
void flush()
------------
Sends any partial frames in memory to the I2S output device. They may NOT play
immediately. Potential use case for this call would be when the frequency of
the output will be changing.
size_t write(uint8_t)
---------------------
Provided for compatibilty, but not very useful. Writes a sample from 0...255
to the I2S buffer. See `write(int16_t)` for a better one
size_t write(const uint8_t \*buffer, size_t size)
-------------------------------------------------
Transfers number of bytes from an application buffer to the I2S output buffer.
Be aware that `size` is in *bytes** and not samples. Size must be a multiple
of **4 bytes** (i.e. one left/right sample). Will not block, so check
the return value to find out how many bytes were actually written.
int availableForWrite()
-----------------------
Returns the number of **32-bit L/R samples** that can be written without
potentially blocking.
bool setFrequency(int newFreq)
------------------------------
Adjusts the I2S output frequency. When changing frequency while I2S output
is underway, be sure to use `I2S.flush()` before changing the frequency to
ensure the older data is played at the right frequency.
size_t write(int16_t)
---------------------
Writes a single 16-bit left or right sample to the I2S output buffer. The
user is required to ensure that an even number of samples is written (i.e.
left and right) over the application lifetime. The application also needs
to track which sample is next to be written (right/left). For this reason,
the `write(void *b, size_t lrsamples)` call may be easier and faster to use.
size_t write(const void \*buffer, size_t lrsamples)
---------------------------------------------------
Writes up to size left+right packed samples to the I2S device. Non-blocking,
will writefrom 0...size samples and return that count. Be sure your app
handles partial writes (i.e. by yield()ing and then retrying to write the
remaining data.)
The `onTransmit` callback is not supported.
See the [ESP8266Audio](https://github.com/earlephilhower/ESP8266Audio) library
for a working example, or look at the included sample tone generator.
IDE Menus
=========
Model
-----
Use the boards menu to select your model of RP2040 board. There will be two
options: `Boardname` and `Boardname (Picoprobe)`. If you want to use a
Picoprobe to upload your sketches and not the default automatic UF2 upload,
use the `(Picoprobe)` option, otherwise use the normal name. No functional
or code changes are done because of this.
There is also a `Generic` board which allows you to individually select
things such as flash size or boot2 flash type. Use this if your board isn't
yet fully supported and isn't working with the normal `Raspberry Pi Pico`
option.
Flash Size
----------
Arduino-Pico supports onboard filesystems which will set aside some of the
flash on your board for the filesystem, shrinking the maximum code size
allowed. Use this menu to select the desired ratio of filesystem to sketch.
CPU Speed
---------
While it is unsupported, the Raspberry Pi Pico RP2040 can often run much
faster than the stock 125MHz. Use the `CPU Speed` menu to select a
desired over or underclock speed. **If the sketch fails at the higher
speed, hold the BOOTSEL while plugging it in to enter update mode and try
a lower overclock.**
Debug Port and Debug Level
--------------------------
Debug messages from `printf` and the Core can be printed to a Serial port
to allow for easier debugging. Select the desired port and verbosity.
Selecting a port for debug output does not stop a sketch from using it
for normal operations.
Arduino-Pico
============
This is the documentation for the Raspberry Pi Pico Arduino core,
Arduino-Pico. Arduino-Pico is a community port of the RP2040
(Raspberry Pi Pico processor) to the Arduino ecosystem, intended
to make it easier and more fun to use and program the Raspberry Pi
Pico / RP2040 based boards.
This Arduino core uses a custom toolset with GCC 10.2 and Newlib 4.0.0
and doesn't require any system-installed prerequisites.
For the latest version, always check https://github.com/earlephilhower/arduino-pico
.. toctree::
:maxdepth: 2
:caption: Contents:
Getting Help and Contributing <help>
Installation <install>
Using the IDE <ide>
Pin (Re)Assignment <pins>
Analog I/O <analog>
Digital I/O <digital>
EEPROM <eeprom>
I2S Audio <i2s>
Serial USB and UARTs <serial>
Servo <servo>
SPI <spi>
Wire(I2C) <wire>
File Systems (SD, SDFS, LittleFS) <fs>
Ported/Optimized Libraries <libraries>
Using Pico-SDK <sdk>
Licenses <license>
Indices and Tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
Intallation
===========
The Arduino-Pico core can be installed using the Arduino IDE Boards Manager
or using `git`. If you want to simply write programs for your RP2040 board,
the Boards Manager installation will suffice, but if you want to try the
latest pre-release versions and submit improvements, you will need the `git`
instllation.
Installing via Arduino Boards Manager
-------------------------------------
**Note for Windows Users**: Please do not use the Windows Store version of
the actual Arduino application because it has issues detecting attached Pico
boards. Use the "Windows ZIP" or plain "Windows" executable (EXE) download
direct from https://arduino.cc. and allow it to install any device drivers
it suggests. Otherwise the Pico board may not be detected. Also, if trying
out the 2.0 beta Arduino please install the release 1.8 version beforehand
to ensure needed device drivers are present.
1. Open up the Arduino IDE and go to File->Preferences.
2. In the dialog that pops up, enter the following URL in the "Additional Boards Manager URLs" field: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
.. image:: images/install1.png
3. Hit OK to close the dialog.
4. Go to Tools->Boards->Board Manager in the IDE
5. Type "pico" in the search box and select "Add":
.. image:: images/install2.png
Installing via GIT
------------------
To install via GIT (for latest and greatest versions):
.. code:: bash
mkdir -p ~/Arduino/hardware/pico
git clone https://github.com/earlephilhower/arduino-pico.git ~/Arduino/hardware/pico/rp2040
cd ~/Arduino/hardware/pico/rp2040
git submodule update --init
cd pico-sdk
git submodule update --init
cd pico-extras
git submodule update --init
cd ../tools
python3 ./get.py
Installing both Arduino and CMake
---------------------------------
Tom's Hardware presented a very nice writeup on installing `arduino-pico` on
both Windows and Linux, available at [Tom's Hardware](https://www.tomshardware.com/how-to/program-raspberry-pi-pico-with-arduino-ide)
If you follow their step-by-step you will also have a fully functional
`CMake`-based environment to build Pico apps on if you outgrow the Arduino
ecosystem.
Uploading Sketches
To upload your first sketch, you will need to hold the BOOTSEL button down while plugging in the Pico to your computer.
Then hit the upload button and the sketch should be transferred and start to run.
After the first upload, this should not be necessary as the `arduino-pico` core has auto-reset support.
Select the appropriate serial port shown in the Arduino Tools->Port->Serial Port menu once (this setting will stick and does not need to be
touched for multiple uploads). This selection allows the auto-reset tool to identify the proper device to reset.
Them hit the upload button and your sketch should upload and run.
In some cases the Pico will encounter a hard hang and its USB port will not respond to the auto-reset request. Should this happen, just
follow the initial procedure of holding the BOOTSEL button down while plugging in the Pico to enter the ROM bootloader.
# Uploading Filesystem Images
The onboard flash filesystem for the Pico, LittleFS, lets you upload a filesystem image from the sketch directory for your sketch to use. Download the needed plugin from
* https://github.com/earlephilhower/arduino-pico-littlefs-plugin/releases
To install, follow the directions in
* https://github.com/earlephilhower/arduino-pico-littlefs-plugin/blob/master/README.md
For detailed usage information, please check the ESP8266 repo documentation (ignore SPIFFS related notes) available at
* https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html
# Uploading Sketches with Picoprobe
If you have built a Raspberry Pi Picoprobe, you can use OpenOCD to handle your sketch uploads and for debugging with GDB.
Under Windows a local admin user should be able to access the Picoprobe port automatically, but under Linux `udev` must be told about the device and to allow normal users access.
To set up user-level access to Picoprobes on Ubuntu (and other OSes which use `udev`):
.. code::
echo 'SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", GROUP="users", MODE="0666"' | sudo tee -a /etc/udev/rules.d/98-PicoProbe.rules
sudo udevadm control --reload
The first line creates a file with the USB vendor and ID of the Picoprobe and tells UDEV to give users full access to it. The second causes `udev` to load this new rule. Note that you will need to unplug and re-plug in your device the first time you create this file, to allow udev to make the device node properly.
Once Picoprobe permissions are set up properly, then select the board "Raspberry Pi Pico (Picoprobe)" in the Tools menu and upload as normal.
# Debugging with Picoprobe, OpenOCD, and GDB
The installed tools include a version of OpenOCD (in the pqt-openocd directory) and GDB (in the pqt-gcc directory). These may be used to run GDB in an interactive window as documented in the Pico Getting Started manuals from the Raspberry Pi Foundation.
Libraries Ported/Optimizef for the RP2040
=========================================
Most Arduino libraries that work on modern 32-bit CPU based Arduino boards
will run fine using Arduino-Pico.
The following libraries have undergone additional porting and optimizations
specifically for the RP2040 and you should consider using them instead of
the generic versions available in the Library Manager
* [Adafruit GFX Library](https://github.com/Bodmer/Adafruit-GFX-Library) by @Bodmer, 2-20x faster than the standard version on the Pico
* [Adafruit ILI9341 Library](https://github.com/Bodmer/Adafruit_ILI9341), again by @Bodmer
* [ESP8266Audio](https://github.com/earlephilhower/ESP8266Audio), ported to use the included `I2S` library
Licensing and Credits
=====================
Arduino-Pico is licensed under the LGPL license as detailed in the included README.
In addition, it contains code from additional open source projects:
* The [Arduino IDE and ArduinoCore-API](https://arduino.cc) are developed and maintained by the Arduino team. The IDE is licensed under GPL.
* The [RP2040 GCC-based toolchain](https://github.com/earlephilhower/pico-quick-toolchain) is licensed under under the GPL.
* The [Pico-SDK](https://github.com/raspberrypi/pico-sdk) and [Pico-Extras](https://github.com/raspberrypi/pico-extras) are by Raspberry Pi (Trading) Ltd and licensed under the BSD 3-Clause license.
* [Arduino-Pico](https://github.com/earlephilhower/arduino-pico) core files are licenses under the LGPL.
* [LittleFS](https://github.com/ARMmbed/littlefs) library written by ARM Limited and released under the [BSD 3-clause license](https://github.com/ARMmbed/littlefs/blob/master/LICENSE.md).
* [UF2CONV.PY](https://github.com/microsoft/uf2) is by Microsoft Corporatio and licensed under the MIT license.
* Some filesystem code taken from the [ESP8266 Arduino Core](https://github.com/esp8266/Arduino) and licensed under the LGPL.
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
set SPHINXPROJ=Arduino-Pico
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd
Pin Assignments
===============
The Raspberry Pi Pico has an incredibly flexible I/O configuration and most
built-in peripherals (except for the ADC) can be used on multiple sets of
pins. Note, however, that not all peripherals can use all I/Os. Refer to
the RP2040 datasheet or an online pinout diagram for more details.
Additional methods have been added to allow you to select a peripheral's
I/O pins **before calling ::begin**. This is especially helpful when
using third party libraries: the library doesn't need to be modified,
only your own code in `setup()` is needed to adjust pinouts.
I2S:
----
.. code:: cpp
::setBCLK(pin)
::setDOUT(pin)
Serial1 (UART0), Serial2 (UART1):
---------------------------------
.. code:: cpp
::setRX(pin)
::setTX(pin)
SPI (SPI0), SPI1 (SPI1):
------------------------
.. code:: cpp
::setSCK(pin)
::setRX(pin)
::setTX(pin)
Wire (I2C0), Wire1 (I2C1):
--------------------------
.. code:: cpp
::setSDA(pin)
::setSCL(pin)
For example, because the `SD` library uses the `SPI` library, we can make
it use a non-default pinout with a simple call
.. code:: cpp
void setup() {
SPI.setRX(4);
SPI.setTX(7);
SPI.setSCK(6);
SPI.setCS(5);
SD.begin(5);
}
Using the Raspberry Pi Pico SDK (PICO-SDK)
==========================================
A complete copy of the [Raspberry Pi Pico SDK](https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdf)
is included with the Arduino core, and all functions in the core are available
inside the standard link libraries.
For simple programs wishing to call these functions, simply include the
appropriate header as shown below
.. code:: cpp
#include "pico/stdlib.h"
void setup() {
const uint LED_PIN = 25;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (true) {
gpio_put(LED_PIN, 1);
sleep_ms(250);
gpio_put(LED_PIN, 0);
sleep_ms(250);
}
}
void loop() {}
**Note:** When you call SDK functions in your own app, the core and
libraries are not aware of any changes to the Pico you perform. So,
you may break the functionality of certain libraries in doing so.
**Warning:** While you may spawn multicore applications on CORE1
using the SDK, the Arduino core may have issues running properly with
them. In particular, anything involving flash writes (i.e. EEPROM,
filesystems) will probably crash due to CORE1 attempting to read from
flash while CORE0 is writing to it.
Serial Ports (USB and UART)
===========================
The Arduino-Pico core implements a software-based Serial-over-USB port
using the USB ACM-CDC model to support a wide variety of operating
systems.
`Serial` is the USB serial port, and while `Serial.begin()` doea allow
specifying a baud rate, this rate is ignored since it is USB-based.
(Also be aware that this USB `Serial` port is responsible for resetting
the RP2040 during the upload process, following the Arduino standard
of 1200bps = reset to bootloader).
The RP2040 provides two hardware-based UARTS with configurable
pin selection.
`Serial1` is UART0, and `Serial2` is UART1.
Configure their pins using the `setXXX` calls prior to calling `begin()`
.. code:: cpp
Serial1.setRX(pin);
Serial1.setTX(pin);
Serial1.begin(baud);
For detailed information about the Serial ports, see the
Arduino [Serial reference](https://www.arduino.cc/reference/en/language/functions/communication/serial/)
Servo Library
=============
A hardware-based servo controller is provided using the `Servo` library.
It utilizes the PIO state machines and generates the appropriate servo
control pulses, glitch-free and jitter-free (within crystal limits).
Up to 8 Servos can be controlled in parallel assuming no other tasks
require the use of a PIO machine.
See the Arduino standard [Servo documentation](https://www.arduino.cc/reference/en/libraries/servo/)
for detailed usage instructions. There is also an included `sweep` example.
SPI (Serial Peripheral Interface)
=================================
The RP2040 has two hardware SPI interfaces, `spi0 (SPI)` and `spi1 (SPI1)`.
These interfaces are supported by the `SPI` library in master mode.
SPI pinouts can be set **before SPI.begin()** using the following calls:
.. code:: cpp
bool setRX(pin_size_t pin);
bool setCS(pin_size_t pin);
bool setSCK(pin_size_t pin);
bool setTX(pin_size_t pin);
Note that the `CS` pin can be hardware or software controlled by the sketch.
When software controlled, the `setCS()` call is ignored.
The [Arduino SPI documention](https://www.arduino.cc/en/reference/SPI) gives
a detailed overview of the library, except for the following RP2040-specific
changes:
* `SPI.begin(bool hwCS)` can take an options `hwCS` parameter.
By passing in `true` for `hwCS` the sketch does not need to worry about
asserting and deasserting the `CS` pin between transactions. The default
is `false` and requires the sketch to handle the CS pin itself, as is the
standard way in Arduino.
* The interrupt calls (`usingInterrupt`, `notUsingInterrupt`,
`attachInterrupt`, and `detachInterrpt`) are not implemented.
Wire (I2C Master and Slave)
===========================
The RP2040 has two I2C devices, `i2c0 (Wire)` and `i2c1 (Wire1)`
The current implementation is compatible with the Arduino standard
with the addition of two calls to allof the `SDA` and `SCL` pins
to be set **before calling Wire.begin()**
.. code:: cpp
bool setSDA(pin_size_t sda);
bool setSCL(pin_size_t scl);
Both master and slave operation is supported.
Master transmissions are buffered (up to 128 bytes) and only performed
on `endTransmission`, as is standard with modern Arduino Wire implementations.
For more detailed information, check the [Arduino Wire documentation.](https://www.arduino.cc/en/reference/wire)
......@@ -27,9 +27,25 @@ I2SClass::I2SClass() {
_curBuff = nullptr;
_bps = 0;
_writtenHalf = false;
_pinBCLK = 26;
_pinDOUT = 28;
}
bool I2SClass::begin(long sampleRate, pin_size_t sck, pin_size_t data) {
bool I2SClass::setBCLK(pin_size_t pin) {
if (_running || (pin < 0) || (pin > 28)) {
return false;
}
_pinBCLK = pin;
}
bool I2SClass::setDOUT(pin_size_t pin) {
if (_running || (pin < 0) || (pin > 29)) {
return false;
}
_pinDOUT = pin;
}
bool I2SClass::begin(long sampleRate) {
if (_running) {
return false;
}
......@@ -48,8 +64,8 @@ bool I2SClass::begin(long sampleRate, pin_size_t sck, pin_size_t data) {
}
bzero(&_config, sizeof(_config));
_config.data_pin = data;
_config.clock_pin_base = sck;
_config.data_pin = _pinDOUT;
_config.clock_pin_base = _pinBCLK;
_config.dma_channel = 0;
_config.pio_sm = 1;
......
......@@ -29,7 +29,9 @@ public:
I2SClass();
// Only 16 bitsPerSample are allowed by the PIO code. Only write, no read.
bool begin(long sampleRate, pin_size_t sck = 26, /* lrclk is sck+1 */ pin_size_t data = 28);
bool setBCLK(pin_size_t pin);
bool setDOUT(pin_size_t pin);
bool begin(long sampleRate);
void end();
// from Stream
......@@ -60,6 +62,8 @@ public:
//void onReceive(void(*)(void)); -- no I2S input yet
private:
pin_size_t _pinBCLK;
pin_size_t _pinDOUT;
int _bps;
int _freq;
bool _running;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment