RP2040 Datasheet
Colophon
Copyright © 2020-2022 Raspberry Pi Ltd (formerly Raspberry Pi (Trading) Ltd.)
The documentation of the RP2040 microcontroller is licensed under a Creative Commons Attribution-NoDerivatives 4.0
International (CC BY-ND).
Portions Copyright © 2019 Synopsys, Inc.
All rights reserved. Used with permission. Synopsys & DesignWare are registered trademarks of Synopsys, Inc.
Portions Copyright © 2000-2001, 2005, 2007, 2009, 2011-2012, 2016 ARM Limited.
All rights reserved. Used with permission.
build-date: 2022-06-17
build-version: 7028f9f-clean
About the SDK
Throughout the text "the SDK" refers to our Raspberry Pi Pico SDK. More details about the SDK can be
found in the Raspberry Pi Pico C/C++ SDK book. Source code included in the documentation is
Copyright © 2020-2022 Raspberry Pi Ltd (formerly Raspberry Pi (Trading) Ltd.) and licensed under the 3Clause BSD license.
Legal Disclaimer Notice
TECHNICAL AND RELIABILITY DATA FOR RASPBERRY PI PRODUCTS (INCLUDING DATASHEETS) AS MODIFIED FROM
TIME TO TIME (“RESOURCES”) ARE PROVIDED BY RASPBERRY PI LTD (“RPL”) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW IN NO
EVENT SHALL RPL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THE RESOURCES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
RPL reserves the right to make any enhancements, improvements, corrections or any other modifications to the
RESOURCES or any products described in them at any time and without further notice.
The RESOURCES are intended for skilled users with suitable levels of design knowledge. Users are solely responsible for
their selection and use of the RESOURCES and any application of the products described in them. User agrees to
indemnify and hold RPL harmless against all liabilities, costs, damages or other losses arising out of their use of the
RESOURCES.
RPL grants users permission to use the RESOURCES solely in conjunction with the Raspberry Pi products. All other use
of the RESOURCES is prohibited. No licence is granted to any other RPL or other third party intellectual property right.
HIGH RISK ACTIVITIES. Raspberry Pi products are not designed, manufactured or intended for use in hazardous
environments requiring fail safe performance, such as in the operation of nuclear facilities, aircraft navigation or
communication systems, air traffic control, weapons systems or safety-critical applications (including life support
systems and other medical devices), in which the failure of the products could lead directly to death, personal injury or
severe physical or environmental damage (“High Risk Activities”). RPL specifically disclaims any express or implied
warranty of fitness for High Risk Activities and accepts no liability for use or inclusions of Raspberry Pi products in High
Risk Activities.
Raspberry Pi products are provided subject to RPL’s Standard Terms. RPL’s provision of the RESOURCES does not
Legal Disclaimer Notice
1
RP2040 Datasheet
expand or otherwise modify RPL’s Standard Terms including but not limited to the disclaimers and warranties
expressed in them.
Legal Disclaimer Notice
2
RP2040 Datasheet
Table of Contents
Colophon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Legal Disclaimer Notice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.1. Why is the chip called RP2040?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3. The Chip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.4. Pinout Reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.4.1. Pin Locations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.4.2. Pin Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.4.3. GPIO Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2. System Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.1. Bus Fabric . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.1.1. AHB-Lite Crossbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.1.2. Atomic Register Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.1.3. APB Bridge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.1.4. Narrow IO Register Writes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.1.5. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2. Address Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.2.1. Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.2.2. Detail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3. Processor subsystem. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.3.1. SIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.3.2. Interrupts. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
2.3.3. Event Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
2.3.4. Debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
2.4. Cortex-M0+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
2.4.1. Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
2.4.2. Functional Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
2.4.3. Programmer’s model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
2.4.4. System control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
2.4.5. NVIC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
2.4.6. MPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
2.4.7. Debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
2.4.8. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
2.5. DMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
2.5.1. Configuring Channels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
2.5.2. Starting Channels. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
2.5.3. Data Request (DREQ). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
2.5.4. Interrupts. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
2.5.5. Additional Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
2.5.6. Example Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
2.5.7. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
2.6. Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
2.6.1. ROM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
2.6.2. SRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
2.6.3. Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
2.7. Boot Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
2.8. Bootrom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
2.8.1. Processor Controlled Boot Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
2.8.2. Launching Code On Processor Core 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
2.8.3. Bootrom Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
2.8.4. USB Mass Storage Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
2.8.5. USB PICOBOOT Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
2.9. Power Supplies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
2.9.1. Digital IO Supply (IOVDD) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Table of Contents
3
RP2040 Datasheet
2.9.2. Digital Core Supply (DVDD). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.3. On-Chip Voltage Regulator Input Supply (VREG_VIN) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.4. USB PHY Supply (USB_VDD) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.5. ADC Supply (ADC_AVDD) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.6. Power Supply Sequencing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.7. Power Supply Schemes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10. Core Supply Regulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.1. Application Circuit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.2. Operating Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.3. Output Voltage Select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.4. Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.5. Current Limit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.6. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.7. Detailed Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.11. Power Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.11.1. Top-level Clock Gates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.11.2. SLEEP State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.11.3. DORMANT State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.11.4. Memory Power Down . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.11.5. Programmer’s Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12. Chip-Level Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.2. Power-on Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.3. Brown-out Detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.4. Supply Monitor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.5. External Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.6. Rescue Debug Port Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.7. Source of Last Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.8. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13. Power-On State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.2. Power On Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.3. Register Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.4. Interaction with Watchdog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.5. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.14. Subsystem Resets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.14.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.14.2. Programmer’s Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.14.3. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.15. Clocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.15.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.15.2. Clock sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.15.3. Clock Generators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.15.4. Frequency Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.15.5. Resus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.15.6. Programmer’s Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.15.7. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16. Crystal Oscillator (XOSC). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.2. Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.3. Startup Delay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.4. XOSC Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.5. DORMANT mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.6. Programmer’s Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.7. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17. Ring Oscillator (ROSC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.2. ROSC/XOSC trade-offs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.3. Modifying the frequency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.4. ROSC divider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table of Contents
154
154
154
155
155
155
158
158
159
160
160
160
160
163
163
163
164
164
164
165
166
166
167
168
170
170
170
170
171
171
171
171
172
172
172
175
175
176
178
181
181
182
185
188
189
189
196
217
217
217
218
218
218
219
220
222
222
222
223
223
4
RP2040 Datasheet
2.17.5. Random Number Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.6. ROSC Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.7. DORMANT mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17.8. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.18. PLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.18.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.18.2. Calculating PLL parameters. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.18.3. Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.18.4. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19. GPIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19.2. Function Select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19.3. Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19.4. Pads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19.5. Software Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.19.6. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.20. Sysinfo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.20.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.20.2. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.21. Syscfg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.21.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.21.2. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.22. TBMAN. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.22.1. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3. PIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2. Programmer’s Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.1. PIO Programs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.2. Control Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.3. Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.4. Stalling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.5. Pin Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.6. IRQ Flags. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.7. Interactions Between State Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3. PIO Assembler (pioasm) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.1. Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.2. Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.3. Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.4. Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.5. Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.6. Instructions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.7. Pseudoinstructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4. Instruction Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.1. Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.2. JMP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.3. WAIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.4. IN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.5. OUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.6. PUSH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.7. PULL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.8. MOV. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.9. IRQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.10. SET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5. Functional Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.1. Side-set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.2. Program Wrapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.3. FIFO Joining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.4. Autopush and Autopull . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.5. Clock Dividers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.6. GPIO Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table of Contents
223
223
224
224
228
228
229
232
234
235
235
236
238
239
240
243
303
303
303
304
304
304
307
307
309
309
310
310
311
312
315
316
316
316
317
317
318
318
318
318
319
319
319
319
320
321
322
323
324
325
326
327
328
329
329
330
332
333
337
338
5
RP2040 Datasheet
3.5.7. Forced and EXEC’d Instructions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6.1. Duplex SPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6.2. WS2812 LEDs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6.3. UART TX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6.4. UART RX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6.5. Manchester Serial TX and RX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6.6. Differential Manchester (BMC) TX and RX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6.7. I2C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6.8. PWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6.9. Addition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6.10. Further Examples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.7. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4. Peripherals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1. USB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.2. Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.3. Programmer’s Model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.4. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2. UART . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.2. Functional description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.3. Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.4. UART hardware flow control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.5. UART DMA Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.6. Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.7. Programmer’s Model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.8. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3. I2C. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.1. Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.2. IP Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.3. I2C Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.4. I2C Terminology. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.5. I2C Behaviour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.6. I2C Protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.7. Tx FIFO Management and START, STOP and RESTART Generation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.8. Multiple Master Arbitration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.9. Clock Synchronization. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.10. Operation Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.11. Spike Suppression. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.12. Fast Mode Plus Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.13. Bus Clear Feature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.14. IC_CLK Frequency Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.15. DMA Controller Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.16. Operation of Interrupt Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.17. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4. SPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.2. Functional Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.3. Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.4. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.5. PWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.5.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.5.2. Programmer’s Model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.5.3. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.6. Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.6.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.6.2. Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.6.3. Alarms. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table of Contents
340
342
342
346
348
350
353
355
358
362
364
366
366
381
381
381
382
392
396
415
415
416
416
418
421
422
423
425
427
439
440
440
441
443
443
445
448
450
451
452
457
458
458
459
463
464
464
502
503
504
506
516
523
523
523
530
535
535
536
536
6
RP2040 Datasheet
4.6.4. Programmer’s Model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.6.5. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.7. Watchdog. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.7.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.7.2. Tick generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.7.3. Watchdog Counter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.7.4. Scratch Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.7.5. Programmer’s Model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.7.6. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8. RTC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8.1. Storage Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8.2. Leap year . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8.3. Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8.4. Reference clock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8.5. Programmer’s Model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8.6. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.9. ADC and Temperature Sensor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.9.1. ADC controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.9.2. SAR ADC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.9.3. ADC ENOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.9.4. INL and DNL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.9.5. Temperature Sensor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.9.6. List of Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10. SSI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.2. Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.3. IP Modifications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.4. Clock Ratios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.5. Transmit and Receive FIFO Buffers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.6. 32-Bit Frame Size Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.7. SSI Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.8. Transfer Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.9. Operation Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.10. Partner Connection Interfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.11. DMA Controller Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.12. APB Interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10.13. List of Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5. Electrical and Mechanical . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.1. Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.1.1. Recommended PCB Footprint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2. Solder profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2.1. Compliance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3. Pinout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3.1. Pin Locations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3.2. Pin Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3.3. Pin Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.4. Power Supplies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.5. Power Consumption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.5.1. Power Consumption versus frequency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Appendix A: Register Field Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Standard types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RO. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
WO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Clear types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
SC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
WC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
FIFO types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
WF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table of Contents
537
540
545
545
545
545
546
546
547
549
549
550
550
550
551
554
558
559
560
562
563
564
565
568
568
569
570
571
572
573
573
574
575
580
596
598
599
608
608
608
609
611
611
611
611
614
618
619
619
621
621
621
621
621
621
621
621
621
621
621
7
RP2040 Datasheet
RWF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Appendix B: Errata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Bootrom. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Clocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
DMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
GPIO / ADC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
USB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Watchdog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
XIP Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RP2040-E8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Appendix C: Documentation Release History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table of Contents
622
623
623
623
623
624
624
624
625
625
625
626
626
626
626
626
627
627
627
629
629
629
629
630
8
RP2040 Datasheet
Chapter 1. Introduction
Microcontrollers connect the world of software to the world of hardware. They allow developers to write software which
interacts with the physical world in the same deterministic, cycle-accurate manner as digital logic. They occupy the
bottom left corner of the price/performance space, outselling their more powerful brethren by a factor of ten to one.
They are the workhorses that power the digital transformation of our world.
RP2040 is the debut microcontroller from Raspberry Pi. It brings our signature values of high performance, low cost,
and ease of use to the microcontroller space.
With a large on-chip memory, symmetric dual-core processor complex, deterministic bus fabric, and rich peripheral set
augmented with our unique Programmable I/O (PIO) subsystem, it provides professional users with unrivalled power
and flexibility. With detailed documentation, a polished MicroPython port, and a UF2 bootloader in ROM, it has the
lowest possible barrier to entry for beginner and hobbyist users.
RP2040 is a stateless device, with support for cached execute-in-place from external QSPI memory. This design
decision allows you to choose the appropriate density of non-volatile storage for your application, and to benefit from
the low pricing of commodity Flash parts.
RP2040 is manufactured on a modern 40nm process node, delivering high performance, low dynamic power
consumption, and low leakage, with a variety of low-power modes to support extended-duration operation on battery
power.
Key features:
• Dual ARM Cortex-M0+ @ 133MHz
• 264kB on-chip SRAM in six independent banks
• Support for up to 16MB of off-chip Flash memory via dedicated QSPI bus
• DMA controller
• Fully-connected AHB crossbar
• Interpolator and integer divider peripherals
• On-chip programmable LDO to generate core voltage
• 2 on-chip PLLs to generate USB and core clocks
• 30 GPIO pins, 4 of which can be used as analogue inputs
• Peripherals
◦ 2 UARTs
◦ 2 SPI controllers
◦ 2 I2C controllers
◦ 16 PWM channels
◦ USB 1.1 controller and PHY, with host and device support
◦ 8 PIO state machines
Whatever your microcontroller application, from machine learning to motor control, from agriculture to audio, RP2040
has the performance, feature set, and support to make your product fly.
1.1. Why is the chip called RP2040?
The post-fix numeral on RP2040 comes from the following,
1.1. Why is the chip called RP2040?
9
RP2040 Datasheet
1. Number of processor cores (2)
2. Loosely which type of processor (M0+)
3. floor(log2(ram / 16k))
4. floor(log2(nonvolatile / 16k)) or 0 if no onboard nonvolatile storage
see Figure 1.
Figure 1. An
explanation for the
RP 2 0 4 0
name of the RP2040
chip.
floor(log2(nonvolatile / 16k))
floor(log2(ram / 16k))
Type of core (e.g. M0+)
Number of cores
Raspberry Pi
1.2. Summary
RP2040 is a low-cost, high-performance microcontroller device with flexible digital interfaces. Key features:
• Dual Cortex M0+ processor cores, up to 133MHz
• 264kB of embedded SRAM in 6 banks
• 30 multifunction GPIO
• 6 dedicated IO for SPI Flash (supporting XIP)
• Dedicated hardware for commonly used peripherals
• Programmable IO for extended peripheral support
• 4 channel ADC with internal temperature sensor, 500ksps, 12-bit conversion
• USB 1.1 Host/Device
1.3. The Chip
RP2040 has a dual M0+ processor cores, DMA, internal memory and peripheral blocks connected via AHB/APB bus
fabric.
1.2. Summary
10
RP2040 Datasheet
Figure 2. A system
overview of the
RP2040 chip
Code may be executed directly from external memory through a dedicated SPI, DSPI or QSPI interface. A small cache
improves performance for typical applications.
Debug is available via the SWD interface.
Internal SRAM can contain code or data. It is addressed as a single 264 kB region, but physically partitioned into 6
banks to allow simultaneous parallel access from different masters.
DMA bus masters are available to offload repetitive data transfer tasks from the processors.
GPIO pins can be driven directly, or from a variety of dedicated logic functions.
Dedicated hardware for fixed functions such as SPI, I2C, UART.
Flexible configurable PIO controllers can be used to provide a wide variety of IO functions.
A USB controller with embedded PHY can be used to provide FS/LS Host or Device connectivity under software control.
Four ADC inputs which are shared with GPIO pins.
Two PLLs to provide a fixed 48MHz clock for USB or ADC, and a flexible system clock up to 133MHz.
An internal Voltage Regulator to supply the core voltage so the end product only needs supply the IO voltage.
1.4. Pinout Reference
This section provides a quick reference for pinout and pin functions. Full details, including electrical specifications and
package drawings, can be found in Chapter 5.
1.4.1. Pin Locations
1.4. Pinout Reference
11
RP2040 Datasheet
Figure 3. RP2040
Pinout for QFN-56
7×7mm (reduced ePad
size)
1.4.2. Pin Descriptions
Table 1. The function
of each pin is briefly
described here. Full
electrical
Name
Description
GPIOx
General-purpose digital input and output. RP2040 can connect one of a number of internal
peripherals to each GPIO, or control GPIOs directly from software.
specifications can be
found in Chapter 5.
GPIOx/ADCy
General-purpose digital input and output, with analogue-to-digital converter function. The RP2040
ADC has an analogue multiplexer which can select any one of these pins, and sample the voltage.
QSPIx
Interface to a SPI, Dual-SPI or Quad-SPI flash device, with execute-in-place support. These pins can
also be used as software-controlled GPIOs, if they are not required for flash access.
USB_DM and
USB controller, supporting Full Speed device and Full/Low Speed host. A 27Ω series termination
USB_DP
resistor is required on each pin, but bus pullups and pulldowns are provided internally.
XIN and XOUT
Connect a crystal to RP2040’s crystal oscillator. XIN can also be used as a single-ended CMOS
clock input, with XOUT disconnected. The USB bootloader requires a 12MHz crystal or 12MHz
clock input.
RUN
Global asynchronous reset pin. Reset when driven low, run when driven high. If no external reset is
required, this pin can be tied directly to IOVDD.
SWCLK and
Access to the internal Serial Wire Debug multi-drop bus. Provides debug access to both
SWDIO
processors, and can be used to download code.
TESTEN
Factory test mode pin. Tie to GND.
GND
Single external ground connection, bonded to a number of internal ground pads on the RP2040 die.
IOVDD
Power supply for digital GPIOs, nominal voltage 1.8V to 3.3V
1.4. Pinout Reference
12
RP2040 Datasheet
Name
Description
USB_VDD
Power supply for internal USB Full Speed PHY, nominal voltage 3.3V
ADC_AVDD
Power supply for analogue-to-digital converter, nominal voltage 3.3V
VREG_VIN
Power input for the internal core voltage regulator, nominal voltage 1.8V to 3.3V
VREG_VOUT
Power output for the internal core voltage regulator, nominal voltage 1.1V, 100mA max current
DVDD
Digital core power supply, nominal voltage 1.1V. Can be connected to VREG_VOUT, or to some
other board-level power supply.
1.4.3. GPIO Functions
Each individual GPIO pin can be connected to an internal peripheral via the GPIO functions defined below. Some internal
peripheral connections appear in multiple places to allow some system level flexibility. SIO, PIO0 and PIO1 can connect
to all GPIO pins and are controlled by software (or software controlled state machines) so can be used to implement
many functions.
Table 2. General
Function
Purpose Input/Output
(GPIO) Bank 0
Functions
GPIO
F1
F2
F3
F4
F5
F6
F7
0
SPI0 RX
UART0 TX
I2C0 SDA
PWM0 A
SIO
PIO0
PIO1
USB OVCUR DET
1
SPI0 CSn
UART0 RX
I2C0 SCL
PWM0 B
SIO
PIO0
PIO1
USB VBUS DET
2
SPI0 SCK
UART0 CTS
I2C1 SDA
PWM1 A
SIO
PIO0
PIO1
USB VBUS EN
3
SPI0 TX
UART0 RTS
I2C1 SCL
PWM1 B
SIO
PIO0
PIO1
USB OVCUR DET
4
SPI0 RX
UART1 TX
I2C0 SDA
PWM2 A
SIO
PIO0
PIO1
USB VBUS DET
5
SPI0 CSn
UART1 RX
I2C0 SCL
PWM2 B
SIO
PIO0
PIO1
USB VBUS EN
6
SPI0 SCK
UART1 CTS
I2C1 SDA
PWM3 A
SIO
PIO0
PIO1
USB OVCUR DET
7
SPI0 TX
UART1 RTS
I2C1 SCL
PWM3 B
SIO
PIO0
PIO1
USB VBUS DET
8
SPI1 RX
UART1 TX
I2C0 SDA
PWM4 A
SIO
PIO0
PIO1
USB VBUS EN
9
SPI1 CSn
UART1 RX
I2C0 SCL
PWM4 B
SIO
PIO0
PIO1
USB OVCUR DET
10
SPI1 SCK
UART1 CTS
I2C1 SDA
PWM5 A
SIO
PIO0
PIO1
USB VBUS DET
11
SPI1 TX
UART1 RTS
I2C1 SCL
PWM5 B
SIO
PIO0
PIO1
USB VBUS EN
12
SPI1 RX
UART0 TX
I2C0 SDA
PWM6 A
SIO
PIO0
PIO1
USB OVCUR DET
13
SPI1 CSn
UART0 RX
I2C0 SCL
PWM6 B
SIO
PIO0
PIO1
USB VBUS DET
14
SPI1 SCK
UART0 CTS
I2C1 SDA
PWM7 A
SIO
PIO0
PIO1
USB VBUS EN
15
SPI1 TX
UART0 RTS
I2C1 SCL
PWM7 B
SIO
PIO0
PIO1
USB OVCUR DET
16
SPI0 RX
UART0 TX
I2C0 SDA
PWM0 A
SIO
PIO0
PIO1
USB VBUS DET
17
SPI0 CSn
UART0 RX
I2C0 SCL
PWM0 B
SIO
PIO0
PIO1
USB VBUS EN
18
SPI0 SCK
UART0 CTS
I2C1 SDA
PWM1 A
SIO
PIO0
PIO1
USB OVCUR DET
19
SPI0 TX
UART0 RTS
I2C1 SCL
PWM1 B
SIO
PIO0
PIO1
USB VBUS DET
20
SPI0 RX
UART1 TX
I2C0 SDA
PWM2 A
SIO
PIO0
PIO1
CLOCK GPIN0
USB VBUS EN
21
SPI0 CSn
UART1 RX
I2C0 SCL
PWM2 B
SIO
PIO0
PIO1
CLOCK GPOUT0
USB OVCUR DET
1.4. Pinout Reference
F8
F9
13
RP2040 Datasheet
Function
Table 3. GPIO bank 0
function descriptions
22
SPI0 SCK
UART1 CTS
I2C1 SDA
PWM3 A
SIO
PIO0
PIO1
CLOCK GPIN1
USB VBUS DET
23
SPI0 TX
UART1 RTS
I2C1 SCL
PWM3 B
SIO
PIO0
PIO1
CLOCK GPOUT1
USB VBUS EN
24
SPI1 RX
UART1 TX
I2C0 SDA
PWM4 A
SIO
PIO0
PIO1
CLOCK GPOUT2
USB OVCUR DET
25
SPI1 CSn
UART1 RX
I2C0 SCL
PWM4 B
SIO
PIO0
PIO1
CLOCK GPOUT3
USB VBUS DET
26
SPI1 SCK
UART1 CTS
I2C1 SDA
PWM5 A
SIO
PIO0
PIO1
USB VBUS EN
27
SPI1 TX
UART1 RTS
I2C1 SCL
PWM5 B
SIO
PIO0
PIO1
USB OVCUR DET
28
SPI1 RX
UART0 TX
I2C0 SDA
PWM6 A
SIO
PIO0
PIO1
USB VBUS DET
29
SPI1 CSn
UART0 RX
I2C0 SCL
PWM6 B
SIO
PIO0
PIO1
USB VBUS EN
Function Name
Description
SPIx
Connect one of the internal PL022 SPI peripherals to GPIO
UARTx
Connect one of the internal PL011 UART peripherals to GPIO
I2Cx
Connect one of the internal DW I2C peripherals to GPIO
PWMx A/B
Connect a PWM slice to GPIO. There are eight PWM slices, each with two output
channels (A/B). The B pin can also be used as an input, for frequency and duty cycle
measurement.
SIO
Software control of GPIO, from the single-cycle IO (SIO) block. The SIO function (F5)
must be selected for the processors to drive a GPIO, but the input is always connected,
so software can check the state of GPIOs at any time.
PIOx
Connect one of the programmable IO blocks (PIO) to GPIO. PIO can implement a wide
variety of interfaces, and has its own internal pin mapping hardware, allowing flexible
placement of digital interfaces on bank 0 GPIOs. The PIO function (F6, F7) must be
selected for PIO to drive a GPIO, but the input is always connected, so the PIOs can
always see the state of all pins.
CLOCK GPINx
General purpose clock inputs. Can be routed to a number of internal clock domains on
RP2040, e.g. to provide a 1Hz clock for the RTC, or can be connected to an internal
frequency counter.
CLOCK GPOUTx
General purpose clock outputs. Can drive a number of internal clocks (including PLL
outputs) onto GPIOs, with optional integer divide.
USB OVCUR DET/VBUS
USB power control signals to/from the internal USB controller
DET/VBUS EN
1.4. Pinout Reference
14
RP2040 Datasheet
Chapter 2. System Description
This chapter describes the RP2040 key system features including processor, memory, how blocks are connected,
clocks, resets, power, and IO. Refer to Figure 2 for an overview diagram.
2.1. Bus Fabric
The RP2040 bus fabric routes addresses and data across the chip.
Figure 4 shows the high-level structure of the bus fabric. The main AHB-Lite crossbar routes addresses and data
between its 4 upstream ports and 10 downstream ports: up to four bus transfers can take place each cycle. All data
paths are 32 bits wide. Memory devices have dedicated ports on the main crossbar, to satisfy their high bandwidth
requirements. High-bandwidth AHB-Lite peripherals have a shared port on the crossbar, and an APB bridge provides bus
access to system control registers and lower-bandwidth peripherals.
Figure 4. RP2040 bus
fabric overview.
The bus fabric connects 4 AHB-Lite masters, i.e. devices which generate addresses:
• Processor core 0
• Processor core 1
• DMA controller Read port
• DMA controller Write port
These are routed through to 10 downstream ports on the main crossbar:
• ROM
• Flash XIP
• SRAM 0 to 5 (one port each)
• Fast AHB-Lite peripherals: PIO0, PIO1, USB, DMA control registers, XIP aux (one shared port)
• Bridge to all APB peripherals, and system control registers
The four bus masters can access any four different crossbar ports simultaneously, the bus fabric does not add wait
states to any AHB-Lite slave access. So at a system clock of 125MHz the maximum sustained bus bandwidth is
2.1. Bus Fabric
15
RP2040 Datasheet
2.0GBps. The system address map has been arranged to make this parallel bandwidth available to as many software
use cases as possible — for example, the striped SRAM alias (Section 2.6.2) scatters main memory accesses across
four crossbar ports (SRAM0…3), so that more memory accesses can proceed in parallel.
2.1.1. AHB-Lite Crossbar
At the centre of the RP2040 bus fabric is a 4:10 fully-connected crossbar. Its 4 upstream ports are connected to the 4
system bus masters, and the 10 downstream ports connect to the highest-bandwidth AHB-Lite slaves (namely the
memory interfaces) and to lower layers of the fabric. Figure 5 shows the structure of a 2:3 AHB-Lite crossbar, arranged
identically to the 4:10 crossbar on RP2040, but easier to show in the diagram.
Figure 5. A 2:3 AHBLite crossbar. Each
upstream port
connects to a splitter,
which routes bus
requests toward one
of the 3 downstream
ports, and routes
responses back. Each
downstream port
connects to an arbiter,
which safely manages
concurrent access to
the port.
The crossbar is built from two components:
• Splitters
◦ Perform coarse address decode
◦ Route requests (addresses, write data) to the downstream port indicated by the initial address decode
◦ Route responses (read data, bus errors) from the correct arbiter back to the upstream port
• Arbiters
◦ Manage concurrent requests to a downstream port
◦ Route responses (read data, bus errors) to the correct splitter
◦ Implement bus priority rules
The main crossbar on RP2040 consists of 4 1:10 splitters and 10 4:1 arbiters, with a mesh of 40 AHB-Lite bus channels
between them. Note that, as AHB-Lite is a pipelined bus, the splitter may be routing back a response to an earlier
request from downstream port A, whilst a new request to downstream port B is already in progress. This does not incur
any cycle penalty.
2.1.1.1. Bus Priority
The arbiters in the main AHB-Lite crossbar implement a two-level bus priority scheme. Priority levels are configured permaster, using the BUS_PRIORITY register in the BUSCTRL register block.
When there are multiple simultaneous accesses to same arbiter, any requests from high-priority masters (priority level
1) will be considered before any requests from low-priority masters (priority 0). If multiple masters of the same priority
level attempt to access the same slave simultaneously, a round-robin tie break is applied, i.e. the arbiter grants access
to each master in turn.
2.1. Bus Fabric
16
RP2040 Datasheet
NOTE
Priority arbitration only applies to multiple masters attempting to access the same slave on the same cycle.
Accesses to different slaves, e.g. different SRAM banks, can proceed simultaneously.
When accessing a slave with zero wait states, such as SRAM (i.e. can be accessed once per system clock cycle), highpriority masters will never observe any slowdown or other timing effects caused by accesses from low-priority masters.
This allows guaranteed latency and throughput for hard real time use cases; it does however mean a low-priority master
may get stalled until there is a free cycle.
2.1.1.2. Bus Performance Counters
The performance counters automatically count accesses to the main AHB-Lite crossbar arbiters. This can assist in
diagnosing performance issues, in high-traffic use cases.
There are four performance counters. Each is a 24-bit saturating counter. Counter values can be read from
BUSCTRL_PERFCTRx, and cleared by writing any value to BUSCTRL_PERFCTRx. Each counter can count one of the 20 available
events at a time, as selected by BUSCTRL_PERFSELx. The available bus events are:
PERFSEL Event
Description
x
0
APB access,
Completion of an access to the APB arbiter (which is upstream of all APB
contested
peripherals), which was previously delayed due to an access by another master.
1
APB access
Completion of an access to the APB arbiter
2
FASTPERI access,
Completion of an access to the FASTPERI arbiter (which is upstream of PIOs, DMA
contested
config port, USB, XIP aux FIFO port), which was previously delayed due to an access
by another master.
3
FASTPERI access
Completion of an access to the FASTPERI arbiter
4
SRAM5 access,
Completion of an access to the SRAM5 arbiter, which was previously delayed due to
contested
an access by another master.
5
SRAM5 access
Completion of an access to the SRAM5 arbiter
6
SRAM4 access,
Completion of an access to the SRAM4 arbiter, which was previously delayed due to
contested
an access by another master.
7
SRAM4 access
Completion of an access to the SRAM4 arbiter
8
SRAM3 access,
Completion of an access to the SRAM3 arbiter, which was previously delayed due to
contested
an access by another master.
9
SRAM3 access
Completion of an access to the SRAM3 arbiter
10
SRAM2 access,
Completion of an access to the SRAM2 arbiter, which was previously delayed due to
contested
an access by another master.
11
SRAM2 access
Completion of an access to the SRAM2 arbiter
12
SRAM1 access,
Completion of an access to the SRAM1 arbiter, which was previously delayed due to
contested
an access by another master.
13
SRAM1 access
Completion of an access to the SRAM1 arbiter
14
SRAM0 access,
Completion of an access to the SRAM0 arbiter, which was previously delayed due to
contested
an access by another master.
SRAM0 access
Completion of an access to the SRAM0 arbiter
15
2.1. Bus Fabric
17
RP2040 Datasheet
PERFSEL Event
Description
x
16
XIP_MAIN access,
Completion of an access to the XIP_MAIN arbiter, which was previously delayed due
contested
to an access by another master.
17
XIP_MAIN access
Completion of an access to the XIP_MAIN arbiter
18
ROM access,
Completion of an access to the ROM arbiter, which was previously delayed due to an
contested
access by another master.
ROM access
Completion of an access to the ROM arbiter
19
2.1.2. Atomic Register Access
Each peripheral register block is allocated 4kB of address space, with registers accessed using one of 4 methods,
selected by address decode.
• Addr + 0x0000 : normal read write access
• Addr + 0x1000 : atomic XOR on write
• Addr + 0x2000 : atomic bitmask set on write
• Addr + 0x3000 : atomic bitmask clear on write
This allows individual fields of a control register to be modified without performing a read-modify-write sequence in
software: instead the changes are posted to the peripheral, and performed in-situ. Without this capability, it is difficult to
safely access IO registers when an interrupt service routine is concurrent with code running in the foreground, or when
the two processors are running code in parallel.
The four atomic access aliases occupy a total of 16kB. Most peripherals on RP2040 provide this functionality natively,
and atomic writes have the same timing as normal read/write access. Some peripherals (I2C, UART, SPI and SSI)
instead have this functionality added using a bus interposer, which translates upstream atomic writes into downstream
read-modify-write sequences, at the boundary of the peripheral. This extends the access time by two system clock
cycles.
The SIO (Section 2.3.1), a single-cycle IO block attached directly to the cores' IO ports, does not support atomic
accesses at the bus level, although some individual registers (e.g. GPIO) have set/clear/xor aliases.
2.1.3. APB Bridge
The APB bridge interfaces the high-speed main AHB-Lite interconnect to the lower-bandwidth peripherals. Whilst the
AHB-Lite fabric offers zero-wait-state access everywhere, APB accesses have a cycle penalty:
• APB bus accesses take two cycles minimum (setup phase and access phase)
• The bridge adds an additional cycle to read accesses, as the bus request and response are registered
• The bridge adds two additional cycles to write accesses, as the APB setup phase can not begin until the AHB-Lite
write data is valid
As a result, the throughput of the APB portion of the bus fabric is somewhat lower than the AHB-Lite portion. However,
there is more than sufficient bandwidth to saturate the APB serial peripherals.
2.1.4. Narrow IO Register Writes
Memory-mapped IO registers on RP2040 ignore the width of bus read/write accesses. They treat all writes as though
they were 32 bits in size. This means software can not use byte or halfword writes to modify part of an IO register: any
write to an address where the 30 address MSBs match the register address will affect the contents of the entire
register.
2.1. Bus Fabric
18
RP2040 Datasheet
To update part of an IO register, without a read-modify-write sequence, the best solution on RP2040 is atomic
set/clear/XOR (see Section 2.1.2). Note that this is more flexible than byte or halfword writes, as any combination of
fields can be updated in one operation.
Upon a 8-bit or 16-bit write (such as a strb instruction on the Cortex-M0+), an IO register will sample the entire 32-bit
write databus. The Cortex-M0+ and DMA on RP2040 will always replicate narrow data across the bus:
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/system/narrow_io_write/narrow_io_write.c Lines 19 - 60
19 int main() {
20
stdio_init_all();
21
22
// We'll use WATCHDOG_SCRATCH0 as a convenient 32 bit read/write register
23
// that we can assign arbitrary values to
24
io_rw_32 *scratch32 = &watchdog_hw->scratch[0];
25
// Alias the scratch register as two halfwords at offsets +0x0 and +0x2
26
volatile uint16_t *scratch16 = (volatile uint16_t *) scratch32;
27
// Alias the scratch register as four bytes at offsets +0x0, +0x1, +0x2, +0x3:
28
volatile uint8_t *scratch8 = (volatile uint8_t *) scratch32;
29
30
// Show that we can read/write the scratch register as normal:
31
printf("Writing 32 bit value\n");
32
*scratch32 = 0xdeadbeef;
33
printf("Should be 0xdeadbeef: 0x%08x\n", *scratch32);
34
35
// We can do narrow reads just fine -- IO registers treat this as a 32 bit
36
// read, and the processor/DMA will pick out the correct byte lanes based
37
// on transfer size and address LSBs
38
printf("\nReading back 1 byte at a time\n");
39
// Little-endian!
40
printf("Should be ef be ad de: %02x %02x %02x %02x\n",
41
scratch8[0], scratch8[1], scratch8[2], scratch8[3]);
42
43
// The Cortex-M0+ and the RP2040 DMA replicate byte writes across the bus,
44
// and IO registers will sample the entire write bus always.
45
printf("\nWriting 8 bit value 0xa5 at offset 0\n");
46
scratch8[0] = 0xa5;
47
// Read back the whole scratch register in one go
48
printf("Should be 0xa5a5a5a5: 0x%08x\n", *scratch32);
49
50
// The IO register ignores the address LSBs [1:0] as well as the transfer
51
// size, so it doesn't matter what byte offset we use
52
printf("\nWriting 8 bit value at offset 1\n");
53
scratch8[1] = 0x3c;
54
printf("Should be 0x3c3c3c3c: 0x%08x\n", *scratch32);
55
56
// Halfword writes are also replicated across the write data bus
57
printf("\nWriting 16 bit value at offset 0\n");
58
scratch16[0] = 0xf00d;
59
printf("Should be 0xf00df00d: 0x%08x\n", *scratch32);
60 }
2.1.5. List of Registers
The Bus Fabric registers start at a base address of 0x40030000 (defined as BUSCTRL_BASE in SDK).
Table 4. List of
BUSCTRL registers
2.1. Bus Fabric
Offset
Name
Info
0x00
BUS_PRIORITY
Set the priority of each master for bus arbitration.
19
RP2040 Datasheet
Offset
Name
Info
0x04
BUS_PRIORITY_ACK
Bus priority acknowledge
0x08
PERFCTR0
Bus fabric performance counter 0
0x0c
PERFSEL0
Bus fabric performance event select for PERFCTR0
0x10
PERFCTR1
Bus fabric performance counter 1
0x14
PERFSEL1
Bus fabric performance event select for PERFCTR1
0x18
PERFCTR2
Bus fabric performance counter 2
0x1c
PERFSEL2
Bus fabric performance event select for PERFCTR2
0x20
PERFCTR3
Bus fabric performance counter 3
0x24
PERFSEL3
Bus fabric performance event select for PERFCTR3
BUSCTRL: BUS_PRIORITY Register
Offset: 0x00
Description
Set the priority of each master for bus arbitration.
Table 5.
BUS_PRIORITY
Register
Bits
Name
Description
Type
Reset
31:13
Reserved.
-
-
-
12
DMA_W
0 - low priority, 1 - high priority
RW
0x0
11:9
Reserved.
-
-
-
8
DMA_R
0 - low priority, 1 - high priority
RW
0x0
7:5
Reserved.
-
-
-
4
PROC1
0 - low priority, 1 - high priority
RW
0x0
3:1
Reserved.
-
-
-
0
PROC0
0 - low priority, 1 - high priority
RW
0x0
BUSCTRL: BUS_PRIORITY_ACK Register
Offset: 0x04
Description
Bus priority acknowledge
Table 6.
BUS_PRIORITY_ACK
Register
Bits
Description
Type
Reset
31:1
Reserved.
-
-
0
Goes to 1 once all arbiters have registered the new global priority levels.
RO
0x0
Arbiters update their local priority when servicing a new nonsequential access.
In normal circumstances this will happen almost immediately.
BUSCTRL: PERFCTR0 Register
Offset: 0x08
2.1. Bus Fabric
20
RP2040 Datasheet
Description
Bus fabric performance counter 0
Table 7. PERFCTR0
Register
Bits
Description
Type
Reset
31:24
Reserved.
-
-
23:0
Busfabric saturating performance counter 0
WC
0x000000
Count some event signal from the busfabric arbiters.
Write any value to clear. Select an event to count using PERFSEL0
BUSCTRL: PERFSEL0 Register
Offset: 0x0c
Description
Bus fabric performance event select for PERFCTR0
Table 8. PERFSEL0
Register
Bits
Description
Type
Reset
31:5
Reserved.
-
-
4:0
Select an event for PERFCTR0. Count either contested accesses, or all
RW
0x1f
accesses, on a downstream port of the main crossbar.
0x00 → apb_contested
0x01 → apb
0x02 → fastperi_contested
0x03 → fastperi
0x04 → sram5_contested
0x05 → sram5
0x06 → sram4_contested
0x07 → sram4
0x08 → sram3_contested
0x09 → sram3
0x0a → sram2_contested
0x0b → sram2
0x0c → sram1_contested
0x0d → sram1
0x0e → sram0_contested
0x0f → sram0
0x10 → xip_main_contested
0x11 → xip_main
0x12 → rom_contested
0x13 → rom
BUSCTRL: PERFCTR1 Register
Offset: 0x10
Description
Bus fabric performance counter 1
2.1. Bus Fabric
21
RP2040 Datasheet
Table 9. PERFCTR1
Register
Bits
Description
Type
Reset
31:24
Reserved.
-
-
23:0
Busfabric saturating performance counter 1
WC
0x000000
Count some event signal from the busfabric arbiters.
Write any value to clear. Select an event to count using PERFSEL1
BUSCTRL: PERFSEL1 Register
Offset: 0x14
Description
Bus fabric performance event select for PERFCTR1
Table 10. PERFSEL1
Register
Bits
Description
Type
Reset
31:5
Reserved.
-
-
4:0
Select an event for PERFCTR1. Count either contested accesses, or all
RW
0x1f
accesses, on a downstream port of the main crossbar.
0x00 → apb_contested
0x01 → apb
0x02 → fastperi_contested
0x03 → fastperi
0x04 → sram5_contested
0x05 → sram5
0x06 → sram4_contested
0x07 → sram4
0x08 → sram3_contested
0x09 → sram3
0x0a → sram2_contested
0x0b → sram2
0x0c → sram1_contested
0x0d → sram1
0x0e → sram0_contested
0x0f → sram0
0x10 → xip_main_contested
0x11 → xip_main
0x12 → rom_contested
0x13 → rom
BUSCTRL: PERFCTR2 Register
Offset: 0x18
Description
Bus fabric performance counter 2
2.1. Bus Fabric
22
RP2040 Datasheet
Table 11. PERFCTR2
Register
Bits
Description
Type
Reset
31:24
Reserved.
-
-
23:0
Busfabric saturating performance counter 2
WC
0x000000
Count some event signal from the busfabric arbiters.
Write any value to clear. Select an event to count using PERFSEL2
BUSCTRL: PERFSEL2 Register
Offset: 0x1c
Description
Bus fabric performance event select for PERFCTR2
Table 12. PERFSEL2
Register
Bits
Description
Type
Reset
31:5
Reserved.
-
-
4:0
Select an event for PERFCTR2. Count either contested accesses, or all
RW
0x1f
accesses, on a downstream port of the main crossbar.
0x00 → apb_contested
0x01 → apb
0x02 → fastperi_contested
0x03 → fastperi
0x04 → sram5_contested
0x05 → sram5
0x06 → sram4_contested
0x07 → sram4
0x08 → sram3_contested
0x09 → sram3
0x0a → sram2_contested
0x0b → sram2
0x0c → sram1_contested
0x0d → sram1
0x0e → sram0_contested
0x0f → sram0
0x10 → xip_main_contested
0x11 → xip_main
0x12 → rom_contested
0x13 → rom
BUSCTRL: PERFCTR3 Register
Offset: 0x20
Description
Bus fabric performance counter 3
2.1. Bus Fabric
23
RP2040 Datasheet
Table 13. PERFCTR3
Register
Bits
Description
Type
Reset
31:24
Reserved.
-
-
23:0
Busfabric saturating performance counter 3
WC
0x000000
Count some event signal from the busfabric arbiters.
Write any value to clear. Select an event to count using PERFSEL3
BUSCTRL: PERFSEL3 Register
Offset: 0x24
Description
Bus fabric performance event select for PERFCTR3
Table 14. PERFSEL3
Register
Bits
Description
Type
Reset
31:5
Reserved.
-
-
4:0
Select an event for PERFCTR3. Count either contested accesses, or all
RW
0x1f
accesses, on a downstream port of the main crossbar.
0x00 → apb_contested
0x01 → apb
0x02 → fastperi_contested
0x03 → fastperi
0x04 → sram5_contested
0x05 → sram5
0x06 → sram4_contested
0x07 → sram4
0x08 → sram3_contested
0x09 → sram3
0x0a → sram2_contested
0x0b → sram2
0x0c → sram1_contested
0x0d → sram1
0x0e → sram0_contested
0x0f → sram0
0x10 → xip_main_contested
0x11 → xip_main
0x12 → rom_contested
0x13 → rom
2.2. Address Map
The address map for the device is split in to sections as shown in Table 15. Details are shown in the following sections.
Unmapped address ranges raise a bus error when accessed.
2.2.1. Summary
Table 15. Address
Map Summary
ROM
0x00000000
XIP
0x10000000
SRAM
0x20000000
APB Peripherals
0x40000000
2.2. Address Map
24
RP2040 Datasheet
AHB-Lite Peripherals
0x50000000
IOPORT Registers
0xd0000000
Cortex-M0+ internal registers
0xe0000000
2.2.2. Detail
ROM:
ROM_BASE
0x00000000
XIP:
XIP_BASE
0x10000000
XIP_NOALLOC_BASE
0x11000000
XIP_NOCACHE_BASE
0x12000000
XIP_NOCACHE_NOALLOC_BASE
0x13000000
XIP_CTRL_BASE
0x14000000
XIP_SRAM_BASE
0x15000000
XIP_SRAM_END
0x15004000
XIP_SSI_BASE
0x18000000
SRAM. SRAM0-3 striped:
SRAM_BASE
0x20000000
SRAM_STRIPED_BASE
0x20000000
SRAM_STRIPED_END
0x20040000
SRAM 4-5 are always non-striped:
SRAM4_BASE
0x20040000
SRAM5_BASE
0x20041000
SRAM_END
0x20042000
Non-striped aliases of SRAM0-3:
SRAM0_BASE
0x21000000
SRAM1_BASE
0x21010000
SRAM2_BASE
0x21020000
SRAM3_BASE
0x21030000
APB Peripherals:
SYSINFO_BASE
0x40000000
SYSCFG_BASE
0x40004000
CLOCKS_BASE
0x40008000
2.2. Address Map
25
RP2040 Datasheet
RESETS_BASE
0x4000c000
PSM_BASE
0x40010000
IO_BANK0_BASE
0x40014000
IO_QSPI_BASE
0x40018000
PADS_BANK0_BASE
0x4001c000
PADS_QSPI_BASE
0x40020000
XOSC_BASE
0x40024000
PLL_SYS_BASE
0x40028000
PLL_USB_BASE
0x4002c000
BUSCTRL_BASE
0x40030000
UART0_BASE
0x40034000
UART1_BASE
0x40038000
SPI0_BASE
0x4003c000
SPI1_BASE
0x40040000
I2C0_BASE
0x40044000
I2C1_BASE
0x40048000
ADC_BASE
0x4004c000
PWM_BASE
0x40050000
TIMER_BASE
0x40054000
WATCHDOG_BASE
0x40058000
RTC_BASE
0x4005c000
ROSC_BASE
0x40060000
VREG_AND_CHIP_RESET_BASE
0x40064000
TBMAN_BASE
0x4006c000
AHB-Lite peripherals:
DMA_BASE
0x50000000
USB has a DPRAM at its base followed by registers:
USBCTRL_BASE
0x50100000
USBCTRL_DPRAM_BASE
0x50100000
USBCTRL_REGS_BASE
0x50110000
Remaining AHB-Lite peripherals:
PIO0_BASE
0x50200000
PIO1_BASE
0x50300000
XIP_AUX_BASE
0x50400000
IOPORT Peripherals:
2.2. Address Map
26
RP2040 Datasheet
0xd0000000
SIO_BASE
Cortex-M0+ Internal Peripherals:
0xe0000000
PPB_BASE
2.3. Processor subsystem
The RP2040 processor subsystem consists of two Arm Cortex-M0+ processors — each with its standard internal Arm
CPU peripherals — alongside external peripherals for GPIO access and inter-core communication. Details of the Arm
Cortex-M0+ processors, including the specific feature configuration used on RP2040, can be found in Section 2.4.
Figure 6. Two CortexM0+ processors, each
with a dedicated 32-bit
From peripherals
From external debugger
Interrupts
Serial Wire Debug
AHB-Lite bus port, for
code fetch, loads and
stores. The SIO is
connected to the
single-cycle IOPORT
NVIC
bus of each processor,
DAP
NVIC
Core 0
and provides GPIO
Core 1
Events
Cortex-M0+
DAP
Cortex-M0+
access, two-way
communications, and
Bus Interface
other core-local
SIO
IOPORT
Bus Interface
AHB-Lite
GPIO ×36
AHB-Lite
To bus fabric
To GPIO Muxing
To bus fabric
peripherals. Both
processors can be
IOPORT
debugged via a single
multi-drop Serial Wire
Debug bus. 26
interrupts (plus NMI)
NOTE
are routed to the NVIC
and WIC on each
The terms core0 and core1, proc0 and proc1 are used interchangeably in RP2040’s registers and documentation to
processor.
refer to processor 0, and processor 1 respectively.
The processors use a number of interfaces to communicate with the rest of the system:
• Each processor uses its own independent 32-bit AHB-Lite bus to access memory and memory-mapped peripherals
(more detail in Section 2.1)
• The single-cycle IO block provides high-speed, deterministic access to GPIOs via each processor’s IOPORT
• 26 system-level interrupts are routed to both processors
• A multi-drop Serial Wire Debug bus provides debug access to both processors from an external debug host
2.3.1. SIO
The Single-cycle IO block (SIO) contains several peripherals that require low-latency, deterministic access from the
processors. It is accessed via each processor’s IOPORT: this is an auxiliary bus port on the Cortex-M0+ which can
perform rapid 32-bit reads and writes. The SIO has a dedicated bus interface for each processor’s IOPORT, as shown in
Figure 7. Processors access their IOPORT with normal load and store instructions, directed to the special IOPORT
address segment, 0xd0000000…0xdfffffff. The SIO appears as memory-mapped hardware within the IOPORT space.
2.3. Processor subsystem
27
RP2040 Datasheet
NOTE
The SIO is not connected to the main system bus due to its tight timing requirements. It can only be accessed by the
processors, or by the debugger via the processor debug ports.
Figure 7. The singlecycle IO block
contains memory-
Core 0
Core 1
mapped hardware
Single-cycle IO
which the processors
must be able to
IOPORT
IOPORT
access quickly. The
FIFOs and spinlocks
CPUID 1
CPUID 0
support message
passing and
FIFO 0 to 1
synchronisation
between the two
cores. The shared
FIFO 1 to 0
GPIO registers provide
fast and concurrency-
Bus
safe direct access to
GPIO-capable pins.
Interface
Hardware Spinlock ×32
Bus
Interface
Some core-local
arithmetic hardware
can be used to
Integer Divider
Integer Divider
Interpolator 0
Interpolator 0
Interpolator 1
Interpolator 1
accelerate common
tasks on the
processors.
GPIO Registers Shared, atomic
set/clear/xor
GPIO ×36
To GPIO Muxing
All IOPORT reads and writes (and therefore all SIO accesses) take place in exactly one cycle, unlike the main AHB-Lite
system bus, where the Cortex-M0+ requires two cycles for a load or store, and may have to wait longer due to
contention from other system bus masters. This is vital for interfaces such as GPIO, which have tight timing
requirements.
SIO registers are mapped to word-aligned addresses in the range 0xd0000000…0xd000017c. The remainder of the IOPORT
space is reserved for future use.
The SIO peripherals are described in more detail in the following sections.
2.3.1.1. CPUID
The register CPUID is the first register in the IOPORT space. Core 0 reads a value of 0 when accessing this address, and
core 1 reads a value of 1. This is a convenient method for software to determine on which core it is running. This is
checked during the initial boot sequence: both cores start running simultaneously, core 1 goes into a deep sleep state,
and core 0 continues with the main boot sequence.
2.3. Processor subsystem
28
RP2040 Datasheet
IMPORTANT
CPUID should not be confused with the Cortex-M0+ CPUID register (Section 2.4.4.1.1) on each processor’s internal
Private Peripheral Bus, which lists the processor’s part number and version.
2.3.1.2. GPIO Control
The processors have access to GPIO registers for fast and direct control of pins with GPIO functionality. There are two
identical sets of registers:
• GPIO_x for direct control of IO bank 0 (user GPIOs 0 to 29, starting at the LSB)
• GPIO_HI_x for direct control of the QSPI IO bank (in the order SCLK, SSn, SD0, SD1, SD2, SD3, starting at the LSB)
NOTE
To drive a pin with the SIO’s GPIO registers, the GPIO multiplexer for this pin must first be configured to select the
SIO GPIO function. See Table 278.
These GPIO registers are shared between the two cores, and both cores can access them simultaneously. There are
three registers for each bank:
• Output registers, GPIO_OUT and GPIO_HI_OUT, are used to set the output level of the GPIO (1/0 for high/low)
• Output enable registers, GPIO_OE and GPIO_HI_OE, are used to enable the output driver. 0 for high-impedance, 1
for drive high/low based on GPIO_OUT and GPIO_HI_OUT.
• Input registers, GPIO_IN and GPIO_HI_IN, allow the processor to sample the current state of the GPIOs
Reading GPIO_IN returns all 30 GPIO values (or 6 for GPIO_HI_IN) in a single read. Software can then mask out
individual pins it is interested in.
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_gpio/include/hardware/gpio.h Lines 444 - 446
444 static inline bool gpio_get(uint gpio) {
445
return !!((1ul gpio_in);
446 }
The OUT and OE registers also have atomic SET, CLR, and XOR aliases, which allows software to update a subset of the
pins in one operation. This is vital not only for safe parallel GPIO access between the two cores, but also safe
concurrent GPIO access in an interrupt handler and foreground code running on one core.
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_gpio/include/hardware/gpio.h Lines 466 - 468
466 static inline void gpio_set_mask(uint32_t mask) {
467
sio_hw->gpio_set = mask;
468 }
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_gpio/include/hardware/gpio.h Lines 475 - 477
475 static inline void gpio_clr_mask(uint32_t mask) {
476
sio_hw->gpio_clr = mask;
477 }
2.3. Processor subsystem
29
RP2040 Datasheet
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_gpio/include/hardware/gpio.h Lines 518 - 524
518 static inline void gpio_put(uint gpio, bool value) {
519
uint32_t mask = 1ul accum[0] = 0;
19
interp0->base[0] = 9;
20
21
22
for (int i = 0; i < 10; ++i)
printf("%d\n", interp0->pop[0]);
23 }
2.3. Processor subsystem
33
RP2040 Datasheet
NOTE
By sheer coincidence, the interpolators are extremely well suited to SNES MODE7-style graphics routines. For
example, on each core, INTERP0 can provide a stream of tile lookups for some affine transform, and INTERP1 can
provide offsets into the tiles for the same transform.
2.3.1.6.1. Lane Operations
Figure 9. Each lane of
each interpolator can
be configured to
perform mask, shift
and sign-extension on
Result 0
0
0
Accumulator 0
Result 1
1
Right Shift
Mask
1
Sign-extend
fromMask
Accumulator 1
one of the
1
1
0
0
Add to BASE1
(for PEEK0/POP0)
Add to BASE2
(forms part of
accumulators. This is
PEEK2/POP2)
fed into adders which
produces final results,
which may optionally
be fed back into the
accumulators with
each read. The
datapath can be
configured using a
handful of 32-bit
multiplexers. From left
Each lane performs these three operations, in sequence:
• A right shift by CTRL_LANEx_SHIFT (0 to 31 bits)
• A mask of bits from CTRL_LANEx_MASK_LSB to CTRL_LANEx_MASK_MSB inclusive (each ranging from bit 0 to bit 31)
• A sign extension from the top of the mask, i.e. take bit CTRL_LANEx_MASK_MSB and OR it into all more-significant bits, if
CTRL_LANEx_SIGNED is set
to right, these are
controlled by the
following CTRL flags:
CROSS_RESULT,
CROSS_INPUT,
SIGNED, ADD_RAW.
For example, if:
• ACCUM0 = 0xdeadbeef
• CTRL_LANE0_SHIFT = 8
• CTRL_LANE0_MASK_LSB = 4
• CTRL_LANE0_MASK_MSB = 7
• CTRL_SIGNED = 1
Then lane 0 would produce the following results at each stage:
• Right shift by 8 to produce 0x00deadbe
• Mask bits 7 to 4 to produce 0x00deadbe & 0x000000f0 = 0x000000b0
• Sign-extend up from bit 7 to produce 0xffffffb0
In software:
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/interp/hello_interp/hello_interp.c Lines 25 - 46
25 void moving_mask() {
26
interp_config cfg = interp_default_config();
27
interp0->accum[0] = 0x1234abcd;
28
29
puts("Masking:");
30
printf("ACCUM0 = %08x\n", interp0->accum[0]);
31
for (int i = 0; i < 8; ++i) {
32
// LSB, then MSB. These are inclusive, so 0,31 means "the entire 32 bit register"
33
interp_config_set_mask(&cfg, i * 4, i * 4 + 3);
34
interp_set_config(interp0, 0, &cfg);
35
// Reading from ACCUMx_ADD returns the raw lane shift and mask value, without BASEx
added
36
37
printf("Nibble %d: %08x\n", i, interp0->add_raw[0]);
}
38
2.3. Processor subsystem
34
RP2040 Datasheet
39
puts("Masking with sign extension:");
40
interp_config_set_signed(&cfg, true);
41
for (int i = 0; i < 8; ++i) {
42
interp_config_set_mask(&cfg, i * 4, i * 4 + 3);
43
interp_set_config(interp0, 0, &cfg);
44
45
printf("Nibble %d: %08x\n", i, interp0->add_raw[0]);
}
46 }
The above example should print:
ACCUM0 = 1234abcd
Nibble 0: 0000000d
Nibble 1: 000000c0
Nibble 2: 00000b00
Nibble 3: 0000a000
Nibble 4: 00040000
Nibble 5: 00300000
Nibble 6: 02000000
Nibble 7: 10000000
Masking with sign extension:
Nibble 0: fffffffd
Nibble 1: ffffffc0
Nibble 2: fffffb00
Nibble 3: ffffa000
Nibble 4: 00040000
Nibble 5: 00300000
Nibble 6: 02000000
Nibble 7: 10000000
Changing the result and input multiplexers can create feedback between the accumulators. This is useful e.g. for audio
dithering.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/interp/hello_interp/hello_interp.c Lines 48 - 63
48 void cross_lanes() {
49
interp_config cfg = interp_default_config();
50
interp_config_set_cross_result(&cfg, true);
51
// ACCUM0 gets lane 1 result:
52
interp_set_config(interp0, 0, &cfg);
53
// ACCUM1 gets lane 0 result:
54
interp_set_config(interp0, 1, &cfg);
55
56
interp0->accum[0] = 123;
57
interp0->accum[1] = 456;
58
interp0->base[0] = 1;
59
interp0->base[1] = 0;
60
puts("Lane result crossover:");
61
for (int i = 0; i < 10; ++i)
62
printf("PEEK0, POP1: %d, %d\n", interp0->peek[0], interp0->pop[1]);
63 }
This should print:
PEEK0, POP1: 124, 456
PEEK0, POP1: 457, 124
PEEK0, POP1: 125, 457
2.3. Processor subsystem
35
RP2040 Datasheet
PEEK0, POP1: 458, 125
PEEK0, POP1: 126, 458
PEEK0, POP1: 459, 126
PEEK0, POP1: 127, 459
PEEK0, POP1: 460, 127
PEEK0, POP1: 128, 460
PEEK0, POP1: 461, 128
2.3.1.6.2. Blend Mode
Blend mode is available on INTERP0 on each core, and is enabled by the CTRL_LANE0_BLEND control flag. It performs linear
interpolation, which we define as follows:
Where
is the register BASE0,
is the register BASE1, and
is a fractional value formed from the least significant 8 bits
of the lane 1 shift and mask value.
Blend mode has the following differences from normal mode:
• PEEK0, POP0 return the 8-bit alpha value (the 8 LSBs of the lane 1 shift and mask value), with zeroes in result bits 31
down to 24.
• PEEK1, POP1 return the linear interpolation between BASE0 and BASE1
• PEEK2, POP2 do not include lane 1 result in the addition (i.e. it is BASE2 + lane 0 shift and mask value)
The result of the linear interpolation is equal to BASE0 when the alpha value is 0, and equal to BASE0 + 255/256 * (BASE1 BASE0) when the alpha value is all-ones.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/interp/hello_interp/hello_interp.c Lines 65 - 84
65 void simple_blend1() {
66
puts("Simple blend 1:");
67
68
interp_config cfg = interp_default_config();
69
interp_config_set_blend(&cfg, true);
70
interp_set_config(interp0, 0, &cfg);
71
72
cfg = interp_default_config();
73
interp_set_config(interp0, 1, &cfg);
74
75
interp0->base[0] = 500;
76
interp0->base[1] = 1000;
77
78
for (int i = 0; i accum[1] = 255 * i / 6;
81
// ≈ 500 + (1000 - 500) * i / 6;
82
83
printf("%d\n", (int) interp0->peek[1]);
}
84 }
This should print (note the 255/256 resulting in 998 not 1000):
500
582
666
748
832
2.3. Processor subsystem
36
RP2040 Datasheet
914
998
CTRL_LANE1_SIGNED controls whether BASE0 and BASE1 are sign-extended for this interpolation (this sign extension is
required because the interpolation produces an intermediate product value 40 bits in size). CTRL_LANE0_SIGNED continues
to control the sign extension of the lane 0 intermediate result in PEEK2, POP2 as normal.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/interp/hello_interp/hello_interp.c Lines 87 - 118
87 void print_simple_blend2_results(bool is_signed) {
88
// lane 1 signed flag controls whether base 0/1 are treated as signed or unsigned
89
interp_config cfg = interp_default_config();
90
interp_config_set_signed(&cfg, is_signed);
91
interp_set_config(interp0, 1, &cfg);
92
93
for (int i = 0; i accum[1] = 255 * i / 6;
95
if (is_signed) {
96
printf("%d\n", (int) interp0->peek[1]);
97
} else {
98
printf("0x%08x\n", (uint) interp0->peek[1]);
99
100
}
}
101 }
102
103 void simple_blend2() {
104
puts("Simple blend 2:");
105
106
interp_config cfg = interp_default_config();
107
interp_config_set_blend(&cfg, true);
108
interp_set_config(interp0, 0, &cfg);
109
110
interp0->base[0] = -1000;
111
interp0->base[1] = 1000;
112
113
puts("signed:");
114
print_simple_blend2_results(true);
115
116
puts("unsigned:");
117
print_simple_blend2_results(false);
118 }
This should print:
signed:
-1000
-672
-336
-8
328
656
992
unsigned:
0xfffffc18
0xd5fffd60
0xaafffeb0
0x80fffff8
0x56000148
0x2c000290
2.3. Processor subsystem
37
RP2040 Datasheet
0x010003e0
Finally, in blend mode when using the BASE_1AND0 register to send a 16-bit value to each of BASE0 and BASE1 with a single
32-bit write, the sign-extension of these 16-bit values to full 32-bit values during the write is controlled by
CTRL_LANE1_SIGNED for both bases, as opposed to non-blend-mode operation, where CTRL_LANE0_SIGNED affects extension
into BASE0 and CTRL_LANE1_SIGNED affects extension into BASE1.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/interp/hello_interp/hello_interp.c Lines 121 - 142
121 void simple_blend3() {
122
puts("Simple blend 3:");
123
124
interp_config cfg = interp_default_config();
125
interp_config_set_blend(&cfg, true);
126
interp_set_config(interp0, 0, &cfg);
127
128
cfg = interp_default_config();
129
interp_set_config(interp0, 1, &cfg);
130
131
interp0->accum[1] = 128;
132
interp0->base01 = 0x30005000;
133
printf("0x%08x\n", (int) interp0->peek[1]);
134
interp0->base01 = 0xe000f000;
135
printf("0x%08x\n", (int) interp0->peek[1]);
136
137
interp_config_set_signed(&cfg, true);
138
interp_set_config(interp0, 1, &cfg);
139
140
interp0->base01 = 0xe000f000;
141
printf("0x%08x\n", (int) interp0->peek[1]);
142 }
This should print:
0x00004000
0x0000e800
0xffffe800
2.3.1.6.3. Clamp Mode
Clamp mode is available on INTERP1 on each core, and is enabled by the CTRL_LANE0_CLAMP control flag. In clamp mode, the
PEEK0/POP0 result is the lane value (shifted, masked, sign-extended ACCUM0) clamped between BASE0 and BASE1. In other
words, if the lane value is greater than BASE1, a value of BASE1 is produced; if less than BASE0, a value of BASE0 is produced;
otherwise, the value passes through. No addition is performed. The signedness of these comparisons is controlled by
the CTRL_LANE0_SIGNED flag.
Other than this, the interpolator behaves the same as in normal mode.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/interp/hello_interp/hello_interp.c Lines 188 - 206
188 void clamp() {
189
puts("Clamp:");
190
interp_config cfg = interp_default_config();
191
interp_config_set_clamp(&cfg, true);
192
interp_config_set_shift(&cfg, 2);
193
// set mask according to new position of sign bit..
2.3. Processor subsystem
38
RP2040 Datasheet
194
interp_config_set_mask(&cfg, 0, 29);
195
// ...so that the shifted value is correctly sign extended
196
interp_config_set_signed(&cfg, true);
197
interp_set_config(interp1, 0, &cfg);
198
199
interp1->base[0] = 0;
200
interp1->base[1] = 255;
201
202
for (int i = -1024; i accum[0] = i;
204
205
printf("%d\t%d\n", i, (int) interp1->peek[0]);
}
206 }
This should print:
-1024
0
-768
0
-512
0
-256
0
0
0
256
64
512
128
768
192
1024
255
2.3.1.6.4. Sample Use Case: Linear Interpolation
Linear interpolation is a more complete example of using blend mode in conjunction with other interpolator
functionality:
In this example, ACCUM0 is used to track a fixed point (integer/fraction) position within a list of values to be interpolated.
Lane 0 is used to produce an address into the value array for the integer part of the position. The fractional part of the
position is shifted to produce a value from 0-255 for the blend. The blend is performed between two consecutive values
in the array.
Finally the fractional position is updated via a single write to ACCUM0_ADD_RAW.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/interp/hello_interp/hello_interp.c Lines 144 - 186
144 void linear_interpolation() {
145
puts("Linear interpolation:");
146
const int uv_fractional_bits = 12;
147
148
// for lane 0
149
// shift and mask XXXX XXXX XXXX XXXX XXXX FFFF FFFF FFFF (accum 0)
150
// to
151
// i.e. non fractional part times 2 (for uint16_t)
152
interp_config cfg = interp_default_config();
153
interp_config_set_shift(&cfg, uv_fractional_bits - 1);
154
interp_config_set_mask(&cfg, 1, 32 - uv_fractional_bits);
155
interp_config_set_blend(&cfg, true);
156
interp_set_config(interp0, 0, &cfg);
0000 0000 000X XXXX XXXX XXXX XXXX XXX0
157
158
// for lane 1
159
// shift XXXX XXXX XXXX XXXX XXXX FFFF FFFF FFFF (accum 0 via cross input)
160
// to
0000 XXXX XXXX XXXX XXXX FFFF FFFF FFFF
161
2.3. Processor subsystem
39
RP2040 Datasheet
162
cfg = interp_default_config();
163
interp_config_set_shift(&cfg, uv_fractional_bits - 8);
164
interp_config_set_signed(&cfg, true);
165
interp_config_set_cross_input(&cfg, true); // signed blending
166
interp_set_config(interp0, 1, &cfg);
167
168
int16_t samples[] = {0, 10, -20, -1000, 500};
169
170
// step is 1/4 in our fractional representation
171
uint step = (1 accum[0] = 0; // initial sample_offset;
174
interp0->base[2] = (uintptr_t) samples;
175
for (int i = 0; i < 16; i++) {
176
// result2 = samples + (lane0 raw result)
177
// i.e. ptr to the first of two samples to blend between
178
int16_t *sample_pair = (int16_t *) interp0->peek[2];
179
interp0->base[0] = sample_pair[0];
180
interp0->base[1] = sample_pair[1];
181
printf("%d\t(%d%% between %d and %d)\n", (int) interp0->peek[1],
182
100 * (interp0->add_raw[1] & 0xff) / 0xff,
183
sample_pair[0], sample_pair[1]);
184
185
interp0->add_raw[0] = step;
}
186 }
This should print:
0
(0% between 0 and 10)
2
(25% between 0 and 10)
5
(50% between 0 and 10)
7
(75% between 0 and 10)
10
(0% between 10 and -20)
2
(25% between 10 and -20)
-5
(50% between 10 and -20)
-13
(75% between 10 and -20)
-20
(0% between -20 and -1000)
-265
(25% between -20 and -1000)
-510
(50% between -20 and -1000)
-755
(75% between -20 and -1000)
-1000
(0% between -1000 and 500)
-625
(25% between -1000 and 500)
-250
(50% between -1000 and 500)
125
(75% between -1000 and 500)
This method is used for fast approximate audio upscaling in the SDK
2.3.1.6.5. Sample Use Case: Simple Affine Texture Mapping
Simple affine texture mapping can be implemented by using fixed point arithmetic for texture coordinates, and stepping
a fixed amount in each coordinate for every pixel in a scanline. The integer part of the texture coordinates are used to
form an address within the texture to lookup a pixel colour.
By using two lanes, all three base values and the CTRL_LANEx_ADD_RAW flag, it is possible to reduce what would be quite an
expensive CPU operation to a single cycle iteration using the interpolator.
2.3. Processor subsystem
40
RP2040 Datasheet
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/interp/hello_interp/hello_interp.c Lines 209 - 267
209 void texture_mapping_setup(uint8_t *texture, uint texture_width_bits, uint
texture_height_bits,
210
uint uv_fractional_bits) {
211
interp_config cfg = interp_default_config();
212
// set add_raw flag to use raw (un-shifted and un-masked) lane accumulator value when
adding
213
// it to the the lane base to make the lane result
214
interp_config_set_add_raw(&cfg, true);
215
interp_config_set_shift(&cfg, uv_fractional_bits);
216
interp_config_set_mask(&cfg, 0, texture_width_bits - 1);
217
interp_set_config(interp0, 0, &cfg);
218
219
interp_config_set_shift(&cfg, uv_fractional_bits - texture_width_bits);
220
interp_config_set_mask(&cfg, texture_width_bits, texture_width_bits +
texture_height_bits - 1);
221
interp_set_config(interp0, 1, &cfg);
222
223
interp0->base[2] = (uintptr_t) texture;
224 }
225
226 void texture_mapped_span(uint8_t *output, uint32_t u, uint32_t v, uint32_t du, uint32_t dv,
uint count) {
227
// u, v are texture coordinates in fixed point with uv_fractional_bits fractional bits
228
// du, dv are texture coordinate steps across the span in same fixed point.
229
interp0->accum[0] = u;
230
interp0->base[0] = du;
231
interp0->accum[1] = v;
232
interp0->base[1] = dv;
233
for (uint i = 0; i < count; i++) {
234
// equivalent to
235
// uint32_t sm_result0 = (accum0 >> uv_fractional_bits) & (1 > uv_fractional_bits) & (1 dr,
97
NULL,
// Initial read address and transfer count are unimportant;
98
0,
// the control channel will reprogram them each time.
99
false
// Don't start yet.
100
);
101
102
// Everything is ready to go. Tell the control channel to load the first
103
// control block. Everything is automatic from here.
104
dma_start_channel_mask(1u sleep_en1 = 0x0;
113
114
rtc_set_alarm(t, callback);
115
116
uint save = scb_hw->scr;
117
// Enable deep sleep at the proc
118
scb_hw->scr = save | M0PLUS_SCR_SLEEPDEEP_BITS;
119
120
// Go to sleep
121
__wfi();
122 }
2.11. Power Control
165
RP2040 Datasheet
2.11.5.2. Dormant
The
hello_dormant
example,
https://github.com/raspberrypi/pico-playground/tree/master/sleep/hello_dormant/
hello_dormant.c, demonstrates dormant mode. The example takes the following steps:
• Run all clocks in the system from XOSC
• Configure a GPIO interrupt for the "dormant_wake" hardware which can wake both the ROSC and XOSC from
dormant mode
• Put the XOSC into dormant mode which stops all processor execution (and all other clocked logic on the chip)
immediately
• When GPIO 10 goes high, the XOSC is started again and execution of the program continues
hello_dormant uses sleep_goto_dormant_until_pin under the hood:
Pico Extras: https://github.com/raspberrypi/pico-extras/tree/master/src/rp2_common/pico_sleep/sleep.c Lines 134 - 155
134 void sleep_goto_dormant_until_pin(uint gpio_pin, bool edge, bool high) {
135
bool low = !high;
136
bool level = !edge;
137
138
// Configure the appropriate IRQ at IO bank 0
139
assert(gpio_pin < NUM_BANK0_GPIOS);
140
141
uint32_t event = 0;
142
143
if (level && low) event = IO_BANK0_DORMANT_WAKE_INTE0_GPIO0_LEVEL_LOW_BITS;
144
if (level && high) event = IO_BANK0_DORMANT_WAKE_INTE0_GPIO0_LEVEL_HIGH_BITS;
145
if (edge && high) event = IO_BANK0_DORMANT_WAKE_INTE0_GPIO0_EDGE_HIGH_BITS;
146
if (edge && low) event = IO_BANK0_DORMANT_WAKE_INTE0_GPIO0_EDGE_LOW_BITS;
147
148
gpio_set_dormant_irq_enabled(gpio_pin, event, true);
149
150
_go_dormant();
151
// Execution stops here until woken up
152
153
// Clear the irq so we can go back to dormant mode again if we want
154
gpio_acknowledge_irq(gpio_pin, event);
155 }
2.12. Chip-Level Reset
2.12.1. Overview
The chip-level reset subsystem resets the whole chip, placing it in a default state. This happens at initial power-on,
during a power supply brown-out event or when the chip’s RUN pin is taken low. The chip can also be reset via the
Rescue Debug Port. See Section 2.3.4.2, “Rescue DP” for details.
The subsystem has two reset outputs. rst_n_psm, which resets the whole chip, except the debug port, and rst_n_dp, which
only resets the Rescue DP. Both resets are held low at initial power-on, during a brown-out event or when RUN is low.
rst_n_psm can additionally be held low by the Rescue DP via the subsystem’s psm_restart input. This allows the chip to be
reset via the Rescue DP without resetting the Rescue DP itself. The subsystem releases chip level reset by taking
rst_n_psm high, handing control to the Power-on State Machine, which continues to start up the chip. See Section 2.13,
“Power-On State Machine” for details.
The chip level reset subsystem is shown in Figure 21, and more information is available in the following sections.
2.12. Chip-Level Reset
166
RP2040 Datasheet
Figure 21. The chiplevel reset subsystem
2.12.2. Power-on Reset
The power-on reset block makes sure the chip starts up cleanly when power is first applied by holding it in reset until the
digital core supply (DVDD) can reliably power the chip’s core logic. The block holds its por_n output low until DVDD has
been above the power-on reset threshold (DVDDTH.POR) for a period greater than the power-on reset assertion delay
(tPOR.ASSERT). Once high, por_n remains high even if DVDD subsequently falls below DVDDTH.POR, unless brown-out detection
is enabled. The behaviour of por_n when power is applied is shown in Figure 22.
DVDDTH.POR is fixed at a nominal 0.957V, which should result in a threshold between 0.924V and 0.99V. The threshold
assumes a nominal DVDD of 1.1V at initial power-on, and por_n may never go high if a lower voltage is used. Once the
chip is out of reset, DVDD can be reduced without por_n going low, as long as brown-out detection has been disabled or
a suitable threshold voltage has been set.
Figure 22. A power-on
reset cycle
DVDDTH.POR
DVDD
tPOR.ASSERT
por_n
2.12.2.1. Detailed Specifications
2.12. Chip-Level Reset
167
RP2040 Datasheet
Table 193. Power-on
Reset Parameters
Parameter
Description
Min
Typ
Max
Units
DVDDTH.POR
power-on reset
0.924
0.957
0.99
V
3
10
μs
threshold
tPOR.ASSERT
power-on reset
assertion delay
2.12.3. Brown-out Detection
The brown-out detection block prevents unreliable operation by initiating a power-on reset cycle if the digital core supply
(DVDD) drops below a safe operating level. The block’s bod_n output is taken low if DVDD drops below the brown-out
detection threshold (DVDDTH.BOD) for a period longer than the brown-out detection assertion delay (tBOD.ASSERT). This reinitialises the power-on reset block, which resets the chip, by taking its por_n output low, and holds it in reset until DVDD
returns to a safe operating level. Figure 23 shows a brown-out event and the subsequent power-on reset cycle.
Figure 23. A brown-out
detection cycle
DVDD
DVDDTH.POR
DVDDTH.BOD
tPOR.ASSERT
por_n
tBOD.ASSERT
bod_n
2.12.3.1. Detection Enable
Brown-out detection is automatically enabled at initial power-on or after a brown-out initiated reset. There is, however, a
short delay, the brown-out detection activation delay (tBOD.ACTIVE), between por_n going high and detection becoming active.
This is shown in Figure 24.
Figure 24. Activation
of brown-out detection
DVDDTH.POR
DVDDTH.POR
DVDDTH.BOD
DVDD
at initial power-on and
tPOR.ASSERT
following a brown-out
tPOR.ASSERT
event.
por_n
tBOD.ASSERT
bod_n
tBOD.ACTIVE
detection
inactive
tBOD.ACTIVE
detection
active
detection
inactive
detection
active
Once the chip is out of reset, detection can be disabled under software control. This also saves a small amount of
power. If detection is subsequently re-enabled, there will be another short delay, the brown-out detection enable delay
(tBOD.ENABLE), before it becomes active again. This is shown in Figure 25.
Detection is disabled by writing a zero to the EN field in the BOD register and is re-enabled by writing a one to the same
field. The block’s bod_n output is high when detection is disabled.
2.12. Chip-Level Reset
168
RP2040 Datasheet
Figure 25. Disabling
and enabling brownout detection
EN
1
0
1
tBOD.ENABLE
detection
inactive
detection
inactive
detection
active
Detection is re-enabled if the BOD register is reset, as this sets the register’s EN field to one. Again, detection will become
active after a delay equal to the brown-out detection enable delay (tBOD.ENABLE).
NOTE
If the BOD register is reset by a power-on or brown-out initiated reset, the delay between the register being reset and
brown-out detection becoming active will be equal to the brown-out detection activation delay (tBOD.ACTIVE). The delay
will be equal to the brown-out detection enable delay (tBOD.ENABLE) for all other reset sources.
2.12.3.2. Adjusting the Detection Threshold
The brown-out detection threshold (DVDDTH.BOD) has a nominal value of 0.86V at initial power-on or after a reset event.
This should result in a detection threshold between 0.83V and 0.89V. Once out of reset, the threshold can be adjusted
under software control. The new detection threshold will take effect after the brown-out detection programming delay
((tBOD.PROG). An example of this is shown in Figure 26.
The threshold is adjusted by writing to the VSEL field in the BOD register. See the BOD register description for details.
Figure 26. Adjusting
the brown-out
detection threshold
VSEL
1001
0111
tBOD.PROG
threshold
0.86V
threshold
0.774V
2.12.3.3. Detailed Specifications
Table 194. Brown-out
Detection Parameters
Parameter
Description
Min
Typ
Max
DVDDTH.BOD
brown-out
96.5
100
103.5
detection
Units
% of selected
threshold voltage
threshold
tBOD.ACTIVE
brown-out
55
80
μs
detection
activation delay
2.12. Chip-Level Reset
169
RP2040 Datasheet
Parameter
Description
tBOD.ASSERT
brown-out
Min
Typ
Max
Units
3
10
μs
35
55
μs
20
30
μs
detection
assertion delay
tBOD.ENABLE
brown-out
detection enable
delay
tBOD.PROG
brown-out
detection
programming
delay
2.12.4. Supply Monitor
The power-on and brown-out reset blocks are powered by the on-chip voltage regulator’s input supply (VREG_VIN). The
blocks are initialised when power is first applied, but may not be reliably re-initialised if power is removed and then
reapplied before VREG_VIN has dropped to a sufficiently low level. To prevent this happening, VREG_VIN is monitored
and the power-on reset block is re-initialised if it drops below the VREG_VIN activation threshold (VREG_VINTH.ACTIVE).
VREG_VINTH.ACTIVE is fixed at a nominal 1.1V, which should result in a threshold between 0.87V and 1.26V. This threshold
does not represent a safe operating voltage. It is the voltage that VREG_VIN must drop below to reliably re-initialise the
power-on reset block. For safe operation, VREG_VIN must be at a nominal voltage between 1.8V and 3.3V.
2.12.4.1. Detailed Specifications
Table 195. Voltage
Regulator Input Supply
Monitor Parameters
Parameter
Description
Min
Typ
Max
Units
VREG_VINTH.ACTIVE
VREG_VIN
0.87
1.1
1.26
V
activation
threshold
2.12.5. External Reset
The chip can also be reset by taking its RUN pin low. Taking RUN low will hold the chip in reset irrespective of the state
of the core power supply (DVDD) and the power-on reset / brown-out detection blocks. The chip will come out of reset
as soon as RUN is taken high, if all other reset sources have been released. RUN can be used to extend the initial poweron reset, or can be driven from an external source to start and stop the chip as required. If RUN is not used, it should be
tied high.
2.12.6. Rescue Debug Port Reset
The chip can also be reset via the Rescue Debug Port. This allows the chip to be recovered from a locked up state. In
addition to resetting the chip, a Rescue Debug Port reset also sets the PSM_RESTART_FLAG in the CHIP_RESET register. This
is checked by the bootcode at startup, causing it to enter a safe state if the bit is set. See Section 2.3.4.2, “Rescue DP”
for more information.
2.12.7. Source of Last Reset
The source of the most recent chip-level reset can be determined by reading the state of the HAD_POR, HAD_RUN and
HAD_PSM_RESTART fields in the CHIP_RESET register. A one in the HAD_POR field indicates a power supply related reset, i.e.
either a power-on or brown-out initiated reset, a one in the HAD_RUN field indicates the chip was last reset by the RUN pin,
2.12. Chip-Level Reset
170
RP2040 Datasheet
and a one in the HAD_PSM_RESTART field indicates the chip has been reset via Rescue Debug Port. There should never be
more than one field set to one.
2.12.8. List of Registers
The chip-level reset subsystem shares a register address space with the on-chip voltage regulator. The registers for
both subsystems are listed in Section 2.10.6. The shared address space is referred to as vreg_and_chip_reset elsewhere
in this document.
2.13. Power-On State Machine
2.13.1. Overview
The power-on state machine removes the reset from various hardware blocks in a specific order. Each peripheral in the
power-on state machine is controlled by an internal rst_n active-low reset signal and generates an internal rst_done
active-high reset done signal. The power-on state machine deasserts the reset to each peripheral, waits for that
peripheral to assert its rst_done and then deasserts the reset to the next peripheral. An important use of this is to wait
for a clock source to be running cleanly in the chip before the reset to the clock generators is deasserted. This avoids
potentially glitchy clocks being distributed to the chip.
The power-on state machine is itself taken out of reset when the Chip-Level Reset subsystem confirms that the digital
core supply (DVDD) is powered and stable, and the RUN pin is high. The power-on state machine takes a number of other
blocks out of reset at this point via its rst_n_run output. This is used to reset things that need to be reset at start-up but
must not be reset if the power-on state machine is restarted. This list includes:
• Power on logic in the ring oscillator and crystal oscillator
• Clock dividers which must keep on running during a power-on state machine restart (clk_ref and clk_sys)
• Watchdog (contains scratch registers which need to persist through a soft-restart of the power-on state machine)
2.13.2. Power On Sequence
Figure 27. Power-On
State Machine
Sequence.
Chip Level Reset
Released
Ring Oscillator
Crystal Oscillator
Clock Generators
Reset Controller
Chip Level Reset
and Voltage
Regulator Registers
XIP
(Execute-In-Place)
ROM / SRAM
Bus Fabric
Processor Complex
The power-on state machine sequence is as follows:
• Chip-Level Reset subsystem deasserts power-on state machine reset once digital core supply (DVDD) is powered
and stable, and RUN pin is high (rst_n_run is also deasserted at this point)
• Ring Oscillator is started. rst_done is asserted once the ripple counter has seen a sufficient number of clock edges
to indicate the ring oscillator is stable
2.13. Power-On State Machine
171
RP2040 Datasheet
• Crystal Oscillator reset is deasserted. The crystal oscillator is not started at this point, so rst_done is asserted
instantly.
• clk_ref and clk_sys clock generators are taken out of reset. In the initial configuration clk_ref is running from the
ring oscillator with no divider. clk_sys is running from clk_ref. These clocks are needed for the rest of the sequence
to progress.
The rest of the sequence is fairly simple, with the following coming out of reset in order one by one:
• Reset Controller - used to reset all non-boot peripherals
• Chip-Level Reset and Voltage Regulator registers - used by the bootrom to check the boot state of the chip. In
particular, the PSM_RESTART_FLAG flag in the CHIP_RESET register can be set via SWD to indicate to the boot code that
there is bad code in flash and it should stop executing. The reset state of the CHIP_RESET register is determined
by the Chip-Level Reset subsystem and is not affected by reset coming from the power-on state machine
• XIP (Execute-In-Place) - used by the bootrom to execute code from an external SPI flash
• ROM and SRAM - Boot code is executed from the ROM. SRAM is used by processors and Bus Fabric.
• Bus Fabric - Allows the processors to communicate with peripherals
• Processor complex - Finally the processors can start running
The final thing to come out of reset is the processor complex. This includes both core0 and core1. Both cores will start
executing the bootcode from ROM. One of the first things the bootrom does is read the core id. At this point, core1 will
go to sleep leaving core0 to continue with the bootrom execution. The processor complex has its own reset control and
various low-power modes which is why both the core0 and core1 resets are deasserted, despite only core0 being needed
for the bootrom.
2.13.3. Register Control
The power-on state machine is a fully automated piece of hardware. It requires no input from the user to work. There
are register controls that can be used to override and see the status of the power-on state machine. This allows
hardware blocks in the power-on state machine to be reset by software if necessary. There is also a WDSEL register which
is used to control what is reset by a Watchdog reset.
2.13.4. Interaction with Watchdog
The power-on state machine can be restarted from a software-programmable position if the Watchdog fires. For
example, in the case the processor is stuck in an infinite loop, or the programmer has somehow misconfigured the chip.
It is important to note that if a peripheral in the power-on state machine has the WDSEL bit set, every peripheral after it in
the power-on sequence will also be reset because the rst_done of the selected peripheral will be deasserted, asserting
rst_n for the remaining peripherals.
2.13.5. List of Registers
The PSM registers start at a base address of 0x40010000 (defined as PSM_BASE in SDK).
Table 196. List of PSM
registers
Offset
Name
Info
0x0
FRCE_ON
Force block out of reset (i.e. power it on)
0x4
FRCE_OFF
Force into reset (i.e. power it off)
0x8
WDSEL
Set to 1 if this peripheral should be reset when the watchdog
fires.
0xc
DONE
2.13. Power-On State Machine
Indicates the peripheral’s registers are ready to access.
172
RP2040 Datasheet
PSM: FRCE_ON Register
Offset: 0x0
Description
Force block out of reset (i.e. power it on)
Table 197. FRCE_ON
Register
Bits
Name
Description
Type
Reset
31:17
Reserved.
-
-
-
16
PROC1
RW
0x0
15
PROC0
RW
0x0
14
SIO
RW
0x0
13
VREG_AND_CHIP_RESET
RW
0x0
12
XIP
RW
0x0
11
SRAM5
RW
0x0
10
SRAM4
RW
0x0
9
SRAM3
RW
0x0
8
SRAM2
RW
0x0
7
SRAM1
RW
0x0
6
SRAM0
RW
0x0
5
ROM
RW
0x0
4
BUSFABRIC
RW
0x0
3
RESETS
RW
0x0
2
CLOCKS
RW
0x0
1
XOSC
RW
0x0
0
ROSC
RW
0x0
PSM: FRCE_OFF Register
Offset: 0x4
Description
Force into reset (i.e. power it off)
Table 198. FRCE_OFF
Register
Bits
Name
Description
Type
Reset
31:17
Reserved.
-
-
-
16
PROC1
RW
0x0
15
PROC0
RW
0x0
14
SIO
RW
0x0
13
VREG_AND_CHIP_RESET
RW
0x0
12
XIP
RW
0x0
11
SRAM5
RW
0x0
10
SRAM4
RW
0x0
2.13. Power-On State Machine
173
RP2040 Datasheet
Bits
Name
9
Description
Type
Reset
SRAM3
RW
0x0
8
SRAM2
RW
0x0
7
SRAM1
RW
0x0
6
SRAM0
RW
0x0
5
ROM
RW
0x0
4
BUSFABRIC
RW
0x0
3
RESETS
RW
0x0
2
CLOCKS
RW
0x0
1
XOSC
RW
0x0
0
ROSC
RW
0x0
PSM: WDSEL Register
Offset: 0x8
Description
Set to 1 if this peripheral should be reset when the watchdog fires.
Table 199. WDSEL
Register
Bits
Name
Description
Type
Reset
31:17
Reserved.
-
-
-
16
PROC1
RW
0x0
15
PROC0
RW
0x0
14
SIO
RW
0x0
13
VREG_AND_CHIP_RESET
RW
0x0
12
XIP
RW
0x0
11
SRAM5
RW
0x0
10
SRAM4
RW
0x0
9
SRAM3
RW
0x0
8
SRAM2
RW
0x0
7
SRAM1
RW
0x0
6
SRAM0
RW
0x0
5
ROM
RW
0x0
4
BUSFABRIC
RW
0x0
3
RESETS
RW
0x0
2
CLOCKS
RW
0x0
1
XOSC
RW
0x0
0
ROSC
RW
0x0
PSM: DONE Register
Offset: 0xc
2.13. Power-On State Machine
174
RP2040 Datasheet
Description
Indicates the peripheral’s registers are ready to access.
Table 200. DONE
Register
Bits
Name
Description
Type
Reset
31:17
Reserved.
-
-
-
16
PROC1
RO
0x0
15
PROC0
RO
0x0
14
SIO
RO
0x0
13
VREG_AND_CHIP_RESET
RO
0x0
12
XIP
RO
0x0
11
SRAM5
RO
0x0
10
SRAM4
RO
0x0
9
SRAM3
RO
0x0
8
SRAM2
RO
0x0
7
SRAM1
RO
0x0
6
SRAM0
RO
0x0
5
ROM
RO
0x0
4
BUSFABRIC
RO
0x0
3
RESETS
RO
0x0
2
CLOCKS
RO
0x0
1
XOSC
RO
0x0
0
ROSC
RO
0x0
2.14. Subsystem Resets
2.14.1. Overview
The reset controller allows software control of the resets to all of the peripherals that are not critical to boot the
processor in RP2040. This includes:
• USB Controller
• PIO
• Peripherals such as UART, I2C, SPI, PWM, Timer, ADC
• PLLs
• IO and Pad registers
The full list can be seen in the register descriptions.
Every peripheral reset by the reset controller is held in reset at power-up. It is up to software to deassert the reset of
peripherals it intends to use. Note that if you are using the SDK some peripherals may already be out of reset.
2.14. Subsystem Resets
175
RP2040 Datasheet
2.14.2. Programmer’s Model
The SDK defines a struct to represent the resets registers.
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2040/hardware_structs/include/hardware/structs/resets.h Lines 24 - 113
24 typedef struct {
25
_REG_(RESETS_RESET_OFFSET) // RESETS_RESET
26
// Reset control
27
// 0x01000000 [24]
: usbctrl (1)
28
// 0x00800000 [23]
: uart1 (1)
29
// 0x00400000 [22]
: uart0 (1)
30
// 0x00200000 [21]
: timer (1)
31
// 0x00100000 [20]
: tbman (1)
32
// 0x00080000 [19]
: sysinfo (1)
33
// 0x00040000 [18]
: syscfg (1)
34
// 0x00020000 [17]
: spi1 (1)
35
// 0x00010000 [16]
: spi0 (1)
36
// 0x00008000 [15]
: rtc (1)
37
// 0x00004000 [14]
: pwm (1)
38
// 0x00002000 [13]
: pll_usb (1)
39
// 0x00001000 [12]
: pll_sys (1)
40
// 0x00000800 [11]
: pio1 (1)
41
// 0x00000400 [10]
: pio0 (1)
42
// 0x00000200 [9]
: pads_qspi (1)
43
// 0x00000100 [8]
: pads_bank0 (1)
44
// 0x00000080 [7]
: jtag (1)
45
// 0x00000040 [6]
: io_qspi (1)
46
// 0x00000020 [5]
: io_bank0 (1)
47
// 0x00000010 [4]
: i2c1 (1)
48
// 0x00000008 [3]
: i2c0 (1)
49
// 0x00000004 [2]
: dma (1)
50
// 0x00000002 [1]
: busctrl (1)
51
// 0x00000001 [0]
: adc (1)
52
io_rw_32 reset;
53
54
_REG_(RESETS_WDSEL_OFFSET) // RESETS_WDSEL
55
// Watchdog select
56
// 0x01000000 [24]
: usbctrl (0)
57
// 0x00800000 [23]
: uart1 (0)
58
// 0x00400000 [22]
: uart0 (0)
59
// 0x00200000 [21]
: timer (0)
60
// 0x00100000 [20]
: tbman (0)
61
// 0x00080000 [19]
: sysinfo (0)
62
// 0x00040000 [18]
: syscfg (0)
63
// 0x00020000 [17]
: spi1 (0)
64
// 0x00010000 [16]
: spi0 (0)
65
// 0x00008000 [15]
: rtc (0)
66
// 0x00004000 [14]
: pwm (0)
67
// 0x00002000 [13]
: pll_usb (0)
68
// 0x00001000 [12]
: pll_sys (0)
69
// 0x00000800 [11]
: pio1 (0)
70
// 0x00000400 [10]
: pio0 (0)
71
// 0x00000200 [9]
: pads_qspi (0)
72
// 0x00000100 [8]
: pads_bank0 (0)
73
// 0x00000080 [7]
: jtag (0)
74
// 0x00000040 [6]
: io_qspi (0)
75
// 0x00000020 [5]
: io_bank0 (0)
76
// 0x00000010 [4]
: i2c1 (0)
77
// 0x00000008 [3]
: i2c0 (0)
78
// 0x00000004 [2]
: dma (0)
79
// 0x00000002 [1]
: busctrl (0)
80
// 0x00000001 [0]
: adc (0)
2.14. Subsystem Resets
176
RP2040 Datasheet
81
io_rw_32 wdsel;
82
83
_REG_(RESETS_RESET_DONE_OFFSET) // RESETS_RESET_DONE
84
// Reset done
85
// 0x01000000 [24]
: usbctrl (0)
86
// 0x00800000 [23]
: uart1 (0)
87
// 0x00400000 [22]
: uart0 (0)
88
// 0x00200000 [21]
: timer (0)
89
// 0x00100000 [20]
: tbman (0)
90
// 0x00080000 [19]
: sysinfo (0)
91
// 0x00040000 [18]
: syscfg (0)
92
// 0x00020000 [17]
: spi1 (0)
93
// 0x00010000 [16]
: spi0 (0)
94
// 0x00008000 [15]
: rtc (0)
95
// 0x00004000 [14]
: pwm (0)
96
// 0x00002000 [13]
: pll_usb (0)
97
// 0x00001000 [12]
: pll_sys (0)
98
// 0x00000800 [11]
: pio1 (0)
99
// 0x00000400 [10]
: pio0 (0)
100
// 0x00000200 [9]
: pads_qspi (0)
101
// 0x00000100 [8]
: pads_bank0 (0)
102
// 0x00000080 [7]
: jtag (0)
103
// 0x00000040 [6]
: io_qspi (0)
104
// 0x00000020 [5]
: io_bank0 (0)
105
// 0x00000010 [4]
: i2c1 (0)
106
// 0x00000008 [3]
: i2c0 (0)
107
// 0x00000004 [2]
: dma (0)
108
// 0x00000002 [1]
: busctrl (0)
109
// 0x00000001 [0]
: adc (0)
110
io_ro_32 reset_done;
111 } resets_hw_t;
112
113 #define resets_hw ((resets_hw_t *)RESETS_BASE)
Three registers are defined:
• reset: this register contains a bit for each peripheral that can be reset. If the bit is set to 1 then the reset is asserted.
If the bit is cleared then the reset is deasserted.
• wdsel: if the bit is set then this peripheral will be reset if the watchdog fires (note that the power on state machine
can potentially reset the whole reset controller, which will reset everything)
• reset_done: a bit for each peripheral, that gets set once the peripheral is out of reset. This allows software to wait
for this status bit in case the peripheral has some initialisation to do before it can be used.
The reset functions in the SDK are defined as follows:
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_resets/include/hardware/resets.h Lines 70 - 72
70 static inline void reset_block(uint32_t bits) {
71
hw_set_bits(&resets_hw->reset, bits);
72 }
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_resets/include/hardware/resets.h Lines 79 - 81
79 static inline void unreset_block(uint32_t bits) {
80
hw_clear_bits(&resets_hw->reset, bits);
81 }
2.14. Subsystem Resets
177
RP2040 Datasheet
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_resets/include/hardware/resets.h Lines 88 - 92
88 static inline void unreset_block_wait(uint32_t bits) {
89
hw_clear_bits(&resets_hw->reset, bits);
90
while (~resets_hw->reset_done & bits)
91
tight_loop_contents();
92 }
An example use of these is in the UART driver, where the driver defines a uart_reset function, selecting a different bit of
the reset register depending on the uart specified:
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_uart/uart.c Lines 27 - 35
27 static inline void uart_reset(uart_inst_t *uart) {
28
invalid_params_if(UART, uart != uart0 && uart != uart1);
29
reset_block(uart_get_index(uart) ? RESETS_RESET_UART1_BITS : RESETS_RESET_UART0_BITS);
30 }
31
32 static inline void uart_unreset(uart_inst_t *uart) {
33
invalid_params_if(UART, uart != uart0 && uart != uart1);
34
unreset_block_wait(uart_get_index(uart) ? RESETS_RESET_UART1_BITS :
RESETS_RESET_UART0_BITS);
35 }
2.14.3. List of Registers
The reset controller registers start at a base address of 0x4000c000 (defined as RESETS_BASE in SDK).
Table 201. List of
RESETS registers
Offset
Name
Info
0x0
RESET
Reset control.
0x4
WDSEL
Watchdog select.
0x8
RESET_DONE
Reset done.
RESETS: RESET Register
Offset: 0x0
Description
Reset control. If a bit is set it means the peripheral is in reset. 0 means the peripheral’s reset is deasserted.
Table 202. RESET
Register
Bits
Name
Description
Type
Reset
31:25
Reserved.
-
-
-
24
USBCTRL
RW
0x1
23
UART1
RW
0x1
22
UART0
RW
0x1
21
TIMER
RW
0x1
20
TBMAN
RW
0x1
19
SYSINFO
RW
0x1
18
SYSCFG
RW
0x1
2.14. Subsystem Resets
178
RP2040 Datasheet
Bits
Name
17
Description
Type
Reset
SPI1
RW
0x1
16
SPI0
RW
0x1
15
RTC
RW
0x1
14
PWM
RW
0x1
13
PLL_USB
RW
0x1
12
PLL_SYS
RW
0x1
11
PIO1
RW
0x1
10
PIO0
RW
0x1
9
PADS_QSPI
RW
0x1
8
PADS_BANK0
RW
0x1
7
JTAG
RW
0x1
6
IO_QSPI
RW
0x1
5
IO_BANK0
RW
0x1
4
I2C1
RW
0x1
3
I2C0
RW
0x1
2
DMA
RW
0x1
1
BUSCTRL
RW
0x1
0
ADC
RW
0x1
RESETS: WDSEL Register
Offset: 0x4
Description
Watchdog select. If a bit is set then the watchdog will reset this peripheral when the watchdog fires.
Table 203. WDSEL
Register
Bits
Name
Description
Type
Reset
31:25
Reserved.
-
-
-
24
USBCTRL
RW
0x0
23
UART1
RW
0x0
22
UART0
RW
0x0
21
TIMER
RW
0x0
20
TBMAN
RW
0x0
19
SYSINFO
RW
0x0
18
SYSCFG
RW
0x0
17
SPI1
RW
0x0
16
SPI0
RW
0x0
15
RTC
RW
0x0
14
PWM
RW
0x0
2.14. Subsystem Resets
179
RP2040 Datasheet
Bits
Name
13
Description
Type
Reset
PLL_USB
RW
0x0
12
PLL_SYS
RW
0x0
11
PIO1
RW
0x0
10
PIO0
RW
0x0
9
PADS_QSPI
RW
0x0
8
PADS_BANK0
RW
0x0
7
JTAG
RW
0x0
6
IO_QSPI
RW
0x0
5
IO_BANK0
RW
0x0
4
I2C1
RW
0x0
3
I2C0
RW
0x0
2
DMA
RW
0x0
1
BUSCTRL
RW
0x0
0
ADC
RW
0x0
RESETS: RESET_DONE Register
Offset: 0x8
Description
Reset done. If a bit is set then a reset done signal has been returned by the peripheral. This indicates that the
peripheral’s registers are ready to be accessed.
Table 204.
RESET_DONE Register
Bits
Name
Description
Type
Reset
31:25
Reserved.
-
-
-
24
USBCTRL
RO
0x0
23
UART1
RO
0x0
22
UART0
RO
0x0
21
TIMER
RO
0x0
20
TBMAN
RO
0x0
19
SYSINFO
RO
0x0
18
SYSCFG
RO
0x0
17
SPI1
RO
0x0
16
SPI0
RO
0x0
15
RTC
RO
0x0
14
PWM
RO
0x0
13
PLL_USB
RO
0x0
12
PLL_SYS
RO
0x0
11
PIO1
RO
0x0
10
PIO0
RO
0x0
2.14. Subsystem Resets
180
RP2040 Datasheet
Bits
Name
9
Description
Type
Reset
PADS_QSPI
RO
0x0
8
PADS_BANK0
RO
0x0
7
JTAG
RO
0x0
6
IO_QSPI
RO
0x0
5
IO_BANK0
RO
0x0
4
I2C1
RO
0x0
3
I2C0
RO
0x0
2
DMA
RO
0x0
1
BUSCTRL
RO
0x0
0
ADC
RO
0x0
2.15. Clocks
2.15.1. Overview
The clocks block provides independent clocks to on-chip and external components. It takes inputs from a variety of
clock sources allowing the user to trade off performance against cost, board area and power consumption. From these
sources it uses multiple clock generators to provide the required clocks. This architecture allows the user flexibility to
start and stop clocks independently and to vary some clock frequencies whilst maintaining others at their optimum
frequencies.
Figure 28. Clocks
overview
For very low cost or low power applications where precise timing is not required, the chip can be run from the internal
Ring Oscillator (ROSC). Alternatively the user can provide external clocks or construct simple relaxation oscillators
2.15. Clocks
181
RP2040 Datasheet
using the GPIOs and appropriate external passive components. Where timing is more critical, the Crystal Oscillator
(XOSC) can provide an accurate reference to the 2 on-chip PLLs to provide fast clocking at precise frequencies.
The clock generators select from the clock sources and optionally divide the selected clock before outputting through
enable logic which provides automatic clock disabling in SLEEP mode (see Section 2.11.2).
An on-chip frequency counter facilitates debugging of the clock setup and also allows measurement of the frequencies
of external clocks. The on-chip resus component restarts the system clock from a known good clock if it is accidentally
stopped. This allows the software debugger to access registers and debug the problem.
The chip has an ultra-low power mode called DORMANT (see Section 2.11.3) in which all on-chip clock sources are
stopped to save power. External sources are not stopped and can be used to provide a clock to the on-chip RTC which
can provide an alarm to wake the chip from DORMANT mode. Alternatively the GPIO interrupts can be configured to
wake the chip from DORMANT mode in response to an external event.
Up to 4 generated clocks can be output to GPIOs at up to 50MHz. This allows the user to supply clocks to external
devices, thus reducing component counts in power, space and cost sensitive applications.
2.15.2. Clock sources
The RP2040 can be run from a variety of clock sources. This flexibility allows the user to optimise the clock setup for
performance, cost, board area and power consumption. The sources include the on-chip Ring Oscillator (Section 2.17),
the Crystal Oscillator (Section 2.16), external clocks from GPIOs (Section 2.15.6.4) and the PLLs (Section 2.18).
The list of clock sources is different per clock generator and can be found as enumerated values in the CTRL register.
See CLK_SYS_CTRL as an example.
2.15.2.1. Ring Oscillator
The on-chip Ring Oscillator (Section 2.17) requires no external components. It runs automatically from power-up and is
used to clock the chip during the initial boot stages. The startup frequency is typically 6MHz but varies with PVT
(Process, Voltage and Temperature). The frequency is likely to be in the range 4-8MHz and is guaranteed to be in the
range 1.8-12MHz.
For low cost applications where frequency accuracy is unimportant, the chip can continue to run from the ROSC. If
greater performance is required the frequency can be increased by programming the registers as described in Section
2.17. The frequency will vary with PVT (Process, Voltage and Temperature) so the user must take care to avoid
exceeding the maximum frequencies described in the clock generators section. This variation can be mitigated in
various ways (see Section 2.15.2.1.1) if the user wants to continue running from the ROSC at a frequency close to the
maximum. Alternatively, the user can use an external clock or the XOSC to provide a stable reference clock and use the
PLLs to generate higher frequencies. This will require external components, which will cost board area and increase
power consumption.
If an external clock or the XOSC is used then the ROSC can be stopped to save power. However, the reference clock
generator and the system clock generator must be switched to an alternate source before doing so.
The ROSC is not affected by SLEEP mode. If required the frequency can be reduced before entering SLEEP mode to
save power. On entering DORMANT mode the ROSC is automatically stopped and is restarted in the same configuration
when exiting DORMANT mode. If the ROSC is driving clocks at close to their maximum frequencies then it is
recommended to drop the frequency before entering SLEEP or DORMANT mode to allow for frequency variation due to
changes in environmental conditions during SLEEP or DORMANT mode.
If the user wants to use the ROSC clock externally then it can be output to a GPIO pin using one of the clk_gpclk0-3
generators.
The following sections describe techniques for mitigating PVT variation of the ROSC frequency. They also provide some
interesting design challenges for use in teaching both the effects of PVT and writing software to control real time
functions.
2.15. Clocks
182
RP2040 Datasheet
NOTE
The ROSC frequency varies with PVT so the user can send its output to the frequency counter and use it to measure
any 1 of these 3 variables if the other 2 are known.
2.15.2.1.1. Mitigating ROSC frequency variation due to process
Process varies for two reasons. Firstly, chips leave the factory with a spread of process parameters which cause
variation in the ROSC frequency across chips. Secondly, process parameters vary slightly as the chip ages, though this
will only be observable over many thousands of hours of operation. To mitigate for process variation, the user can
characterise individual chips and program the ROSC frequency accordingly. This is an adequate solution for small
numbers of chips but is not suitable for volume production. In such applications the user should consider using the
automatic mitigation techniques described below.
2.15.2.1.2. Mitigating ROSC frequency variation due to voltage
Supply voltage varies for two reasons. Firstly, the power supply itself may vary, and secondly, there will be varying onchip IR drop as chip activity varies. If the application has a minimum performance target then the user needs to
calibrate for that application and adjust the ROSC frequency to ensure it always exceeds the minimum required.
2.15.2.1.3. Mitigating ROSC frequency variation due to temperature
Temperature varies for two reasons. Firstly, the ambient temperature may vary, and secondly, the chip temperature will
vary as chip activity varies due to self-heating. This can be mitigated by stabilising the temperature using a temperature
controlled environment and passive or active cooling. Alternatively the user can track the temperature using the on-chip
temperature sensor and adjust the ROSC frequency so it remains within the required bounds.
2.15.2.1.4. Automatic mitigation of ROSC frequency variation due to PVT
Techniques for automatic ROSC frequency control avoid the need to calibrate individual chips but require periodic
access to a clock reference or to a time reference. If a clock reference is available then it can be used to periodically
measure the ROSC frequency and adjust it accordingly. The reference could be the on-chip XOSC which can be turned
on periodically for this purpose. This may be useful in a very low power application where it is too costly to run the
XOSC continuously and too costly to use the PLLs to achieve high frequencies. If a time reference is available then the
user could clock the on-chip RTC from the ROSC and periodically compare it against the time reference, then adjust the
ROSC frequency as necessary. Using these techniques the ROSC frequency will drift due to VT variation so the user
must take care that these variations do not allow the ROSC frequency to drift out of the acceptable range.
2.15.2.1.5. Automatic overclocking using the ROSC
The datasheet maximum frequencies for any digital device are quoted for worst case PVT. Most chips in most normal
environments can run significantly faster than the quoted maximum and can therefore be overclocked. If the RP2040 is
running from the ROSC then both the ROSC and the digital components are similarly affected by PVT, so, as the ROSC
gets faster, the processors can also run faster. This means the user can overclock from the ROSC then rely on the ROSC
frequency tracking with PVT variations. The tracking of ROSC frequency and the processor capability is not perfect and
currently there is insufficient data to specify a safe ROSC setting for this mode of operation, so some experimentation is
required.
This mode of operation will maximise processor performance but will lead to variations in the time taken to complete a
task, which may be unacceptable in some applications. Also, if the user wants to use frequency sensitive interfaces
such as USB or UART then the XOSC and PLL must be used to provide a precise clock for those components.
2.15. Clocks
183
RP2040 Datasheet
2.15.2.2. Crystal Oscillator
The Crystal Oscillator (Section 2.16) provides a precise, stable clock reference and should be used where accurate
timing is required and no suitable external clocks are available. The frequency is determined by the external crystal and
the oscillator supports frequencies in the range 1MHz to 15MHz. The on-chip PLLs can be used to synthesise higher
frequencies if required. The RP2040 reference design (see Hardware design with RP2040, Minimal Design Example)
uses a 12MHz crystal. Using the XOSC and the PLLs, the on-chip components can be run at their maximum frequencies.
Appropriate margin is built into the design to tolerate up to 1000ppm variation in the XOSC frequency.
The XOSC is inactive on power up. If required it must be enabled in software. XOSC startup takes several milliseconds
and the software must wait for the XOSC_STABLE flag to be set before starting the PLLs and before changing any clock
generators to use it. Prior to that the output from the XOSC may be non-existent or may have very short pulse widths
which will corrupt logic if used. Once it is running the reference clock (clk_ref) and the system clock (clk_sys) can be
switched to run from the XOSC and the ROSC can be stopped to save power.
The XOSC is not affected by SLEEP mode. It is automatically stopped and restarted in the same configuration when
entering and exiting DORMANT mode.
If the user wants to use the XOSC clock externally then it can be output to a GPIO pin using one of the clk_gpclk0-3
generators. It cannot be taken directly from the XIN or XOUT pins.
2.15.2.3. External Clocks
If external clocks exist in your hardware design then they can be used to clock the RP2040 either on their own or in
conjunction with the XOSC or ROSC. This will potentially save power and will allow components on the RP2040 to be run
synchronously with external components to simplify data transfer between chips. External clocks can be input on the
GPIN0 & GPIN1 GPIO inputs and on the XIN input to the XOSC. If the XIN input is used in this way the XOSC must be
configured to pass through the XIN signal. All 3 inputs are limited to 50MHz but the on-chip PLLs can be used to
synthesise higher frequencies from the XIN input if required. If the frequency accuracy of the external clocks is poorer
than 1000ppm then the generated clocks should not be run at their maximum frequencies because they may exceed
their design margins.
Once the external clocks are running, the reference clock (clk_ref) and the system clock (clk_sys) can be switched to run
from the external clocks and the ROSC can be stopped to save power.
The external clock sources are not affected by SLEEP mode or DORMANT mode.
2.15.2.4. Relaxation Oscillators
If the user wants to use external clocks to replace or supplement the other clock sources but does not have an
appropriate clock available, then 1 or 2 relaxation oscillators can be constructed using external passive components.
Simply send the clock source (GPIN0 or GPIN1) to one of the gpclk0-3 generators, invert it through the GPIO inverter
OUTOVER and connect back to the clock source input via an RC circuit.
Figure 29. Simple
relaxation oscillator
example
The frequency of clocks generated from relaxation oscillators will depend on the delay through the chip and the drive
current from the GPIO output both of which vary with PVT. They will also depend on the quality and accuracy of the
external components. It may be possible to improve the frequency accuracy using more elaborate external components
such as ceramic resonators but that will increase cost and complexity and can never rival the XOSC. For that reason
they are not discussed here. Given that these oscillators will not achieve 1000ppm then they cannot be used to drive
internal clocks at their maximum frequencies.
The relaxation oscillators are not affected by SLEEP mode or DORMANT mode.
2.15. Clocks
184
RP2040 Datasheet
2.15.2.5. PLLs
The PLLs (Section 2.18) are used to provide fast clocks when running from the XOSC (or an external clock source driven
into the XIN pin). In a fully featured application the USB PLL provides a fixed 48MHz clock to the ADC and USB while
clk_rtc and clk_ref are driven from the XOSC or external source. This allows the user to drive clk_sys from the system
PLL and vary the frequency according to demand to save power without having to change the setups of the other
clocks. clk_peri can be driven either from the fixed frequency USB PLL or from the variable frequency system PLL. If
clk_sys never needs to exceed 48MHz then one PLL can be used and the divider in the clk_sys clock generator can be
used to scale the clk_sys frequency according to demand.
When a PLL is started, its output cannot be used until the PLL locks as indicated by the LOCK bit in the STATUS register.
Thereafter the PLL output cannot be used during changes to the reference clock divider, the output dividers or the
bypass mode. The output can be used during feedback divisor changes with the proviso that the output frequency may
overshoot or undershoot on large changes to the feedback divisor. For more information, see Section 2.18.
If the PLL reference clock is accurate to 1000ppm then the PLLs can be used to drive clocks at their maximum
frequency because the frequency of the generated clocks will be within the margins allowed in the design.
The PLLs are not affected by SLEEP mode. If the user wants to save power in SLEEP mode then all clock generators
must be switched away from the PLLs and they must be stopped in software before entering SLEEP mode. The PLLs
are not stopped and restarted automatically when entering and exiting DORMANT mode. If they are left running on entry
to DORMANT mode they will be corrupted and will generate out of control clocks that will consume power
unnecessarily. This happens because their reference clock from XOSC will be stopped. It is therefore essential to switch
all clock generators away from the PLLs and stop the PLLs in software before entering DORMANT mode.
2.15.3. Clock Generators
The clock generators are built on a standard design which incorporates clock source multiplexing, division, duty cycle
correction and SLEEP mode enabling. To save chip area and power, the individual clock generators do not support all
features.
Figure 30. A generic
clock generator
2.15.3.1. Instances
RP2040 has several clock generators which are listed below.
Table 205. RP2040
clock generators
Clock
Description
Nominal Frequency
clk_gpout0
Clock output to GPIO. Can be used to
N/A
clk_gpout1
clk_gpout2
clock external devices or debug on
chip clocks with a logic analyser or
oscilloscope.
clk_gpout3
clk_ref
Reference clock that is always running 6 - 12MHz
unless in DORMANT mode. Runs from
Ring Oscillator (ROSC) at power-up
but can be switched to Crystal
Oscillator (XOSC) for more accuracy.
2.15. Clocks
185
RP2040 Datasheet
Clock
Description
Nominal Frequency
clk_sys
System clock that is always running
125MHz
unless in DORMANT mode. Runs from
clk_ref at power-up but is typically
switched to a PLL.
clk_peri
Peripheral clock. Typically runs from
12 - 125MHz
clk_sys but allows peripherals to run at
a consistent speed if clk_sys is
changed by software.
clk_usb
USB reference clock. Must be 48MHz. 48MHz
clk_adc
ADC reference clock. Must be 48MHz. 48MHz
clk_rtc
RTC reference clock. The RTC divides
46875Hz
this clock to generate a 1 second
reference.
For a full list of clock sources for each clock generator see the appropriate CTRL register. For example, CLK_SYS_CTRL.
2.15.3.2. Multiplexers
All clock generators have a multiplexer referred to as the auxiliary (aux) mux. This mux has a conventional design
whose output will glitch when changing the select control. Two clock generators (clk_sys and clk_ref) have an additional
multiplexer, referred to as the glitchless mux. The glitchless mux can switch between clock sources without generating
a glitch on the output.
Clock glitches should be avoided at all costs because they may corrupt the logic running on that clock. This means that
any clock generator with only an aux mux must be disabled while switching the clock source. If the clock generator has
a glitchless mux (clk_sys and clk_ref), then the glitchless mux should switch away from the aux mux while changing the
aux mux source. The clock generators require 2 cycles of the source clock to stop the output and 2 cycles of the new
source to restart the output. The user must wait for the generator to stop before changing the auxiliary mux, and
therefore must be aware of the source clock frequency.
The glitchless mux is only implemented for always-on clocks. On RP2040 the always-on clocks are the reference clock
(clk_ref) and the system clock (clk_sys). Such clocks must run continuously unless the chip is in DORMANT mode. The
glitchless mux has a status output (SELECTED) which indicates which source is selected and can be read from
software to confirm that a change of clock source has been completed.
The recommended control sequences are as follows.
To switch the glitchless mux:
• switch the glitchless mux to an alternate source
• poll the SELECTED register until the switch is completed
To switch the auxiliary mux when the generator has a glitchless mux:
• switch the glitchless mux to a source that isn’t the aux mux
• poll the SELECTED register until the switch is completed
• change the auxiliary mux select control
• switch the glitchless mux back to the aux mux
• if required, poll the SELECTED register until the switch is completed
To switch the auxiliary mux when the generator does not have a glitchless mux:
• disable the clock divider
2.15. Clocks
186
RP2040 Datasheet
• wait for the generated clock to stop (2 cycles of the clock source)
• change the auxiliary mux select control
• enable the clock divider
• if required, wait for the clock generator to restart (2 cycles of the clock source)
See Section 2.15.6.1 for a code example of this.
2.15.3.3. Divider
A fully featured divider divides by 1 or a fractional number in the range 2.0 to 2^24-0.01. Fractional division is achieved
by toggling between 2 integer divisors therefore it yields a jittery clock which may not be suitable for some applications.
For example, when dividing by 2.4 the divider will divide by 2 for 3 cycles and by 3 for 2 cycles. For divisors with large
integer components the jitter will be much smaller and less critical.
Figure 31. An example
of fractional division.
All dividers support on-the-fly divisor changes meaning the output clock will switch cleanly from one divisor to another.
The clock generator does not need to be stopped during clock divisor changes. It does this by synchronising the divisor
change to the end of the clock cycle. Similarly, the enable is synchronised to the end of the clock cycle so will not
generate glitches when the clock generator is enabled or disabled. Clock generators for always-on clocks are
permanently enabled and therefore do not have an enable control.
In the event that a clock generator locks up and never completes the current clock cycle it can be forced to stop using
the KILL control. This may result in an output glitch which may corrupt the logic driven by the clock. It is therefore
recommended the destination logic is reset prior to this operation. It is worth mentioning that this clock generator
design has been used in numerous chips and has never been known to lock up. The KILL control is inelegant and
unnecessary and should not be used as an alternative to the enable. Clock generators for always-on clocks are
permanently active and therefore do not have a KILL control.
2.15.3.4. Duty Cycle Correction
The divider operates on the rising edge of the input clock and so does not generate an even duty cycle clock when
dividing by odd numbers.
Divide by 3 will give a duty cycle of 33.3%, divide by 5 will be 40% etc. If enabled, the duty cycle correction logic will shift
the falling edge of the output clock to the falling edge of the input clock and restore a 50% duty cycle. The duty cycle
correction can be enabled and disabled while the clock is running. It will not operate when dividing by an even number.
Figure 32. An example
of
duty_cycle_correction.
Clock source
Generated clock
without DCC
Generated clock
with DCC
2.15.3.5. Clock Enables
Each clock goes to multiple destinations and, with a few exceptions, there are 2 enables for each destination. The
WAKE_EN registers are used to enable the clocks when the system is awake and the SLEEP_EN registers are used to enable
2.15. Clocks
187
RP2040 Datasheet
the clocks when the system is in sleep mode. The purpose of these enables is to reduce power in the clock distribution
networks for components that are not being used. It is worth noting that a component which is not clocked will retain its
configuration so can be restarted quickly.
NOTE
The WAKE_EN and SLEEP_EN registers reset to 0x1, which means that by default all clocks are enabled. The programmer
only needs to use this feature if they desire a low-power design.
2.15.3.5.1. Clock Enable Exceptions
The processor cores do not have clock enables because they require a clock at all times to manage their own power
saving features.
clk_sys_busfabric cannot be disabled in wake mode because that would prevent the cores from accessing any chip
registers, including those that control the clock enables.
clk_sys_clocks does not have a wake mode enable because disabling it would prevent the cores from accessing the
clocks control registers.
The gpclks do not have clock enables.
2.15.3.5.2. System Sleep Mode
System sleep mode is entered automatically when both cores are in sleep and the DMA has no outstanding
transactions. In system sleep mode, the clock enables described in the previous paragraphs are switched from the
WAKE_EN registers to the SLEEP_EN registers. The intention is to reduce power consumed in the clock distribution networks
when the chip is inactive. If the user has not configured the WAKE_EN and SLEEP_EN registers then system sleep will do
nothing.
There is little value in using system sleep without taking other measures to reduce power before the cores are put to
sleep. Things to consider include:
• stop unused clock sources such as the PLLs and Crystal Oscillator
• reduce the frequencies of generated clocks by increasing the clock divisors
• stop external clocks
For maximum power saving when the chip is inactive, the user should consider DORMANT (see Section 2.11.3) mode in
which clocks are sourced from the Crystal Oscillator and/or the Ring Oscillator and those clock sources are stopped.
2.15.4. Frequency Counter
The frequency counter measures the frequency of internal and external clocks by counting the clock edges seen over a
test interval. The interval is defined by counting cycles of clk_ref which must be driven either from XOSC or from a
stable external source of known frequency.
The user can pick between accuracy and test time using the FC0_INTERVAL register. Table 206 shows the trade off.
Table 206. Frequency
Counter Test Interval
vs Accuracy
2.15. Clocks
Interval Register
Test Interval
Accuracy
0
1μs
2048kHz
1
2μs
1024kHz
2
4μs
512kHz
3
8μs
256kHz
4
16μs
128kHz
188
RP2040 Datasheet
Interval Register
Test Interval
Accuracy
5
32μs
64kHz
6
64μs
32kHz
7
125μs
16kHz
8
250μs
8kHz
9
500μs
4kHz
10
1ms
2kHz
11
2ms
1kHz
12
4ms
500Hz
13
8ms
250Hz
14
16ms
125Hz
15
32ms
62.5Hz
2.15.5. Resus
It is possible to write software that inadvertently stops clk_sys. This will normally cause an unrecoverable lock-up of the
cores and the on-chip debugger, leaving the user unable to trace the problem. To mitigate against that, an automatic
resuscitation circuit is provided which will switch clk_sys to a known good clock source if no edges are detected over a
user-defined interval. The known good source is clk_ref which can be driven from the XOSC, ROSC or an external
source.
The resus block counts edges on clk_sys during a timeout interval controlled by clk_ref, and forces clk_sys to be driven
from clk_ref if no clk_sys edges are detected. The interval is programmable via CLK_SYS_RESUS_CTRL.
WARNING
There is no way for resus to revive the chip if clk_ref is also stopped.
To enable the resus, the programmer must set the timeout interval and then set the ENABLE bit in CLK_SYS_RESUS_CTRL.
To detect a resus event, the CLK_SYS_RESUS interrupt must be enabled by setting the interrupt enable bit in INTE. The
CLOCKS_DEFAULT_IRQ (see Section 2.3.2) must also be enabled at the processor.
Resus is intended as a debugging aid. The intention is for the user to trace the software error that triggered the resus,
then correct the error and reboot. It is possible to continue running after a resus event by reconfiguring clk_sys then
clearing the resus by writing the CLEAR bit in CLK_SYS_RESUS_CTRL However, it should be noted that a resus can be
triggered by clk_sys running more slowly than expected and that could result in a clk_sys glitch when resus is triggered.
That glitch could corrupt the chip. This would be a rare event but is tolerable in a debugging scenario. However it is
unacceptable in normal operation therefore it is recommended to only use resus for debug.
WARNING
Resus is a debugging aid and should not be used as a means of switching clocks in normal operation.
2.15.6. Programmer’s Model
2.15. Clocks
189
RP2040 Datasheet
2.15.6.1. Configuring a clock generator
The SDK defines an enum of clocks:
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2040/hardware_structs/include/hardware/structs/clocks.h Lines 27 - 39
27 enum clock_index {
28
clk_gpout0 = 0,
///< GPIO Muxing 0
29
clk_gpout1,
///< GPIO Muxing 1
30
clk_gpout2,
///< GPIO Muxing 2
31
clk_gpout3,
///< GPIO Muxing 3
32
clk_ref,
///< Watchdog and timers reference clock
33
clk_sys,
///< Processors, bus fabric, memory, memory mapped registers
34
clk_peri,
///< Peripheral clock for UART and SPI
35
clk_usb,
///< USB clock
36
clk_adc,
///< ADC clock
37
clk_rtc,
///< Real time clock
38
CLK_COUNT
39 };
And also a struct to describe the registers of a clock generator:
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2040/hardware_structs/include/hardware/structs/clocks.h Lines 43 - 63
43 typedef struct {
44
_REG_(CLOCKS_CLK_GPOUT0_CTRL_OFFSET) // CLOCKS_CLK_GPOUT0_CTRL
45
// Clock control, can be changed on-the-fly (except for auxsrc)
46
47
// 0x00100000 [20]
: NUDGE (0): An edge on this signal shifts the phase of the output
by 1 cycle of the input clock
// 0x00030000 [17:16] : PHASE (0): This delays the enable signal by up to 3 cycles of the
input clock
48
// 0x00001000 [12]
: DC50 (0): Enables duty cycle correction for odd divisors
49
// 0x00000800 [11]
: ENABLE (0): Starts and stops the clock generator cleanly
50
// 0x00000400 [10]
: KILL (0): Asynchronously kills the clock generator
51
// 0x000001e0 [8:5]
: AUXSRC (0): Selects the auxiliary clock source, will glitch when
52
switching
io_rw_32 ctrl;
53
54
_REG_(CLOCKS_CLK_GPOUT0_DIV_OFFSET) // CLOCKS_CLK_GPOUT0_DIV
55
// Clock divisor, can be changed on-the-fly
56
// 0xffffff00 [31:8]
: INT (1): Integer component of the divisor, 0 -> divide by 2^16
57
// 0x000000ff [7:0]
: FRAC (0): Fractional component of the divisor
58
io_rw_32 div;
59
60
_REG_(CLOCKS_CLK_GPOUT0_SELECTED_OFFSET) // CLOCKS_CLK_GPOUT0_SELECTED
61
// Indicates which SRC is currently selected by the glitchless mux (one-hot)
62
io_ro_32 selected;
63 } clock_hw_t;
To configure a clock, we need to know the following pieces of information:
• The frequency of the clock source
• The mux / aux mux position of the clock source
• The desired output frequency
The SDK provides clock_configure to configure a clock:
2.15. Clocks
190
RP2040 Datasheet
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_clocks/clocks.c Lines 42 - 118
42 bool clock_configure(enum clock_index clk_index, uint32_t src, uint32_t auxsrc, uint32_t
43
src_freq, uint32_t freq) {
uint32_t div;
44
45
assert(src_freq >= freq);
46
47
if (freq > src_freq)
48
return false;
49
50
// Div register is 24.8 int.frac divider so multiply by 2^8 (left shift by 8)
51
div = (uint32_t) (((uint64_t) src_freq clk[clk_index];
54
55
// If increasing divisor, set divisor before source. Otherwise set source
56
// before divisor. This avoids a momentary overspeed when e.g. switching
57
// to a faster source and increasing divisor to compensate.
58
if (div > clock->div)
59
clock->div = div;
60
61
// If switching a glitchless slice (ref or sys) to an aux source, switch
62
// away from aux *first* to avoid passing glitches when changing aux mux.
63
// Assume (!!!) glitchless source 0 is no faster than the aux source.
64
if (has_glitchless_mux(clk_index) && src ==
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX) {
65
hw_clear_bits(&clock->ctrl, CLOCKS_CLK_REF_CTRL_SRC_BITS);
66
while (!(clock->selected & 1u))
67
tight_loop_contents();
68
}
69
// If no glitchless mux, cleanly stop the clock to avoid glitches
70
// propagating when changing aux mux. Note it would be a really bad idea
71
// to do this on one of the glitchless clocks (clk_sys, clk_ref).
72
else {
73
// Disable clock. On clk_ref and clk_sys this does nothing,
74
// all other clocks have the ENABLE bit in the same position.
75
hw_clear_bits(&clock->ctrl, CLOCKS_CLK_GPOUT0_CTRL_ENABLE_BITS);
76
if (configured_freq[clk_index] > 0) {
77
// Delay for 3 cycles of the target clock, for ENABLE propagation.
78
// Note XOSC_COUNT is not helpful here because XOSC is not
79
// necessarily running, nor is timer... so, 3 cycles per loop:
80
uint delay_cyc = configured_freq[clk_sys] / configured_freq[clk_index] + 1;
81
asm volatile (
82
".syntax unified \n\t"
83
"1: \n\t"
84
"subs %0, #1 \n\t"
85
"bne 1b"
86
: "+r" (delay_cyc)
87
);
88
89
}
}
90
91
// Set aux mux first, and then glitchless mux if this clock has one
92
hw_write_masked(&clock->ctrl,
93
(auxsrc ctrl,
99
src selected & (1u ctrl, CLOCKS_CLK_GPOUT0_CTRL_ENABLE_BITS);
109
110
// Now that the source is configured, we can trust that the user-supplied
111
// divisor is a safe value.
112
clock->div = div;
113
114
// Store the configured frequency
115
configured_freq[clk_index] = (uint32_t)(((uint64_t) src_freq fc0;
220
221
// If frequency counter is running need to wait for it. It runs even if the source is
NULL
222
while(fc->status & CLOCKS_FC0_STATUS_RUNNING_BITS) {
223
224
tight_loop_contents();
}
225
226
// Set reference freq
227
fc->ref_khz = clock_get_hz(clk_ref) / 1000;
228
229
// FIXME: Don't pick random interval. Use best interval
230
fc->interval = 10;
231
232
// No min or max
233
fc->min_khz = 0;
234
fc->max_khz = 0xffffffff;
235
236
// Set SRC which automatically starts the measurement
237
fc->src = src;
238
239
while(!(fc->status & CLOCKS_FC0_STATUS_DONE_BITS)) {
240
241
tight_loop_contents();
}
242
243
// Return the result
244
return fc->result >> CLOCKS_FC0_RESULT_KHZ_LSB;
245 }
There is also a wrapper function to change the unit to MHz`:
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_clocks/include/hardware/clocks.h Lines 148 - 150
148 static inline float frequency_count_mhz(uint src) {
149
return ((float) (frequency_count_khz(src))) / KHZ;
150 }
NOTE
The frequency counter can also be used in a test mode. This allows the hardware to check if the frequency is within
a minimum frequency and a maximum frequency, set in FC0_MIN_KHZ and FC0_MAX_KHZ. In this mode, the PASS bit
in FC0_STATUS will be set when DONE is set if the frequency is within the specified range. Otherwise, either the FAST or
SLOW bit will be set.
If the programmer attempts to count a stopped clock, or the clock stops running then the DIED bit will be set. If any of
DIED, FAST, or SLOW are set then FAIL will be set.
2.15.6.3. Configuring a GPIO output clock
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_clocks/clocks.c Lines 317 - 337
317 void clock_gpio_init(uint gpio, uint src, uint div) {
2.15. Clocks
318
// Bit messy but it's as much code to loop through a lookup
319
// table. The sources for each gpout generators are the same
193
RP2040 Datasheet
320
// so just call with the sources from GP0
321
uint gpclk = 0;
322
if
323
else if (gpio == 23) gpclk = clk_gpout1;
324
else if (gpio == 24) gpclk = clk_gpout2;
325
else if (gpio == 25) gpclk = clk_gpout3;
326
else {
327
(gpio == 21) gpclk = clk_gpout0;
invalid_params_if(CLOCKS, true);
328
}
329
330
// Set up the gpclk generator
331
clocks_hw->clk[gpclk].ctrl = (src clk[gpclk].div = div io[gpio].ctrl = fn proc1_irq_ctrl : &iobank0_hw-
241
RP2040 Datasheet
>proc0_irq_ctrl;
176
_gpio_set_irq_enabled(gpio, events, enabled, irq_ctrl_base);
177 }
gpio_set_irq_enabled uses a lower level function _gpio_set_irq_enabled:
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_gpio/gpio.c Lines 158 - 169
158 static void _gpio_set_irq_enabled(uint gpio, uint32_t events, bool enabled,
io_irq_ctrl_hw_t *irq_ctrl_base) {
159
// Clear stale events which might cause immediate spurious handler entry
160
gpio_acknowledge_irq(gpio, events);
161
162
io_rw_32 *en_reg = &irq_ctrl_base->inte[gpio / 8];
163
events instr_mem[i] = auto_push_pull_program[i];
mm_pio->sm[0].shiftctrl =
20
(1u = threshold:
2
if tx fifo not empty:
3
osr = pull()
4
5
osr count = 0
stall
6 else:
7
output(osr)
8
osr = shift(osr, out count)
9
osr count = saturate(osr count + out count)
10
11
if osr count >= threshold:
12
if tx fifo not empty:
13
osr = pull()
14
osr count = 0
The hardware is capable of refilling the OSR simultaneously with shifting out the last of the shift data, as these two
operations can proceed in parallel. However, it cannot fill an empty OSR and 'OUT' it on the same cycle, due to the long
logic path this would create.
The refill is somewhat asynchronous to your program, but an 'OUT' behaves as a data fence, and the state machine will
never 'OUT' data which you didn’t write into the FIFO.
Note that a 'MOV' from the OSR is undefined whilst autopull is enabled; you will read either any residual data that has
not been shifted out, or a fresh word from the FIFO, depending on a race against system DMA. Likewise, a 'MOV' to the
OSR may overwrite data which has just been autopulled. However, data which you 'MOV' into the OSR will never be
overwritten, since 'MOV' updates the shift counter.
If you do need to read the OSR contents, you should perform an explicit 'PULL' of some kind. The nondeterminism
described above is the cost of the hardware managing pulls automatically. When autopull is enabled, the behaviour of
'PULL' is altered: it becomes a no-op if the OSR is full. This is to avoid a race condition against the system DMA. It
behaves as a fence: either an autopull has already taken place, in which case the 'PULL' has no effect, or the program
will stall on the 'PULL' until data becomes available in the FIFO.
'PUSH' does not need a similar behaviour, because autopush does not have the same nondeterminism.
3.5.5. Clock Dividers
PIO runs off the system clock, but this is simply too fast for many interfaces, and the number of Delay cycles which can
be inserted is limited. Some devices, such as UART, require the signalling rate to be precisely controlled and varied, and
ideally multiple state machines can be varied independently while running identical programs. Each state machine is
equipped with a clock divider, for this purpose.
Rather than slowing the system clock itself, the clock divider redefines how many system clock periods are considered
to be "one cycle", for execution purposes. It does this by generating a clock enable signal, which can pause and resume
execution on a per-system-clock-cycle basis. The clock divider generates clock enable pulses at regular intervals, so
3.5. Functional Details
337
RP2040 Datasheet
that the state machine runs at some steady pace, potentially much slower than the system clock.
Implementing the clock dividers in this way allows interfacing between the state machines and the system to be
simpler, lower-latency, and with a smaller footprint. The state machine is completely idle on cycles where clock enable
is low, though the system can still access the state machine’s FIFOs and change its configuration.
The clock dividers are 16-bit integer, 8-bit fractional, with first-order delta-sigma for the fractional divider. The clock
divisor can vary between 1 and 65536, in increments of
.
If the clock divisor is set to 1, the state machine runs on every cycle, i.e. full speed:
Figure 45. State
machine operation
System Clock
CLKDIV_INT
1
CLKDIV_FRAC
.0
with a clock divisor of
1. Once the state
machine is enabled via
the CTRL register, its
clock enable is
CTRL_SM_ENABLE
Clock Enable
asserted on every
cycle.
In general, an integer clock divisor of n will cause the state machine to run 1 cycle in every n, giving an effective clock
speed of
Figure 46. Integer
clock divisors yield a
System Clock
CLKDIV_INT
2
CLKDIV_FRAC
.0
periodic clock enable.
The clock divider
repeatedly counts
down from n, and
emits an enable pulse
.
CTRL_SM_ENABLE
Clock Enable
when it reaches 1.
Fractional division will maintain a steady state division rate of
, where n and f are the integer and fractional
fields of this state machine’s CLKDIV register. It does this by selectively extending some division periods from
cycles to
.
Figure 47. Fractional
clock division with an
average divisor of 2.5.
The clock divider
maintains a running
total of the fractional
value from each
System Clock
CLKDIV_INT
2
CLKDIV_FRAC
.5
CTRL_SM_ENABLE
Clock Enable
division period, and
every time this value
wraps through 1, the
For small n, the jitter introduced by a fractional divider may be unacceptable. However, for larger values, this effect is
integer divisor is
much less apparent.
increased by one for
the next division
period.
NOTE
For fast asynchronous serial, it is recommended to use even divisions or multiples of 1 Mbaud where possible,
rather than the traditional multiples of 300, to avoid unnecessary jitter.
3.5.6. GPIO Mapping
Internally, PIO has a 32-bit register for the output levels of each GPIO it can drive, and another register for the output
enables (Hi/Lo-Z). On every system clock cycle, each state machine can write to some or all of the GPIOs in each of
these registers.
3.5. Functional Details
338
RP2040 Datasheet
Figure 48. The state
machine has two
independent output
channels, one shared
by OUT/SET, and
another used by sideset (which can happen
at any time). Three
independent mappings
(first GPIO, number of
GPIOs) control which
GPIOs OUT, SET and
side-set are directed
to. Input data is
rotated according to
which GPIO is mapped
to the LSB of the IN
data.
The write data and write masks for the output level and output enable registers come from the following sources:
• An OUT instruction writes to up to 32 bits. Depending on the instruction’s Destination field, this is applied to either
pins or pindirs. The least-significant bit of OUT data is mapped to PINCTRL_OUT_BASE, and this mapping continues for
PINCTRL_OUT_COUNT bits, wrapping after GPIO31.
• A SET instruction writes up to 5 bits. Depending on the instruction’s Destination field, this is applied to either pins or
pindirs. The least-significant bit of SET data is mapped to PINCTRL_SET_BASE, and this mapping continues for
PINCTRL_SET_COUNT bits, wrapping after GPIO31.
• A side-set operation writes up to 5 bits. Depending on the register field EXECCTRL_SIDE_PINDIR, this is applied to either
pins or pindirs. The least-significant bit of side-set data is mapped to PINCTRL_SIDESET_BASE, continuing for
PINCTRL_SIDESET_COUNT pins, minus one if EXECCTRL_SIDE_EN is set.
Each OUT/SET/side-set operation writes to a contiguous range of pins, but each of these ranges is independently sized
and positioned in the 32-bit GPIO space. This is sufficiently flexible for many applications. For example, if one state
machine is implementing some interface such as an SPI on a group of pins, another state machine can run the same
program, mapped to a different group of pins, and provide a second SPI interface.
On any given clock cycle, the state machine may perform an OUT or a SET, and may simultaneously perform a side-set.
The pin mapping logic generates a 32-bit write mask and write data bus for the output level and output enable registers,
based on this request, and the pin mapping configuration.
If a side-set overlaps with an OUT/SET performed by that state machine on the same cycle, the side-set takes precedence
in the overlapping region.
3.5.6.1. Output Priority
3.5. Functional Details
339
RP2040 Datasheet
Figure 49. Per-GPIO
priority select of write
masks from each
state machine. Each
GPIO considers level
and direction writes
from each of the four
state machines, and
applies the value from
the highest-numbered
state machine.
Each state machine may assert an OUT/SET and a side-set through its pin mapping hardware on each cycle. This
generates 32 bits of write data and write mask for the GPIO output level and output enable registers, from each state
machine.
For each GPIO, PIO collates the writes from all four state machines, and applies the write from the highest-numbered
state machine. This occurs separately for output levels and output values — it is possible for a state machine to change
both the level and direction of the same pin on the same cycle (e.g. via simultaneous SET and side-set), or for one state
machine to change a GPIO’s direction while another changes that GPIO’s level. If no state machine asserts a write to a
GPIO’s level or direction, the value does not change.
3.5.6.2. Input Mapping
The data observed by IN instructions is mapped such that the LSB is the GPIO selected by PINCTRL_IN_BASE, and
successively more-significant bits come from successively higher-numbered GPIOs, wrapping after 31.
In other words, the IN bus is a right-rotate of the GPIO input values, by PINCTRL_IN_BASE. If fewer than 32 GPIOs are
present, the PIO input is padded with zeroes up to 32 bits.
Some instructions, such as WAIT GPIO, use an absolute GPIO number, rather than an index into the IN data bus. In this
case, the right-rotate is not applied.
3.5.6.3. Input Synchronisers
To protect PIO from metastabilities, each GPIO input is equipped with a standard 2-flipflop synchroniser. This adds two
cycles of latency to input sampling, but the benefit is that state machines can perform an IN PINS at any point, and will
see only a clean high or low level, not some intermediate value that could disturb the state machine circuitry. This is
absolutely necessary for asynchronous interfaces such as UART RX.
It is possible to bypass these synchronisers, on a per-GPIO basis. This reduces input latency, but it is then up to the user
to guarantee that the state machine does not sample its inputs at inappropriate times. Generally this is only possible for
synchronous interfaces such as SPI. Synchronisers are bypassed by setting the corresponding bit in INPUT_SYNC_BYPASS.
WARNING
Sampling a metastable input can lead to unpredictable state machine behaviour. This should be avoided.
3.5.7. Forced and EXEC’d Instructions
Besides the instruction memory, state machines can execute instructions from 3 other sources:
3.5. Functional Details
340
RP2040 Datasheet
• MOV EXEC which executes an instruction from some register Source
• OUT EXEC which executes data shifted out from the OSR
• The SMx_INSTR control registers, to which the system can write instructions for immediate execution
1 .program exec_example
2
3 hang:
4
jmp hang
5 execute:
6
out exec, 32
7
jmp execute
8
9 .program instructions_to_push
10
11
out x, 32
12
in x, 32
13
push
1 #include "tb.h" // TODO this is built against existing sw tree, so that we get printf etc
2
3 #include "platform.h"
4 #include "pio_regs.h"
5 #include "system.h"
6 #include "hardware.h"
7
8 #include "exec_example.pio.h"
9
10 int main()
11 {
12
tb_init();
13
14
15
for (int i = 0; i < count_of(exec_example_program); ++i)
mm_pio->instr_mem[i] = exec_example_program[i];
16
17
// Enable autopull, threshold of 32
18
mm_pio->sm[0].shiftctrl = (1u ctrl, 1u sm[0].instr = 0x0000 | 0x1; // jmp execute
25
26
// Feed a mixture of instructions and data into FIFO
27
mm_pio->txf[0] = instructions_to_push_program[0]; // out x, 32
28
mm_pio->txf[0] = 12345678;
29
mm_pio->txf[0] = instructions_to_push_program[1]; // in x, 32
30
mm_pio->txf[0] = instructions_to_push_program[2]; // push
// data to be OUTed
31
32
// The program pushed into TX FIFO will return some data in RX FIFO
33
while (mm_pio->fstat & (1u rxf[0]);
37
38
return 0;
39 }
3.5. Functional Details
341
RP2040 Datasheet
Here we load an example program into the state machine, which does two things:
• Enters an infinite loop
• Enters a loop which repeatedly pulls 32 bits of data from the TX FIFO, and executes the lower 16 bits as an
instruction
The C program sets the state machine running, at which point it enters the hang loop. While the state machine is still
running, the C program forces in a jmp instruction, which causes the state machine to break out of the loop.
When an instruction is written to the INSTR register, the state machine immediately decodes and executes that
instruction, rather than the instruction it would have fetched from the PIO’s instruction memory. The program counter
does not advance, so on the next cycle (assuming the instruction forced into the INSTR interface did not stall) the state
machine continues to execute its current program from the point where it left off, unless the written instruction itself
manipulated PC.
Delay cycles are ignored on instructions written to the INSTR register, and execute immediately, ignoring the state
machine clock divider. This interface is provided for performing initial setup and effecting control flow changes, so it
executes instructions in a timely manner, no matter how the state machine is configured.
Instructions written to the INSTR register are permitted to stall, in which case the state machine will latch this instruction
internally until it completes. This is signified by the EXECCTRL_EXEC_STALLED flag. This can be cleared by restarting the state
machine, or writing a NOP to INSTR.
In the second phase of the example state machine program, the OUT EXEC instruction is used. The OUT itself occupies one
execution cycle, and the instruction which the OUT executes is on the next execution cycle. Note that one of the
instructions we execute is also an OUT — the state machine is only capable of executing one OUT instruction on any given
cycle.
OUT EXEC works by writing the OUT shift data to an internal instruction latch. On the next cycle, the state machine
remembers it must execute from this latch rather than the instruction memory, and also knows to not advance PC on this
second cycle.
This program will print "12345678" when run.
CAUTION
If an instruction written to INSTR stalls, it is stored in the same instruction latch used by OUT EXEC and MOV EXEC, and will
overwrite an in-progress instruction there. If EXEC instructions are used, instructions written to INSTR must not stall.
3.6. Examples
These examples illustrate some of PIO’s hardware features, by implementing common I/O interfaces.
Looking to get started?
The Raspberry Pi Pico C/C++ SDK book has a comprehensive PIO chapter, which walks through writing
and building a first PIO application, and goes on to walk through some programs line-by-line. It also
covers broader topics such as using PIO with DMA, and goes into much more depth on how PIO can be
integrated into your software.
3.6.1. Duplex SPI
3.6. Examples
342
RP2040 Datasheet
Figure 50. In SPI, a
host and device
exchange data over a
bidirectional pair of
serial data lines,
synchronous with a
clock (SCK). Two
flags, CPOL and
CPHA, specify the
clock’s behaviour.
CPOL is the idle state
of the clock: 0 for low,
1 for high. The clock
pulses a number of
times, transferring one
bit in each direction
per pulse, but always
SPI is a common serial interface with a twisty history. The following program implements full-duplex (i.e. transferring
data in both directions simultaneously) SPI, with a CPHA parameter of 0.
returns to its idle
state. CPHA
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/pio/spi/spi.pio Lines 14 - 32
determines on which
edge of the clock data
is captured: 0 for
14 .program spi_cpha0
leading edge, and 1 for
15 .side_set 1
trailing edge. The
16
arrows in the figure
show the clock edge
where data is captured
17 ; Pin assignments:
18 ; - SCK is side-set pin 0
by both the host and
19 ; - MOSI is OUT pin 0
device.
20 ; - MISO is IN pin 0
21 ;
22 ; Autopush and autopull must be enabled, and the serial frame size is set by
23 ; configuring the push/pull threshold. Shift left/right is fine, but you must
24 ; justify the data yourself. This is done most conveniently for frame sizes of
25 ; 8 or 16 bits by using the narrow store replication and narrow load byte
26 ; picking behaviour of RP2040's IO fabric.
27
28 ; Clock phase = 0: data is captured on the leading edge of each SCK pulse, and
29 ; transitions on the trailing edge, or some time before the first leading edge.
30
31
out pins, 1 side 0 [1] ; Stall here on empty (sideset proceeds even if
32
in pins, 1
side 1 [1] ; instruction stalls, so we stall with SCK low)
This code uses autopush and autopull to continuously stream data from the FIFOs. The entire program runs once for
every bit that is transferred, and then loops. The state machine tracks how many bits have been shifted in/out, and
automatically pushes/pulls the FIFOs at the correct point. A similar program handles the CPHA=1 case:
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/pio/spi/spi.pio Lines 34 - 42
34 .program spi_cpha1
35 .side_set 1
36
37 ; Clock phase = 1: data transitions on the leading edge of each SCK pulse, and
38 ; is captured on the trailing edge.
39
3.6. Examples
40
out x, 1
41
mov pins, x side 1 [1] ; Output data, assert SCK (mov pins uses OUT mapping)
side 0
42
in pins, 1
side 0
; Stall here on empty (keep SCK deasserted)
; Input data, deassert SCK
343
RP2040 Datasheet
NOTE
These programs do not control the chip select line; chip select is often implemented as a software-controlled GPIO,
due to wildly different behaviour between different SPI hardware. The full spi.pio source linked above contains some
examples how PIO can implement a hardware chip select line.
A C helper function configures the state machine, connects the GPIOs, and sets the state machine running. Note that
the SPI frame size — that is, the number of bits transferred for each FIFO record — can be programmed to any value
from 1 to 32, without modifying the program. Once configured, the state machine is set running.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/pio/spi/spi.pio Lines 46 - 72
46 static inline void pio_spi_init(PIO pio, uint sm, uint prog_offs, uint n_bits,
47
float clkdiv, bool cpha, bool cpol, uint pin_sck, uint pin_mosi, uint pin_miso) {
48
pio_sm_config c = cpha ? spi_cpha1_program_get_default_config(prog_offs) :
spi_cpha0_program_get_default_config(prog_offs);
49
sm_config_set_out_pins(&c, pin_mosi, 1);
50
sm_config_set_in_pins(&c, pin_miso);
51
sm_config_set_sideset_pins(&c, pin_sck);
52
// Only support MSB-first in this example code (shift to left, auto push/pull,
threshold=nbits)
53
sm_config_set_out_shift(&c, false, true, n_bits);
54
sm_config_set_in_shift(&c, false, true, n_bits);
55
sm_config_set_clkdiv(&c, clkdiv);
56
57
// MOSI, SCK output are low, MISO is input
58
pio_sm_set_pins_with_mask(pio, sm, 0, (1u pio, spi->sm)) {
26
*txfifo = *src++;
27
--tx_remain;
344
RP2040 Datasheet
28
}
29
if (rx_remain && !pio_sm_is_rx_fifo_empty(spi->pio, spi->sm)) {
30
(void) *rxfifo;
31
--rx_remain;
32
}
33
}
34 }
Putting this all together, this complete C program will loop back some data through a PIO SPI at 1MHz, with all four
CPOL/CPHA combinations:
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/pio/spi/spi_loopback.c Lines 1 - 77
1 /**
2
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3
*
4
* SPDX-License-Identifier: BSD-3-Clause
5
*/
6
7 #include
8 #include
9
10 #include "pico/stdlib.h"
11 #include "pio_spi.h"
12
13 // This program instantiates a PIO SPI with each of the four possible
14 // CPOL/CPHA combinations, with the serial input and output pin mapped to the
15 // same GPIO. Any data written into the state machine's TX FIFO should then be
16 // serialised, deserialised, and reappear in the state machine's RX FIFO.
17
18 #define PIN_SCK 18
19 #define PIN_MOSI 16
20 #define PIN_MISO 16 // same as MOSI, so we get loopback
21
22 #define BUF_SIZE 20
23
24 void test(const pio_spi_inst_t *spi) {
25
static uint8_t txbuf[BUF_SIZE];
26
static uint8_t rxbuf[BUF_SIZE];
27
printf("TX:");
28
for (int i = 0; i < BUF_SIZE; ++i) {
29
txbuf[i] = rand() >> 16;
30
rxbuf[i] = 0;
31
printf(" %02x", (int) txbuf[i]);
32
}
33
printf("\n");
34
35
pio_spi_write8_read8_blocking(spi, txbuf, rxbuf, BUF_SIZE);
36
37
printf("RX:");
38
bool mismatch = false;
39
for (int i = 0; i < BUF_SIZE; ++i) {
40
printf(" %02x", (int) rxbuf[i]);
41
mismatch = mismatch || rxbuf[i] != txbuf[i];
42
}
43
if (mismatch)
44
45
46
printf("\nNope\n");
else
printf("\nOK\n");
47 }
48
49 int main() {
3.6. Examples
345
RP2040 Datasheet
50
stdio_init_all();
51
52
pio_spi_inst_t spi = {
53
.pio = pio0,
54
.sm = 0
55
};
56
float clkdiv = 31.25f;
57
uint cpha0_prog_offs = pio_add_program(spi.pio, &spi_cpha0_program);
58
uint cpha1_prog_offs = pio_add_program(spi.pio, &spi_cpha1_program);
// 1 MHz @ 125 clk_sys
59
60
for (int cpha = 0; cpha 0, remainder of this OSR is invalid
69 do_exec:
70
out exec, 16
; Execute one instruction per FIFO word
71
jmp x-- do_exec
; Repeat n + 1 times
72 .wrap
The IO mapping required by the I2C program is quite complex, due to the different ways that the two serial lines must be
driven and sampled. One interesting feature is that state machine must drive the output enable high when the output is
low, since the bus is open-drain, so the sense of the data is inverted. This could be handled in the PIO program (e.g. mov
osr, ~osr), but instead we can use the IO controls on RP2040 to perform this inversion in the GPIO muxes, saving an
instruction.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/pio/i2c/i2c.pio Lines 80 - 120
80 static inline void i2c_program_init(PIO pio, uint sm, uint offset, uint pin_sda, uint
pin_scl) {
81
assert(pin_scl == pin_sda + 1);
82
pio_sm_config c = i2c_program_get_default_config(offset);
83
84
// IO mapping
85
sm_config_set_out_pins(&c, pin_sda, 1);
86
sm_config_set_set_pins(&c, pin_sda, 1);
87
sm_config_set_in_pins(&c, pin_sda);
88
sm_config_set_sideset_pins(&c, pin_scl);
89
sm_config_set_jmp_pin(&c, pin_sda);
90
91
sm_config_set_out_shift(&c, false, true, 16);
92
sm_config_set_in_shift(&c, false, true, 8);
93
94
float div = (float)clock_get_hz(clk_sys) / (32 * 100000);
95
sm_config_set_clkdiv(&c, div);
96
3.6. Examples
97
// Try to avoid glitching the bus while connecting the IOs. Get things set
98
// up so that pin is driven down when PIO asserts OE low, and pulled up
99
// otherwise.
100
gpio_pull_up(pin_scl);
360
RP2040 Datasheet
101
gpio_pull_up(pin_sda);
102
uint32_t both_pins = (1u pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS;
199
200
// Enable the USB controller in device mode.
201
usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS;
202
203
// Enable an interrupt per EP0 transaction
204
usb_hw->sie_ctrl = USB_SIE_CTRL_EP0_INT_1BUF_BITS; ②
205
206
// Enable interrupts for when a buffer is done, when the bus is reset,
207
// and when a setup packet is received
208
usb_hw->inte = USB_INTS_BUFF_STATUS_BITS |
209
USB_INTS_BUS_RESET_BITS |
210
USB_INTS_SETUP_REQ_BITS;
211
212
// Set up endpoints (endpoint control registers)
213
// described by device configuration
214
usb_setup_endpoints();
215
4.1. USB
393
RP2040 Datasheet
216
// Present full speed device by enabling pull up on DP
217
usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS;
218 }
4.1.3.2.2. Configuring the endpoint control registers for EP1 and EP2
The function usb_configure_endpoints loops through each endpoint defined in the device configuration (including EP0 in
and EP0 out, which don’t have an endpoint control register defined) and calls the usb_configure_endpoint function. This
sets up the endpoint control register for that endpoint:
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/usb/device/dev_lowlevel/dev_lowlevel.c Lines 149 - 164
149 void usb_setup_endpoint(const struct usb_endpoint_configuration *ep) {
150
printf("Set up endpoint 0x%x with buffer address 0x%p\n", ep->descriptor>bEndpointAddress, ep->data_buffer);
151
152
// EP0 doesn't have one so return if that is the case
153
if (!ep->endpoint_control) {
154
return;
155
}
156
157
// Get the data buffer as an offset of the USB controller's DPRAM
158
uint32_t dpram_offset = usb_buffer_offset(ep->data_buffer);
159
uint32_t reg = EP_CTRL_ENABLE_BITS
160
| EP_CTRL_INTERRUPT_PER_BUFFER
161
| (ep->descriptor->bmAttributes endpoint_control = reg;
164 }
4.1.3.2.3. Receiving a setup packet
An interrupt is raised when a setup packet is received, so the interrupt handler must handle this event:
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/usb/device/dev_lowlevel/dev_lowlevel.c Lines 492 - 502
492 void isr_usbctrl(void) {
493
// USB interrupt handler
494
uint32_t status = usb_hw->ints;
495
uint32_t handled = 0;
496
497
// Setup packet received
498
if (status & USB_INTS_SETUP_REQ_BITS) {
499
handled |= USB_INTS_SETUP_REQ_BITS;
500
usb_hw_clear->sie_status = USB_SIE_STATUS_SETUP_REC_BITS;
501
502
usb_handle_setup_packet();
}
The setup packet gets written to the first 8 bytes of the USB ram, so the setup packet handler casts that area of memory
to struct usb_setup_packet *.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/usb/device/dev_lowlevel/dev_lowlevel.c Lines 384 - 428
384 void usb_handle_setup_packet(void) {
385
4.1. USB
volatile struct usb_setup_packet *pkt = (volatile struct usb_setup_packet *) &usb_dpram
->setup_packet;
394
RP2040 Datasheet
386
uint8_t req_direction = pkt->bmRequestType;
387
uint8_t req = pkt->bRequest;
388
389
// Reset PID to 1 for EP0 IN
390
usb_get_endpoint_configuration(EP0_IN_ADDR)->next_pid = 1u;
391
392
if (req_direction == USB_DIR_OUT) {
393
if (req == USB_REQUEST_SET_ADDRESS) {
394
usb_set_device_address(pkt);
395
} else if (req == USB_REQUEST_SET_CONFIGURATION) {
396
usb_set_device_configuration(pkt);
397
} else {
398
usb_acknowledge_out_request();
399
printf("Other OUT request (0x%x)\r\n", pkt->bRequest);
400
401
}
} else if (req_direction == USB_DIR_IN) {
402
if (req == USB_REQUEST_GET_DESCRIPTOR) {
403
uint16_t descriptor_type = pkt->wValue >> 8;
404
405
switch (descriptor_type) {
406
case USB_DT_DEVICE:
407
usb_handle_device_descriptor();
408
printf("GET DEVICE DESCRIPTOR\r\n");
409
break;
410
411
case USB_DT_CONFIG:
412
usb_handle_config_descriptor(pkt);
413
printf("GET CONFIG DESCRIPTOR\r\n");
414
break;
415
416
case USB_DT_STRING:
417
usb_handle_string_descriptor(pkt);
418
printf("GET STRING DESCRIPTOR\r\n");
419
break;
420
421
default:
422
printf("Unhandled GET_DESCRIPTOR type 0x%x\r\n", descriptor_type);
423
}
424
} else {
425
printf("Other IN request (0x%x)\r\n", pkt->bRequest);
426
427
}
}
428 }
4.1.3.2.4. Replying to a setup packet on EP0 IN
The first thing a host will request is the device descriptor, the following code handles that setup request.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/usb/device/dev_lowlevel/dev_lowlevel.c Lines 267 - 274
267 void usb_handle_device_descriptor(void) {
268
const struct usb_device_descriptor *d = dev_config.device_descriptor;
269
// EP0 in
270
struct usb_endpoint_configuration *ep = usb_get_endpoint_configuration(EP0_IN_ADDR);
271
// Always respond with pid 1
272
ep->next_pid = 1;
273
usb_start_transfer(ep, (uint8_t *) d, sizeof(struct usb_device_descriptor));
274 }
4.1. USB
395
RP2040 Datasheet
The usb_start_transfer function copies the data to send into the appropriate hardware buffer, and configures the buffer
control register. Once the buffer control register has been written to, the device controller will respond to the host with
the data. Before this point, the device will reply with a NAK.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/usb/device/dev_lowlevel/dev_lowlevel.c Lines 239 - 261
239 void usb_start_transfer(struct usb_endpoint_configuration *ep, uint8_t *buf, uint16_t len)
{
240
// We are asserting that the length is bEndpointAddress);
245
246
// Prepare buffer control register value
247
uint32_t val = len | USB_BUF_CTRL_AVAIL;
248
249
if (ep_is_tx(ep)) {
250
// Need to copy the data from the user buffer to the usb memory
251
memcpy((void *) ep->data_buffer, (void *) buf, len);
252
// Mark as full
253
254
val |= USB_BUF_CTRL_FULL;
}
255
256
// Set pid and flip for next transfer
257
val |= ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID;
258
ep->next_pid ^= 1u;
259
260
*ep->buffer_control = val;
261 }
4.1.4. List of Registers
The USB registers start at a base address of 0x50110000 (defined as USBCTRL_REGS_BASE in SDK).
Table 396. List of USB
registers
4.1. USB
Offset
Name
Info
0x00
ADDR_ENDP
Device address and endpoint control
0x04
ADDR_ENDP1
Interrupt endpoint 1. Only valid for HOST mode.
0x08
ADDR_ENDP2
Interrupt endpoint 2. Only valid for HOST mode.
0x0c
ADDR_ENDP3
Interrupt endpoint 3. Only valid for HOST mode.
0x10
ADDR_ENDP4
Interrupt endpoint 4. Only valid for HOST mode.
0x14
ADDR_ENDP5
Interrupt endpoint 5. Only valid for HOST mode.
0x18
ADDR_ENDP6
Interrupt endpoint 6. Only valid for HOST mode.
0x1c
ADDR_ENDP7
Interrupt endpoint 7. Only valid for HOST mode.
0x20
ADDR_ENDP8
Interrupt endpoint 8. Only valid for HOST mode.
0x24
ADDR_ENDP9
Interrupt endpoint 9. Only valid for HOST mode.
0x28
ADDR_ENDP10
Interrupt endpoint 10. Only valid for HOST mode.
0x2c
ADDR_ENDP11
Interrupt endpoint 11. Only valid for HOST mode.
0x30
ADDR_ENDP12
Interrupt endpoint 12. Only valid for HOST mode.
396
RP2040 Datasheet
Offset
Name
Info
0x34
ADDR_ENDP13
Interrupt endpoint 13. Only valid for HOST mode.
0x38
ADDR_ENDP14
Interrupt endpoint 14. Only valid for HOST mode.
0x3c
ADDR_ENDP15
Interrupt endpoint 15. Only valid for HOST mode.
0x40
MAIN_CTRL
Main control register
0x44
SOF_WR
Set the SOF (Start of Frame) frame number in the host controller.
The SOF packet is sent every 1ms and the host will increment the
frame number by 1 each time.
0x48
SOF_RD
Read the last SOF (Start of Frame) frame number seen. In device
mode the last SOF received from the host. In host mode the last
SOF sent by the host.
0x4c
SIE_CTRL
SIE control register
0x50
SIE_STATUS
SIE status register
0x54
INT_EP_CTRL
interrupt endpoint control register
0x58
BUFF_STATUS
Buffer status register. A bit set here indicates that a buffer has
completed on the endpoint (if the buffer interrupt is enabled). It
is possible for 2 buffers to be completed, so clearing the buffer
status bit may instantly re set it on the next clock cycle.
0x5c
BUFF_CPU_SHOULD_HANDLE
Which of the double buffers should be handled. Only valid if
using an interrupt per buffer (i.e. not per 2 buffers). Not valid for
host interrupt endpoint polling because they are only single
buffered.
0x60
EP_ABORT
Device only: Can be set to ignore the buffer control register for
this endpoint in case you would like to revoke a buffer. A NAK
will be sent for every access to the endpoint until this bit is
cleared. A corresponding bit in EP_ABORT_DONE is set when it is safe
to modify the buffer control register.
0x64
EP_ABORT_DONE
Device only: Used in conjunction with EP_ABORT. Set once an
endpoint is idle so the programmer knows it is safe to modify the
buffer control register.
0x68
EP_STALL_ARM
Device: this bit must be set in conjunction with the STALL bit in the
buffer control register to send a STALL on EP0. The device
controller clears these bits when a SETUP packet is received
because the USB spec requires that a STALL condition is cleared
when a SETUP packet is received.
0x6c
NAK_POLL
Used by the host controller. Sets the wait time in microseconds
before trying again if the device replies with a NAK.
0x70
EP_STATUS_STALL_NAK
Device: bits are set when the IRQ_ON_NAK or IRQ_ON_STALL bits are
set. For EP0 this comes from SIE_CTRL. For all other endpoints it
comes from the endpoint control register.
0x74
USB_MUXING
Where to connect the USB controller. Should be to_phy by
default.
0x78
USB_PWR
Overrides for the power signals in the event that the VBUS
signals are not hooked up to GPIO. Set the value of the override
and then the override enable to switch over to the override value.
4.1. USB
397
RP2040 Datasheet
Offset
Name
Info
0x7c
USBPHY_DIRECT
This register allows for direct control of the USB phy. Use in
conjunction with usbphy_direct_override register to enable each
override bit.
0x80
USBPHY_DIRECT_OVERRIDE
Override enable for each control in usbphy_direct
0x84
USBPHY_TRIM
Used to adjust trim values of USB phy pull down resistors.
0x8c
INTR
Raw Interrupts
0x90
INTE
Interrupt Enable
0x94
INTF
Interrupt Force
0x98
INTS
Interrupt status after masking & forcing
USB: ADDR_ENDP Register
Offset: 0x00
Description
Device address and endpoint control
Table 397.
ADDR_ENDP Register
Bits
Name
Description
Type
Reset
31:20
Reserved.
-
-
-
19:16
ENDPOINT
Device endpoint to send data to. Only valid for HOST
RW
0x0
mode.
15:7
Reserved.
-
-
-
6:0
ADDRESS
In device mode, the address that the device should
RW
0x00
respond to. Set in response to a SET_ADDR setup packet
from the host. In host mode set to the address of the
device to communicate with.
USB: ADDR_ENDP1,
Registers
ADDR_ENDP2,
…,
ADDR_ENDP14,
ADDR_ENDP15
Offsets: 0x04, 0x08, …, 0x38, 0x3c
Description
Interrupt endpoint N. Only valid for HOST mode.
Table 398.
ADDR_ENDP1,
ADDR_ENDP2, …,
ADDR_ENDP14,
ADDR_ENDP15
Registers
Bits
Name
Description
Type
Reset
31:27
Reserved.
-
-
-
26
INTEP_PREAMBL
Interrupt EP requires preamble (is a low speed device on a RW
E
full speed hub)
25
INTEP_DIR
Direction of the interrupt endpoint. In=0, Out=1
RW
0x0
24:20
Reserved.
-
-
-
19:16
ENDPOINT
Endpoint number of the interrupt endpoint
RW
0x0
15:7
Reserved.
-
-
-
6:0
ADDRESS
Device address
RW
0x00
0x0
USB: MAIN_CTRL Register
4.1. USB
398
RP2040 Datasheet
Offset: 0x40
Description
Main control register
Table 399.
MAIN_CTRL Register
Bits
Name
Description
Type
Reset
31
SIM_TIMING
Reduced timings for simulation
RW
0x0
30:2
Reserved.
-
-
-
1
HOST_NDEVICE
Device mode = 0, Host mode = 1
RW
0x0
0
CONTROLLER_EN Enable controller
RW
0x0
USB: SOF_WR Register
Offset: 0x44
Description
Set the SOF (Start of Frame) frame number in the host controller. The SOF packet is sent every 1ms and the host
will increment the frame number by 1 each time.
Table 400. SOF_WR
Register
Bits
Name
Description
Type
Reset
31:11
Reserved.
-
-
-
10:0
COUNT
WF
0x000
USB: SOF_RD Register
Offset: 0x48
Description
Read the last SOF (Start of Frame) frame number seen. In device mode the last SOF received from the host. In host
mode the last SOF sent by the host.
Table 401. SOF_RD
Register
Bits
Name
Description
Type
Reset
31:11
Reserved.
-
-
-
10:0
COUNT
RO
0x000
USB: SIE_CTRL Register
Offset: 0x4c
Description
SIE control register
Table 402. SIE_CTRL
Register
Bits
Name
Description
Type
Reset
31
EP0_INT_STALL
Device: Set bit in EP_STATUS_STALL_NAK when EP0
RW
0x0
sends a STALL
30
EP0_DOUBLE_BUF Device: EP0 single buffered = 0, double buffered = 1
RW
0x0
29
EP0_INT_1BUF
RW
0x0
RW
0x0
Device: Set bit in BUFF_STATUS for every buffer
completed on EP0
28
EP0_INT_2BUF
Device: Set bit in BUFF_STATUS for every 2 buffers
completed on EP0
4.1. USB
399
RP2040 Datasheet
Bits
Name
Description
Type
Reset
27
EP0_INT_NAK
Device: Set bit in EP_STATUS_STALL_NAK when EP0
RW
0x0
sends a NAK
26
DIRECT_EN
Direct bus drive enable
RW
0x0
25
DIRECT_DP
Direct control of DP
RW
0x0
24
DIRECT_DM
Direct control of DM
RW
0x0
23:19
Reserved.
-
-
-
18
TRANSCEIVER_PD Power down bus transceiver
RW
0x0
17
RPU_OPT
Device: Pull-up strength (0=1K2, 1=2k3)
RW
0x0
16
PULLUP_EN
Device: Enable pull up resistor
RW
0x0
15
PULLDOWN_EN
Host: Enable pull down resistors
RW
0x0
14
Reserved.
-
-
-
13
RESET_BUS
Host: Reset bus
SC
0x0
12
RESUME
Device: Remote wakeup. Device can initiate its own
SC
0x0
resume after suspend.
11
VBUS_EN
Host: Enable VBUS
RW
0x0
10
KEEP_ALIVE_EN
Host: Enable keep alive packet (for low speed bus)
RW
0x0
9
SOF_EN
Host: Enable SOF generation (for full speed bus)
RW
0x0
8
SOF_SYNC
Host: Delay packet(s) until after SOF
RW
0x0
7
Reserved.
-
-
-
6
PREAMBLE_EN
Host: Preable enable for LS device on FS hub
RW
0x0
5
Reserved.
-
-
-
4
STOP_TRANS
Host: Stop transaction
SC
0x0
3
RECEIVE_DATA
Host: Receive transaction (IN to host)
RW
0x0
2
SEND_DATA
Host: Send transaction (OUT from host)
RW
0x0
1
SEND_SETUP
Host: Send Setup packet
RW
0x0
0
START_TRANS
Host: Start transaction
SC
0x0
USB: SIE_STATUS Register
Offset: 0x50
Description
SIE status register
Table 403.
SIE_STATUS Register
4.1. USB
400
RP2040 Datasheet
Bits
Name
Description
Type
Reset
31
DATA_SEQ_ERRO
Data Sequence Error.
WC
0x0
R
The device can raise a sequence error in the following
conditions:
* A SETUP packet is received followed by a DATA1 packet
(data phase should always be DATA0) * An OUT packet is
received from the host but doesn’t match the data pid in
the buffer control register read from DPSRAM
The host can raise a data sequence error in the following
conditions:
* An IN packet from the device has the wrong data PID
30
ACK_REC
ACK received. Raised by both host and device.
WC
0x0
29
STALL_REC
Host: STALL received
WC
0x0
28
NAK_REC
Host: NAK received
WC
0x0
27
RX_TIMEOUT
RX timeout is raised by both the host and device if an ACK WC
0x0
is not received in the maximum time specified by the USB
spec.
26
RX_OVERFLOW
RX overflow is raised by the Serial RX engine if the
WC
0x0
Bit Stuff Error. Raised by the Serial RX engine.
WC
0x0
incoming data is too fast.
25
BIT_STUFF_ERRO
R
24
CRC_ERROR
CRC Error. Raised by the Serial RX engine.
WC
0x0
23:20
Reserved.
-
-
-
19
BUS_RESET
Device: bus reset received
WC
0x0
18
TRANS_COMPLET Transaction complete.
WC
0x0
E
Raised by device if:
* An IN or OUT packet is sent with the LAST_BUFF bit set in
the buffer control register
Raised by host if:
* A setup packet is sent when no data in or data out
transaction follows * An IN packet is received and the
LAST_BUFF bit is set in the buffer control register * An IN
packet is received with zero length * An OUT packet is
sent and the LAST_BUFF bit is set
17
SETUP_REC
Device: Setup packet received
WC
0x0
16
CONNECTED
Device: connected
WC
0x0
15:12
Reserved.
-
-
-
11
RESUME
Host: Device has initiated a remote resume. Device: host
WC
0x0
has initiated a resume.
4.1. USB
401
RP2040 Datasheet
Bits
Name
Description
Type
Reset
10
VBUS_OVER_CUR
VBUS over current detected
RO
0x0
R
9:8
SPEED
Host: device speed. Disconnected = 00, LS = 01, FS = 10
WC
0x0
7:5
Reserved.
-
-
-
4
SUSPENDED
Bus in suspended state. Valid for device and host. Host
WC
0x0
and device will go into suspend if neither Keep Alive / SOF
frames are enabled.
3:2
LINE_STATE
USB bus line state
RO
0x0
1
Reserved.
-
-
-
0
VBUS_DETECTED
Device: VBUS Detected
RO
0x0
USB: INT_EP_CTRL Register
Offset: 0x54
Description
interrupt endpoint control register
Table 404.
INT_EP_CTRL Register
Bits
Name
Description
Type
Reset
31:16
Reserved.
-
-
-
15:1
INT_EP_ACTIVE
Host: Enable interrupt endpoint 1 → 15
RW
0x0000
0
Reserved.
-
-
-
USB: BUFF_STATUS Register
Offset: 0x58
Description
Buffer status register. A bit set here indicates that a buffer has completed on the endpoint (if the buffer interrupt is
enabled). It is possible for 2 buffers to be completed, so clearing the buffer status bit may instantly re set it on the
next clock cycle.
Table 405.
BUFF_STATUS
Register
4.1. USB
Bits
Name
31
Description
Type
Reset
EP15_OUT
WC
0x0
30
EP15_IN
WC
0x0
29
EP14_OUT
WC
0x0
28
EP14_IN
WC
0x0
27
EP13_OUT
WC
0x0
26
EP13_IN
WC
0x0
25
EP12_OUT
WC
0x0
24
EP12_IN
WC
0x0
23
EP11_OUT
WC
0x0
22
EP11_IN
WC
0x0
21
EP10_OUT
WC
0x0
402
RP2040 Datasheet
Bits
Name
20
Description
Type
Reset
EP10_IN
WC
0x0
19
EP9_OUT
WC
0x0
18
EP9_IN
WC
0x0
17
EP8_OUT
WC
0x0
16
EP8_IN
WC
0x0
15
EP7_OUT
WC
0x0
14
EP7_IN
WC
0x0
13
EP6_OUT
WC
0x0
12
EP6_IN
WC
0x0
11
EP5_OUT
WC
0x0
10
EP5_IN
WC
0x0
9
EP4_OUT
WC
0x0
8
EP4_IN
WC
0x0
7
EP3_OUT
WC
0x0
6
EP3_IN
WC
0x0
5
EP2_OUT
WC
0x0
4
EP2_IN
WC
0x0
3
EP1_OUT
WC
0x0
2
EP1_IN
WC
0x0
1
EP0_OUT
WC
0x0
0
EP0_IN
WC
0x0
USB: BUFF_CPU_SHOULD_HANDLE Register
Offset: 0x5c
Description
Which of the double buffers should be handled. Only valid if using an interrupt per buffer (i.e. not per 2 buffers). Not
valid for host interrupt endpoint polling because they are only single buffered.
Table 406.
BUFF_CPU_SHOULD_H
ANDLE Register
4.1. USB
Bits
Name
31
Description
Type
Reset
EP15_OUT
RO
0x0
30
EP15_IN
RO
0x0
29
EP14_OUT
RO
0x0
28
EP14_IN
RO
0x0
27
EP13_OUT
RO
0x0
26
EP13_IN
RO
0x0
25
EP12_OUT
RO
0x0
24
EP12_IN
RO
0x0
23
EP11_OUT
RO
0x0
403
RP2040 Datasheet
Bits
Name
22
Description
Type
Reset
EP11_IN
RO
0x0
21
EP10_OUT
RO
0x0
20
EP10_IN
RO
0x0
19
EP9_OUT
RO
0x0
18
EP9_IN
RO
0x0
17
EP8_OUT
RO
0x0
16
EP8_IN
RO
0x0
15
EP7_OUT
RO
0x0
14
EP7_IN
RO
0x0
13
EP6_OUT
RO
0x0
12
EP6_IN
RO
0x0
11
EP5_OUT
RO
0x0
10
EP5_IN
RO
0x0
9
EP4_OUT
RO
0x0
8
EP4_IN
RO
0x0
7
EP3_OUT
RO
0x0
6
EP3_IN
RO
0x0
5
EP2_OUT
RO
0x0
4
EP2_IN
RO
0x0
3
EP1_OUT
RO
0x0
2
EP1_IN
RO
0x0
1
EP0_OUT
RO
0x0
0
EP0_IN
RO
0x0
USB: EP_ABORT Register
Offset: 0x60
Description
Device only: Can be set to ignore the buffer control register for this endpoint in case you would like to revoke a
buffer. A NAK will be sent for every access to the endpoint until this bit is cleared. A corresponding bit in
EP_ABORT_DONE is set when it is safe to modify the buffer control register.
Table 407. EP_ABORT
Register
4.1. USB
Bits
Name
31
Description
Type
Reset
EP15_OUT
RW
0x0
30
EP15_IN
RW
0x0
29
EP14_OUT
RW
0x0
28
EP14_IN
RW
0x0
27
EP13_OUT
RW
0x0
26
EP13_IN
RW
0x0
404
RP2040 Datasheet
Bits
Name
25
Description
Type
Reset
EP12_OUT
RW
0x0
24
EP12_IN
RW
0x0
23
EP11_OUT
RW
0x0
22
EP11_IN
RW
0x0
21
EP10_OUT
RW
0x0
20
EP10_IN
RW
0x0
19
EP9_OUT
RW
0x0
18
EP9_IN
RW
0x0
17
EP8_OUT
RW
0x0
16
EP8_IN
RW
0x0
15
EP7_OUT
RW
0x0
14
EP7_IN
RW
0x0
13
EP6_OUT
RW
0x0
12
EP6_IN
RW
0x0
11
EP5_OUT
RW
0x0
10
EP5_IN
RW
0x0
9
EP4_OUT
RW
0x0
8
EP4_IN
RW
0x0
7
EP3_OUT
RW
0x0
6
EP3_IN
RW
0x0
5
EP2_OUT
RW
0x0
4
EP2_IN
RW
0x0
3
EP1_OUT
RW
0x0
2
EP1_IN
RW
0x0
1
EP0_OUT
RW
0x0
0
EP0_IN
RW
0x0
USB: EP_ABORT_DONE Register
Offset: 0x64
Description
Device only: Used in conjunction with EP_ABORT. Set once an endpoint is idle so the programmer knows it is safe to
modify the buffer control register.
Table 408.
EP_ABORT_DONE
Register
4.1. USB
Bits
Name
31
Description
Type
Reset
EP15_OUT
WC
0x0
30
EP15_IN
WC
0x0
29
EP14_OUT
WC
0x0
28
EP14_IN
WC
0x0
405
RP2040 Datasheet
Bits
Name
27
Description
Type
Reset
EP13_OUT
WC
0x0
26
EP13_IN
WC
0x0
25
EP12_OUT
WC
0x0
24
EP12_IN
WC
0x0
23
EP11_OUT
WC
0x0
22
EP11_IN
WC
0x0
21
EP10_OUT
WC
0x0
20
EP10_IN
WC
0x0
19
EP9_OUT
WC
0x0
18
EP9_IN
WC
0x0
17
EP8_OUT
WC
0x0
16
EP8_IN
WC
0x0
15
EP7_OUT
WC
0x0
14
EP7_IN
WC
0x0
13
EP6_OUT
WC
0x0
12
EP6_IN
WC
0x0
11
EP5_OUT
WC
0x0
10
EP5_IN
WC
0x0
9
EP4_OUT
WC
0x0
8
EP4_IN
WC
0x0
7
EP3_OUT
WC
0x0
6
EP3_IN
WC
0x0
5
EP2_OUT
WC
0x0
4
EP2_IN
WC
0x0
3
EP1_OUT
WC
0x0
2
EP1_IN
WC
0x0
1
EP0_OUT
WC
0x0
0
EP0_IN
WC
0x0
USB: EP_STALL_ARM Register
Offset: 0x68
Description
Device: this bit must be set in conjunction with the STALL bit in the buffer control register to send a STALL on EP0.
The device controller clears these bits when a SETUP packet is received because the USB spec requires that a
STALL condition is cleared when a SETUP packet is received.
4.1. USB
406
RP2040 Datasheet
Table 409.
EP_STALL_ARM
Register
Bits
Name
Description
Type
Reset
31:2
Reserved.
-
-
-
1
EP0_OUT
RW
0x0
0
EP0_IN
RW
0x0
USB: NAK_POLL Register
Offset: 0x6c
Description
Used by the host controller. Sets the wait time in microseconds before trying again if the device replies with a NAK.
Table 410. NAK_POLL
Register
Bits
Name
Description
Type
Reset
31:26
Reserved.
-
-
-
25:16
DELAY_FS
NAK polling interval for a full speed device
RW
0x010
15:10
Reserved.
-
-
-
9:0
DELAY_LS
NAK polling interval for a low speed device
RW
0x010
USB: EP_STATUS_STALL_NAK Register
Offset: 0x70
Description
Device: bits are set when the IRQ_ON_NAK or IRQ_ON_STALL bits are set. For EP0 this comes from SIE_CTRL. For all other
endpoints it comes from the endpoint control register.
Table 411.
EP_STATUS_STALL_N
AK Register
4.1. USB
Bits
Name
31
Description
Type
Reset
EP15_OUT
WC
0x0
30
EP15_IN
WC
0x0
29
EP14_OUT
WC
0x0
28
EP14_IN
WC
0x0
27
EP13_OUT
WC
0x0
26
EP13_IN
WC
0x0
25
EP12_OUT
WC
0x0
24
EP12_IN
WC
0x0
23
EP11_OUT
WC
0x0
22
EP11_IN
WC
0x0
21
EP10_OUT
WC
0x0
20
EP10_IN
WC
0x0
19
EP9_OUT
WC
0x0
18
EP9_IN
WC
0x0
17
EP8_OUT
WC
0x0
16
EP8_IN
WC
0x0
15
EP7_OUT
WC
0x0
407
RP2040 Datasheet
Bits
Name
14
Description
Type
Reset
EP7_IN
WC
0x0
13
EP6_OUT
WC
0x0
12
EP6_IN
WC
0x0
11
EP5_OUT
WC
0x0
10
EP5_IN
WC
0x0
9
EP4_OUT
WC
0x0
8
EP4_IN
WC
0x0
7
EP3_OUT
WC
0x0
6
EP3_IN
WC
0x0
5
EP2_OUT
WC
0x0
4
EP2_IN
WC
0x0
3
EP1_OUT
WC
0x0
2
EP1_IN
WC
0x0
1
EP0_OUT
WC
0x0
0
EP0_IN
WC
0x0
USB: USB_MUXING Register
Offset: 0x74
Description
Where to connect the USB controller. Should be to_phy by default.
Table 412.
USB_MUXING Register
Bits
Name
Description
Type
Reset
31:4
Reserved.
-
-
-
3
SOFTCON
RW
0x0
2
TO_DIGITAL_PAD
RW
0x0
1
TO_EXTPHY
RW
0x0
0
TO_PHY
RW
0x0
USB: USB_PWR Register
Offset: 0x78
Description
Overrides for the power signals in the event that the VBUS signals are not hooked up to GPIO. Set the value of the
override and then the override enable to switch over to the override value.
Table 413. USB_PWR
Register
4.1. USB
Bits
Name
Description
Type
Reset
31:6
Reserved.
-
-
-
5
OVERCURR_DETECT_EN
RW
0x0
4
OVERCURR_DETECT
RW
0x0
3
VBUS_DETECT_OVERRIDE_EN
RW
0x0
408
RP2040 Datasheet
Bits
Name
2
Description
Type
Reset
VBUS_DETECT
RW
0x0
1
VBUS_EN_OVERRIDE_EN
RW
0x0
0
VBUS_EN
RW
0x0
USB: USBPHY_DIRECT Register
Offset: 0x7c
Description
This register allows for direct control of the USB phy. Use in conjunction with usbphy_direct_override register to
enable each override bit.
Table 414.
USBPHY_DIRECT
Register
Bits
Name
Description
Type
Reset
31:23
Reserved.
-
-
-
22
DM_OVV
DM over voltage
RO
0x0
21
DP_OVV
DP over voltage
RO
0x0
20
DM_OVCN
DM overcurrent
RO
0x0
19
DP_OVCN
DP overcurrent
RO
0x0
18
RX_DM
DPM pin state
RO
0x0
17
RX_DP
DPP pin state
RO
0x0
16
RX_DD
Differential RX
RO
0x0
15
TX_DIFFMODE
TX_DIFFMODE=0: Single ended mode
RW
0x0
RW
0x0
RW
0x0
RW
0x0
RW
0x0
RW
0x0
RW
0x0
RW
0x0
TX_DIFFMODE=1: Differential drive mode (TX_DM,
TX_DM_OE ignored)
14
TX_FSSLEW
TX_FSSLEW=0: Low speed slew rate
TX_FSSLEW=1: Full speed slew rate
13
TX_PD
TX power down override (if override enable is set). 1 =
powered down.
12
RX_PD
RX power down override (if override enable is set). 1 =
powered down.
11
TX_DM
Output data. TX_DIFFMODE=1, Ignored
TX_DIFFMODE=0, Drives DPM only. TX_DM_OE=1 to
enable drive. DPM=TX_DM
10
TX_DP
Output data. If TX_DIFFMODE=1, Drives DPP/DPM diff
pair. TX_DP_OE=1 to enable drive. DPP=TX_DP,
DPM=~TX_DP
If TX_DIFFMODE=0, Drives DPP only. TX_DP_OE=1 to
enable drive. DPP=TX_DP
9
TX_DM_OE
Output enable. If TX_DIFFMODE=1, Ignored.
If TX_DIFFMODE=0, OE for DPM only. 0 - DPM in Hi-Z
state; 1 - DPM driving
8
TX_DP_OE
Output enable. If TX_DIFFMODE=1, OE for DPP/DPM diff
pair. 0 - DPP/DPM in Hi-Z state; 1 - DPP/DPM driving
If TX_DIFFMODE=0, OE for DPP only. 0 - DPP in Hi-Z state;
1 - DPP driving
4.1. USB
409
RP2040 Datasheet
Bits
Name
Description
Type
Reset
7
Reserved.
-
-
-
6
DM_PULLDN_EN
DM pull down enable
RW
0x0
5
DM_PULLUP_EN
DM pull up enable
RW
0x0
4
DM_PULLUP_HISE Enable the second DM pull up resistor. 0 - Pull = Rpu2; 1 -
RW
0x0
L
Pull = Rpu1 + Rpu2
3
Reserved.
-
-
-
2
DP_PULLDN_EN
DP pull down enable
RW
0x0
1
DP_PULLUP_EN
DP pull up enable
RW
0x0
0
DP_PULLUP_HISE Enable the second DP pull up resistor. 0 - Pull = Rpu2; 1 -
RW
0x0
L
Pull = Rpu1 + Rpu2
USB: USBPHY_DIRECT_OVERRIDE Register
Offset: 0x80
Description
Override enable for each control in usbphy_direct
Table 415.
USBPHY_DIRECT_OVE
RRIDE Register
Bits
Name
Description
Type
Reset
31:16
Reserved.
-
-
-
15
TX_DIFFMODE_OVERRIDE_EN
RW
0x0
14:13
Reserved.
-
-
12
DM_PULLUP_OVERRIDE_EN
RW
0x0
11
TX_FSSLEW_OVERRIDE_EN
RW
0x0
10
TX_PD_OVERRIDE_EN
RW
0x0
9
RX_PD_OVERRIDE_EN
RW
0x0
8
TX_DM_OVERRIDE_EN
RW
0x0
7
TX_DP_OVERRIDE_EN
RW
0x0
6
TX_DM_OE_OVERRIDE_EN
RW
0x0
5
TX_DP_OE_OVERRIDE_EN
RW
0x0
4
DM_PULLDN_EN_OVERRIDE_EN
RW
0x0
3
DP_PULLDN_EN_OVERRIDE_EN
RW
0x0
2
DP_PULLUP_EN_OVERRIDE_EN
RW
0x0
1
DM_PULLUP_HISEL_OVERRIDE_EN
RW
0x0
0
DP_PULLUP_HISEL_OVERRIDE_EN
RW
0x0
-
USB: USBPHY_TRIM Register
Offset: 0x84
Description
Used to adjust trim values of USB phy pull down resistors.
4.1. USB
410
RP2040 Datasheet
Table 416.
USBPHY_TRIM
Register
Bits
Name
Description
Type
Reset
31:13
Reserved.
-
-
-
12:8
DM_PULLDN_TRI
Value to drive to USB PHY
RW
0x1f
M
DM pulldown resistor trim control
Experimental data suggests that the reset value will work,
but this register allows adjustment if required
7:5
Reserved.
-
-
-
4:0
DP_PULLDN_TRI
Value to drive to USB PHY
RW
0x1f
M
DP pulldown resistor trim control
Experimental data suggests that the reset value will work,
but this register allows adjustment if required
USB: INTR Register
Offset: 0x8c
Description
Raw Interrupts
Table 417. INTR
Register
Bits
Name
Description
Type
Reset
31:20
Reserved.
-
-
-
19
EP_STALL_NAK
Raised when any bit in EP_STATUS_STALL_NAK is set.
RO
0x0
RO
0x0
RO
0x0
Clear by clearing all bits in EP_STATUS_STALL_NAK.
18
ABORT_DONE
Raised when any bit in ABORT_DONE is set. Clear by
clearing all bits in ABORT_DONE.
17
DEV_SOF
Set every time the device receives a SOF (Start of Frame)
packet. Cleared by reading SOF_RD
16
SETUP_REQ
Device. Source: SIE_STATUS.SETUP_REC
RO
0x0
15
DEV_RESUME_FR
Set when the device receives a resume from the host.
RO
0x0
OM_HOST
Cleared by writing to SIE_STATUS.RESUME
DEV_SUSPEND
Set when the device suspend state changes. Cleared by
RO
0x0
Set when the device connection state changes. Cleared by RO
0x0
14
writing to SIE_STATUS.SUSPENDED
13
DEV_CONN_DIS
writing to SIE_STATUS.CONNECTED
12
BUS_RESET
Source: SIE_STATUS.BUS_RESET
RO
0x0
11
VBUS_DETECT
Source: SIE_STATUS.VBUS_DETECTED
RO
0x0
10
STALL
Source: SIE_STATUS.STALL_REC
RO
0x0
9
ERROR_CRC
Source: SIE_STATUS.CRC_ERROR
RO
0x0
8
ERROR_BIT_STUF Source: SIE_STATUS.BIT_STUFF_ERROR
RO
0x0
Source: SIE_STATUS.RX_OVERFLOW
RO
0x0
Source: SIE_STATUS.RX_TIMEOUT
RO
0x0
Source: SIE_STATUS.DATA_SEQ_ERROR
RO
0x0
F
7
ERROR_RX_OVER
FLOW
6
ERROR_RX_TIME
OUT
5
ERROR_DATA_SE
Q
4.1. USB
411
RP2040 Datasheet
Bits
Name
Description
Type
Reset
4
BUFF_STATUS
Raised when any bit in BUFF_STATUS is set. Clear by
RO
0x0
RO
0x0
RO
0x0
RO
0x0
RO
0x0
clearing all bits in BUFF_STATUS.
3
TRANS_COMPLET Raised every time SIE_STATUS.TRANS_COMPLETE is set.
2
E
Clear by writing to this bit.
HOST_SOF
Host: raised every time the host sends a SOF (Start of
Frame). Cleared by reading SOF_RD
1
HOST_RESUME
Host: raised when a device wakes up the host. Cleared by
writing to SIE_STATUS.RESUME
0
HOST_CONN_DIS
Host: raised when a device is connected or disconnected
(i.e. when SIE_STATUS.SPEED changes). Cleared by
writing to SIE_STATUS.SPEED
USB: INTE Register
Offset: 0x90
Description
Interrupt Enable
Table 418. INTE
Register
Bits
Name
Description
Type
Reset
31:20
Reserved.
-
-
-
19
EP_STALL_NAK
Raised when any bit in EP_STATUS_STALL_NAK is set.
RW
0x0
RW
0x0
RW
0x0
Clear by clearing all bits in EP_STATUS_STALL_NAK.
18
ABORT_DONE
Raised when any bit in ABORT_DONE is set. Clear by
clearing all bits in ABORT_DONE.
17
DEV_SOF
Set every time the device receives a SOF (Start of Frame)
packet. Cleared by reading SOF_RD
16
SETUP_REQ
Device. Source: SIE_STATUS.SETUP_REC
RW
0x0
15
DEV_RESUME_FR
Set when the device receives a resume from the host.
RW
0x0
OM_HOST
Cleared by writing to SIE_STATUS.RESUME
DEV_SUSPEND
Set when the device suspend state changes. Cleared by
RW
0x0
Set when the device connection state changes. Cleared by RW
0x0
14
writing to SIE_STATUS.SUSPENDED
13
DEV_CONN_DIS
writing to SIE_STATUS.CONNECTED
12
BUS_RESET
Source: SIE_STATUS.BUS_RESET
RW
0x0
11
VBUS_DETECT
Source: SIE_STATUS.VBUS_DETECTED
RW
0x0
10
STALL
Source: SIE_STATUS.STALL_REC
RW
0x0
9
ERROR_CRC
Source: SIE_STATUS.CRC_ERROR
RW
0x0
8
ERROR_BIT_STUF Source: SIE_STATUS.BIT_STUFF_ERROR
RW
0x0
Source: SIE_STATUS.RX_OVERFLOW
RW
0x0
Source: SIE_STATUS.RX_TIMEOUT
RW
0x0
F
7
ERROR_RX_OVER
FLOW
6
ERROR_RX_TIME
OUT
4.1. USB
412
RP2040 Datasheet
Bits
Name
Description
Type
Reset
5
ERROR_DATA_SE
Source: SIE_STATUS.DATA_SEQ_ERROR
RW
0x0
Raised when any bit in BUFF_STATUS is set. Clear by
RW
0x0
RW
0x0
RW
0x0
RW
0x0
RW
0x0
Q
4
BUFF_STATUS
clearing all bits in BUFF_STATUS.
3
TRANS_COMPLET Raised every time SIE_STATUS.TRANS_COMPLETE is set.
2
E
Clear by writing to this bit.
HOST_SOF
Host: raised every time the host sends a SOF (Start of
Frame). Cleared by reading SOF_RD
1
HOST_RESUME
Host: raised when a device wakes up the host. Cleared by
writing to SIE_STATUS.RESUME
0
HOST_CONN_DIS
Host: raised when a device is connected or disconnected
(i.e. when SIE_STATUS.SPEED changes). Cleared by
writing to SIE_STATUS.SPEED
USB: INTF Register
Offset: 0x94
Description
Interrupt Force
Table 419. INTF
Register
Bits
Name
Description
Type
Reset
31:20
Reserved.
-
-
-
19
EP_STALL_NAK
Raised when any bit in EP_STATUS_STALL_NAK is set.
RW
0x0
RW
0x0
RW
0x0
Clear by clearing all bits in EP_STATUS_STALL_NAK.
18
ABORT_DONE
Raised when any bit in ABORT_DONE is set. Clear by
clearing all bits in ABORT_DONE.
17
DEV_SOF
Set every time the device receives a SOF (Start of Frame)
packet. Cleared by reading SOF_RD
16
SETUP_REQ
Device. Source: SIE_STATUS.SETUP_REC
RW
0x0
15
DEV_RESUME_FR
Set when the device receives a resume from the host.
RW
0x0
OM_HOST
Cleared by writing to SIE_STATUS.RESUME
DEV_SUSPEND
Set when the device suspend state changes. Cleared by
RW
0x0
Set when the device connection state changes. Cleared by RW
0x0
14
writing to SIE_STATUS.SUSPENDED
13
DEV_CONN_DIS
writing to SIE_STATUS.CONNECTED
12
BUS_RESET
Source: SIE_STATUS.BUS_RESET
RW
0x0
11
VBUS_DETECT
Source: SIE_STATUS.VBUS_DETECTED
RW
0x0
10
STALL
Source: SIE_STATUS.STALL_REC
RW
0x0
9
ERROR_CRC
Source: SIE_STATUS.CRC_ERROR
RW
0x0
8
ERROR_BIT_STUF Source: SIE_STATUS.BIT_STUFF_ERROR
RW
0x0
RW
0x0
F
7
ERROR_RX_OVER
Source: SIE_STATUS.RX_OVERFLOW
FLOW
4.1. USB
413
RP2040 Datasheet
Bits
Name
Description
Type
Reset
6
ERROR_RX_TIME
Source: SIE_STATUS.RX_TIMEOUT
RW
0x0
Source: SIE_STATUS.DATA_SEQ_ERROR
RW
0x0
Raised when any bit in BUFF_STATUS is set. Clear by
RW
0x0
RW
0x0
RW
0x0
RW
0x0
RW
0x0
OUT
5
ERROR_DATA_SE
Q
4
BUFF_STATUS
clearing all bits in BUFF_STATUS.
3
TRANS_COMPLET Raised every time SIE_STATUS.TRANS_COMPLETE is set.
2
E
Clear by writing to this bit.
HOST_SOF
Host: raised every time the host sends a SOF (Start of
Frame). Cleared by reading SOF_RD
1
HOST_RESUME
Host: raised when a device wakes up the host. Cleared by
writing to SIE_STATUS.RESUME
0
HOST_CONN_DIS
Host: raised when a device is connected or disconnected
(i.e. when SIE_STATUS.SPEED changes). Cleared by
writing to SIE_STATUS.SPEED
USB: INTS Register
Offset: 0x98
Description
Interrupt status after masking & forcing
Table 420. INTS
Register
Bits
Name
Description
Type
Reset
31:20
Reserved.
-
-
-
19
EP_STALL_NAK
Raised when any bit in EP_STATUS_STALL_NAK is set.
RO
0x0
RO
0x0
RO
0x0
Clear by clearing all bits in EP_STATUS_STALL_NAK.
18
ABORT_DONE
Raised when any bit in ABORT_DONE is set. Clear by
clearing all bits in ABORT_DONE.
17
DEV_SOF
Set every time the device receives a SOF (Start of Frame)
packet. Cleared by reading SOF_RD
16
SETUP_REQ
Device. Source: SIE_STATUS.SETUP_REC
RO
0x0
15
DEV_RESUME_FR
Set when the device receives a resume from the host.
RO
0x0
OM_HOST
Cleared by writing to SIE_STATUS.RESUME
DEV_SUSPEND
Set when the device suspend state changes. Cleared by
RO
0x0
Set when the device connection state changes. Cleared by RO
0x0
14
writing to SIE_STATUS.SUSPENDED
13
DEV_CONN_DIS
writing to SIE_STATUS.CONNECTED
12
BUS_RESET
Source: SIE_STATUS.BUS_RESET
RO
0x0
11
VBUS_DETECT
Source: SIE_STATUS.VBUS_DETECTED
RO
0x0
10
STALL
Source: SIE_STATUS.STALL_REC
RO
0x0
9
ERROR_CRC
Source: SIE_STATUS.CRC_ERROR
RO
0x0
8
ERROR_BIT_STUF Source: SIE_STATUS.BIT_STUFF_ERROR
RO
0x0
F
4.1. USB
414
RP2040 Datasheet
Bits
Name
Description
Type
Reset
7
ERROR_RX_OVER
Source: SIE_STATUS.RX_OVERFLOW
RO
0x0
Source: SIE_STATUS.RX_TIMEOUT
RO
0x0
Source: SIE_STATUS.DATA_SEQ_ERROR
RO
0x0
Raised when any bit in BUFF_STATUS is set. Clear by
RO
0x0
RO
0x0
RO
0x0
RO
0x0
RO
0x0
FLOW
6
ERROR_RX_TIME
OUT
5
ERROR_DATA_SE
Q
4
BUFF_STATUS
clearing all bits in BUFF_STATUS.
3
2
TRANS_COMPLET Raised every time SIE_STATUS.TRANS_COMPLETE is set.
E
Clear by writing to this bit.
HOST_SOF
Host: raised every time the host sends a SOF (Start of
Frame). Cleared by reading SOF_RD
1
HOST_RESUME
Host: raised when a device wakes up the host. Cleared by
writing to SIE_STATUS.RESUME
0
HOST_CONN_DIS
Host: raised when a device is connected or disconnected
(i.e. when SIE_STATUS.SPEED changes). Cleared by
writing to SIE_STATUS.SPEED
References
▪ http://www.usbmadesimple.co.uk/
▪ https://www.usb.org/document-library/usb-20-specification
4.2. UART
ARM Documentation
Excerpted from the PrimeCell UART (PL011) Technical Reference Manual. Used with permission.
RP2040 has 2 identical instances of a UART peripheral, based on the ARM Primecell UART (PL011) (Revision r1p5).
Each instance supports the following features:
• Separate 32×8 Tx and 32×12 Rx FIFOs
• Programmable baud rate generator, clocked by clk_peri (see Section 2.15.1)
• Standard asynchronous communication bits (start, stop, parity) added on transmit and removed on receive
• line break detection
• programmable serial interface (5, 6, 7, or 8 bits)
• 1 or 2 stop bits
• programmable hardware flow control
Each UART can be connected to a number of GPIO pins as defined in the GPIO muxing table in Section 2.19.2.
Connections to the GPIO muxing are prefixed with the UART instance name uart0_ or uart1_, and include the following:
4.2. UART
415
RP2040 Datasheet
• Transmit data tx (referred to as UARTTXD in the following sections)
• Received data rx (referred to as UARTRXD in the following sections)
• Output flow control rts (referred to as nUARTRTS in the following sections)
• Input flow control cts (referred to as nUARTCTS in the following sections)
The modem mode and IrDA mode of the PL011 are not supported.
The UARTCLK is driven from clk_peri, and PCLK is driven from the system clock clk_sys (see Section 2.15.1).
4.2.1. Overview
The UART performs:
• Serial-to-parallel conversion on data received from a peripheral device
• Parallel-to-serial conversion on data transmitted to the peripheral device.
The CPU reads and writes data and control/status information through the AMBA APB interface. The transmit and
receive paths are buffered with internal FIFO memories enabling up to 32-bytes to be stored independently in both
transmit and receive modes.
The UART:
• Includes a programmable baud rate generator that generates a common transmit and receive internal clock from
the UART internal reference clock input, UARTCLK
• Offers similar functionality to the industry-standard 16C650 UART device
• Supports a maximum baud rate of UARTCLK / 16 in UART mode (7.8 Mbaud at 125MHz)
The UART operation and baud rate values are controlled by the Line Control Register, UARTLCR_H and the baud rate
divisor registers (Integer Baud Rate Register, UARTIBRD and Fractional Baud Rate Register, UARTFBRD).
The UART can generate:
• Individually-maskable interrupts from the receive (including timeout), transmit, modem status and error conditions
• A single combined interrupt so that the output is asserted if any of the individual interrupts are asserted, and
unmasked
• DMA request signals for interfacing with a Direct Memory Access (DMA) controller.
If a framing, parity, or break error occurs during reception, the appropriate error bit is set, and is stored in the FIFO. If an
overrun condition occurs, the overrun register bit is set immediately and FIFO data is prevented from being overwritten.
You can program the FIFOs to be 1-byte deep providing a conventional double-buffered UART interface.
There is a programmable hardware flow control feature that uses the nUARTCTS input and the nUARTRTS output to
automatically control the serial data flow.
4.2.2. Functional description
4.2. UART
416
RP2040 Datasheet
Figure 59. UART block
diagram. Test logic is
not shown for clarity.
4.2.2.1. AMBA APB interface
The AMBA APB interface generates read and write decodes for accesses to status/control registers, and the transmit
and receive FIFOs.
4.2.2.2. Register block
The register block stores data written, or to be read across the AMBA APB interface.
4.2.2.3. Baud rate generator
The baud rate generator contains free-running counters that generate the internal clocks: Baud16 and IrLPBaud16
signals. Baud16 provides timing information for UART transmit and receive control. Baud16 is a stream of pulses with a
width of one UARTCLK clock period and a frequency of 16 times the baud rate.
4.2.2.4. Transmit FIFO
The transmit FIFO is an 8-bit wide, 32 location deep, FIFO memory buffer. CPU data written across the APB interface is
stored in the FIFO until read out by the transmit logic. You can disable the transmit FIFO to act like a one-byte holding
register.
4.2.2.5. Receive FIFO
The receive FIFO is a 12-bit wide, 32 location deep, FIFO memory buffer. Received data and corresponding error bits, are
stored in the receive FIFO by the receive logic until read out by the CPU across the APB interface. The receive FIFO can
be disabled to act like a one-byte holding register.
4.2. UART
417
RP2040 Datasheet
4.2.2.6. Transmit logic
The transmit logic performs parallel-to-serial conversion on the data read from the transmit FIFO. Control logic outputs
the serial bit stream beginning with a start bit, data bits with the Least Significant Bit (LSB) first, followed by the parity
bit, and then the stop bits according to the programmed configuration in control registers.
4.2.2.7. Receive logic
The receive logic performs serial-to-parallel conversion on the received bit stream after a valid start pulse has been
detected. Overrun, parity, frame error checking, and line break detection are also performed, and their status
accompanies the data that is written to the receive FIFO.
4.2.2.8. Interrupt generation logic
Individual maskable active HIGH interrupts are generated by the UART. A combined interrupt output is generated as an
OR function of the individual interrupt requests and is connected to the processor interrupt controllers.
See Section 4.2.6 for more information.
4.2.2.9. DMA interface
The UART provides an interface to connect to the DMA controller as UART DMA interface in Section 4.2.5 describes.
4.2.2.10. Synchronizing registers and logic
The UART supports both asynchronous and synchronous operation of the clocks, PCLK and UARTCLK. Synchronization
registers and handshaking logic have been implemented, and are active at all times. This has a minimal impact on
performance or area. Synchronization of control signals is performed on both directions of data flow, that is from the
PCLK to the UARTCLK domain, and from the UARTCLK to the PCLK domain.
4.2.3. Operation
4.2.3.1. Clock signals
The frequency selected for UARTCLK must accommodate the required range of baud rates:
• FUARTCLK (min) ≥ 16 × baud_rate(max)
• FUARTCLK(max) ≤ 16 × 65535 × baud_rate(min)
For example, for a range of baud rates from 110 baud to 460800 baud the UARTCLK frequency must be between
7.3728MHz to 115.34MHz.
The frequency of UARTCLK must also be within the required error limits for all baud rates to be used.
There is also a constraint on the ratio of clock frequencies for PCLK to UARTCLK. The frequency of UARTCLK must be
no more than 5/3 times faster than the frequency of PCLK:
• FUARTCLK ≤ 5/3 × FPCLK
For example, in UART mode, to generate 921600 baud when UARTCLK is 14.7456MHz then PCLK must be greater than
or equal to 8.85276MHz. This ensures that the UART has sufficient time to write the received data to the receive FIFO.
4.2. UART
418
RP2040 Datasheet
4.2.3.2. UART operation
Control data is written to the UART Line Control Register, UARTLCR. This register is 30-bits wide internally, but is
externally accessed through the APB interface by writes to the following registers:
The UARTLCR_H register defines the:
• transmission parameters
• word length
• buffer mode
• number of transmitted stop bits
• parity mode
• break generation.
The UARTIBRD register defines the integer baud rate divider, and the UARTFBRD register defines the fractional baud
rate divider.
4.2.3.2.1. Fractional baud rate divider
The baud rate divisor is a 22-bit number consisting of a 16-bit integer and a 6-bit fractional part. This is used by the
baud rate generator to determine the bit period. The fractional baud rate divider enables the use of any clock with a
frequency >3.6864MHz to act as UARTCLK, while it is still possible to generate all the standard baud rates.
The 16-bit integer is written to the Integer Baud Rate Register, UARTIBRD. The 6-bit fractional part is written to the
Fractional Baud Rate Register, UARTFBRD. The Baud Rate Divisor has the following relationship to UARTCLK:
Baud Rate Divisor = UARTCLK/(16×Baud Rate) =
where
is the integer part and
is the
fractional part separated by a decimal point as Figure 60.
Figure 60. Baud rate
divisor.
You can calculate the 6-bit number ( ) by taking the fractional part of the required baud rate divisor and multiplying it by
64 (that is,
, where
is the width of the UARTFBRD Register) and adding 0.5 to account for rounding errors:
An internal clock enable signal, Baud16, is generated, and is a stream of one UARTCLK wide pulses with an average
frequency of 16 times the required baud rate. This signal is then divided by 16 to give the transmit clock. A low number
in the baud rate divisor gives a short bit period, and a high number in the baud rate divisor gives a long bit period.
4.2.3.2.2. Data transmission or reception
Data received or transmitted is stored in two 32-byte FIFOs, though the receive FIFO has an extra four bits per character
for status information. For transmission, data is written into the transmit FIFO. If the UART is enabled, it causes a data
frame to start transmitting with the parameters indicated in the Line Control Register, UARTLCR_H. Data continues to be
transmitted until there is no data left in the transmit FIFO. The BUSY signal goes HIGH as soon as data is written to the
transmit FIFO (that is, the FIFO is non-empty) and remains asserted HIGH while data is being transmitted. BUSY is
negated only when the transmit FIFO is empty, and the last character has been transmitted from the shift register,
including the stop bits. BUSY can be asserted HIGH even though the UART might no longer be enabled.
For each sample of data, three readings are taken and the majority value is kept. In the following paragraphs the middle
sampling point is defined, and one sample is taken either side of it.
When the receiver is idle (UARTRXD continuously 1, in the marking state) and a LOW is detected on the data input (a
start bit has been received), the receive counter, with the clock enabled by Baud16, begins running and data is sampled
on the eighth cycle of that counter in UART mode, or the fourth cycle of the counter in SIR mode to allow for the shorter
4.2. UART
419
RP2040 Datasheet
logic 0 pulses (half way through a bit period).
The start bit is valid if UARTRXD is still LOW on the eighth cycle of Baud16, otherwise a false start bit is detected and it
is ignored.
If the start bit was valid, successive data bits are sampled on every 16th cycle of Baud16 (that is, one bit period later)
according to the programmed length of the data characters. The parity bit is then checked if parity mode was enabled.
Lastly, a valid stop bit is confirmed if UARTRXD is HIGH, otherwise a framing error has occurred. When a full word is
received, the data is stored in the receive FIFO, with any error bits associated with that word
4.2.3.2.3. Error bits
Three error bits are stored in bits [10:8] of the receive FIFO, and are associated with a particular character. There is an
additional error that indicates an overrun error and this is stored in bit 11 of the receive FIFO.
4.2.3.2.4. Overrun bit
The overrun bit is not associated with the character in the receive FIFO. The overrun error is set when the FIFO is full,
and the next character is completely received in the shift register. The data in the shift register is overwritten, but it is
not written into the FIFO. When an empty location is available in the receive FIFO, and another character is received, the
state of the overrun bit is copied into the receive FIFO along with the received character. The overrun state is then
cleared. Table 421 lists the bit functions of the receive FIFO.
Table 421. Receive
FIFO bit functions
FIFO bit
Function
11
Overrun indicator
10
Break error
9
Parity error
8
Framing error
7:0
Received data
4.2.3.2.5. Disabling the FIFOs
Additionally, you can disable the FIFOs. In this case, the transmit and receive sides of the UART have 1-byte holding
registers (the bottom entry of the FIFOs). The overrun bit is set when a word has been received, and the previous one
was not yet read. In this implementation, the FIFOs are not physically disabled, but the flags are manipulated to give the
illusion of a 1-byte register. When the FIFOs are disabled, a write to the data register bypasses the holding register
unless the transmit shift register is already in use.
4.2.3.2.6. System and diagnostic loopback testing
You can perform loopback testing for UART data by setting the Loop Back Enable (LBE) bit to 1 in the Control Register,
UARTCR.
Data transmitted on UARTTXD is received on the UARTRXD input.
4.2.3.3. UART character frame
4.2. UART
420
RP2040 Datasheet
Figure 61. UART
Data bits
Start bit
character frame.
TXD
0
1
0
1
0
Stop bit
0
1
1
0
1
DMASREQ
Bit period
3/16
Bit period
1
0
DMABREQ
DMACLR
0
1
0
1
0
Start
0
Data bits
1
1
Stop
4.2.4. UART hardware flow control
The hardware flow control feature is fully selectable, and enables you to control the serial data flow by using the
nUARTRTS output and nUARTCTS input signals. Figure 62 shows how two devices can communicate with each other
using hardware flow control.
Figure 62. Hardware
flow control between
two similar devices.
When the RTS flow control is enabled, nUARTRTS is asserted until the receive FIFO is filled up to the programmed
watermark level. When the CTS flow control is enabled, the transmitter can only transmit data when nUARTCTS is
asserted.
The hardware flow control is selectable using the RTSEn and CTSEn bits in the Control Register, UARTCR. Table 422
lists how you must set the bits to enable RTS and CTS flow control both simultaneously, and independently.
Table 422. Control bits
to enable and disable
hardware flow control.
UARTCR Register bits
CTSEn
RTSEn
Description
1
1
Both RTS and CTS flow control
enabled
1
0
Only CTS flow control enabled
0
1
Only RTS flow control enabled
0
0
Both RTS and CTS flow control
disabled
NOTE
When RTS flow control is enabled, the software cannot use the RTSEn bit in the Control Register, UARTCR, to control
the status of nUARTRTS.
4.2.4.1. RTS flow control
The RTS flow control logic is linked to the programmable receive FIFO watermark levels. When RTS flow control is
enabled, the nUARTRTS is asserted until the receive FIFO is filled up to the watermark level. When the receive FIFO
watermark level is reached, the nUARTRTS signal is deasserted, indicating that there is no more room to receive any
more data. The transmission of data is expected to cease after the current character has been transmitted.
4.2. UART
421
RP2040 Datasheet
The nUARTRTS signal is reasserted when data has been read out of the receive FIFO so that it is filled to less than the
watermark level. If RTS flow control is disabled and the UART is still enabled, then data is received until the receive FIFO
is full, or no more data is transmitted to it.
4.2.4.2. CTS flow control
If CTS flow control is enabled, then the transmitter checks the nUARTCTS signal before transmitting the next byte. If the
nUARTCTS signal is asserted, it transmits the byte otherwise transmission does not occur.
The data continues to be transmitted while nUARTCTS is asserted, and the transmit FIFO is not empty. If the transmit
FIFO is empty and the nUARTCTS signal is asserted no data is transmitted.
If the nUARTCTS signal is deasserted and CTS flow control is enabled, then the current character transmission is
completed before stopping. If CTS flow control is disabled and the UART is enabled, then the data continues to be
transmitted until the transmit FIFO is empty.
4.2.5. UART DMA Interface
The UART provides an interface to connect to a DMA controller. The DMA operation of the UART is controlled using the
DMA Control Register, UARTDMACR. The DMA interface includes the following signals:
For receive:
UARTRXDMASREQ
Single character DMA transfer request, asserted by the UART. For receive, one character consists of up to 12 bits.
This signal is asserted when the receive FIFO contains at least one character.
UARTRXDMABREQ
Burst DMA transfer request, asserted by the UART. This signal is asserted when the receive FIFO contains more
characters than the programmed watermark level. You can program the watermark level for each FIFO using the
Interrupt FIFO Level Select Register, UARTIFLS
UARTRXDMACLR
DMA request clear, asserted by a DMA controller to clear the receive request signals. If DMA burst transfer is
requested, the clear signal is asserted during the transfer of the last data in the burst.
For transmit:
UARTTXDMASREQ
Single character DMA transfer request, asserted by the UART. For transmit one character consists of up to eight
bits. This signal is asserted when there is at least one empty location in the transmit FIFO.
UARTTXDMABREQ
Burst DMA transfer request, asserted by the UART. This signal is asserted when the transmit FIFO contains less
characters than the watermark level. You can program the watermark level for each FIFO using the Interrupt FIFO
Level Select Register, UARTIFLS.
UARTTXDMACLR
DMA request clear, asserted by a DMA controller to clear the transmit request signals. If DMA burst transfer is
requested, the clear signal is asserted during the transfer of the last data in the burst.
The burst transfer and single transfer request signals are not mutually exclusive, they can both be asserted at the same
time. For example, when there is more data than the watermark level in the receive FIFO, the burst transfer request and
the single transfer request are asserted. When the amount of data left in the receive FIFO is less than the watermark
level, the single request only is asserted. This is useful for situations where the number of characters left to be received
in the stream is less than a burst.
For example, if 19 characters have to be received and the watermark level is programmed to be four. The DMA
controller then transfers four bursts of four characters and three single transfers to complete the stream.
4.2. UART
422
RP2040 Datasheet
NOTE
For the remaining three characters the UART cannot assert the burst request.
Each request signal remains asserted until the relevant DMACLR signal is asserted. After the request clear signal is
deasserted, a request signal can become active again, depending on the conditions described previously. All request
signals are deasserted if the UART is disabled or the relevant DMA enable bit, TXDMAE or RXDMAE, in the DMA Control
Register, UARTDMACR, is cleared.
If you disable the FIFOs in the UART then it operates in character mode and only the DMA single transfer mode can
operate, because only one character can be transferred to, or from the FIFOs at any time. UARTRXDMASREQ and
UARTTXDMASREQ are the only request signals that can be asserted. See the Line Control Register, UARTLCR_H, for
information about disabling the FIFOs.
When the UART is in the FIFO enabled mode, data transfers can be made by either single or burst transfers depending
on the programmed watermark level and the amount of data in the FIFO. Table 423 lists the trigger points for
UARTRXDMABREQ and UARTTXDMABREQ depending on the watermark level, for the transmit and receive FIFOs.
Table 423. DMA
trigger points for the
Watermark level
transmit and receive
Burst length
Transmit (number of empty
FIFOs.
Receive (number of filled locations)
locations)
1/8
28
4
1/4
24
8
1/2
16
16
3/4
8
24
7/8
4
28
In addition, the DMAONERR bit in the DMA Control Register, UARTDMACR, supports the use of the receive error
interrupt, UARTEINTR. It enables the DMA receive request outputs, UARTRXDMASREQ or UARTRXDMABREQ, to be
masked out when the UART error interrupt, UARTEINTR, is asserted. The DMA receive request outputs remain inactive
until the UARTEINTR is cleared. The DMA transmit request outputs are unaffected.
Figure 63. DMA
transfer waveforms.
Figure 63 shows the timing diagram for both a single transfer request and a burst transfer request with the appropriate
DMACLR signal. The signals are all synchronous to PCLK. For the sake of clarity it is assumed that there is no
synchronization of the request signals in the DMA controller.
4.2.6. Interrupts
There are eleven maskable interrupts generated in the UART. On RP2040, only the combined interrupt output, UARTINTR, is
connected.
You can enable or disable the individual interrupts by changing the mask bits in the Interrupt Mask Set/Clear Register,
UARTIMSC. Setting the appropriate mask bit HIGH enables the interrupt.
Provision of individual outputs and the combined interrupt output, enables you to use either a global interrupt service
routine, or modular device drivers to handle interrupts.
The transmit and receive dataflow interrupts UARTRXINTR and UARTTXINTR have been separated from the status
interrupts. This enables you to use UARTRXINTR and UARTTXINTR so that data can be read or written in response to
4.2. UART
423
RP2040 Datasheet
the FIFO trigger levels.
The error interrupt, UARTEINTR, can be triggered when there is an error in the reception of data. A number of error
conditions are possible.
The modem status interrupt, UARTMSINTR, is a combined interrupt of all the individual modem status signals.
The status of the individual interrupt sources can be read either from the Raw Interrupt Status Register, UARTRIS, or
from the Masked Interrupt Status Register, UARTMIS.
4.2.6.1. UARTMSINTR
The modem status interrupt is asserted if any of the modem status signals (nUARTCTS, nUARTDCD, nUARTDSR, and
nUARTRI) change. It is cleared by writing a 1 to the corresponding bit(s) in the Interrupt Clear Register, UARTICR,
depending on the modem status signals that generated the interrupt.
4.2.6.2. UARTRXINTR
The receive interrupt changes state when one of the following events occurs:
• If the FIFOs are enabled and the receive FIFO reaches the programmed trigger level. When this happens, the
receive interrupt is asserted HIGH. The receive interrupt is cleared by reading data from the receive FIFO until it
becomes less than the trigger level, or by clearing the interrupt.
• If the FIFOs are disabled (have a depth of one location) and data is received thereby filling the location, the receive
interrupt is asserted HIGH. The receive interrupt is cleared by performing a single read of the receive FIFO, or by
clearing the interrupt.
4.2.6.3. UARTTXINTR
The transmit interrupt changes state when one of the following events occurs:
• If the FIFOs are enabled and the transmit FIFO is equal to or lower than the programmed trigger level then the
transmit interrupt is asserted HIGH. The transmit interrupt is cleared by writing data to the transmit FIFO until it
becomes greater than the trigger level, or by clearing the interrupt.
• If the FIFOs are disabled (have a depth of one location) and there is no data present in the transmitters single
location, the transmit interrupt is asserted HIGH. It is cleared by performing a single write to the transmit FIFO, or
by clearing the interrupt.
To update the transmit FIFO you must:
• Write data to the transmit FIFO, either prior to enabling the UART and the interrupts, or after enabling the UART and
interrupts.
NOTE
The transmit interrupt is based on a transition through a level, rather than on the level itself. When the interrupt and
the UART is enabled before any data is written to the transmit FIFO the interrupt is not set. The interrupt is only set,
after written data leaves the single location of the transmit FIFO and it becomes empty.
4.2.6.4. UARTRTINTR
The receive timeout interrupt is asserted when the receive FIFO is not empty, and no more data is received during a 32bit period. The receive timeout interrupt is cleared either when the FIFO becomes empty through reading all the data (or
by reading the holding register), or when a 1 is written to the corresponding bit of the Interrupt Clear Register, UARTICR.
4.2. UART
424
RP2040 Datasheet
4.2.6.5. UARTEINTR
The error interrupt is asserted when an error occurs in the reception of data by the UART. The interrupt can be caused
by a number of different error conditions:
• framing
• parity
• break
• overrun.
You can determine the cause of the interrupt by reading the Raw Interrupt Status Register, UARTRIS, or the Masked
Interrupt Status Register, UARTMIS. It can be cleared by writing to the relevant bits of the Interrupt Clear Register,
UARTICR (bits 7 to 10 are the error clear bits).
4.2.6.6. UARTINTR
The interrupts are also combined into a single output, that is an OR function of the individual masked sources. You can
connect this output to a system interrupt controller to provide another level of masking on a individual peripheral basis.
The combined UART interrupt is asserted if any of the individual interrupts are asserted and enabled.
4.2.7. Programmer’s Model
The SDK provides a uart_init function to configure the UART with a particular baud rate. Once the UART is initialised,
the user must configure a GPIO pin as UART_TX and UART_RX. See Section 2.19.5.1 for more information on selecting a
GPIO function.
To initialise the UART, the uart_init function takes the following steps:
• Deassert the reset
• Enable clk_peri
• Set enable bits in the control register
• Enable the FIFOs
• Set the baud rate divisors
• Set the format
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_uart/uart.c Lines 39 - 64
39 uint uart_init(uart_inst_t *uart, uint baudrate) {
40
invalid_params_if(UART, uart != uart0 && uart != uart1);
41
42
if (clock_get_hz(clk_peri) == 0)
43
return 0;
44
45
uart_reset(uart);
46
uart_unreset(uart);
47
48 #if PICO_UART_ENABLE_CRLF_SUPPORT
49
uart_set_translate_crlf(uart, PICO_UART_DEFAULT_CRLF);
50 #endif
51
52
// Any LCR writes need to take place before enabling the UART
53
uint baud = uart_set_baudrate(uart, baudrate);
54
uart_set_format(uart, 8, 1, UART_PARITY_NONE);
55
56
4.2. UART
// Enable the UART, both TX and RX
425
RP2040 Datasheet
57
uart_get_hw(uart)->cr = UART_UARTCR_UARTEN_BITS | UART_UARTCR_TXE_BITS |
UART_UARTCR_RXE_BITS;
58
// Enable FIFOs
59
hw_set_bits(&uart_get_hw(uart)->lcr_h, UART_UARTLCR_H_FEN_BITS);
60
// Always enable DREQ signals -- no harm in this if DMA is not listening
61
uart_get_hw(uart)->dmacr = UART_UARTDMACR_TXDMAE_BITS | UART_UARTDMACR_RXDMAE_BITS;
62
63
return baud;
64 }
4.2.7.1. Baud Rate Calculation
The uart baud rate is derived from dividing clk_peri.
If the required baud rate is 115200 and UARTCLK = 125MHz then:
Baud Rate Divisor = (125 * 10^6)/(16 * 115200) ~= 67.817
Therefore, BRDI = 67 and BRDF = 0.817,
Therefore, fractional part, m = integer((0.817 * 64) + 0.5) = 52
Generated baud rate divider = 67 + 52/64 = 67.8125
Generated baud rate = (125 * 10^6)/(16 * 67.8125) ~= 115207
Error = (abs(115200 - 115207) / 115200) * 100 ~= 0.006%
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_uart/uart.c Lines 73 - 99
73 uint uart_set_baudrate(uart_inst_t *uart, uint baudrate) {
74
invalid_params_if(UART, baudrate == 0);
75
uint32_t baud_rate_div = (8 * clock_get_hz(clk_peri) / baudrate);
76
uint32_t baud_ibrd = baud_rate_div >> 7;
77
uint32_t baud_fbrd;
78
79
if (baud_ibrd == 0) {
80
baud_ibrd = 1;
81
82
baud_fbrd = 0;
} else if (baud_ibrd >= 65535) {
83
baud_ibrd = 65535;
84
85
baud_fbrd = 0;
}
86
87
else {
baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2;
}
88
89
// Load PL011's baud divisor registers
90
uart_get_hw(uart)->ibrd = baud_ibrd;
91
uart_get_hw(uart)->fbrd = baud_fbrd;
92
93
// PL011 needs a (dummy) line control register write to latch in the
94
// divisors. We don't want to actually change LCR contents here.
95
hw_set_bits(&uart_get_hw(uart)->lcr_h, 0);
96
97
// See datasheet
98
return (4 * clock_get_hz(clk_peri)) / (64 * baud_ibrd + baud_fbrd);
99 }
4.2. UART
426
RP2040 Datasheet
4.2.8. List of Registers
The UART0 and UART1 registers start at base addresses of 0x40034000 and 0x40038000 respectively (defined as
UART0_BASE and UART1_BASE in SDK).
Table 424. List of
UART registers
Offset
Name
Info
0x000
UARTDR
Data Register, UARTDR
0x004
UARTRSR
Receive Status Register/Error Clear Register,
UARTRSR/UARTECR
0x018
UARTFR
Flag Register, UARTFR
0x020
UARTILPR
IrDA Low-Power Counter Register, UARTILPR
0x024
UARTIBRD
Integer Baud Rate Register, UARTIBRD
0x028
UARTFBRD
Fractional Baud Rate Register, UARTFBRD
0x02c
UARTLCR_H
Line Control Register, UARTLCR_H
0x030
UARTCR
Control Register, UARTCR
0x034
UARTIFLS
Interrupt FIFO Level Select Register, UARTIFLS
0x038
UARTIMSC
Interrupt Mask Set/Clear Register, UARTIMSC
0x03c
UARTRIS
Raw Interrupt Status Register, UARTRIS
0x040
UARTMIS
Masked Interrupt Status Register, UARTMIS
0x044
UARTICR
Interrupt Clear Register, UARTICR
0x048
UARTDMACR
DMA Control Register, UARTDMACR
0xfe0
UARTPERIPHID0
UARTPeriphID0 Register
0xfe4
UARTPERIPHID1
UARTPeriphID1 Register
0xfe8
UARTPERIPHID2
UARTPeriphID2 Register
0xfec
UARTPERIPHID3
UARTPeriphID3 Register
0xff0
UARTPCELLID0
UARTPCellID0 Register
0xff4
UARTPCELLID1
UARTPCellID1 Register
0xff8
UARTPCELLID2
UARTPCellID2 Register
0xffc
UARTPCELLID3
UARTPCellID3 Register
UART: UARTDR Register
Offset: 0x000
Description
Data Register, UARTDR
Table 425. UARTDR
Register
Bits
Name
Description
Type
Reset
31:12
Reserved.
-
-
-
11
OE
Overrun error. This bit is set to 1 if data is received and the RO
-
receive FIFO is already full. This is cleared to 0 once there
is an empty space in the FIFO and a new character can be
written to it.
4.2. UART
427
RP2040 Datasheet
Bits
Name
Description
Type
Reset
10
BE
Break error. This bit is set to 1 if a break condition was
RO
-
RO
-
Framing error. When set to 1, it indicates that the received RO
-
detected, indicating that the received data input was held
LOW for longer than a full-word transmission time
(defined as start, data, parity and stop bits). In FIFO mode,
this error is associated with the character at the top of the
FIFO. When a break occurs, only one 0 character is loaded
into the FIFO. The next character is only enabled after the
receive data input goes to a 1 (marking state), and the
next valid start bit is received.
9
PE
Parity error. When set to 1, it indicates that the parity of
the received data character does not match the parity that
the EPS and SPS bits in the Line Control Register,
UARTLCR_H. In FIFO mode, this error is associated with
the character at the top of the FIFO.
8
FE
character did not have a valid stop bit (a valid stop bit is
1). In FIFO mode, this error is associated with the
character at the top of the FIFO.
7:0
DATA
Receive (read) data character. Transmit (write) data
RWF
-
character.
UART: UARTRSR Register
Offset: 0x004
Description
Receive Status Register/Error Clear Register, UARTRSR/UARTECR
Table 426. UARTRSR
Register
Bits
Name
Description
Type
Reset
31:4
Reserved.
-
-
-
3
OE
Overrun error. This bit is set to 1 if data is received and the WC
0x0
FIFO is already full. This bit is cleared to 0 by a write to
UARTECR. The FIFO contents remain valid because no
more data is written when the FIFO is full, only the
contents of the shift register are overwritten. The CPU
must now read the data, to empty the FIFO.
2
BE
Break error. This bit is set to 1 if a break condition was
WC
0x0
detected, indicating that the received data input was held
LOW for longer than a full-word transmission time
(defined as start, data, parity, and stop bits). This bit is
cleared to 0 after a write to UARTECR. In FIFO mode, this
error is associated with the character at the top of the
FIFO. When a break occurs, only one 0 character is loaded
into the FIFO. The next character is only enabled after the
receive data input goes to a 1 (marking state) and the next
valid start bit is received.
4.2. UART
428
RP2040 Datasheet
Bits
Name
Description
Type
Reset
1
PE
Parity error. When set to 1, it indicates that the parity of
WC
0x0
Framing error. When set to 1, it indicates that the received WC
0x0
the received data character does not match the parity that
the EPS and SPS bits in the Line Control Register,
UARTLCR_H. This bit is cleared to 0 by a write to
UARTECR. In FIFO mode, this error is associated with the
character at the top of the FIFO.
0
FE
character did not have a valid stop bit (a valid stop bit is
1). This bit is cleared to 0 by a write to UARTECR. In FIFO
mode, this error is associated with the character at the top
of the FIFO.
UART: UARTFR Register
Offset: 0x018
Description
Flag Register, UARTFR
Table 427. UARTFR
Register
Bits
Name
Description
Type
Reset
31:9
Reserved.
-
-
-
8
RI
Ring indicator. This bit is the complement of the UART
RO
-
RO
0x1
RO
0x0
Transmit FIFO full. The meaning of this bit depends on the RO
0x0
ring indicator, nUARTRI, modem status input. That is, the
bit is 1 when nUARTRI is LOW.
7
TXFE
Transmit FIFO empty. The meaning of this bit depends on
the state of the FEN bit in the Line Control Register,
UARTLCR_H. If the FIFO is disabled, this bit is set when
the transmit holding register is empty. If the FIFO is
enabled, the TXFE bit is set when the transmit FIFO is
empty. This bit does not indicate if there is data in the
transmit shift register.
6
RXFF
Receive FIFO full. The meaning of this bit depends on the
state of the FEN bit in the UARTLCR_H Register. If the
FIFO is disabled, this bit is set when the receive holding
register is full. If the FIFO is enabled, the RXFF bit is set
when the receive FIFO is full.
5
TXFF
state of the FEN bit in the UARTLCR_H Register. If the
FIFO is disabled, this bit is set when the transmit holding
register is full. If the FIFO is enabled, the TXFF bit is set
when the transmit FIFO is full.
4
RXFE
Receive FIFO empty. The meaning of this bit depends on
RO
0x1
the state of the FEN bit in the UARTLCR_H Register. If the
FIFO is disabled, this bit is set when the receive holding
register is empty. If the FIFO is enabled, the RXFE bit is set
when the receive FIFO is empty.
4.2. UART
429
RP2040 Datasheet
Bits
Name
Description
Type
Reset
3
BUSY
UART busy. If this bit is set to 1, the UART is busy
RO
0x0
RO
-
RO
-
RO
-
transmitting data. This bit remains set until the complete
byte, including all the stop bits, has been sent from the
shift register. This bit is set as soon as the transmit FIFO
becomes non-empty, regardless of whether the UART is
enabled or not.
2
DCD
Data carrier detect. This bit is the complement of the
UART data carrier detect, nUARTDCD, modem status
input. That is, the bit is 1 when nUARTDCD is LOW.
1
DSR
Data set ready. This bit is the complement of the UART
data set ready, nUARTDSR, modem status input. That is,
the bit is 1 when nUARTDSR is LOW.
0
CTS
Clear to send. This bit is the complement of the UART
clear to send, nUARTCTS, modem status input. That is, the
bit is 1 when nUARTCTS is LOW.
UART: UARTILPR Register
Offset: 0x020
Description
IrDA Low-Power Counter Register, UARTILPR
Table 428. UARTILPR
Register
Bits
Name
Description
Type
Reset
31:8
Reserved.
-
-
-
7:0
ILPDVSR
8-bit low-power divisor value. These bits are cleared to 0
RW
0x00
at reset.
UART: UARTIBRD Register
Offset: 0x024
Description
Integer Baud Rate Register, UARTIBRD
Table 429. UARTIBRD
Register
Bits
Name
Description
Type
Reset
31:16
Reserved.
-
-
-
15:0
BAUD_DIVINT
The integer baud rate divisor. These bits are cleared to 0
RW
0x0000
on reset.
UART: UARTFBRD Register
Offset: 0x028
Description
Fractional Baud Rate Register, UARTFBRD
4.2. UART
430
RP2040 Datasheet
Table 430. UARTFBRD
Register
Bits
Name
Description
Type
Reset
31:6
Reserved.
-
-
-
5:0
BAUD_DIVFRAC
The fractional baud rate divisor. These bits are cleared to
RW
0x00
0 on reset.
UART: UARTLCR_H Register
Offset: 0x02c
Description
Line Control Register, UARTLCR_H
Table 431.
UARTLCR_H Register
Bits
Name
Description
Type
Reset
31:8
Reserved.
-
-
-
7
SPS
Stick parity select. 0 = stick parity is disabled 1 = either: *
RW
0x0
RW
0x0
RW
0x0
Two stop bits select. If this bit is set to 1, two stop bits are RW
0x0
if the EPS bit is 0 then the parity bit is transmitted and
checked as a 1 * if the EPS bit is 1 then the parity bit is
transmitted and checked as a 0. This bit has no effect
when the PEN bit disables parity checking and generation.
6:5
WLEN
Word length. These bits indicate the number of data bits
transmitted or received in a frame as follows: b11 = 8 bits
b10 = 7 bits b01 = 6 bits b00 = 5 bits.
4
FEN
Enable FIFOs: 0 = FIFOs are disabled (character mode)
that is, the FIFOs become 1-byte-deep holding registers 1
= transmit and receive FIFO buffers are enabled (FIFO
mode).
3
STP2
transmitted at the end of the frame. The receive logic
does not check for two stop bits being received.
2
EPS
Even parity select. Controls the type of parity the UART
RW
0x0
Parity enable: 0 = parity is disabled and no parity bit added RW
0x0
uses during transmission and reception: 0 = odd parity.
The UART generates or checks for an odd number of 1s in
the data and parity bits. 1 = even parity. The UART
generates or checks for an even number of 1s in the data
and parity bits. This bit has no effect when the PEN bit
disables parity checking and generation.
1
PEN
to the data frame 1 = parity checking and generation is
enabled.
0
BRK
Send break. If this bit is set to 1, a low-level is continually
RW
0x0
output on the UARTTXD output, after completing
transmission of the current character. For the proper
execution of the break command, the software must set
this bit for at least two complete frames. For normal use,
this bit must be cleared to 0.
UART: UARTCR Register
Offset: 0x030
4.2. UART
431
RP2040 Datasheet
Description
Control Register, UARTCR
Table 432. UARTCR
Register
Bits
Name
Description
Type
Reset
31:16
Reserved.
-
-
-
15
CTSEN
CTS hardware flow control enable. If this bit is set to 1,
RW
0x0
RW
0x0
This bit is the complement of the UART Out2 (nUARTOut2) RW
0x0
CTS hardware flow control is enabled. Data is only
transmitted when the nUARTCTS signal is asserted.
14
RTSEN
RTS hardware flow control enable. If this bit is set to 1,
RTS hardware flow control is enabled. Data is only
requested when there is space in the receive FIFO for it to
be received.
13
OUT2
modem status output. That is, when the bit is
programmed to a 1, the output is 0. For DTE this can be
used as Ring Indicator (RI).
12
OUT1
This bit is the complement of the UART Out1 (nUARTOut1) RW
0x0
modem status output. That is, when the bit is
programmed to a 1 the output is 0. For DTE this can be
used as Data Carrier Detect (DCD).
11
RTS
Request to send. This bit is the complement of the UART
RW
0x0
RW
0x0
Receive enable. If this bit is set to 1, the receive section of RW
0x1
request to send, nUARTRTS, modem status output. That
is, when the bit is programmed to a 1 then nUARTRTS is
LOW.
10
DTR
Data transmit ready. This bit is the complement of the
UART data transmit ready, nUARTDTR, modem status
output. That is, when the bit is programmed to a 1 then
nUARTDTR is LOW.
9
RXE
the UART is enabled. Data reception occurs for either
UART signals or SIR signals depending on the setting of
the SIREN bit. When the UART is disabled in the middle of
reception, it completes the current character before
stopping.
8
TXE
Transmit enable. If this bit is set to 1, the transmit section
RW
0x1
of the UART is enabled. Data transmission occurs for
either UART signals, or SIR signals depending on the
setting of the SIREN bit. When the UART is disabled in the
middle of transmission, it completes the current character
before stopping.
4.2. UART
432
RP2040 Datasheet
Bits
Name
Description
Type
Reset
7
LBE
Loopback enable. If this bit is set to 1 and the SIREN bit is
RW
0x0
set to 1 and the SIRTEST bit in the Test Control Register,
UARTTCR is set to 1, then the nSIROUT path is inverted,
and fed through to the SIRIN path. The SIRTEST bit in the
test register must be set to 1 to override the normal halfduplex SIR operation. This must be the requirement for
accessing the test registers during normal operation, and
SIRTEST must be cleared to 0 when loopback testing is
finished. This feature reduces the amount of external
coupling required during system test. If this bit is set to 1,
and the SIRTEST bit is set to 0, the UARTTXD path is fed
through to the UARTRXD path. In either SIR mode or UART
mode, when this bit is set, the modem outputs are also fed
through to the modem inputs. This bit is cleared to 0 on
reset, to disable loopback.
6:3
Reserved.
-
-
-
2
SIRLP
SIR low-power IrDA mode. This bit selects the IrDA
RW
0x0
RW
0x0
UART enable: 0 = UART is disabled. If the UART is disabled RW
0x0
encoding mode. If this bit is cleared to 0, low-level bits are
transmitted as an active high pulse with a width of 3 /
16th of the bit period. If this bit is set to 1, low-level bits
are transmitted with a pulse width that is 3 times the
period of the IrLPBaud16 input signal, regardless of the
selected bit rate. Setting this bit uses less power, but
might reduce transmission distances.
1
SIREN
SIR enable: 0 = IrDA SIR ENDEC is disabled. nSIROUT
remains LOW (no light pulse generated), and signal
transitions on SIRIN have no effect. 1 = IrDA SIR ENDEC is
enabled. Data is transmitted and received on nSIROUT and
SIRIN. UARTTXD remains HIGH, in the marking state.
Signal transitions on UARTRXD or modem status inputs
have no effect. This bit has no effect if the UARTEN bit
disables the UART.
0
UARTEN
in the middle of transmission or reception, it completes
the current character before stopping. 1 = the UART is
enabled. Data transmission and reception occurs for
either UART signals or SIR signals depending on the
setting of the SIREN bit.
UART: UARTIFLS Register
Offset: 0x034
Description
Interrupt FIFO Level Select Register, UARTIFLS
Table 433. UARTIFLS
Register
4.2. UART
Bits
Name
Description
Type
Reset
31:6
Reserved.
-
-
-
433
RP2040 Datasheet
Bits
Name
Description
Type
Reset
5:3
RXIFLSEL
Receive interrupt FIFO level select. The trigger points for
RW
0x2
RW
0x2
the receive interrupt are as follows: b000 = Receive FIFO
becomes >= 1 / 8 full b001 = Receive FIFO becomes >= 1 /
4 full b010 = Receive FIFO becomes >= 1 / 2 full b011 =
Receive FIFO becomes >= 3 / 4 full b100 = Receive FIFO
becomes >= 7 / 8 full b101-b111 = reserved.
2:0
TXIFLSEL
Transmit interrupt FIFO level select. The trigger points for
the transmit interrupt are as follows: b000 = Transmit
FIFO becomes timerawh;
49
if (hi == next_hi) break;
50
hi = next_hi;
537
RP2040 Datasheet
51
} while (true);
52
return ((uint64_t) hi intr, 1u inte, 1u timerawl + delay_us;
54
55
// Write the lower 32 bits of the target time to the alarm which
56
// will arm it
57
timer_hw->alarm[ALARM_NUM] = (uint32_t) target;
58 }
59
60 int main() {
61
stdio_init_all();
62
printf("Timer lowlevel!\n");
63
64
// Set alarm every 2 seconds
65
while (1) {
66
alarm_fired = false;
67
alarm_in_us(1000000 * 2);
68
// Wait for alarm to fire
69
70
while (!alarm_fired);
}
71 }
4.6. Timer
538
RP2040 Datasheet
4.6.4.3. Busy wait
If you don’t want to use an alarm to wait for a period of time, instead use a while loop. The SDK provides various
busy_wait_ functions to do this:
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_timer/timer.c Lines 57 - 102
57 void busy_wait_us_32(uint32_t delay_us) {
58
if (0 timerawl;
62
while (timer_hw->timerawl - start < delay_us) {
63
tight_loop_contents();
64
65
}
} else {
66
67
busy_wait_us(delay_us);
}
68 }
69
70 void busy_wait_us(uint64_t delay_us) {
71
uint64_t base = time_us_64();
72
uint64_t target = base + delay_us;
73
if (target < base) {
74
target = (uint64_t)-1;
75
}
76
absolute_time_t t;
77
update_us_since_boot(&t, target);
78
busy_wait_until(t);
79 }
80
81 void busy_wait_ms(uint32_t delay_ms)
82 {
83
if (delay_ms > 32u);
93
uint32_t hi = timer_hw->timerawh;
94
while (hi < hi_target) {
95
hi = timer_hw->timerawh;
96
tight_loop_contents();
97
}
98
while (hi == hi_target && timer_hw->timerawl < (uint32_t) target) {
99
hi = timer_hw->timerawh;
100
101
tight_loop_contents();
}
102 }
4.6.4.4. Complete example using SDK
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/timer/hello_timer/hello_timer.c Lines 11 - 57
11 volatile bool timer_fired = false;
4.6. Timer
539
RP2040 Datasheet
12
13 int64_t alarm_callback(alarm_id_t id, void *user_data) {
14
printf("Timer %d fired!\n", (int) id);
15
timer_fired = true;
16
// Can return a value here in us to fire in the future
17
return 0;
18 }
19
20 bool repeating_timer_callback(struct repeating_timer *t) {
21
printf("Repeat at %lld\n", time_us_64());
22
return true;
23 }
24
25 int main() {
26
stdio_init_all();
27
printf("Hello Timer!\n");
28
29
// Call alarm_callback in 2 seconds
30
add_alarm_in_ms(2000, alarm_callback, NULL, false);
31
32
// Wait for alarm callback to set timer_fired
33
while (!timer_fired) {
34
tight_loop_contents();
35
}
36
37
// Create a repeating timer that calls repeating_timer_callback.
38
// If the delay is > 0 then this is the delay between the previous callback ending and the
next starting.
39
// If the delay is negative (see below) then the next call to the callback will be exactly
500ms after the
40
// start of the call to the last callback
41
struct repeating_timer timer;
42
add_repeating_timer_ms(500, repeating_timer_callback, NULL, &timer);
43
sleep_ms(3000);
44
bool cancelled = cancel_repeating_timer(&timer);
45
printf("cancelled... %d\n", cancelled);
46
sleep_ms(2000);
47
48
// Negative delay so means we will call repeating_timer_callback, and call it again
49
// 500ms later regardless of how long the callback took to execute
50
add_repeating_timer_ms(-500, repeating_timer_callback, NULL, &timer);
51
sleep_ms(3000);
52
cancelled = cancel_repeating_timer(&timer);
53
printf("cancelled... %d\n", cancelled);
54
sleep_ms(2000);
55
printf("Done\n");
56
return 0;
57 }
4.6.5. List of Registers
The Timer registers start at a base address of 0x40054000 (defined as TIMER_BASE in SDK).
Table 526. List of
TIMER registers
Offset
Name
Info
0x00
TIMEHW
Write to bits 63:32 of time
always write timelw before timehw
0x04
TIMELW
Write to bits 31:0 of time
writes do not get copied to time until timehw is written
4.6. Timer
540
RP2040 Datasheet
Offset
Name
Info
0x08
TIMEHR
Read from bits 63:32 of time
always read timelr before timehr
0x0c
TIMELR
Read from bits 31:0 of time
0x10
ALARM0
Arm alarm 0, and configure the time it will fire.
Once armed, the alarm fires when TIMER_ALARM0 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.
0x14
ALARM1
Arm alarm 1, and configure the time it will fire.
Once armed, the alarm fires when TIMER_ALARM1 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.
0x18
ALARM2
Arm alarm 2, and configure the time it will fire.
Once armed, the alarm fires when TIMER_ALARM2 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.
0x1c
ALARM3
Arm alarm 3, and configure the time it will fire.
Once armed, the alarm fires when TIMER_ALARM3 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.
0x20
ARMED
Indicates the armed/disarmed status of each alarm.
A write to the corresponding ALARMx register arms the alarm.
Alarms automatically disarm upon firing, but writing ones here
will disarm immediately without waiting to fire.
0x24
TIMERAWH
Raw read from bits 63:32 of time (no side effects)
0x28
TIMERAWL
Raw read from bits 31:0 of time (no side effects)
0x2c
DBGPAUSE
Set bits high to enable pause when the corresponding debug
ports are active
0x30
PAUSE
Set high to pause the timer
0x34
INTR
Raw Interrupts
0x38
INTE
Interrupt Enable
0x3c
INTF
Interrupt Force
0x40
INTS
Interrupt status after masking & forcing
TIMER: TIMEHW Register
Offset: 0x00
Table 527. TIMEHW
Register
Bits
Description
Type
Reset
31:0
Write to bits 63:32 of time
WF
0x00000000
always write timelw before timehw
TIMER: TIMELW Register
Offset: 0x04
4.6. Timer
541
RP2040 Datasheet
Table 528. TIMELW
Register
Bits
Description
Type
Reset
31:0
Write to bits 31:0 of time
WF
0x00000000
writes do not get copied to time until timehw is written
TIMER: TIMEHR Register
Offset: 0x08
Table 529. TIMEHR
Register
Bits
Description
Type
Reset
31:0
Read from bits 63:32 of time
RO
0x00000000
always read timelr before timehr
TIMER: TIMELR Register
Offset: 0x0c
Table 530. TIMELR
Register
Bits
Description
Type
Reset
31:0
Read from bits 31:0 of time
RO
0x00000000
TIMER: ALARM0 Register
Offset: 0x10
Table 531. ALARM0
Register
Bits
Description
Type
Reset
31:0
Arm alarm 0, and configure the time it will fire.
RW
0x00000000
Once armed, the alarm fires when TIMER_ALARM0 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.
TIMER: ALARM1 Register
Offset: 0x14
Table 532. ALARM1
Register
Bits
Description
Type
Reset
31:0
Arm alarm 1, and configure the time it will fire.
RW
0x00000000
Once armed, the alarm fires when TIMER_ALARM1 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.
TIMER: ALARM2 Register
Offset: 0x18
Table 533. ALARM2
Register
Bits
Description
Type
Reset
31:0
Arm alarm 2, and configure the time it will fire.
RW
0x00000000
Once armed, the alarm fires when TIMER_ALARM2 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.
TIMER: ALARM3 Register
Offset: 0x1c
4.6. Timer
542
RP2040 Datasheet
Table 534. ALARM3
Register
Bits
Description
Type
Reset
31:0
Arm alarm 3, and configure the time it will fire.
RW
0x00000000
Once armed, the alarm fires when TIMER_ALARM3 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.
TIMER: ARMED Register
Offset: 0x20
Table 535. ARMED
Register
Bits
Description
Type
Reset
31:4
Reserved.
-
-
3:0
Indicates the armed/disarmed status of each alarm.
WC
0x0
A write to the corresponding ALARMx register arms the alarm.
Alarms automatically disarm upon firing, but writing ones here
will disarm immediately without waiting to fire.
TIMER: TIMERAWH Register
Offset: 0x24
Table 536. TIMERAWH
Register
Bits
Description
Type
Reset
31:0
Raw read from bits 63:32 of time (no side effects)
RO
0x00000000
TIMER: TIMERAWL Register
Offset: 0x28
Table 537. TIMERAWL
Register
Bits
Description
Type
Reset
31:0
Raw read from bits 31:0 of time (no side effects)
RO
0x00000000
TIMER: DBGPAUSE Register
Offset: 0x2c
Description
Set bits high to enable pause when the corresponding debug ports are active
Table 538. DBGPAUSE
Register
Bits
Name
Description
Type
Reset
31:3
Reserved.
-
-
-
2
DBG1
Pause when processor 1 is in debug mode
RW
0x1
1
DBG0
Pause when processor 0 is in debug mode
RW
0x1
0
Reserved.
-
-
-
TIMER: PAUSE Register
Offset: 0x30
4.6. Timer
543
RP2040 Datasheet
Table 539. PAUSE
Register
Bits
Description
Type
Reset
31:1
Reserved.
-
-
0
Set high to pause the timer
RW
0x0
TIMER: INTR Register
Offset: 0x34
Description
Raw Interrupts
Table 540. INTR
Register
Bits
Name
Description
Type
Reset
31:4
Reserved.
-
-
-
3
ALARM_3
WC
0x0
2
ALARM_2
WC
0x0
1
ALARM_1
WC
0x0
0
ALARM_0
WC
0x0
TIMER: INTE Register
Offset: 0x38
Description
Interrupt Enable
Table 541. INTE
Register
Bits
Name
Description
Type
Reset
31:4
Reserved.
-
-
-
3
ALARM_3
RW
0x0
2
ALARM_2
RW
0x0
1
ALARM_1
RW
0x0
0
ALARM_0
RW
0x0
TIMER: INTF Register
Offset: 0x3c
Description
Interrupt Force
Table 542. INTF
Register
Bits
Name
Description
Type
Reset
31:4
Reserved.
-
-
-
3
ALARM_3
RW
0x0
2
ALARM_2
RW
0x0
1
ALARM_1
RW
0x0
0
ALARM_0
RW
0x0
TIMER: INTS Register
Offset: 0x40
4.6. Timer
544
RP2040 Datasheet
Description
Interrupt status after masking & forcing
Table 543. INTS
Register
Bits
Name
Description
Type
Reset
31:4
Reserved.
-
-
-
3
ALARM_3
RO
0x0
2
ALARM_2
RO
0x0
1
ALARM_1
RO
0x0
0
ALARM_0
RO
0x0
4.7. Watchdog
4.7.1. Overview
The watchdog is a countdown timer that can restart parts of the chip if it reaches zero. This can be used to restart the
processor if software gets stuck in an infinite loop. The programmer must periodically write a value to the watchdog to
stop it from reaching zero.
The watchdog is reset by rst_n_run, which is deasserted as soon as the digital core supply (DVDD) is powered and
stable, and the RUN pin is high. This allows the watchdog reset to feed into the power-on state machine (see Section
2.13) and reset controller (see Section 2.14), resetting their dependants if they are selected in the WDSEL register. The
WDSEL register exists in both the power-on state machine and reset controller.
4.7.2. Tick generation
The watchdog reference clock, clk_tick, is driven from clk_ref. Ideally clk_ref will be configured to use the Crystal
Oscillator (Section 2.16) so that it provides an accurate reference clock. The reference clock is divided internally to
generate a tick (nominally 1μs) to use as the watchdog tick. The tick is configured using the TICK register.
NOTE
To avoid duplicating logic, this tick is also distributed to the timer (see Section 4.6) and used as the timer reference.
The SDK starts the watchdog tick in clocks_init:
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_watchdog/watchdog.c Lines 14 - 17
14 void watchdog_start_tick(uint cycles) {
15
// Important: This function also provides a tick reference to the timer
16
watchdog_hw->tick = cycles | WATCHDOG_TICK_ENABLE_BITS;
17 }
4.7.3. Watchdog Counter
The watchdog counter is loaded by the LOAD register. The current value can be seen in CTRL.TIME.
4.7. Watchdog
545
RP2040 Datasheet
WARNING
Due to a logic error, the watchdog counter is decremented twice per tick. Which means the programmer needs to
program double the intended count down value. The SDK examples take this issue into account. See RP2040-E1 for
more information.
4.7.4. Scratch Registers
The watchdog contains eight 32-bit scratch registers that can be used to store information between soft resets of the
chip. A rst_n_run event triggered by toggling the RUN pin or cycling the digital core supply (DVDD) will reset the scratch
registers.
The bootrom checks the watchdog scratch registers for a magic number on boot. This can be used to soft reset the
chip into some user specified code. See Section 2.8.1.1 for more information.
4.7.5. Programmer’s Model
The SDK provides a hardware_watchdog driver to control the watchdog.
4.7.5.1. Enabling the watchdog
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_watchdog/watchdog.c Lines 35 - 65
35 // Helper function used by both watchdog_enable and watchdog_reboot
36 void _watchdog_enable(uint32_t delay_ms, bool pause_on_debug) {
37
hw_clear_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_ENABLE_BITS);
38
39
// Reset everything apart from ROSC and XOSC
40
hw_set_bits(&psm_hw->wdsel, PSM_WDSEL_BITS & ~(PSM_WDSEL_ROSC_BITS |
PSM_WDSEL_XOSC_BITS));
41
42
uint32_t dbg_bits = WATCHDOG_CTRL_PAUSE_DBG0_BITS |
43
WATCHDOG_CTRL_PAUSE_DBG1_BITS |
44
WATCHDOG_CTRL_PAUSE_JTAG_BITS;
45
46
if (pause_on_debug) {
47
48
hw_set_bits(&watchdog_hw->ctrl, dbg_bits);
} else {
49
50
hw_clear_bits(&watchdog_hw->ctrl, dbg_bits);
}
51
52
if (!delay_ms) {
53
54
hw_set_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_TRIGGER_BITS);
} else {
55
// Note, we have x2 here as the watchdog HW currently decrements twice per tick
56
load_value = delay_ms * 1000 * 2;
57
58
if (load_value > 0xffffffu)
59
load_value = 0xffffffu;
60
61
watchdog_update();
62
63
64
hw_set_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_ENABLE_BITS);
}
65 }
4.7. Watchdog
546
RP2040 Datasheet
4.7.5.2. Updating the watchdog counter
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_watchdog/watchdog.c Lines 23 - 27
23 static uint32_t load_value;
24
25 void watchdog_update(void) {
26
watchdog_hw->load = load_value;
27 }
4.7.5.3. Usage
The Pico Examples repository provides a hello_watchdog example that uses the hardware_watchdog to demonstrate
use of the watchdog.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/watchdog/hello_watchdog/hello_watchdog.c Lines 11 - 33
11 int main() {
12
stdio_init_all();
13
14
if (watchdog_caused_reboot()) {
15
printf("Rebooted by Watchdog!\n");
16
return 0;
17
} else {
18
printf("Clean boot\n");
19
}
20
21
// Enable the watchdog, requiring the watchdog to be updated every 100ms or the chip will
reboot
22
// second arg is pause on debug which means the watchdog will pause when stepping through
code
23
watchdog_enable(100, 1);
24
25
for (uint i = 0; i < 5; i++) {
26
printf("Updating watchdog %d\n", i);
27
28
watchdog_update();
}
29
30
// Wait in an infinite loop and don't update the watchdog so it reboots us
31
printf("Waiting to be rebooted by watchdog\n");
32
while(1);
33 }
4.7.6. List of Registers
The watchdog registers start at a base address of 0x40058000 (defined as WATCHDOG_BASE in SDK).
Table 544. List of
WATCHDOG registers
4.7. Watchdog
Offset
Name
Info
0x00
CTRL
Watchdog control
0x04
LOAD
Load the watchdog timer.
0x08
REASON
Logs the reason for the last reset.
0x0c
SCRATCH0
Scratch register
0x10
SCRATCH1
Scratch register
547
RP2040 Datasheet
Offset
Name
Info
0x14
SCRATCH2
Scratch register
0x18
SCRATCH3
Scratch register
0x1c
SCRATCH4
Scratch register
0x20
SCRATCH5
Scratch register
0x24
SCRATCH6
Scratch register
0x28
SCRATCH7
Scratch register
0x2c
TICK
Controls the tick generator
WATCHDOG: CTRL Register
Offset: 0x00
Description
Watchdog control
The rst_wdsel register determines which subsystems are reset when the watchdog is triggered.
The watchdog can be triggered in software.
Table 545. CTRL
Register
Bits
Name
Description
Type
Reset
31
TRIGGER
Trigger a watchdog reset
SC
0x0
30
ENABLE
When not enabled the watchdog timer is paused
RW
0x0
29:27
Reserved.
-
-
-
26
PAUSE_DBG1
Pause the watchdog timer when processor 1 is in debug
RW
0x1
RW
0x1
RW
0x1
RO
0x000000
mode
25
PAUSE_DBG0
Pause the watchdog timer when processor 0 is in debug
mode
24
PAUSE_JTAG
Pause the watchdog timer when JTAG is accessing the
bus fabric
23:0
TIME
Indicates the number of ticks / 2 (see errata RP2040-E1)
before a watchdog reset will be triggered
WATCHDOG: LOAD Register
Offset: 0x04
Table 546. LOAD
Register
Bits
Description
Type
Reset
31:24
Reserved.
-
-
23:0
Load the watchdog timer. The maximum setting is 0xffffff which corresponds
WF
0x000000
to 0xffffff / 2 ticks before triggering a watchdog reset (see errata RP2040-E1).
WATCHDOG: REASON Register
Offset: 0x08
Description
Logs the reason for the last reset. Both bits are zero for the case of a hardware reset.
4.7. Watchdog
548
RP2040 Datasheet
Table 547. REASON
Register
Bits
Name
Description
Type
Reset
31:2
Reserved.
-
-
-
1
FORCE
RO
0x0
0
TIMER
RO
0x0
WATCHDOG: SCRATCH0, SCRATCH1, …, SCRATCH6, SCRATCH7 Registers
Offsets: 0x0c, 0x10, …, 0x24, 0x28
Table 548. SCRATCH0,
SCRATCH1, …,
SCRATCH6,
SCRATCH7 Registers
Bits
Description
Type
Reset
31:0
Scratch register. Information persists through soft reset of the chip.
RW
0x00000000
WATCHDOG: TICK Register
Offset: 0x2c
Description
Controls the tick generator
Table 549. TICK
Register
Bits
Name
Description
Type
Reset
31:20
Reserved.
-
-
-
19:11
COUNT
Count down timer: the remaining number clk_tick cycles
RO
-
before the next tick is generated.
10
RUNNING
Is the tick generator running?
RO
-
9
ENABLE
start / stop tick generation
RW
0x1
8:0
CYCLES
Total number of clk_tick cycles before the next tick.
RW
0x000
4.8. RTC
The Real-time Clock (RTC) provides time in human-readable format and can be used to generate interrupts at specific
times.
4.8.1. Storage Format
Time is stored in binary, separated in seven fields:
Table 550. RTC
storage format
Date/Time Field
Size
Legal values
Year
12 bits
0..4095
Month
4 bits
1..12
Day
5 bits
1..[28,29,30,31], depending on the
month
4.8. RTC
Day of Week
3 bits
0..6. Sunday = 0
Hour
5 bits
0..23
Minute
6 bits
0..59
Seconds
6 bits
0..59
549
RP2040 Datasheet
The RTC does not check that the programmed values are in range. Illegal values may cause unexpected behaviour.
4.8.1.1. Day of the week
Day of the week is encoded as Sun 0, Mon 1, …, Sat 6 (i.e. ISO8601 mod 7).
There is no built-in calendar function. The RTC will not compute the correct day of the week; it will only increment the
existing value.
4.8.2. Leap year
If the current value of YEAR in SETUP_0 is evenly divisible by 4, a leap year is detected, and Feb 28th is followed by Feb
29th instead of March 1st. Since this is not always true (century years for example), the leap year checking can be
forced off by setting CTRL.FORCE_NOTLEAPYEAR.
NOTE
The leap year check is done only when needed (the second following Feb 28, 23:59:59). The software can set
FORCE_NOTLEAPYEAR anytime after 2096 Mar 1 00:00:00 as long as it arrives before 2100 Feb 28 23:59:59 (i.e. taking
into account the clock domain crossing latency)
4.8.3. Interrupts
The RTC can generate an interrupt at a configured time. There is a global bit, MATCH_ENA in IRQ_SETUP_0 to enable this
feature, and individual enables for each time field (year, month, day, day-of-the-week, hour, minute, second). The
individual enables can be used to implement repeating interrupts at specified times.
The alarm interrupt is sent to the processors and also to the ROSC and XOSC to wake them from dormant mode. See
Section 4.8.5.5 for more information on dormant mode.
4.8.4. Reference clock
The RTC uses a reference clock clk_rtc, which should be any integer frequency in the range 1…65536Hz.
The internal 1Hz reference is created by an internal clock divider which divides clk_rtc by an integer value. The divide
value minus 1 is set in CLKDIV_M1.
WARNING
While it is possible to change CLKDIV_M1 while the RTC is enabled, it is not recommended.
clk_rtc can be driven either from an internal or external clock source. Those sources can be prescaled, using a
fractional divider (see Section 2.15).
Examples of possible clock sources include:
• XOSC @ 12MHz / 256 = 46875Hz. To get a 1Hz reference CLKDIV_M1 should be set to 46874.
• An external reference from a GPS, which generates one pulse per second. Configure clk_rtc to run from the GPIN0
clock source from GPIO pin 20. In this case, the clk_rtc divider is 1 and the internal RTC clock divider is also 1 (i.e.
CLKDIV_M1 = 0).
4.8. RTC
550
RP2040 Datasheet
NOTE
All RTC register reads and writes are done from the processor clock domain clk_sys. All data are synchronised back
and forth between the domains. Writing to the RTC will take 2 clk_rtc clock periods to arrive, additional to the clk_sys
domain. This should be taken into account especially when the reference is slow (e.g. 1Hz).
4.8.5. Programmer’s Model
There are three setup tasks:
• Set the 1 sec reference
• Set the clock
• Set an alarm
4.8.5.1. Configuring the 1 second reference clock:
Select the source for clk_rtc. This is done outside the RTC registers (see Section 4.8.4).
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_rtc/rtc.c Lines 22 - 40
22 void rtc_init(void) {
23
// Get clk_rtc freq and make sure it is running
24
uint rtc_freq = clock_get_hz(clk_rtc);
25
assert(rtc_freq != 0);
26
27
// Take rtc out of reset now that we know clk_rtc is running
28
reset_block(RESETS_RESET_RTC_BITS);
29
unreset_block_wait(RESETS_RESET_RTC_BITS);
30
31
// Set up the 1 second divider.
32
// If rtc_freq is 400 then clkdiv_m1 should be 399
33
rtc_freq -= 1;
34
35
// Check the freq is not too big to divide
36
assert(rtc_freq clkdiv_m1 = rtc_freq;
40 }
4.8.5.2. Setting up the clock
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_rtc/rtc.c Lines 55 - 86
55 bool rtc_set_datetime(datetime_t *t) {
56
if (!valid_datetime(t)) {
57
58
return false;
}
59
60
// Disable RTC
61
rtc_hw->ctrl = 0;
62
// Wait while it is still active
63
while (rtc_running()) {
64
4.8. RTC
tight_loop_contents();
551
RP2040 Datasheet
65
}
66
67
// Write to setup registers
68
rtc_hw->setup_0 = (((uint)t->year)
69
month) day)
setup_1 = (((uint)t->dotw)
hour)
min)
sec)
ctrl = RTC_CTRL_LOAD_BITS;
78
79
// Enable RTC and wait for it to be running
80
rtc_hw->ctrl = RTC_CTRL_RTC_ENABLE_BITS;
81
while (!rtc_running()) {
82
83
tight_loop_contents();
}
84
85
return true;
86 }
NOTE
It is possible to change the current time while the RTC is running. Write the desired values, then set the LOAD bit in
the CTRL register.
4.8.5.3. Reading the current time
The RTC time is stored across two 32-bit registers. To ensure a consistent value, RTC_0 should be read before RTC_1.
Reading RTC_0 latches the value of RTC_1.
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_rtc/rtc.c Lines 88 - 107
88 bool rtc_get_datetime(datetime_t *t) {
89
// Make sure RTC is running
90
if (!rtc_running()) {
91
92
return false;
}
93
94
// Note: RTC_0 should be read before RTC_1
95
uint32_t rtc_0 = rtc_hw->rtc_0;
96
uint32_t rtc_1 = rtc_hw->rtc_1;
97
98
t->dotw
= (rtc_0 & RTC_RTC_0_DOTW_BITS ) >> RTC_RTC_0_DOTW_LSB;
99
t->hour
= (rtc_0 & RTC_RTC_0_HOUR_BITS ) >> RTC_RTC_0_HOUR_LSB;
100
t->min
= (rtc_0 & RTC_RTC_0_MIN_BITS
) >> RTC_RTC_0_MIN_LSB;
101
t->sec
= (rtc_0 & RTC_RTC_0_SEC_BITS
) >> RTC_RTC_0_SEC_LSB;
102
t->year
= (rtc_1 & RTC_RTC_1_YEAR_BITS ) >> RTC_RTC_1_YEAR_LSB;
103
t->month = (rtc_1 & RTC_RTC_1_MONTH_BITS) >> RTC_RTC_1_MONTH_LSB;
104
t->day
= (rtc_1 & RTC_RTC_1_DAY_BITS
) >> RTC_RTC_1_DAY_LSB;
105
106
return true;
107 }
4.8. RTC
552
RP2040 Datasheet
4.8.5.4. Configuring an Alarm
SDK: https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/hardware_rtc/rtc.c Lines 147 - 183
147 void rtc_set_alarm(datetime_t *t, rtc_callback_t user_callback) {
148
rtc_disable_alarm();
149
150
// Only add to setup if it isn't -1
151
rtc_hw->irq_setup_0 = ((t->year
152
((t->month < 0) ? 0 : (((uint)t->month) day
RTC_IRQ_SETUP_0_DAY_LSB
154
< 0) ? 0 : (((uint)t->dotw)
hour)
min)
sec)
hour
RTC_IRQ_SETUP_1_HOUR_LSB)) |
((t->min
RTC_IRQ_SETUP_1_MIN_LSB )) |
157
irq_setup_1 = ((t->dotw
156
< 0) ? 0 : (((uint)t->day)
));
RTC_IRQ_SETUP_1_DOTW_LSB)) |
155
year)
RTC_IRQ_SETUP_0_YEAR_LSB )) |
((t->sec
RTC_IRQ_SETUP_1_SEC_LSB ));
158
159
// Set the match enable bits for things we care about
160
if (t->year
161
if (t->month >= 0) hw_set_bits(&rtc_hw->irq_setup_0, RTC_IRQ_SETUP_0_MONTH_ENA_BITS);
162
if (t->day
>= 0) hw_set_bits(&rtc_hw->irq_setup_0, RTC_IRQ_SETUP_0_DAY_ENA_BITS);
163
if (t->dotw
>= 0) hw_set_bits(&rtc_hw->irq_setup_1, RTC_IRQ_SETUP_1_DOTW_ENA_BITS);
164
if (t->hour
>= 0) hw_set_bits(&rtc_hw->irq_setup_1, RTC_IRQ_SETUP_1_HOUR_ENA_BITS);
165
if (t->min
>= 0) hw_set_bits(&rtc_hw->irq_setup_1, RTC_IRQ_SETUP_1_MIN_ENA_BITS);
166
if (t->sec
>= 0) hw_set_bits(&rtc_hw->irq_setup_1, RTC_IRQ_SETUP_1_SEC_ENA_BITS);
>= 0) hw_set_bits(&rtc_hw->irq_setup_0, RTC_IRQ_SETUP_0_YEAR_ENA_BITS);
167
168
// Does it repeat? I.e. do we not match on any of the bits
169
_alarm_repeats = rtc_alarm_repeats(t);
170
171
// Store function pointer we can call later
172
_callback = user_callback;
173
174
irq_set_exclusive_handler(RTC_IRQ, rtc_irq_handler);
175
176
// Enable the IRQ at the peri
177
rtc_hw->inte = RTC_INTE_RTC_BITS;
178
179
// Enable the IRQ at the proc
180
irq_set_enabled(RTC_IRQ, true);
181
182
rtc_enable_alarm();
183 }
NOTE
Recurring alarms can be created by using fewer enable bits when setting up the alarm interrupt. For example, if you
only matched on seconds and the second was configured as 54 then the alarm interrupt would fire once a minute
when the second was 54.
4.8.5.5. Interaction with Dormant / Sleep mode
RP2040 supports two power saving levels:
4.8. RTC
553
RP2040 Datasheet
• Sleep mode, where the processors are asleep and the unused clocks in the chip are stopped (see Section 2.15.3.5)
• Dormant mode, where all clocks in the chip are stopped
The RTC can wake the chip up from both of these modes. In sleep mode, RP2040 can be configured such that only
clk_rtc (a slow RTC reference clock) is running, as well as a small amount of logic that allows the processor to wake
back up. The processor is woken from sleep mode when the RTC alarm interrupt fires. See Section 2.11.5.1 for more
information.
To wake the chip from dormant mode:
• the RTC must be configured to use an external reference clock (supplied by a GPIO pin)
• Set up the RTC to run on an external reference
• If the processor is running off the PLL, change it to run from XOSC/ROSC
• Turn off the PLLs
• Set up the RTC with the desired wake up time (one off, or recurring)
• (optionally) power down most memories
• Invoke DORMANT mode (see Section 2.16, Section 2.17, and Section 2.11.5.2 for more information)
4.8.6. List of Registers
The RTC registers start at a base address of 0x4005c000 (defined as RTC_BASE in SDK).
Table 551. List of RTC
registers
Offset
Name
Info
0x00
CLKDIV_M1
Divider minus 1 for the 1 second counter. Safe to change the
value when RTC is not enabled.
0x04
SETUP_0
RTC setup register 0
0x08
SETUP_1
RTC setup register 1
0x0c
CTRL
RTC Control and status
0x10
IRQ_SETUP_0
Interrupt setup register 0
0x14
IRQ_SETUP_1
Interrupt setup register 1
0x18
RTC_1
RTC register 1.
0x1c
RTC_0
RTC register 0
Read this before RTC 1!
0x20
INTR
Raw Interrupts
0x24
INTE
Interrupt Enable
0x28
INTF
Interrupt Force
0x2c
INTS
Interrupt status after masking & forcing
RTC: CLKDIV_M1 Register
Offset: 0x00
4.8. RTC
554
RP2040 Datasheet
Table 552. CLKDIV_M1
Register
Bits
Description
Type
Reset
31:16
Reserved.
-
-
15:0
Divider minus 1 for the 1 second counter. Safe to change the value when RTC
RW
0x0000
is not enabled.
RTC: SETUP_0 Register
Offset: 0x04
Description
RTC setup register 0
Table 553. SETUP_0
Register
Bits
Name
Description
Type
Reset
31:24
Reserved.
-
-
-
23:12
YEAR
Year
RW
0x000
11:8
MONTH
Month (1..12)
RW
0x0
7:5
Reserved.
-
-
-
4:0
DAY
Day of the month (1..31)
RW
0x00
RTC: SETUP_1 Register
Offset: 0x08
Description
RTC setup register 1
Table 554. SETUP_1
Register
Bits
Name
Description
Type
Reset
31:27
Reserved.
-
-
-
26:24
DOTW
Day of the week: 1-Monday…0-Sunday ISO 8601 mod 7
RW
0x0
23:21
Reserved.
-
-
-
20:16
HOUR
Hours
RW
0x00
15:14
Reserved.
-
-
-
13:8
MIN
Minutes
RW
0x00
7:6
Reserved.
-
-
-
5:0
SEC
Seconds
RW
0x00
RTC: CTRL Register
Offset: 0x0c
Description
RTC Control and status
Table 555. CTRL
Register
Bits
Name
Description
Type
Reset
31:9
Reserved.
-
-
-
8
FORCE_NOTLEAP If set, leapyear is forced off.
RW
0x0
-
-
7:5
4.8. RTC
YEAR
Useful for years divisible by 100 but not by 400
Reserved.
-
555
RP2040 Datasheet
Bits
Name
Description
Type
Reset
4
LOAD
Load RTC
SC
0x0
3:2
Reserved.
-
-
-
1
RTC_ACTIVE
RTC enabled (running)
RO
-
0
RTC_ENABLE
Enable RTC
RW
0x0
RTC: IRQ_SETUP_0 Register
Offset: 0x10
Description
Interrupt setup register 0
Table 556.
IRQ_SETUP_0 Register
Bits
Name
Description
Type
Reset
31:30
Reserved.
-
-
-
29
MATCH_ACTIVE
RO
-
28
MATCH_ENA
RW
0x0
Global match enable. Don’t change any other value while
this one is enabled
27
Reserved.
-
-
-
26
YEAR_ENA
Enable year matching
RW
0x0
25
MONTH_ENA
Enable month matching
RW
0x0
24
DAY_ENA
Enable day matching
RW
0x0
23:12
YEAR
Year
RW
0x000
11:8
MONTH
Month (1..12)
RW
0x0
7:5
Reserved.
-
-
-
4:0
DAY
Day of the month (1..31)
RW
0x00
RTC: IRQ_SETUP_1 Register
Offset: 0x14
Description
Interrupt setup register 1
Table 557.
IRQ_SETUP_1 Register
4.8. RTC
Bits
Name
Description
Type
Reset
31
DOTW_ENA
Enable day of the week matching
RW
0x0
30
HOUR_ENA
Enable hour matching
RW
0x0
29
MIN_ENA
Enable minute matching
RW
0x0
28
SEC_ENA
Enable second matching
RW
0x0
27
Reserved.
-
-
-
26:24
DOTW
Day of the week
RW
0x0
23:21
Reserved.
-
-
-
20:16
HOUR
Hours
RW
0x00
15:14
Reserved.
-
-
-
556
RP2040 Datasheet
Bits
Name
Description
Type
Reset
13:8
MIN
Minutes
RW
0x00
7:6
Reserved.
-
-
-
5:0
SEC
Seconds
RW
0x00
RTC: RTC_1 Register
Offset: 0x18
Description
RTC register 1.
Table 558. RTC_1
Register
Bits
Name
Description
Type
Reset
31:24
Reserved.
-
-
-
23:12
YEAR
Year
RO
-
11:8
MONTH
Month (1..12)
RO
-
7:5
Reserved.
-
-
-
4:0
DAY
Day of the month (1..31)
RO
-
RTC: RTC_0 Register
Offset: 0x1c
Description
RTC register 0
Read this before RTC 1!
Table 559. RTC_0
Register
Bits
Name
Description
Type
Reset
31:27
Reserved.
-
-
-
26:24
DOTW
Day of the week
RF
-
23:21
Reserved.
-
-
-
20:16
HOUR
Hours
RF
-
15:14
Reserved.
-
-
-
13:8
MIN
Minutes
RF
-
7:6
Reserved.
-
-
-
5:0
SEC
Seconds
RF
-
RTC: INTR Register
Offset: 0x20
Description
Raw Interrupts
4.8. RTC
557
RP2040 Datasheet
Table 560. INTR
Register
Bits
Name
Description
Type
Reset
31:1
Reserved.
-
-
-
0
RTC
RO
0x0
RTC: INTE Register
Offset: 0x24
Description
Interrupt Enable
Table 561. INTE
Register
Bits
Name
Description
Type
Reset
31:1
Reserved.
-
-
-
0
RTC
RW
0x0
RTC: INTF Register
Offset: 0x28
Description
Interrupt Force
Table 562. INTF
Register
Bits
Name
Description
Type
Reset
31:1
Reserved.
-
-
-
0
RTC
RW
0x0
RTC: INTS Register
Offset: 0x2c
Description
Interrupt status after masking & forcing
Table 563. INTS
Register
Bits
Name
Description
Type
Reset
31:1
Reserved.
-
-
-
0
RTC
RO
0x0
4.9. ADC and Temperature Sensor
RP2040 has an internal analogue-digital converter (ADC) with the following features:
• SAR ADC (see Section 4.9.2)
• 500ksps (using an independent 48MHz clock)
• 12-bit with 8.7 ENOB (see Section 4.9.3)
• Five input mux:
◦ Four inputs that are available on package pins shared with GPIO[29:26]
◦ One input is dedicated to the internal temperature sensor (see Section 4.9.5)
• Four element receive sample FIFO
4.9. ADC and Temperature Sensor
558
RP2040 Datasheet
• Interrupt generation
• DMA interface (see Section 4.9.2.5)
Figure 114. ADC
Connection Diagram
NOTE
When using an ADC input shared with a GPIO pin, the pin’s digital functions must be disabled by setting IE low and OD
high in the pin’s pad control register. See Section 2.19.6.3, “Pad Control - User Bank” for details. The maximum ADC
input voltage is determined by the digital IO supply voltage (IOVDD), not the ADC supply voltage (ADC_AVDD). For
example, if IOVDD is powered at 1.8V, the voltage on the ADC inputs should not exceed 1.8V even if ADC_AVDD is
powered at 3.3V. Voltages greater than IOVDD will result in leakage currents through the ESD protection diodes. See
Section 5.3.3, “Pin Specifications” for details.
4.9.1. ADC controller
A digital controller manages the details of operating the RP2040 ADC, and provides additional functionality:
• One-shot or free-running capture mode
• Sample FIFO with DMA interface
• Pacing timer (16 integer bits, 8 fractional bits) for setting free-running sample rate
• Round-robin sampling of multiple channels in free-running capture mode
• Optional right-shift to 8 bits in free-running capture mode, so samples can be DMA’d to a byte buffer in system
memory
4.9. ADC and Temperature Sensor
559
RP2040 Datasheet
4.9.2. SAR ADC
The SAR ADC (Successive Approximation Register Analogue to Digital Converter) is a combination of digital controller,
and analogue circuit as show in Figure 115.
Figure 115. SAR ADC
Block diagram
The ADC requires a 48MHz clock (clk_adc), which could come from the USB PLL. Capturing a sample takes 96 clock
cycles (96 × 1/48MHz) = 2μs per sample (500ksps). The clock must be set up correctly before enabling the ADC.
Once the ADC block is provided with a clock, and its reset has been removed, writing a 1 to CS.EN will start a short
internal power-up sequence for the ADC’s analogue hardware. After a few clock cycles, CS.READY will go high,
indicating the ADC is ready to start its first conversion.
The ADC can be disabled again at any time by clearing CS.EN, to save power. CS.EN does not enable the temperature
sensor bias source (see Section 4.9.5). This is controlled separately.
The ADC input is capacitive, and when sampling, it places about 1pF across the input (there will be additional
capacitance from outside the ADC, such as packaging and PCB routing, to add to this). The effective impedance, even
when sampling at 500ksps, is over 100kΩ, and for DC measurements there should be no need to buffer.
4.9.2.1. One-shot Sample
Writing a 1 to CS.START_ONCE will immediately start a new conversion. CS.READY will go low, to show that a
conversion is currently in progress. After 96 cycles of clk_adc, CS.READY will go high. The 12-bit conversion result is
available in RESULT.
The ADC input to be sampled is selected by writing to CS.AINSEL, any time before the conversion starts. An AINSEL
value of 0…3 selects the ADC input on GPIO 26…29. AINSEL of 4 selects the internal temperature sensor.
NOTE
No settling time is required when switching AINSEL.
4.9.2.2. Free-running Sampling
When CS.START_MANY is set,the ADC will automatically start new conversions at regular intervals. The most recent
conversion result is always available in RESULT, but for IRQ or DMA driven streaming of samples, the ADC FIFO must be
enabled (Section 4.9.2.4).
By default (DIV = 0), new conversions start immediately upon the previous conversion finishing, so a new sample is
produced every 96 cycles. At a clock frequency of 48MHz, this produces 500ksps.
Setting DIV.INT to some positive value n will trigger the ADC once per n + 1 cycles, though the ADC ignores this if a
conversion is currently in progress, so generally n will be >= 96. For example, setting DIV.INT to 47999 will run the ADC
at 1ksps, if running from a 48MHz clock.
The pacing timer supports fractional-rate division (first order delta sigma). When setting DIV.FRAC to a nonzero value,
4.9. ADC and Temperature Sensor
560
RP2040 Datasheet
the ADC will start a new conversion once per
between
and
cycles on average, by changing the sample interval
.
4.9.2.3. Sampling Multiple Inputs
CS.RROBIN allows the ADC to sample multiple inputs, in an interleaved fashion, while performing free-running sampling.
Each bit in RROBIN corresponds to one of the five possible values of CS.AINSEL. When the ADC completes a
conversion, CS.AINSEL will automatically cycle to the next input whose corresponding bit is set in RROBIN.
The round-robin sampling feature is disabled by writing all-zeroes to CS.RROBIN.
For example, if AINSEL is initially 0, and RROBIN is set to 0x06 (bits 1 and 2 are set), the ADC will sample channels in the
following order:
1. Channel 0
2. Channel 1
3. Channel 2
4. Channel 1
5. Channel 2
6. Channel 1…
NOTE
The initial value of AINSEL does not need to correspond with a set bit in RROBIN.
4.9.2.4. Sample FIFO
The ADC samples can be read directly from the RESULT register, or stored in a local 4-entry FIFO and read out from
FIFO. FIFO operation is controlled by the FCS register.
If FCS.EN is set, the result of each ADC conversion is written to the FIFO. A software interrupt handler or the RP2040
DMA can read this sample from the FIFO when notified by the ADC’s IRQ or DREQ signals. Alternatively, software can
poll the status bits in FCS to wait for each sample to become available.
If the FIFO is full when a conversion completes, the sticky error flag FCS.OVER is set. The current FIFO contents are not
changed by this event, but any conversion that completes whilst the FIFO is full will be lost.
There are two flags that control the data written to the FIFO by the ADC:
• FCS.SHIFT will right-shift the FIFO data to eight bits in size (i.e. FIFO bits 7:0 are conversion result bits 11:4). This
is suitable for 8-bit DMA transfer to a byte buffer in memory, allowing deeper capture buffers, at the cost of some
precision.
• FCS.ERR will set a flag at bit 12 of each FIFO entry, showing that a conversion error took place, i.e. the SAR failed to
converge (see below)
4.9. ADC and Temperature Sensor
561
RP2040 Datasheet
CAUTION
Conversion errors produce undefined results, and the corresponding sample should be discarded. They indicate that
the comparison of one or more bits failed to complete in the time allowed. Normally this is caused by comparator
metastability, i.e. the closer to the comparator threshold the input signal is, the longer it will take to make a decision.
The high gain of the comparator reduces the probability that no decision is made.
4.9.2.5. DMA
The RP2040 DMA (Section 2.5) can fetch ADC samples from the sample FIFO, by performing a normal memory-mapped
read on the FIFO register, paced by the ADC_DREQ system data request signal. The following must be considered:
• The sample FIFO must be enabled (FCS.EN) so that samples are written to it; the FIFO is disabled by default so
that it does not inadvertently fill when the ADC is used for one-shot conversions.
• The ADC’s data request handshake (DREQ) must be enabled, via FCS.DREQ_EN.
• The DMA channel used for the transfer must select the DREQ_ADC data request signal (Section 2.5.3.1).
• The threshold for DREQ assertion (FCS.THRESH) should be set to 1, so that the DMA transfers as soon as a single
sample is present in the FIFO. Note this is also the threshold used for IRQ assertion, so non-DMA use cases might
prefer a higher value for less frequent interrupts.
• If the DMA transfer size is set to 8 bits, so that the DMA transfers to a byte array in memory, FCS.SHIFT must also
be set, to pre-shift the FIFO samples to 8 bits of significance.
• If multiple input channels are to be sampled, CS.RROBIN contains a 5-bit mask of those channels (4 external inputs
plus temperature sensor). Additionally CS.AINSEL must select the channel for the first sample.
• The ADC sample rate (Section 4.9.2.2) should be configured before starting the ADC.
Once the ADC is suitably configured, the DMA channel should be started first, and the ADC conversion should be started
second, via CS.START_MANY. Once the DMA completes, the ADC can be halted, or a new DMA transfer promptly
started. After clearing CS.START_MANY to halt the ADC, software should also poll CS.READY to make sure the last
conversion has finished, and then drain any stray samples from the FIFO.
4.9.2.6. Interrupts
An interrupt can be generated when the FIFO level reaches a configurable threshold FCS.THRESH. The interrupt output
must be enabled via INTE.
Status can be read from INTS. The interrupt is cleared by draining the FIFO to a level lower than FCS.THRESH.
4.9.2.7. Supply
The ADC supply is separated out on its own pin to allow noise filtering.
4.9.3. ADC ENOB
The ADC was characterised and the ENOB of the ADC was measured. Testing was carried out at room temperature
across silicon lots, with tests being done on 3 typical (tt) as well as 3 fast (ff) and 3 slow (ss) corner RP2040 devices.
The typical, minimum, and maximum values in Table 565 reflect the silicon used in the testing.
Table 564. Parameters
used during the
testing.
Parameter
Value
Sample rate
250ksps
FFT window
5 term Blackman-Harris
4.9. ADC and Temperature Sensor
562
RP2040 Datasheet
Parameter
Value
FFT bins
4,096
FFT averaging
none
Input level min
1
Input level max
4,094
Input frequency
997Hz
It should be noted that THD is normally calculated using the first 5 or 6 harmonics. However as INL/DNL errors (see
Section 4.9.4) create more than this, the first 30 peaks are used. This makes the THD value slightly worse, but more
representative of reality.
Table 565. Results for
Min
Typical
Max
THD1
-55.6dB
55dB
-54.4dB
SNR
60.9dB
61.5dB
62.0dB
SFDR
59.2dB
59.9dB
60.5dB
SINAD
53.6dB
54.0dB
54.6dB
ENOB
8.6
8.7
8.8
various parts tested
(fast, slow, and
typical).
1
As the INL creates a large number of harmonics, the highest 30 peaks were used. This is different from conventional
calculations of THD.
IMPORTANT
Testing was carried out using a board with a low-noise on-board voltage reference as, when characterising the ADC,
it is important that there are no other noise sources affecting the measurements.
4.9.4. INL and DNL
Integral Non-Linearity (INL) and Differential Non-Linearity (DNL) are used to measure the error of the quantisation of the
incoming signal that the ADC generates. In an ideal ADC the input-to-output transfer function should have a linear
quantised transfer between the analogue input signal and the digitised output signal. The RP2040 ADC INL values for
each binary result are shown in Figure 116, illustrating that the error is a sawtooth rather than the expected curve.
Figure 116. ATE
machine results for
INL (RP2040).
4.9. ADC and Temperature Sensor
563
RP2040 Datasheet
Nominally an ADC moves from one digital value to the next digital value, colloquially expressed as “no missing codes”.
However, if the ADC skips a value bin this would cause a spike in the Differential Non-Linearity (DNL) error. These types
of error often only occur at specific codes due to the design of the ADC.
The RP2040 ADC has a DNL which is mostly flat, and below 1 LSB. However at four values — 512, 1,536, 2,560, and
3,584 — the ADC’s DNL error peaks, see Figure 117
Figure 117. ATE
machine results for
DNL (RP2040).
The INL and DNL errors come from an error in the scaling of some internal capacitors of the ADC. These capacitors are
small in value (only tens of femto Farads) and at these very small values, chip simulation of these capacitors can
deviate slightly from reality. If these capacitors had matched correctly, the ADCs performance could have been better.
These INL and DNL errors will somewhat limit the performance of the ADC dependent on use case (See Errata RP2040E11).
4.9.5. Temperature Sensor
The temperature sensor measures the Vbe voltage of a biased bipolar diode, connected to the fifth ADC channel
(AINSEL=4). Typically, Vbe = 0.706V at 27 degrees C, with a slope of -1.721mV per degree. Therefore the temperature
can be approximated as follows:
T = 27 - (ADC_voltage - 0.706)/0.001721
As the Vbe and the Vbe slope can vary over the temperature range, and from device to device, some user calibration
may be required if accurate measurements are required.
The temperature sensor’s bias source must be enabled before use, via CS.TS_EN. This increases current consumption
on ADC_AVDD by approximately 40μA.
NOTE
The on board temperature sensor is very sensitive to errors in the reference voltage. If the ADC returns a value of
891 this would correspond to a temperature of 20.1°C. However if the reference voltage is 1% lower than 3.3V then
the same reading of 891 would correspond to 24.3°C. You would see a change in temperature of over 4°C for a small
1% change in reference voltage. Therefore if you want to improve the accuracy of the internal temperature sensor it
is worth considering adding an external reference voltage.
4.9. ADC and Temperature Sensor
564
RP2040 Datasheet
NOTE
The INL errors, see Section 4.9.4, aren’t in the usable temperature range of the ADC.
4.9.6. List of Registers
The ADC registers start at a base address of 0x4004c000 (defined as ADC_BASE in SDK).
Table 566. List of ADC
registers
Offset
Name
Info
0x00
CS
ADC Control and Status
0x04
RESULT
Result of most recent ADC conversion
0x08
FCS
FIFO control and status
0x0c
FIFO
Conversion result FIFO
0x10
DIV
Clock divider. If non-zero, CS_START_MANY will start
conversions
at regular intervals rather than back-to-back.
The divider is reset when either of these fields are written.
Total period is 1 + INT + FRAC / 256
0x14
INTR
Raw Interrupts
0x18
INTE
Interrupt Enable
0x1c
INTF
Interrupt Force
0x20
INTS
Interrupt status after masking & forcing
ADC: CS Register
Offset: 0x00
Description
ADC Control and Status
Table 567. CS Register
Bits
Name
Description
Type
Reset
31:21
Reserved.
-
-
-
20:16
RROBIN
Round-robin sampling. 1 bit per channel. Set all bits to 0 to RW
0x00
disable.
Otherwise, the ADC will cycle through each enabled
channel in a round-robin fashion.
The first channel to be sampled will be the one currently
indicated by AINSEL.
AINSEL will be updated after each conversion with the
newly-selected channel.
15
Reserved.
-
-
-
14:12
AINSEL
Select analog mux input. Updated automatically in round-
RW
0x0
robin mode.
11
Reserved.
-
-
-
10
ERR_STICKY
Some past ADC conversion encountered an error. Write 1
WC
0x0
to clear.
4.9. ADC and Temperature Sensor
565
RP2040 Datasheet
Bits
Name
Description
Type
Reset
9
ERR
The most recent ADC conversion encountered an error;
RO
0x0
RO
0x0
result is undefined or noisy.
8
READY
1 if the ADC is ready to start a new conversion. Implies
any previous conversion has completed.
0 whilst conversion in progress.
7:4
Reserved.
-
-
-
3
START_MANY
Continuously perform conversions whilst this bit is 1. A
RW
0x0
SC
0x0
new conversion will start immediately after the previous
finishes.
2
START_ONCE
Start a single conversion. Self-clearing. Ignored if
start_many is asserted.
1
TS_EN
Power on temperature sensor. 1 - enabled. 0 - disabled.
RW
0x0
0
EN
Power on ADC and enable its clock.
RW
0x0
1 - enabled. 0 - disabled.
ADC: RESULT Register
Offset: 0x04
Table 568. RESULT
Register
Bits
Description
Type
Reset
31:12
Reserved.
-
-
11:0
Result of most recent ADC conversion
RO
0x000
ADC: FCS Register
Offset: 0x08
Description
FIFO control and status
Table 569. FCS
Register
Bits
Name
Description
Type
Reset
31:28
Reserved.
-
-
-
27:24
THRESH
DREQ/IRQ asserted when level >= threshold
RW
0x0
23:20
Reserved.
-
-
-
19:16
LEVEL
The number of conversion results currently waiting in the
RO
0x0
FIFO
15:12
Reserved.
-
-
-
11
OVER
1 if the FIFO has been overflowed. Write 1 to clear.
WC
0x0
10
UNDER
1 if the FIFO has been underflowed. Write 1 to clear.
WC
0x0
9
FULL
RO
0x0
8
EMPTY
RO
0x0
7:4
Reserved.
-
-
-
3
DREQ_EN
If 1: assert DMA requests when FIFO contains data
RW
0x0
2
ERR
If 1: conversion error bit appears in the FIFO alongside the RW
0x0
result
4.9. ADC and Temperature Sensor
566
RP2040 Datasheet
Bits
Name
Description
Type
Reset
1
SHIFT
If 1: FIFO results are right-shifted to be one byte in size.
RW
0x0
If 1: write result to the FIFO after each conversion.
RW
0x0
Enables DMA to byte buffers.
0
EN
ADC: FIFO Register
Offset: 0x0c
Description
Conversion result FIFO
Table 570. FIFO
Register
Bits
Name
Description
Type
Reset
31:16
Reserved.
-
-
-
15
ERR
1 if this particular sample experienced a conversion error.
RF
-
-
-
RF
-
Remains in the same location if the sample is shifted.
14:12
Reserved.
11:0
VAL
-
ADC: DIV Register
Offset: 0x10
Description
Clock divider. If non-zero, CS_START_MANY will start conversions
at regular intervals rather than back-to-back.
The divider is reset when either of these fields are written.
Total period is 1 + INT + FRAC / 256
Table 571. DIV
Register
Bits
Name
Description
Type
Reset
31:24
Reserved.
-
-
-
23:8
INT
Integer part of clock divisor.
RW
0x0000
7:0
FRAC
Fractional part of clock divisor. First-order delta-sigma.
RW
0x00
ADC: INTR Register
Offset: 0x14
Description
Raw Interrupts
Table 572. INTR
Register
Bits
Name
Description
Type
Reset
31:1
Reserved.
-
-
-
0
FIFO
Triggered when the sample FIFO reaches a certain level.
RO
0x0
This level can be programmed via the FCS_THRESH field.
ADC: INTE Register
Offset: 0x18
4.9. ADC and Temperature Sensor
567
RP2040 Datasheet
Description
Interrupt Enable
Table 573. INTE
Register
Bits
Name
Description
Type
Reset
31:1
Reserved.
-
-
-
0
FIFO
Triggered when the sample FIFO reaches a certain level.
RW
0x0
This level can be programmed via the FCS_THRESH field.
ADC: INTF Register
Offset: 0x1c
Description
Interrupt Force
Table 574. INTF
Register
Bits
Name
Description
Type
Reset
31:1
Reserved.
-
-
-
0
FIFO
Triggered when the sample FIFO reaches a certain level.
RW
0x0
This level can be programmed via the FCS_THRESH field.
ADC: INTS Register
Offset: 0x20
Description
Interrupt status after masking & forcing
Table 575. INTS
Register
Bits
Name
Description
Type
Reset
31:1
Reserved.
-
-
-
0
FIFO
Triggered when the sample FIFO reaches a certain level.
RO
0x0
This level can be programmed via the FCS_THRESH field.
4.10. SSI
Synopsys Documentation
Synopsys Proprietary. Used with permission.
RP2040 has a Synchronous Serial Interface (SSI) controller which appears on the QSPI pins and is used to
communicate with external Flash devices. The SSI forms part of the XIP block.
The SSI controller is based on a configuration of the Synopsys DW_apb_ssi IP (v4.01a).
4.10.1. Overview
In order for the DW_apb_ssi to connect to a serial-master or serial-slave peripheral device, the peripheral must have a
least one of the following interfaces:
4.10. SSI
568
RP2040 Datasheet
Motorola Serial Peripheral Interface (SPI)
A four-wire, full-duplex serial protocol from Motorola. There are four possible combinations for the serial clock
phase and polarity. The clock phase (SCPH) determines whether the serial transfer begins with the falling edge of
the slave select signal or the first edge of the serial clock. The slave select line is held high when the DW_apb_ssi is
idle or disabled.
Texas Instruments Serial Protocol (SSP)
A four-wire, full-duplex serial protocol. The slave select line used for SPI and Microwire protocols doubles as the
frame indicator for the SSP protocol.
National Semiconductor Microwire
A half-duplex serial protocol, which uses a control word transmitted from the serial master to the target serial slave.
You can program the FRF (frame format) bit field in the Control Register 0 (CTRLR0) to select which protocol is used.
The serial protocols supported by the DW_apb_ssi allow for serial slaves to be selected or addressed using either
hardware or software. When implemented in hardware, serial slaves are selected under the control of dedicated
hardware select lines. The number of select lines generated from the serial master is equal to the number of serial
slaves present on the bus. The serial-master device asserts the select line of the target serial slave before data transfer
begins. This architecture is illustrated in Figure 118.
When implemented in software, the input select line for all serial slave devices should originate from a single slave
select output on the serial master. In this mode it is assumed that the serial master has only a single slave select
output. If there are multiple serial masters in the system, the slave select output from all masters can be logically
ANDed to generate a single slave select input for all serial slave devices. The main program in the software domain
controls selection of the target slave device; this architecture is illustrated in Figure 118. Software would use the
SSIENR register in all slaves in order to control which slave is to respond to the serial transfer request from the master
device.
The DW_apb_ssi does not enforce hardware or software control for serial-slave device selection. You can configure the
DW_apb_ssi for either implementation, illustrated in Figure 118.
Figure 118.
Hardware/Software
Master
Slave Selection.
Slave
Data Bus
ss_0
Master
ss
ss
Slave
Data Bus
ss
ss_x
Slave
Slave
ss
A
ss
B
ss = slave select line
4.10.2. Features
The DW_apb_ssi is a configurable and programmable component that is a full-duplex master serial interface. The host
processor accesses data, control, and status information on the DW_apb_ssi through the APB interface. The
DW_apb_ssi also interfaces with the DMA Controller for bulk data transfer.
The DW_apb_ssi is configured as a serial master. The DW_apb_ssi can connect to any serial-slave peripheral device
using one of the following interfaces:
• Motorola Serial Peripheral Interface (SPI)
• Texas Instruments Serial Protocol (SSP)
4.10. SSI
569
RP2040 Datasheet
• National Semiconductor Microwire
On RP2040, the DW_apb_ssi is a component of the flash execute-in-place subsystem (see Section 2.6.3), and provides
communication with an external SPI, dual-SPI or quad-SPI flash device.
4.10.2.1. IO connections
The SSI controller connects to the following pins:
• QSPI_SCLK Connected to output clock sclk_out
• QSPI_SS_N Connected to chip select ss_o_n
• QSPI_SD[3:0] Connected to data bus txd and rxd
Some pins on the IP are tied off as not used:
• ss_in_n is tied high
Clock connections are as follows:
• pclk and sclk are driven from clk_sys
4.10.3. IP Modifications
The following modifications were made to the Synopsys DW_apb_ssi hardware:
1. XIP accesses are byte-swapped, such that the least-addressed byte is in the least-significant position
2. When SPI_CTRLR0_INST_L is 0, the XIP instruction field is appended to the end of the address for XIP accesses,
rather than prepended to the beginning
3. The reset value of DMARDLR is increased from 0 to 4. The SSI to DMA handshaking on RP2040 requests only single
transfers or bursts of four, depending on whether the RX FIFO level has reached DMARDLR, so DMARDLR should not be
changed from this value.
The first of these changes allows mixed-size accesses by a little-endian busmaster, such as the RP2040 DMA, or the
Cortex-M0+ configuration used on RP2040. Note that this only applies to XIP accesses (RP2040 system addresses in
the range 0x10000000 to 0x13ffffff), not to direct access to the DW_apb_ssi FIFOs. When accessing the SSI directly, it
may be necessary for software to swap bytes manually, or to use the RP2040 DMA’s byte swap feature.
The second supports issuing of continuation bits following the XIP address, so that command-prefix-free XIP modes
can be supported (e.g. EBh Quad I/O Fast Read on Winbond devices), for greater performance. For example, the
following configuration would be used to issue a standard 03h serial read command for each access to the XIP address
window:
• SPI_CTRLR0_INST_L = 8 bits
• SPI_CTRLR0_ADDR_L = 24 bits
• SPI_CTRLR0_XIP_CMD = 0x03
This will first issue eight command bits (0x03), then issue 24 address bits, then clock in the data bits. The configuration
used for EBh quad read, after the flash has entered the XIP state, would be:
• SPI_CTRLR0_INST_L = 0
• SPI_CTRLR0_ADDR_L = 32 bits
• SPI_CTRLR0_XIP_CMD = 0xa0 (continuation code on W25Qx devices)
For each XIP access, the DW_apb_ssi will issue 32 "address" bits, consisting of the 24 LSBs of the RP2040 system bus
address, followed by the 8-bit continuation code 0xa0. No command prefix is issued.
4.10. SSI
570
RP2040 Datasheet
4.10.3.1. Example of Target Slave Selection Using Software
The following example is pseudo code that illustrates how to use software to select the target slave.
1 int main() {
2
disable_all_serial_devices(); ①
3
initialize_mst(ssi_mst_1); ②
4
initialize_slv(ssi_slv_1); ③
5
start_serial_xfer(ssi_mst_1); ④
6 }
① This function sets the
SSI_EN bit to logic ‘0’ in the
② This function initializes
the master device for the
③ This function initializes
the target slave device
④ This function begins the
serial transfer by writing
SSIENR register of each
serial transfer;
(slave 1 in this example)
transmit data into the
for the serial transfer;
master’s TX FIFO. User
device on the serial bus.
1. Write CTRLR0 to
match the required
transfer
2. If transfer is receive
only write number of
frames into CTRLR1
3. Write BAUDR to set
the transfer baud rate.
4. Write TXFTLR and
RXFTLR to set FIFO
threshold levels
5. Write IMR register to
set interrupt masks
6. Write SER register
bit[0] to logic '1'
7. Write SSIENR register
1. Write CTRLR0 to
match the required
transfer
2. Write TXFTLR and
can poll the busy status
with a function or use an
ISR to determine when the
serial transfer has
completed.
RXFTLR to set FIFO
threshold levels
3. Write IMR register to
set interrupt masks
4. Write SSIENR register
bit[0] to logic '1' to
enable the slave.
5. If the slave is to
transmit data, write
data into TX FIFO Now
the slave is enabled
and awaiting an active
bit[0] to logic '1' to
level on its ss_in_n
enable the master.
input port. Note all
other serial slaves are
disabled (SSI_EN=0)
and therefore will not
respond to an active
level on their ss_in_n
port.
4.10.4. Clock Ratios
The maximum frequency of the bit-rate clock (sclk_out) is one-half the frequency of ssi_clk. This allows the shift control
logic to capture data on one clock edge of sclk_out and propagate data on the opposite edge.
Figure 119 illustrates the maximum ratio between sclk_out and ssi_clk.
4.10. SSI
571
RP2040 Datasheet
Figure 119. Maximum
capture
sclk_out/ssi_clk Ratio.
drive1
capture1
drive2
capture2
drive3
capture3
ssi_clk
sclk_out
txd/rxd
MSB
The sclk_out line toggles only when an active transfer is in progress. At all other times it is held in an inactive state, as
defined by the serial protocol under which it operates.
The frequency of sclk_out can be derived from the following equation:
SCKDV is a bit field in the programmable register BAUDR, holding any even value in the range 0 to 65,534. If SCKDV is 0,
then sclk_out is disabled.
4.10.4.1. Frequency Ratio Summary
A summary of the frequency ratio restrictions between the bit-rate clock (sclk_out) and the DW_apb_ssi peripheral clock
(ssi_clk) are as follows:
•
4.10.5. Transmit and Receive FIFO Buffers
The FIFO buffers used by the DW_apb_ssi are internal D-type flip-flops that are 16 entries deep. The width of both
transmit and receive FIFO buffers is fixed at 32 bits, due to the serial specifications, which state that a serial transfer
(data frame) can be 4 to 16/32 bits in length. Data frames that are less than 32 bits must be right-justified when written
into the transmit FIFO buffer. The shift control logic automatically right-justifies receive data in the receive FIFO buffer.
Each data entry in the FIFO buffers contains a single data frame. It is impossible to store multiple data frames in a
single FIFO location; for example, you may not store two 8-bit data frames in a single FIFO location. If an 8-bit data
frame is required, the upper bits of the FIFO entry are ignored or unused when the serial shifter transmits the data.
NOTE
The transmit and receive FIFO buffers are cleared when the DW_apb_ssi is disabled (SSI_EN = 0) or when it is reset
(presetn).
The transmit FIFO is loaded by APB write commands to the DW_apb_ssi data register (DR). Data are popped (removed)
from the transmit FIFO by the shift control logic into the transmit shift register. The transmit FIFO generates a FIFO
empty interrupt request (ssi_txe_intr) when the number of entries in the FIFO is less than or equal to the FIFO threshold
value. The threshold value, set through the programmable register TXFTLR, determines the level of FIFO entries at which
an interrupt is generated. The threshold value allows you to provide early indication to the processor that the transmit
FIFO is nearly empty. A transmit FIFO overflow interrupt (ssi_txo_intr) is generated if you attempt to write data into an
already full transmit FIFO.
Data are popped from the receive FIFO by APB read commands to the DW_apb_ssi data register (DR). The receive FIFO
is loaded from the receive shift register by the shift control logic. The receive FIFO generates a FIFO-full interrupt
request (ssi_rxf_intr) when the number of entries in the FIFO is greater than or equal to the FIFO threshold value plus
one. The threshold value, set through programmable register RXFTLR, determines the level of FIFO entries at which an
interrupt is generated.
The threshold value allows you to provide early indication to the processor that the receive FIFO is nearly full. A receive
FIFO overrun interrupt (ssi_rxo_intr) is generated when the receive shift logic attempts to load data into a completely full
receive FIFO. However, this newly received data are lost. A receive FIFO underflow interrupt (ssi_rxu_intr) is generated if
you attempt to read from an empty receive FIFO. This alerts the processor that the read data are invalid.
4.10. SSI
572
RP2040 Datasheet
Table 576 provides description for different Transmit FIFO Threshold values.
Table 576. Transmit
FIFO Threshold (TFT)
Decode Values
TFT Value
Description
0000_0000
ssi_txe_intr is asserted when zero data entries are present in transmit FIFO
0000_0001
ssi_txe_intr is asserted when one or less data entry is present in transmit FIFO
0000_0010
ssi_txe_intr is asserted when two or less data entries are present in transmit FIFO
…
…
0000_1101
ssi_txe_intr is asserted when 13 or less data entries are present in transmit FIFO
0000_1110
ssi_txe_intr is asserted when 14 or less data entries are present in transmit FIFO
0000_1111
ssi_txe_intr is asserted when 15 or less data entries are present in transmit FIFO
Table 577 provides description for different Receive FIFO Threshold values.
Table 577. Receive
FIFO Threshold (TFT)
Decode Values
RFT Value
Description
0000_0000
ssi_rxf_intr is asserted when one or more data entry is present in receive FIFO
0000_0001
ssi_rxf_intr is asserted when two or more data entries are present in receive FIFO
0000_0010
ssi_rxf_intr is asserted when three or more data entries are present in receive FIFO
…
…
0000_1101
ssi_rxf_intr is asserted when 14 or more data entries are present in receive FIFO
0000_1110
ssi_rxf_intr is asserted when 15 or more data entries are present in receive FIFO
0000_1111
ssi_rxf_intr is asserted when 16 data entries are present in receive FIFO
4.10.6. 32-Bit Frame Size Support
The IP is configured to set the maximum programmable value in of data frame size to 32 bits. As a result the following
features exist:
• dfs_32 (CTRLR0[20:16]) are valid, which contains the value of data frame size. The new register field holds the
values 0 to 31. The dfs (CTRLR0[3:0]) is invalid and writing to this register has no effect.
• The receive and transmit FIFO widths are 32 bits.
• All 32 bits of the data register are valid.
4.10.7. SSI Interrupts
The DW_apb_ssi supports combined and individual interrupt requests, each of which can be masked. The combined
interrupt request is the ORed result of all other DW_apb_ssi interrupts after masking. Only the combined interrupt
request is routed to the Interrupt Controller. All DW_apb_ssi interrupts are level interrupts and are active high.
The DW_apb_ssi interrupts are described as follows:
Transmit FIFO Empty Interrupt (ssi_txe_intr)
Set when the transmit FIFO is equal to or below its threshold value and requires service to prevent an under-run. The
threshold value, set through a software-programmable register, determines the level of transmit FIFO entries at
which an interrupt is generated. This interrupt is cleared by hardware when data are written into the transmit FIFO
buffer, bringing it over the threshold level.
4.10. SSI
573
RP2040 Datasheet
Transmit FIFO Overflow Interrupt (ssi_txo_intr)
Set when an APB access attempts to write into the transmit FIFO after it has been completely filled. When set, data
written from the APB is discarded. This interrupt remains set until you read the transmit FIFO overflow interrupt
clear register (TXOICR).
Receive FIFO Full Interrupt (ssi_rxf_intr)
Set when the receive FIFO is equal to or above its threshold value plus 1 and requires service to prevent an
overflow. The threshold value, set through a software-programmable register, determines the level of receive FIFO
entries at which an interrupt is generated. This interrupt is cleared by hardware when data are read from the receive
FIFO buffer, bringing it below the threshold level.
Receive FIFO Overflow Interrupt (ssi_rxo_intr)
Set when the receive logic attempts to place data into the receive FIFO after it has been completely filled. When set,
newly received data are discarded. This interrupt remains set until you read the receive FIFO overflow interrupt clear
register (RXOICR).
Receive FIFO Underflow Interrupt (ssi_rxu_intr)
Set when an APB access attempts to read from the receive FIFO when it is empty. When set, 0s are read back from
the receive FIFO. This interrupt remains set until you read the receive FIFO underflow interrupt clear register
(RXUICR).
Multi-Master Contention Interrupt (ssi_mst_intr)
Present only when the DW_apb_ssi component is configured as a serial-master device. The interrupt is set when
another serial master on the serial bus selects the DW_apb_ssi master as a serial-slave device and is actively
transferring data. This informs the processor of possible contention on the serial bus. This interrupt remains set
until you read the multi-master interrupt clear register (MSTICR).
Combined Interrupt Request (ssi_intr)
OR’ed result of all the above interrupt requests after masking. To mask this interrupt signal, you must mask all other
DW_apb_ssi interrupt requests.
4.10.8. Transfer Modes
When transferring data on the serial bus, the DW_apb_ssi operates in the modes discussed in this section. The transfer
mode (TMOD) is set by writing to control register 0 (CTRLR0).
NOTE
The transfer mode setting does not affect the duplex of the serial transfer. TMOD is ignored for Microwire transfers,
which are controlled by the MWCR register.
4.10.8.1. Transmit and Receive
When TMOD = 00b, both transmit and receive logic are valid. The data transfer occurs as normal according to the
selected frame format (serial protocol). Transmit data are popped from the transmit FIFO and sent through the txd line
to the target device, which replies with data on the rxd line. The receive data from the target device is moved from the
receive shift register into the receive FIFO at the end of each data frame.
4.10.8.2. Transmit Only
When TMOD = 01b, the receive data are invalid and should not be stored in the receive FIFO. The data transfer occurs as
normal, according to the selected frame format (serial protocol). Transmit data are popped from the transmit FIFO and
sent through the txd line to the target device, which replies with data on the rxd line. At the end of the data frame, the
receive shift register does not load its newly received data into the receive FIFO. The data in the receive shift register is
overwritten by the next transfer. You should mask interrupts originating from the receive logic when this mode is
4.10. SSI
574
RP2040 Datasheet
entered.
4.10.8.3. Receive Only
When TMOD = 10b, the transmit data are invalid. When configured as a slave, the transmit FIFO is never popped in
Receive Only mode. The txd output remains at a constant logic level during the transmission. The data transfer occurs
as normal according to the selected frame format (serial protocol). The receive data from the target device is moved
from the receive shift register into the receive FIFO at the end of each data frame. You should mask interrupts
originating from the transmit logic when this mode is entered.
4.10.8.4. EEPROM Read
NOTE
This transfer mode is only valid for master configurations.
When TMOD = 11b, the transmit data is used to transmit an opcode and/or an address to the EEPROM device. Typically
this takes three data frames (8-bit opcode followed by 8-bit upper address and 8-bit lower address). During the
transmission of the opcode and address, no data is captured by the receive logic (as long as the DW_apb_ssi master is
transmitting data on its txd line, data on the rxd line is ignored). The DW_apb_ssi master continues to transmit data until
the transmit FIFO is empty. Therefore, you should ONLY have enough data frames in the transmit FIFO to supply the
opcode and address to the EEPROM. If more data frames are in the transmit FIFO than are needed, then read data is
lost.
When the transmit FIFO becomes empty (all control information has been sent), data on the receive line (rxd) is valid
and is stored in the receive FIFO; the txd output is held at a constant logic level. The serial transfer continues until the
number of data frames received by the DW_apb_ssi master matches the value of the NDF field in the CTRLR1 register +
1.
NOTE
EEPROM read mode is not supported when the DW_apb_ssi is configured to be in the SSP mode.
4.10.9. Operation Modes
The DW_apb_ssi can be configured in the fundamental modes of operation discussed in this section.
4.10.9.1. Serial Master Mode
This mode enables serial communication with serial-slave peripheral devices. When configured as a serial-master
device, the DW_apb_ssi initiates and controls all serial transfers. Figure 120 shows an example of the DW_apb_ssi
configured as a serial master with all other devices on the serial bus configured as serial slaves.
4.10. SSI
575
RP2040 Datasheet
Figure 120.
DW_apb_ssi
Configured as Master
Device
DW_apb_ssi
Master 1
Slave
Peripheral 1
DI
txd
DO
ssi_oe_n
SCLK
rxd
SS
sclk_out
ss_n[0]
Slave
Peripheral n
ss_n[1]
ss_in_n
DI
DO
Glue Logic
SCLK
SS
Should be driven to inactive level
(protocol-dependent) in single master
systems; may not need glue logic
The serial bit-rate clock, generated and controlled by the DW_apb_ssi, is driven out on the sclk_out line. When the
DW_apb_ssi is disabled (SSI_EN = 0), no serial transfers can occur and sclk_out is held in “inactive” state, as defined by
the serial protocol under which it operates.
Multiple master configuration is not supported.
4.10.9.1.1. RXD Sample Delay
When the DW_apb_ssi is configured as a master, additional logic can be included in the design in order to delay the
default sample time of the rxd signal. This additional logic can help to increase the maximum achievable frequency on
the serial bus.
Round trip routing delays on the sclk_out signal from the master and the rxd signal from the slave can mean that the
timing of the rxd signal—as seen by the master—has moved away from the normal sampling time. Figure 121 illustrates
this situation.
dly=0
Figure 121. Effects of
dly=5
dly=6
Round-Trip Routing
Delays on sclk_out
Signal
dly=7
baud-rate=4
ssi_clk
sclk_out
txd_mst
MSB
LSB
MSB
rxd_mst
LSB
sclk_in
rxd_slv
txd_slv
LSB
MSB
MSB
LSB
The Slave uses the sclk_out signal from the master as a strobe in order to drive rxd signal data onto the serial bus.
Routing and sampling delays on the sclk_out signal by the slave device can mean that the rxd bit has not stabilized to
the correct value before the master samples the rxd signal. Figure 121 shows an example of how a routing delay on the
rxd signal can result in an incorrect rxd value at the default time when the master samples the port.
Without the RXD Sample Delay logic, the user would have to increase the baud-rate for the transfer in order to ensure
4.10. SSI
576
RP2040 Datasheet
that the setup times on the rxd signal are within range; this results in reducing the frequency of the serial interface.
When the RXD Sample Delay logic is included, the user can dynamically program a delay value in order to move the
sampling time of the rxd signal equal to a number of ssi_clk cycles from the default.
The sample delay logic has a resolution of one ssi_clk cycle. Software can “train” the serial bus by coding a loop that
continually reads from the slave and increments the master’s RXD Sample Delay value until the correct data is received
by the master.
4.10.9.1.2. Data Transfers
Data transfers are started by the serial-master device. When the DW_apb_ssi is enabled (SSI_EN=1), at least one valid
data entry is present in the transmit FIFO and a serial-slave device is selected. When actively transferring data, the busy
flag (BUSY) in the status register (SR) is set. You must wait until the busy flag is cleared before attempting a new serial
transfer.
NOTE
The BUSY status is not set when the data are written into the transmit FIFO. This bit gets set only when the target
slave has been selected and the transfer is underway. After writing data into the transmit FIFO, the shift logic does
not begin the serial transfer until a positive edge of the sclk_out signal is present. The delay in waiting for this
positive edge depends on the baud rate of the serial transfer. Before polling the BUSY status, you should first poll the
TFE status (waiting for 1) or wait for BAUDR * ssi_clk clock cycles.
4.10.9.1.3. Master SPI and SSP Serial Transfers
When the transfer mode is “transmit and receive” or “transmit only” (TMOD = 00b or TMOD = 01b, respectively), transfers
are terminated by the shift control logic when the transmit FIFO is empty. For continuous data transfers, you must
ensure that the transmit FIFO buffer does not become empty before all the data have been transmitted. The transmit
FIFO threshold level (TXFTLR) can be used to early interrupt (ssi_txe_intr) the processor indicating that the transmit
FIFO buffer is nearly empty. When a DMA is used for APB accesses, the transmit data level (DMATDLR) can be used to
early request (dma_tx_req) the DMA Controller, indicating that the transmit FIFO is nearly empty. The FIFO can then be
refilled with data to continue the serial transfer. The user may also write a block of data (at least two FIFO entries) into
the transmit FIFO before enabling a serial slave. This ensures that serial transmission does not begin until the number
of data-frames that make up the continuous transfer are present in the transmit FIFO.
When the transfer mode is “receive only” (TMOD = 10b), a serial transfer is started by writing one “dummy” data word
into the transmit FIFO when a serial slave is selected. The txd output from the DW_apb_ssi is held at a constant logic
level for the duration of the serial transfer. The transmit FIFO is popped only once at the beginning and may remain
empty for the duration of the serial transfer. The end of the serial transfer is controlled by the “number of data frames”
(NDF) field in control register 1 (CTRLR1).
If, for example, you want to receive 24 data frames from a serial-slave peripheral, you should program the NDF field with
the value 23; the receive logic terminates the serial transfer when the number of frames received is equal to the NDF
value + 1. This transfer mode increases the bandwidth of the APB bus as the transmit FIFO never needs to be serviced
during the transfer. The receive FIFO buffer should be read each time the receive FIFO generates a FIFO full interrupt
request to prevent an overflow.
When the transfer mode is “eeprom_read” (TMOD = 11b), a serial transfer is started by writing the opcode and/or
address into the transmit FIFO when a serial slave (EEPROM) is selected. The opcode and address are transmitted to
the EEPROM device, after which read data is received from the EEPROM device and stored in the receive FIFO. The end
of the serial transfer is controlled by the NDF field in the control register 1 (CTRLR1).
4.10. SSI
577
RP2040 Datasheet
NOTE
EEPROM read mode is not supported when the DW_apb_ssi is configured to be in the SSP mode.
The receive FIFO threshold level (RXFTLR) can be used to give early indication that the receive FIFO is nearly full. When
a DMA is used for APB accesses, the receive data level (DMARDLR) can be used to early request (dma_rx_req) the DMA
Controller, indicating that the receive FIFO is nearly full.
A typical software flow for completing an SPI or SSP serial transfer from the DW_apb_ssi serial master is outlined as
follows:
1. If the DW_apb_ssi is enabled, disable it by writing 0 to the SSI Enable register (SSIENR).
2. Set up the DW_apb_ssi control registers for the transfer; these registers can be set in any order.
◦ Write
Control Register 0 (CTRLR0). For SPI transfers, the serial clock polarity and serial clock phase
parameters must be set identical to target slave device.
◦ If the transfer mode is receive only, write CTRLR1 (Control Register 1) with the number of frames in the
transfer minus 1; for example, if you want to receive four data frames, if you want to receive four data frames,
write '3' into CTRLR1.
◦ Write the Baud Rate Select Register (BAUDR) to set the baud rate for the transfer.
◦ Write the Transmit and Receive FIFO Threshold Level registers (TXFTLR and RXFTLR, respectively) to set FIFO
threshold levels.
◦ Write the IMR register to set up interrupt masks.
◦ The Slave Enable Register (SER) register can be written here to enable the target slave for selection. If a slave
is enabled here, the transfer begins as soon as one valid data entry is present in the transmit FIFO. If no
slaves are enabled prior to writing to the Data Register (DR), the transfer does not begin until a slave is
enabled.
3. Enable the DW_apb_ssi by writing 1 to the SSIENR register.
4. Write data for transmission to the target slave into the transmit FIFO (write DR). If no slaves were enabled in the
SER register at this point, enable it now to begin the transfer.
5. Poll the BUSY status to wait for completion of the transfer. The BUSY status cannot be polled immediately.
6. If a transmit FIFO empty interrupt request is made, write the transmit FIFO (write DR). If a receive FIFO full interrupt
request is made, read the receive FIFO (read DR).
7. The transfer is stopped by the shift control logic when the transmit FIFO is empty. If the transfer mode is receive
only (TMOD = 10b), the transfer is stopped by the shift control logic when the specified number of frames have
been received. When the transfer is done, the BUSY status is reset to 0.
8. If the transfer mode is not transmit only (TMOD != 01b), read the receive FIFO until it is empty.
9. Disable the DW_apb_ssi by writing 0 to SSIENR.
Figure 122 shows a typical software flow for starting a DW_apb_ssi master SPI/SSP serial transfer. The diagram also
shows the hardware flow inside the serial-master component.
4.10. SSI
578
RP2040 Datasheet
Figure 122.
Software Flow
DW_apb_ssi Master
SPI/SSP Transfer Flow
IDLE
Disable
DW_apb_ssi
DW_apb_ssi
IDLE
Configure Master by
writing CTRLR0. CTRLR1,
BAUDR, TXFTLR, RXFTLR,
IMR, SER, SPI_CTRLR0
(if Dual /Quad SPI)
Pop data from
Tx FIFO into shifter
Enable
DW_apb_ssi
Transfer Bit
You may fill FIFO here:
Transfer begins when
first data word is
present in the transmit
FIFO and slave is
enabled.
Write data to
Tx FIFO
Transfer in
progress
No
All bits in frame
transferred?
Yes
TMOD=01
Load Rx FIFO
Interrupt?
No
Yes
BUSY?
TMOD=01
No
Read Rx
FIFO
Yes
Interrupt Service
Routine
If the transmit FIFO
is requesting and all
data have not been
sent, then write data
into transmit FIFO.
If the receive FIFO is
requesting, then
read data from
receive FIFO.
No
TMOD=00
TMOD=01
TMOD=10
Transmit
FIFO empty?
All frames
transferred
Yes
No
Yes
END
4.10.9.1.4. Master Microwire Serial Transfers
Microwire serial transfers from the DW_apb_ssi serial master are controlled by the Microwire Control Register (MWCR).
The MWHS bit field enables and disables the Microwire handshaking interface. The MDD bit field controls the direction
of the data frame (the control frame is always transmitted by the master and received by the slave). The MWMOD bit
field defines whether the transfer is sequential or nonsequential.
All Microwire transfers are started by the DW_apb_ssi serial master when there is at least one control word in the
transmit FIFO and a slave is enabled. When the DW_apb_ssi master transmits the data frame (MDD = 1), the transfer is
terminated by the shift logic when the transmit FIFO is empty. When the DW_apb_ssi master receives the data frame
(MDD = 1), the termination of the transfer depends on the setting of the MWMOD bit field. If the transfer is
nonsequential (MWMOD = 0), it is terminated when the transmit FIFO is empty after shifting in the data frame from the
slave. When the transfer is sequential (MWMOD = 1), it is terminated by the shift logic when the number of data frames
received is equal to the value in the CTRLR1 register + 1.
When the handshaking interface on the DW_apb_ssi master is enabled (MWHS =1), the status of the target slave is
polled after transmission. Only when the slave reports a ready status does the DW_apb_ssi master complete the
transfer and clear its BUSY status. If the transfer is continuous, the next control/data frame is not sent until the slave
device returns a ready status.
A typical software flow for completing a Microwire serial transfer from the DW_apb_ssi serial master is outlined as
follows:
1. If the DW_apb_ssi is enabled, disable it by writing 0 to SSIENR.
2. Set up the DW_apb_ssi control registers for the transfer. These registers can be set in any order. Write CTRLR0 to
set transfer parameters.
◦ If the transfer is sequential and the DW_apb_ssi master receives data, write CTRLR1 with the number of
frames in the transfer minus 1; for instance, if you want to receive four data frames, write '3' into CTRLR1.
◦ Write BAUDR to set the baud rate for the transfer.
◦ Write TXFTLR and RXFTLR to set FIFO threshold levels.
◦ Write the IMR register to set up interrupt masks.
4.10. SSI
579
RP2040 Datasheet
You can write the SER register to enable the target slave for selection. If a slave is enabled here, the transfer
begins as soon as one valid data entry is present in the transmit FIFO. If no slaves are enabled prior to writing
to the DR register, the transfer does not begin until a slave is enabled.
3. Enable the DW_apb_ssi by writing 1 to the SSIENR register.
4. If the DW_apb_ssi master transmits data, write the control and data words into the transmit FIFO (write DR). If the
DW_apb_ssi master receives data, write the control word(s) into the transmit FIFO.
If no slaves were enabled in the SER register at this point, enable now to begin the transfer.
5. Poll the BUSY status to wait for completion of the transfer. The BUSY status cannot be polled immediately.
6. The transfer is stopped by the shift control logic when the transmit FIFO is empty. If the transfer mode is
sequential and the DW_apb_ssi master receives data, the transfer is stopped by the shift control logic when the
specified number of data frames is received. When the transfer is done, the BUSY status is reset to 0.
7. If the DW_apb_ssi master receives data, read the receive FIFO until it is empty.
8. Disable the DW_apb_ssi by writing 0 to SSIENR.
Figure 123 shows a typical software flow for starting a DW_apb_ssi master Microwire serial transfer. The diagram also
shows the hardware flow inside the serial-master component.
Figure 123.
Software Flow
DW_apb_ssi
DW_apb_ssi Master
IDLE
Microwire Transfer
IDLE
Flow
Disable
DW_apb_ssi
Pop control frame
from Tx FIFO into
shifter
Configure Master
by writing CTRLR0.
CTRLR1, BAUDR,
TXFTLR, RXFTLR,
MWCR, IMR, SER
Transfer Bit
No
Enable
DW_apb_ssi
Transfer in
progress
Interrupt?
No
Yes
BUSY?
MWCR[1]=1
No
Read Rx
FIFO
MWCR[1]=1
If master receives
data, user need only
write control frames
into the Tx FIFO.
Transfer begins
when first control
word is present in
the Transmit FIFO
and a slave is
enabled.
Write control &
data to Tx FIFO
Yes
Interrupt Service
Routine
If the transmit FIFO
is requesting and all
data have not been
sent, then write data
into transmit FIFO.
If the receive FIFO is
requesting, then
read data from
receive FIFO.
All bits in
control frame
transmitted?
Yes
MWCR[1]=0
Pop data frame from
Tx FIFO into shifter
Receive Bit
All bits in
data frame
received?
Transfer Bit
No
Yes
All bits in
data frame
transmitted?
Load Rx FIFO
Yes
MWCR[0]=0
MWCR[0]=1
No
No
Transmit
FIFO empty?
Yes
All frames
transferred?
Yes
END
4.10.10. Partner Connection Interfaces
The DW_apb_ssi can connect to any serial-slave peripheral device using one of the interfaces discussed in the following
sections.
4.10.10.1. Motorola Serial Peripheral Interface (SPI)
With the SPI, the clock polarity (SCPOL) configuration parameter determines whether the inactive state of the serial
4.10. SSI
580
RP2040 Datasheet
clock is high or low. To transmit data, both SPI peripherals must have identical serial clock phase (SCPH) and clock
polarity (SCPOL) values. The data frame can be 4 to 16/32 bits (depending upon SSI_MAX_XFER_SIZE) in length.
When the configuration parameter SCPH = 0, data transmission begins on the falling edge of the slave select signal.
The first data bit is captured by the master and slave peripherals on the first edge of the serial clock; therefore, valid
data must be present on the txd and rxd lines prior to the first serial clock edge.
Figure 124 shows a timing diagram for a single SPI data transfer with SCPH = 0. The serial clock is shown for
configuration parameters SCPOL = 0 and SCPOL = 1.
Figure 124. SPI Serial
Format (SCPH = 0)
sclk_out/in 0
sclk_out/in 1
txd
MSB
LSB
4 -32 bits
rxd
MSB
LSB
ss_0_n/ss_in_n
ssi_oe_n
The following signals are illustrated in the timing diagrams in this section:
sclk_out
serial clock from DW_apb_ssi master
ss_0_n
slave select signal from DW_apb_ssi master
ss_in_n
slave select input to the DW_apb_ssi slave
ss_oe_n
output enable for the DW_apb_ssi master
txd
transmit data line for the DW_apb_ssi master
rxd
receive data line for the DW_apb_ssi master
Continuous data transfers are supported when SCPH = 0:
• When CTRLR0. SSTE is set to 1, the DW_apb_ssi toggles the slave select signal between frames and the serial
clock is held to its default value while the slave select signal is active; this operating mode is illustrated in Figure
125.
Figure 125. Serial
Format Continuous
Transfers (SCPH = 0)
sclk_out/in 0
sclk_out/in 1
txd/rxd
LSB
MSB
LSB
MSB
ss_0_n/ss_in_n
ssi_oe_n
When the configuration parameter SCPH = 1, master peripherals begin transmitting data on the first serial clock edge
after the slave select line is activated. The first data bit is captured on the second (trailing) serial clock edge. Data are
propagated by the master peripherals on the leading edge of the serial clock. During continuous data frame transfers,
the slave select line may be held active-low until the last bit of the last frame has been captured.
4.10. SSI
581
RP2040 Datasheet
Figure 126 shows the timing diagram for the SPI format when the configuration parameter SCPH = 1.
Figure 126. SPI Serial
Format (SCPH = 1)
sclk_out/in 0
sclk_out/in 1
txd
MSB
rxd
MSB
LSB
4 -32 bits
LSB
ss_0_n/ss_in_n
ssi_oe_n
Continuous data frames are transferred in the same way as single frames, with the MSB of the next frame following
directly after the LSB of the current frame. The slave select signal is held active for the duration of the transfer.
Figure 127 shows the timing diagram for continuous SPI transfers when the configuration parameter SCPH = 1.
Figure 127. SPI Serial
Format Continuous
Transfer (SCPH = 1)
sclk_out/in 0
sclk_out/in 1
txd
MSB
LSB
MSB
LSB
rxd
MSB
LSB
MSB
LSB
ss_0_n/ss_in_n
ssi_oe_n
There are four possible transfer modes on the DW_apb_ssi for performing SPI serial transactions. For transmit and
receive transfers (transfer mode field (9:8) of the Control Register 0 = 00b), data transmitted from the DW_apb_ssi to the
external serial device is written into the transmit FIFO. Data received from the external serial device into the DW_apb_ssi
is pushed into the receive FIFO.
Figure 128 shows the FIFO levels prior to the beginning of a serial transfer and the FIFO levels on completion of the
transfer. In this example, two data words are transmitted from the DW_apb_ssi to the external serial device in a
continuous transfer. The external serial device also responds with two data words for the DW_apb_ssi.
Figure 128. FIFO
rxd
Status for Transmit &
Write DR
Receive SPI and SSP
Tx FIFO Empty
Tx FIFO Buffer
Transfers
Location n
NULL
Location 2
NULL
Location 1
Tx Data(1)
Location 2
NULL
Location 0
Tx Data(0)
Location 1
Rx_Data(1)
Location 0
Rx_Data(0)
Location n
Rx FIFO Buffer
Rx FIFO Empty
FIFO Status Prior to
Transfer
NULL
SHIFT LOGIC
Read DR
txd
FIFO Status on
Completion of Transfer
For transmit only transfers (transfer mode field (9:8) of the Control Register 0 = 01b), data transmitted from the
DW_apb_ssi to the external serial device is written into the transmit FIFO. As the data received from the external serial
device is deemed invalid, it is not stored in the DW_apb_ssi receive FIFO.
Figure 129 shows the FIFO levels prior to the beginning of a serial transfer and the FIFO levels on completion of the
transfer. In this example, two data words are transmitted from the DW_apb_ssi to the external serial device in a
continuous transfer.
4.10. SSI
582
RP2040 Datasheet
Figure 129. FIFO
rxd
Status for Transmit
Only SPI and SSP
Write DR
Transfers
Tx FIFO Empty
Tx FIFO Buffer
Location n
NULL
Location 2
NULL
Location 1
Location 0
Location n
NULL
Tx Data(1)
Location 2
NULL
Tx Data(0)
Location 1
NULL
Location 0
NULL
SHIFT LOGIC
Rx FIFO Buffer
Rx FIFO Empty
FIFO Status Prior to
Transfer
Read DR
FIFO Status on
Completion of Transfer
txd
For receive only transfers (transfer mode field (9:8) of the Control Register 0 = 10b), data transmitted from the
DW_apb_ssi to the external serial device is invalid, so a single dummy word is written into the transmit FIFO to begin the
serial transfer. The txd output from the DW_apb_ssi is held at a constant logic level for the duration of the serial
transfer. Data received from the external serial device into the DW_apb_ssi is pushed into the receive FIFO.
Figure 130 shows the FIFO levels prior to the beginning of a serial transfer and the FIFO levels on completion of the
transfer. In this example, two data words are received by the DW_apb_ssi from the external serial device in a continuous
transfer.
Figure 130. FIFO
rxd
Status for Receive
Write DR
Only SPI and SSP
Tx FIFO Empty
Tx FIFO Buffer
Transfers
Location n
NULL
Location 2
NULL
Location n
NULL
SHIFT LOGIC
Location 1
NULL
Location 2
NULL
Location 0
Dummy Word
Location 1
Rx_Data(1)
Location 0
Rx_Data(0)
Rx FIFO Buffer
Rx FIFO Empty
FIFO Status Prior to
Transfer
Read DR
txd
FIFO Status on
Completion of Transfer
For eeprom_read transfers (transfer mode field [9:8] of the Control Register 0 = 11b), opcode and/or EEPROM address
are written into the transmit FIFO. During transmission of these control frames, received data is not captured by the
DW_apb_ssi master. After the control frames have been transmitted, receive data from the EEPROM is stored in the
receive FIFO.
Figure 131 shows the FIFO levels prior to the beginning of a serial transfer and the FIFO levels on completion of the
transfer. In this example, one opcode and an upper and lower address are transmitted to the EEPROM, and eight data
frames are read from the EEPROM and stored in the receive FIFO of the DW_apb_ssi master.
4.10. SSI
583
RP2040 Datasheet
Figure 131. FIFO
rxd
Status for EEPROM
Read Transfer Mode
Write DR
Tx FIFO Empty
Tx FIFO Buffer
Location n
NULL
Location 3
NULL
Location n
NULL
SHIFT LOGIC
Location 2
Address[7:0]
Location 7
Rx_Data(7)
Location 1
Address[15:8]
Location 6
Rx_Data(6)
Location 0
Opcode
Location 1
Rx_Data(1)
Location 0
Rx_Data(0)
Rx FIFO Empty
FIFO Status Prior to
Transfer
Rx FIFO Buffer
txd
Read DR
FIFO Status on
Completion of Transfer
4.10.10.2. Texas Instruments Synchronous Serial Protocol (SSP)
Data transfers begin by asserting the frame indicator line (ss_0_n/ss_in_n) for one serial clock period. Data to be
transmitted are driven onto the txd line one serial clock cycle later; similarly data from the slave are driven onto the rxd
line. Data are propagated on the rising edge of the serial clock (sclk_out/sclk_in) and captured on the falling edge. The
length of the data frame ranges from four to 32 bits.
Figure 132 shows the timing diagram for a single SSP serial transfer.
Figure 132. SSP Serial
Format
sclk_out/in
txd/rxd
MSB
LSB
ss_0_n/ss_in_n
ssi_oe_n
Continuous data frames are transferred in the same way as single data frames. The frame indicator is asserted for one
clock period during the same cycle as the LSB from the current transfer, indicating that another data frame follows.
Figure 133 shows the timing for a continuous SSP transfer.
Figure 133. SSP Serial
Format Continuous
Transfer
sclk_out/in
txd/rxd
MSB
LSB
MSB
ss_0_n/ss_in_n
ssi_oe_n
4.10.10.3. National Semiconductor Microwire
Data transmission begins with the falling edge of the slave-select signal (ss_0_n). One-half serial clock (sclk_out) period
later, the first bit of the control is sent out on the txd line. The length of the control word can be in the range 1 to 16 bits
and is set by writing bit field CFS (bits 15:12) in CTRLR0. The remainder of the control word is transmitted (propagated
on the falling edge of sclk_out) by the DW_apb_ssi serial master. During this transmission, no data are present (high
impedance) on the serial master’s rxd line.
4.10. SSI
584
RP2040 Datasheet
The direction of the data word is controlled by the MDD bit field (bit 1) in the Microwire Control Register (MWCR). When
MDD=0, this indicates that the DW_apb_ssi serial master receives data from the external serial slave. One clock cycle
after the LSB of the control word is transmitted, the slave peripheral responds with a dummy 0 bit, followed by the data
frame, which can be four to 32 bits in length. Data are propagated on the falling edge of the serial clock and captured on
the rising edge.
The slave-select signal is held active-low during the transfer and is de-asserted one-half clock cycle later, after the data
are transferred. Figure 134 shows the timing diagram for a single DW_apb_ssi serial master read from an external serial
slave.
Figure 134. Single
DW_apb_ssi Master
sclk_out
Microwire Serial
Control word
Transfer (MDD=0)
MSB
txd
LSB
4 -32 bits
0
rxd
MSB
LSB
ss_0_n
ssi_oe_n
Figure 135 shows how the data and control frames are structured in the transmit FIFO prior to the transfer; the value
programmed into the MWCR register is also shown.
Figure 135. FIFO
Status for Single
MWHS
0
MWCR
MDD MWMOD
0
0
rxd
Microwire Transfer
(receiving data frame)
Write DR
Tx FIFO Empty
Tx FIFO Buffer
Location n
NULL
Location 3
NULL
Location 2
Location 1
Location 0
Location n
NULL
NULL
Location 3
NULL
NULL
Location 2
NULL
Ctrl Word(0)
Location 1
NULL
Location 0
Rx_Data(0)
SHIFT LOGIC
Rx FIFO Buffer
Rx FIFO Empty
Read DR
FIFO Status Prior to
Transfer
FIFO Status on
Completion of Transfer
txd
Continuous transfers for the Microwire protocol can be sequential or nonsequential, and are controlled by the MWMOD
bit field (bit 0) in the MWCR register.
Nonsequential continuous transfers occur as illustrated in Figure 136, with the control word for the next transfer
following immediately after the LSB of the current data word.
Figure 136.
Continuous
sclk_out
Control word 0
Nonsequential
Microwire Transfer
txd
MSB
Control word 1
MSB
LSB
LSB
Data Word 0
(receiving data frame)
rxd
0
MSB
LSB
Data Word 1
0
MSB
LSB
ss_0_n
ssi_oe_n
The only modification needed to perform a continuous nonsequential transfer is to write more control words into the
transmit FIFO buffer; this is illustrated in Figure 137. In this example, two data words are read from the external serialslave device.
4.10. SSI
585
RP2040 Datasheet
Figure 137. FIFO
MWHS
Status for
Nonsequential
MDD MWMOD
0
MWCR
0
Microwire Transfer
0
rxd
Write DR
(receiving data frame)
Tx FIFO Empty
Tx FIFO Buffer
Location n
NULL
Location 3
NULL
Location n
NULL
NULL
SHIFT LOGIC
Location 2
NULL
Location 3
Location 1
Ctrl Word(1)
Location 2
NULL
Location 0
Ctrl Word(0)
Location 1
Rx_Data(1)
Location 0
Rx_Data(0)
Rx FIFO Buffer
Rx FIFO Empty
Read DR
FIFO Status Prior to
Transfer
FIFO Status on
Completion of Transfer
txd
During sequential continuous transfers, only one control word is transmitted from the DW_apb_ssi master. The transfer
is started in the same manner as with nonsequential read operations, but the cycle is continued to read further data.
The slave device automatically increments its address pointer to the next location and continues to provide data from
that location. Any number of locations can be read in this manner; the DW_apb_ssi master terminates the transfer when
the number of words received is equal to the value in the CTRLR1 register plus one.
The timing diagram in Figure 138 and example in Figure 139 show a continuous sequential read of two data frames
from the external slave device.
Figure 138.
Continuous Sequential
sclk_out
Microwire Transfer
Control word
(receiving data frame)
MSB
txd
LSB
Data Word 0
0
rxd
MSB
LSB
Data Word 1
MSB
LSB
ss_0_n
ssi_oe_n
Figure 139. FIFO
Status for Sequential
MWHS
MWCR
0
MDD MWMOD
0
1
Microwire Transfer
(receiving data frame)
rxd
Write DR
Tx FIFO Empty
Tx FIFO Buffer
Location n
NULL
Location 3
NULL
Location 2
Location 1
Location 0
Location n
NULL
NULL
Location 3
NULL
NULL
Location 2
NULL
Ctrl Word(0)
Location 1
Rx_Data(1)
Location 0
Rx_Data(0)
SHIFT LOGIC
Rx FIFO Buffer
Rx FIFO Empty
FIFO Status Prior to
Transfer
Read DR
txd
FIFO Status on
Completion of Transfer
When MDD = 1, this indicates that the DW_apb_ssi serial master transmits data to the external serial slave. Immediately
after the LSB of the control word is transmitted, the DW_apb_ssi master begins transmitting the data frame to the slave
peripheral.
Figure 140 shows the timing diagram for a single DW_apb_ssi serial master write to an external serial slave.
4.10. SSI
586
RP2040 Datasheet
Figure 140. Single
Microwire Transfer
sclk_out
(transmitting data
Control word
frame)
MSB
txd
Data word 0
LSB
LSB
MSB
rxd
ss_0_n
ssi_oe_n
NOTE
The DW_apb_ssi does not support continuous sequential Microwire writes, where MDD = 1 and MWMOD = 1.
Figure 141 shows how the data and control frames are structured in the transmit FIFO prior to the transfer, also shown
is the value programmed into the MWCR register.
Figure 141. FIFO
Status for Single
MWHS
0
MWCR
MDD MWMOD
1
0
rxd
Microwire Transfer
(transmitting data
Write DR
frame)
Tx FIFO Empty
Tx FIFO Buffer
Location n
NULL
Location 3
NULL
Location n
NULL
SHIFT LOGIC
Location 2
NULL
Location 3
NULL
Location 1
Tx Data(0)
Location 2
NULL
Location 0
Ctrl Word(0)
Location 1
NULL
Location 0
NULL
Rx FIFO Buffer
Rx FIFO Empty
FIFO Status Prior to
Transfer
FIFO Status on
Completion of Transfer
txd
Continuous transfers occur as shown in Figure 142, with the control word for the next transfer following immediately
after the LSB of the current data word.
Figure 142.
Continuous Microwire
sclk_out
Control word 0
Transfer (transmitting
data frame)
txd
MSB
LSB
Data word 0
MSB
LSB
Control word 1
MSB
LSB
Data word 1
MSB
LSB
rxd
ss_0_n
ssi_oe_n
The only modification you need to make to perform a continuous transfer is to write more control and data words into
the transmit FIFO buffer, shown in Figure 143. This example shows two data words are written to the external serial
slave device.
4.10. SSI
587
RP2040 Datasheet
Figure 143. FIFO
MWHS
Status for Continuous
Microwire Transfer
MDD MWMOD
0
MWCR
1
(transmitting data
0
rxd
Write DR
frame)
Tx FIFO Empty
Tx FIFO Buffer
Location n
NULL
Location 3
Data Word(1)
Location 2
Location 1
Location 0
Location n
NULL
Ctrl Word(1)
Location 3
NULL
Tx Data(0)
Location 2
NULL
Ctrl Word(0)
Location 1
NULL
Location 0
NULL
SHIFT LOGIC
Rx FIFO Buffer
Rx FIFO Empty
FIFO Status Prior to
Transfer
FIFO Status on
Completion of Transfer
txd
The Microwire handshaking interface can also be enabled for DW_apb_ssi master write operations to external serialslave devices. To enable the handshaking interface, you must write 1 into the MHS bit field (bit 2) on the MWCR register.
When MHS is set to 1, the DW_apb_ssi serial master checks for a ready status from the slave device before completing
the transfer, or transmitting the next control word for continuous transfers.
Figure 144 shows an example of a continuous Microwire transfer with the handshaking interface enabled.
Figure 144.
sclk_out
Continuous Microwire
Control word 0
Transfer with
txd
Handshaking
rxd
(transmitting data
frame)
MSB
Data word 0
LSB
MSB
Control word 1
LSB
MSB
Busy
LSB
Data word 1
MSB
Start
Bit
LSB
Ready
Busy
Ready
ss_0_n
ssi_oe_n
After the first data word has been transmitted to the serial-slave device, the DW_apb_ssi master polls the rxd input
waiting for a ready status from the slave device. Upon reception of the ready status, the DW_apb_ssi master begins
transmission of the next control word. After transmission of the last data frame has completed, the DW_apb_ssi master
transmits a start bit to clear the ready status of the slave device before completing the transfer. The FIFO status for this
transfer is the same as in Figure 143, except that the MWHS bit field is set (1).
To transmit a control word (not followed by data) to a serial-slave device from the DW_apb_ssi master, there must be
only one entry in the transmit FIFO buffer. It is impossible to transmit two control words in a continuous transfer, as the
shift logic in the DW_apb_ssi treats the second control word as a data word. When the DW_apb_ssi master transmits
only a control word, the MDD bit field (bit 1 of MWCR register) must be set (1).
In the example shown in Figure 145 and in the timing diagram in Figure 146, the handshaking interface is enabled. If the
handshaking interface is disabled (MHS=0), the transfer is terminated by the DW_apb_ssi master one sclk_out cycle
after the LSB of the control word is captured by the slave device.
Figure 145. FIFO
Status for Microwire
MWHS
MWCR
1
MDD MWMOD
1
0
Control Word Transfer
rxd
Write DR
Tx FIFO Empty
Tx FIFO Buffer
Location n
NULL
Location 3
NULL
Location 2
Location 1
Location 0
Location n
NULL
NULL
Location 3
NULL
NULL
Location 2
NULL
Ctrl Word(0)
Location 1
NULL
Location 0
NULL
SHIFT LOGIC
Rx FIFO Buffer
Rx FIFO Empty
FIFO Status Prior to
Transfer
4.10. SSI
txd
FIFO Status on
Completion of Transfer
588
RP2040 Datasheet
Figure 146. Microwire
Control Word
sclk_out
Control Word 0
txd
MSB
LSB
rxd
Start Bit
Busy
Ready
ss_0_n
ssi_oe_n
4.10.10.4. Enhanced SPI Modes
DW_apb_ssi supports the dual and quad modes of SPI in RP2040; octal mode is not supported. txd, rxd and ssi_oe_n
signals are four bits wide.
Data is shifted out/in on more than one line, increasing the overall throughput. All four combinations of the serial clock’s
polarity and phase are valid in this mode and work the same as in normal SPI mode. Dual SPI, or Quad SPI modes
function similarly except for the width of txd, rxd and ssi_oe_n signals. The mode of operation (write/read) can be
selected using the CTRLR0.TMOD field.
4.10.10.4.1. Write Operation in Enhanced SPI Modes
Dual, or Quad, SPI write operations can be divided into three parts:
• Instruction phase
• Address phase
• Data phase
The following register fields are used for a write operation:
• CTRLR0.SPI_FRF - Specifies the format in which the transmission happens for the frame.
• SPI_CTRLR0 (Control Register 0 register) – Specifies length of instruction, address, and data.
• SPI_CTRLR0.INST_L – Specifies length of an instruction (possible values for an instruction are 0, 4, 8, or 16 bits.)
• SPI_CTRLR0.ADDR_L – Specifies address length (See Table 578 for decode values)
• CTRLR0.DFS or CTRLR0.DFS_32 – Specifies data length.
An instruction takes one FIFO location. An address can take more than one FIFO locations.
Both the instruction and address must be programmed in the data register (DR). DW_apb_ssi will wait until both have
been programmed to start the write operation.
The instruction, address and data can be programmed to send in dual/quad mode, which can be selected from the
SPI_CTRLR0.TRANS_TYPE and CTRLR0.SPI_FRF fields.
NOTE
• If CTRLR0.SPI_FRF is selected to be "Standard SPI Format", everything is sent in Standard SPI mode and
SPI_CTRLR0.TRANS_TYPE field is ignored.
• CTRLR0.SPI_FRF is only applicable if CTRLR0.FRF is programmed to 00b.
Figure 147 shows a typical write operation in Dual, or Quad, SPI Mode. The value of N will be: 7 if SSI_SPI_MODE is set
to 3, 3 if SSI_SPI_MODE is set to 2, and 1 if SSI_SPI_MODE is set to 1. For 1-write operation, the instruction and address
are sent only once followed by data frames programmed in DR until the transmit FIFO becomes empty.
4.10. SSI
589
RP2040 Datasheet
Figure 147. Typical
Write Operation
Dual/Quad SPI Mode
sclk_out
txd[N:0]
INSTRUCTION
ADDRESS
DATA
ssi_oe_n[N:0]
ss_oe_n
To initiate a Dual/Quad write operation, CTRLR0.SPI_FRF must be set to 01/10/11, respectively. This will set the transfer
type, and for each write command, data will be transferred in the format specified in CTLR0.SPI_FRF field.
Case A: Instruction and address both transmitted in standard SPI format
For this, SPI_CTRLR0.TRANS_TYPE field must be set to 00b. Figure 148 show the timing diagram when both
instruction and address are transmitted in standard SPI format. The value of N will be: 7 if CTRLR0.SPI_FRF is set to
11b, 3 if CTRLR0.SPI_FRF is set to 10b, and 1 if CTRLR0.SPI_FRF is set to 01b.
Figure 148. Instruction
and Address
Transmitted in
Standard SPI Format
sclk_out
txd[0]
INSTRUCTION
ADDRESS
DATA
DATA
txd[N-1:0]
ss_oe_n[0]
ss_oe_n[N-1:0]
ss_oe_n
Case B: Instruction transmitted in standard and address transmitted in Enhanced SPI format
For this, SPI_CTRLR0.TRANS_TYPE field must be set to one. Figure 149 shows the timing diagram when an
instruction is transmitted in standard format and address is transmitted in dual SPI format specified in the
CTRLR0.SPI_FRF field. The value of N will be: 7 if CTRLR0.SPI_FRF is set to 11b, 3 if CTRLR0.SPI_FRF is set to 10b,
and 1 if CTRLR0.SPI_FRF is set to 01b.
Figure 149. Instruction
Transmitted in
Standard and Address
Transmitted in
Enhanced SPI Format
sclk_out
txd[0]
INSTRUCTION
txd[N-1:0]
ADDRESS
DATA
ADDRESS
DATA
ss_oe_n[0]
ss_oe_n[N-1:0]
ss_oe_n
Case C: Instruction and Address both transmitted in Enhanced SPI format
For this, SPI_CTRLR0.TRANS_TYPE field must be set to 10b. Figure 150 shows the timing diagram in which
instruction and address are transmitted in SPI format specified in the CTRLR0.SPI_FRF field. The value of N will be:
7 if CTRLR0.SPI_FRF is set to 11b, 3 if CTRLR0.SPI_FRF is set to 10b, and 1 if CTRLR0.SPI_FRF is set to 01b.
Figure 150. Instruction
and Address Both
Transmitted in
Enhanced SPI Format
sclk_out
txd[N:0]
INSTRUCTION
ADDRESS
DATA
ssi_oe_n[N:0]
ss_0_n
Case D: Instruction only transfer in enhanced SPI format
For this, SPI_CTRLR0.TRANS_TYPE field must be set to 10b. Figure 151 shows the timing diagram for such a
transfer. The value of N will be: 7 if CTRLR0.SPI_FRF is set to 11b, 3 if CTRLR0.SPI_FRF is set to 10b, and 1 if
CTRLR0.SPI_FRF is set to 01b.
Figure 151. Instruction
only transfer in
enhanced SPI Format
sclk_out
txd[N:0]
INSTRUCTION
ssi_oe_n[N:0]
ss_0_n
4.10. SSI
590
RP2040 Datasheet
4.10.10.4.2. Read Operation in Enhanced SPI Modes
A Dual, or Quad, SPI read operation can be divided into four phases:
• Instruction phase
• Address phase
• Wait cycles
• Data phase
Wait
Cycles
can
be
programmed
using
SPI_CTRLR0.WAIT_CYCLES
field.
The
value
programmed
into
SPI_CTRLR0.WAIT_CYCLES is mapped directly to sclk_out times. For example, WAIT_CYCLES=0 indicates no Wait,
WAIT_CYCLES=1, indicates one wait cycle and so on. The wait cycles are introduced for target slave to change their
mode from input to output and the wait cycles can vary for different devices.
For a READ operation, DW_apb_ssi sends instruction and control data once and waits until it receives NDF (CTRLR1
register) number of data frames and then de-asserts slave select signal.
Figure 152 shows a typical read operation in dual quad SPI mode. The value of N will be: 3 if SSI_SPI_MODE is set to
Quad mode, and 1 if SSI_SPI_MODE is set to Dual mode.
Figure 152. Typical
sclk_out
Read Operation in
txd[N:0]
Enhanced SPI Mode
rxd[N:0]
INSTRUCTION
ADDRESS
WAIT CYCLES
DATA
ss_oe_n[N:0]
ss_oe_n
To initiate a dual/quad read operation, CTRLR0.SPI_FRF must be set to 01/10/11 respectively. This will set the transfer
type, now for each read command data will be transferred in the format specified in CTLR0.SPI_FRF field.
Following are the possible cases of write operation in enhanced SPI modes:
Case A: Instruction and address both transmitted in standard SPI format
For this, SPI_CTRLR0.TRANS_TYPE field should be set to 00b. Figure 153 shows the timing diagram when both
instruction and address are transferred in standard SPI format. The figure also shows WAIT cycles after address,
which can be programmed in the SPI_CTRLR0.WAIT_CYCLES field. The value of N will be 7 if CTRLR0.SPI_FRF is set
to 11b, 3 if CTRLR0.SPI_FRF is set to 10b, and 1 if CTRLR0.SPI_FRF is set to 01b.
Figure 153. Instruction
and Address
Transmitted in
Standard SPI Format
sclk_out
txd[0]
INSTRUCTION
ADDRESS
WAIT CYCLES
txd[N-1:0]
DATA
rxd[N:0]
ssi_oe_n[0]
ssi_oe_n[N-1:0]
ss_0_n
Case B: Instruction transmitted in standard and address transmitted in dual SPI format
For this, SPI_CTRLR0.TRANS_TYPE field should be set to 01b. Figure 154 shows the timing diagram in which
instruction is transmitted in standard format and address is transmitted in dual SPI format. The value of N will be 7
if CTRLR0.SPI_FRF is set to 11b, 3 if CTRLR0.SPI_FRF is set to 10b, and 1 if CTRLR0.SPI_FRF is set to 01b.
Figure 154. Instruction
Transmitted in
Standard and Address
Transmitted in
Enhanced SPI Format
sclk_out
txd[0]
txd[N-1:0]
rxd[N:0]
INSTRUCTION
ADDRESS
ADDRESS
DATA
ssi_oe_n[0]
ssi_oe_n[N-1:0]
ss_0_n
4.10. SSI
591
RP2040 Datasheet
Case C: Instruction and Address both transmitted in Dual SPI format
For this, SPI_CTRLR0.TRANS_TYPE field must be set to 10b. Figure 155 shows the timing diagram in which both
instruction and address are transmitted in dual SPI format. The value of N will be: 7 if CTRLR0.SPI_FRF is set to 11b,
3 if CTRLR0.SPI_FRF is set to 10b, and 1 if CTRLR0.SPI_FRF is set to 01b.
Figure 155. Instruction
sclk_out
and Address
INSTRUCTION
txd[N:0]
Transmitted in
ADDRESS
DATA
rxd[N:0]
Enhanced SPI Format
ssi_oe_n[N:0]
ss_0_n
Case D: No Instruction, No Address READ transfer
For this, SPI_CTRLR0.ADDR_L and SPI_CTRLR0.INST_L must be set to 0 and SPI_CTRLR0.WAIT_CYCLES must be
set to a non-zero value. Table 578 lists the ADDR_L decode value and the respective description for enhanced
(Dual/Quad) SPI modes.
Table 578. ADDR_L
Decode in Enhanced
SPI Mode
ADDR_L
Description
Decode Value
0000
0-bit Address Width
0001
4-bit Address Width
0010
8-bit Address Width
0011
12-bit Address Width
0100
16-bit Address Width
0101
20-bit Address Width
0110
24-bit Address Width
0111
28-bit Address Width
1000
32-bit Address Width
1001
36-bit Address Width
1010
40-bit Address Width
1011
44-bit Address Width
1100
48-bit Address Width
1101
52-bit Address Width
1110
56-bit Address Width
1111
60-bit Address Width
Figure 156 shows the timing diagram for such type of transfer. The value of N will be: 7 if CTRLR0.SPI_FRF is set to 11b,
3 if CTRLR0.SPI_FRF is set to 10b, and 1 if CTRLR0.SPI_FRF is set to 01b. To initiate this transfer, the software has to
perform a dummy write in the data register (DR), DW_apb_ssi will wait for programmed wait cycles and then fetch the
amount of data specified in NDF field.
Figure 156. No
Instruction and No
Address READ
Transfer
sclk_out
txd[N:0]
rxd[N:0]
WAIT CYCLES
DATA
ssi_oe_n[N:0]
ss_0_n
4.10. SSI
592
RP2040 Datasheet
4.10.10.4.3. Advanced I/O Mapping for Enhanced SPI Modes
The Input/Output mapping for enhanced SPI modes (dual, and quad) is hardcoded inside the DW_apb_ssi. The rxd[1]
signal will be used to sample incoming data in standard SPI mode of operation.
For other protocols (such as SSP and Microwire), the I/O mapping remains the same. Therefore, it is easy for other
protocols to connect with any device that supports Dual/Quad SPI operation because other protocols do not require a
MUX logic to exist outside the design.
Figure 157 shows the I/O mapping of DW_apb_ssi in Quad mode with another SPI device that supports the Quad mode.
As illustrated in Figure 157, the IO[1] pin is used as DO in standard SPI mode of operation and it is connected to rxd[1]
pin, which will be sampling the input in the standard mode of operation.
Figure 157. Advanced
I/O Mapping in Quad
SPI Modes
txd[3]
IO Buffer
IO[3]
IO Buffer
IO[2]
IO Buffer
IO[1]/DO
IO Buffer
IO[0]/DI
rxd[3]
txd[2]
rxd[2]
txd[1]
rxd[1]
txd[0]
rxd[0]
DW_apb_ssi
SPI slave Device
4.10.10.5. Dual Data-Rate (DDR) Support in SPI Operation
In standard operations, data transfer in SPI modes occur on either the positive or negative edge of the clock. For
improved throughput, the dual data-rate transfer can be used for reading or writing to the memories.
The DDR mode supports the following modes of SPI protocol:
• SCPH=0 & SCPOL=0 (Mode 0)
• SCPH=1 & SCPOL=1 (Mode 3)
DDR commands enable data to be transferred on both edges of clock. Following are the different types of DDR
commands:
• Address and data are transmitted (or received in case of data) in DDR format, while instruction is transmitted in
standard format.
• Instruction, address, and data are all transmitted or received in DDR format.
The DDR_EN (SPI_CTRLR0[16]) bit is used to determine if the Address and data have to be transferred in DDR mode and
INST_DDR_EN (SPI_CTRLR0[17]) bit is used to determine if Instruction must be transferred in DDR format. These bits
are only valid when the CTRLR0.SPI_FRF bit is set to be in Dual, or Quad mode.
Figure 158 describes a DDR write transfer where instructions are continued to be transmitted in standard format. In
Figure 158, the value of N will be 7 if CTRLR0.SPI_FRF is set to 11b, 3 if CTRLR0.SPI_FRF is set to 10b , and 1 if
CTRLR0.SPI_FRF is set to 01b.
4.10. SSI
593
RP2040 Datasheet
Figure 158. DDR
Transfer with SCPH=0
sclk_out
and SCPOL=0
ss_oe_n
A3
INST
txd[N:0]
A2
A1
A0
D3
D2
D1
D0
rxd[N:0]
ss_oe_n[N:0]
INST = Instruction Phase
A3, A2, A1, A0 = Address Bytes
D3, D2, D1, D0 = Data Bytes
Figure 159 describes a DDR write transfer where instruction, address and data all are transferred in DDR format.
Figure 159. DDR
Transfer with
Instruction, Address
and Data Transmitted
in DDR Format
sclk_out
ss_0_n
txd[N:0]
INST-1
INST-2
A3
A2
A1
A0
D3
D2
D1
D0
rxd[N:0]
ssi_oe_n[N:0]
INST-1, INST-2 = Instruction Bytes
A3, A2, A1, A0 = Address Bytes
D3, D2, D1, D0 = Data Bytes
NOTE
In the DDR transfer, address and instruction cannot be programmed to a value of 0.
4.10.10.5.1. Transmitting Data in DDR Mode
In DDR mode, data is transmitted on both edges so that it is difficult to sample data correctly. DW_apb_ssi uses an
internal register to determine the edge on which the data should be transmitted. This will ensure that the receiver is able
to get a stable data while sampling. The internal register (DDR_DRIVE_EDGE) determines the edge on which the data is
transmitted. DW_apb_ssi sends data with respect to baud clock, which is an integral multiple of the internal clock
(ssi_clk * BAUDR). The data needs to be transmitted within half clock cycle (BAUDR/2), therefore the maximum value
for DDR_DRIVE_EDGE is equal to [(BAUDR/2)-1]. If the programmed value of DDR_DRIVE_EDGE is 0 then data is
transmitted edge-aligned with respect to sclk_out (baud clock). If the programmed value of DDR_DRIVE_EDGE is one
then the data is transmitted one ssi_clk before the edge of sclk_out.
NOTE
If the baud rate is programmed to be two, then the data will always be edge aligned.
Figure 160, Figure 161, and Figure 162 show examples of how data is transmitted using different values of the
DDR_DRIVE_EDGE register. The green arrows in these examples represent the points where data is driven. Baud rate
used in all these examples is 12. In Figure 160, transmit edge and driving edge of the data are the same. This is default
behavior in DDR mode.
Figure 160. Transmit
Data With
DDR_DRIVE_EDGE = 0
ssi_clk
sclk_out
ss_0_n
txd[N:0]
INST
A3
A2
A1
A0
D3
D2
D1
D0
rxd[N:0]
ssi_oe_n[N:0]
INST = Instruction Phase
A3, A2, A1, A0 = Address Bytes
D3, D2, D1, D0 = Data Bytes
Figure 160 shows the default behavior in which the transmit and driving edge of the data is the same.
4.10. SSI
594
RP2040 Datasheet
Figure 161. Transmit
Data With
DDR_DRIVE_EDGE = 1
ssi_clk
sclk_out
ss_0_n
txd[N:0]
INST
A3
A2
A1
A0
D3
D2
D1
D0
rxd[N:0]
ssi_oe_n[N:0]
INST = Instruction Phase
A3, A2, A1, A0 = Address Bytes
D3, D2, D1, D0 = Data Bytes
Figure 162. Transmit
Data With
DDR_DRIVE_EDGE = 2
ssi_clk
sclk_out
ss_0_n
txd[N:0]
INST
A3
A2
A1
A0
D3
D2
D1
D0
rxd[N:0]
ssi_oe_n[N:0]
INST = Instruction Phase
A3, A2, A1, A0 = Address Bytes
D3, D2, D1, D0 = Data Bytes
4.10.10.6. XIP Mode Support in SPI Mode
The eXecute In Place (XIP) mode enables transfer of SPI data directly through the APB interface without writing the data
register of DW_apb_ssi. XIP mode is enabled in DW_apb_ssi when the XIP cache is enabled. This control signal
indicates whether APB transfers are register read-write or XIP reads. When in XIP mode, DW_apb_ssi expects only read
request on the APB interface. This request is translated to SPI read on the serial interface and soon after the data is
received, the data is returned to the APB interface in the same transaction.
NOTE
• Only APB reads are supported during an XIP operation
The address length is derived from the SPI_CTRLR0.ADDR_L field, and relevant bits from paddr ([SPI_CTRLR0.ADDR_L1:0]) are transferred as address to the SPI interface. XIP address is managed by the XIP cache controller.
4.10.10.6.1. Read Operation in XIP Mode
The XIP operation is supported only in enhanced SPI modes (Dual, Quad) of operation. Therefore, the CTRLR0.SPI_FRF
bit should not be programmed to 0. An XIP read operation is divided into two phases:
• Address phase
• Data phase
For an XIP read operation
1. Set the SPI frame format and data frame size value in CTRLR0 register. Note that the value of the maximum data
frame size is 32.
2. Set the Address length, Wait cycles, and transaction type in the SPI_CTRLR0 register. Note that the maximum
address length is 32.
After these settings, a user can initiate a read transaction through the APB interface which will transferred to SPI
peripheral using programmed values. Figure 163 shows the typical XIP transfer. The Value of N = 1, 3 and 7 for SPI
mode Dual, and Quad modes, respectively.
4.10. SSI
595
RP2040 Datasheet
Figure 163. Typical
Read Operation in XIP
Mode
4.10.11. DMA Controller Interface
The DW_apb_ssi has built-in DMA capability; it has a handshaking interface to a DMA Controller to request and control
transfers. The APB bus is used to perform the data transfer to or from the DMA.
NOTE
When the DW_apb_ssi interfaces to the DMA controller, the DMA controller is always a flow controller; that is, it
controls the block size. This must be programmed by software in the DMA controller.
The DW_apb_ssi uses two DMA channels, one for the transmit data and one for the receive data. The DW_apb_ssi has
these DMA registers:
DMACR
Control register to enable DMA operation.
DMATDLR
Register to set the transmit the FIFO level at which a DMA request is made.
DMARDLR
Register to set the receive FIFO level at which a DMA request is made.
The DW_apb_ssi uses the following handshaking signals to interface with the DMA controller.
• dma_tx_req
• dma_tx_single
• dma_tx_ack
• dma_rx_req
• dma_tx_req
• dma_tx_single
• dma_tx_ack
• dma_rx_req
To enable the DMA Controller interface on the DW_apb_ssi, you must write the DMA Control Register (DMACR). Writing
a 1 into the TDMAE bit field of DMACR register enables the DW_apb_ssi transmit handshaking interface. Writing a 1 into
the RDMAE bit field of the DMACR register enables the DW_apb_ssi receive handshaking interface.
Table 579 provides description for different DMA transmit data level values.
Table 579. DMA
Transmit Data Level
(DMATDL) Decode
Value
4.10. SSI
DMATDL Value Description
0000_0000
dma_tx_req is asserted when zero data entries are present in the transmit FIFO
0000_0001
dma_tx_req is asserted when one or less data entry is present in the transmit FIFO
596
RP2040 Datasheet
0000_0010
dma_tx_req is asserted when two or less data entries are present in the transmit FIFO
…
…
0000_1101
dma_tx_req is asserted when 13 or less data entries are present in the transmit FIFO
0000_1110
dma_tx_req is asserted when 14 or less data entries are present in the transmit FIFO
0000_1111
dma_tx_req is asserted when 15 or less data entries are present in the transmit FIFO
Table 580 provides description for different DMA Receive Data Level values.
Table 580. DMA
Receive Data Level
(DMARDL) Decode
Value
DMARDL Value Description
0000_0000
dma_rx_req is asserted when one or more data entries are present in the receive FIFO
0000_0001
dma_rx_req is asserted when two or more data entries are present in the receive FIFO
0000_0010
dma_rx_req is asserted when three or more data entries are present in the receive FIFO
…
…
0000_1101
dma_rx_req is asserted when 14 or more data entries are present in the receive FIFO
0000_1110
dma_rx_req is asserted when 15 or more data entries are present in the receive FIFO
0000_1111
dma_rx_req is asserted when 16 data entries are present in the receive FIFO
4.10.11.1. Overview of Operation
As a block flow control device, the DMA Controller is programmed by the processor with the number of data items
(block size) that are to be transmitted or received by the DW_apb_ssi.
The block is broken into a number of transactions, each initiated by a request from the DW_apb_ssi. The DMA Controller
must also be programmed with the number of data items (in this case, DW_apb_ssi FIFO entries) to be transferred for
each DMA request. This is also known as the burst transaction length.
Figure 164 shows a single block transfer, where the block size programmed into the DMA Controller is 12 and the burst
transaction length is set to four. In this case, the block size is a multiple of the burst transaction length; therefore, the
DMA block transfer consists of a series of burst transactions.
CAUTION
On RP2040, the burst transaction length of the SSI’s DMA interface is fixed at four transfers. SSI.DMARDLR must always
be equal to 4, which is the value it takes at reset. The SSI will then request a single transfer when it has between one
and three items in its FIFO, and a 4-burst when it has four or more.
4.10. SSI
597
RP2040 Datasheet
Figure 164.
12 Data Items
Breakdown of DMA
Transfer into Burst
Transactions. Block
DMA
size,
DMA.CTLx.BLOCKS
Multi-block Transfer
_TS = 12. Number of
Level
data items per source
burst transaction,
12 Data Items
DMA.CTLx.SRC_MS
IZE = 4. SSI receive
DMA
FIFO watermark level,
SSI.DMARDLR + 1 =
Block
DMA.CTLx.SRC_MS
Level
IZE = 4
DMA Burst
DMA Burst
DMA Burst
Transaction 1
Transaction 2
Transaction 3
4 Data Items
4 Data Items
4 Data Items
If the DW_apb_ssi makes a transmit request to this channel, four data items are written to the DW_apb_ssi transmit
FIFO. Similarly, if the DW_apb_ssi makes a receive request to this channel, four data items are read from the
DW_apb_ssi receive FIFO. Three separate requests must be made to this DMA channel before all 12 data items are
written or read.
When the block size programmed into the DMA Controller is not a multiple of the burst transaction length, as shown in
Figure 165, a series of burst transactions followed by single transactions are needed to complete the block transfer.
Figure 165.
15 Data Items
Breakdown of DMA
DMA
Transfer into Single
Multi-block Transfer
and Burst
Level
Transactions. Block
size,
15 Data Items
DMA.CTLx.BLOCK_
DMA
TS = 15. Number of
Block
data items per burst
Level
transaction,
DMA.CTLx.DEST_M
SIZE = 4. SSI
DMA Burst
DMA Burst
DMA Burst
DMA Single
DMA Single
DMA Single
transmit FIFO
Transaction 1
Transaction 2
Transaction 3
Transaction 1
Transaction 2
Transaction 3
4 Data Items
4 Data Items
4 Data Items
1 Data Items
1 Data Items
1 Data Items
watermark level,
SSI.DMATDLR =
DMA.CTLx.DEST_M
SIZE = 4
4.10.12. APB Interface
The host processor accesses data, control, and status information on the DW_apb_ssi through the APB interface. APB
accesses to the DW_apb_ssi peripheral are described in the following subsections.
4.10.12.1. Control and Status Register APB Access
Control and status registers within the DW_apb_ssi are byte-addressable. The maximum width of the control or status
register in the DW_apb_ssi is 16 bits. Therefore all read and write operations to the DW_apb_ssi control and status
registers require only one APB access.
4.10.12.2. Data Register APB Access
The data register (DR) within the DW_apb_ssi is 32 bits wide in order to remain consistent with the maximum serial
transfer size (data frame). An APB write operation to DR moves data from pwdata into the transmit FIFO buffer. An APB
4.10. SSI
598
RP2040 Datasheet
read operation from DR moves data from the receive FIFO buffer onto prdata.
The DW_apb_ssi DR can be written/read in one APB access.
NOTE
The DR register in the DW_apb_ssi occupies sixty-four 32-bit locations of the memory map to facilitate AHB burst
transfers. There are no burst transactions on the APB bus itself, but DW_apb_ssi supports the AHB bursts that
happen on the AHB side of the AHB/APB bridge. Writing to any of these address locations has the same effect as
pushing the data from the pwdata bus into the transmit FIFO. Reading from any of these locations has the same
effect as popping data from the receive FIFO onto the prdata bus. The FIFO buffers on the DW_apb_ssi are not
addressable.
4.10.13. List of Registers
The SSI registers start at a base address of 0x18000000 (defined as XIP_SSI_BASE in SDK).
Table 581. List of SSI
registers
4.10. SSI
Offset
Name
Info
0x00
CTRLR0
Control register 0
0x04
CTRLR1
Master Control register 1
0x08
SSIENR
SSI Enable
0x0c
MWCR
Microwire Control
0x10
SER
Slave enable
0x14
BAUDR
Baud rate
0x18
TXFTLR
TX FIFO threshold level
0x1c
RXFTLR
RX FIFO threshold level
0x20
TXFLR
TX FIFO level
0x24
RXFLR
RX FIFO level
0x28
SR
Status register
0x2c
IMR
Interrupt mask
0x30
ISR
Interrupt status
0x34
RISR
Raw interrupt status
0x38
TXOICR
TX FIFO overflow interrupt clear
0x3c
RXOICR
RX FIFO overflow interrupt clear
0x40
RXUICR
RX FIFO underflow interrupt clear
0x44
MSTICR
Multi-master interrupt clear
0x48
ICR
Interrupt clear
0x4c
DMACR
DMA control
0x50
DMATDLR
DMA TX data level
0x54
DMARDLR
DMA RX data level
0x58
IDR
Identification register
0x5c
SSI_VERSION_ID
Version ID
599
RP2040 Datasheet
Offset
Name
Info
0x60
DR0
Data Register 0 (of 36)
0xf0
RX_SAMPLE_DLY
RX sample delay
0xf4
SPI_CTRLR0
SPI control
0xf8
TXD_DRIVE_EDGE
TX drive edge
SSI: CTRLR0 Register
Offset: 0x00
Description
Control register 0
Table 582. CTRLR0
Register
Bits
Name
Description
Type
Reset
31:25
Reserved.
-
-
-
24
SSTE
Slave select toggle enable
RW
0x0
23
Reserved.
-
-
-
22:21
SPI_FRF
SPI frame format
RW
0x0
RW
0x00
RW
0x0
0x0 → Standard 1-bit SPI frame format; 1 bit per SCK, fullduplex
0x1 → Dual-SPI frame format; two bits per SCK, halfduplex
0x2 → Quad-SPI frame format; four bits per SCK, halfduplex
20:16
DFS_32
Data frame size in 32b transfer mode
Value of n → n+1 clocks per frame.
15:12
CFS
Control frame size
Value of n → n+1 clocks per frame.
11
SRL
Shift register loop (test mode)
RW
0x0
10
SLV_OE
Slave output enable
RW
0x0
9:8
TMOD
Transfer mode
RW
0x0
0x0 → Both transmit and receive
0x1 → Transmit only (not for FRF == 0, standard SPI
mode)
0x2 → Receive only (not for FRF == 0, standard SPI mode)
0x3 → EEPROM read mode (TX then RX; RX starts after
control data TX’d)
7
SCPOL
Serial clock polarity
RW
0x0
6
SCPH
Serial clock phase
RW
0x0
5:4
FRF
Frame format
RW
0x0
3:0
DFS
Data frame size
RW
0x0
SSI: CTRLR1 Register
Offset: 0x04
4.10. SSI
600
RP2040 Datasheet
Description
Master Control register 1
Table 583. CTRLR1
Register
Bits
Name
Description
Type
Reset
31:16
Reserved.
-
-
-
15:0
NDF
Number of data frames
RW
0x0000
SSI: SSIENR Register
Offset: 0x08
Description
SSI Enable
Table 584. SSIENR
Register
Bits
Name
Description
Type
Reset
31:1
Reserved.
-
-
-
0
SSI_EN
SSI enable
RW
0x0
SSI: MWCR Register
Offset: 0x0c
Description
Microwire Control
Table 585. MWCR
Register
Bits
Name
Description
Type
Reset
31:3
Reserved.
-
-
-
2
MHS
Microwire handshaking
RW
0x0
1
MDD
Microwire control
RW
0x0
0
MWMOD
Microwire transfer mode
RW
0x0
SSI: SER Register
Offset: 0x10
Description
Slave enable
Table 586. SER
Register
Bits
Description
Type
Reset
31:1
Reserved.
-
-
0
For each bit:
RW
0x0
0 → slave not selected
1 → slave selected
SSI: BAUDR Register
Offset: 0x14
Description
Baud rate
4.10. SSI
601
RP2040 Datasheet
Table 587. BAUDR
Register
Bits
Name
Description
Type
Reset
31:16
Reserved.
-
-
-
15:0
SCKDV
SSI clock divider
RW
0x0000
SSI: TXFTLR Register
Offset: 0x18
Description
TX FIFO threshold level
Table 588. TXFTLR
Register
Bits
Name
Description
Type
Reset
31:8
Reserved.
-
-
-
7:0
TFT
Transmit FIFO threshold
RW
0x00
SSI: RXFTLR Register
Offset: 0x1c
Description
RX FIFO threshold level
Table 589. RXFTLR
Register
Bits
Name
Description
Type
Reset
31:8
Reserved.
-
-
-
7:0
RFT
Receive FIFO threshold
RW
0x00
SSI: TXFLR Register
Offset: 0x20
Description
TX FIFO level
Table 590. TXFLR
Register
Bits
Name
Description
Type
Reset
31:8
Reserved.
-
-
-
7:0
TFTFL
Transmit FIFO level
RO
0x00
SSI: RXFLR Register
Offset: 0x24
Description
RX FIFO level
Table 591. RXFLR
Register
Bits
Name
Description
Type
Reset
31:8
Reserved.
-
-
-
7:0
RXTFL
Receive FIFO level
RO
0x00
SSI: SR Register
Offset: 0x28
4.10. SSI
602
RP2040 Datasheet
Description
Status register
Table 592. SR Register
Bits
Name
Description
Type
Reset
31:7
Reserved.
-
-
-
6
DCOL
Data collision error
RO
0x0
5
TXE
Transmission error
RO
0x0
4
RFF
Receive FIFO full
RO
0x0
3
RFNE
Receive FIFO not empty
RO
0x0
2
TFE
Transmit FIFO empty
RO
0x0
1
TFNF
Transmit FIFO not full
RO
0x0
0
BUSY
SSI busy flag
RO
0x0
SSI: IMR Register
Offset: 0x2c
Description
Interrupt mask
Table 593. IMR
Register
Bits
Name
Description
Type
Reset
31:6
Reserved.
-
-
-
5
MSTIM
Multi-master contention interrupt mask
RW
0x0
4
RXFIM
Receive FIFO full interrupt mask
RW
0x0
3
RXOIM
Receive FIFO overflow interrupt mask
RW
0x0
2
RXUIM
Receive FIFO underflow interrupt mask
RW
0x0
1
TXOIM
Transmit FIFO overflow interrupt mask
RW
0x0
0
TXEIM
Transmit FIFO empty interrupt mask
RW
0x0
SSI: ISR Register
Offset: 0x30
Description
Interrupt status
Table 594. ISR
Register
4.10. SSI
Bits
Name
Description
Type
Reset
31:6
Reserved.
-
-
-
5
MSTIS
Multi-master contention interrupt status
RO
0x0
4
RXFIS
Receive FIFO full interrupt status
RO
0x0
3
RXOIS
Receive FIFO overflow interrupt status
RO
0x0
2
RXUIS
Receive FIFO underflow interrupt status
RO
0x0
1
TXOIS
Transmit FIFO overflow interrupt status
RO
0x0
0
TXEIS
Transmit FIFO empty interrupt status
RO
0x0
603
RP2040 Datasheet
SSI: RISR Register
Offset: 0x34
Description
Raw interrupt status
Table 595. RISR
Register
Bits
Name
Description
Type
Reset
31:6
Reserved.
-
-
-
5
MSTIR
Multi-master contention raw interrupt status
RO
0x0
4
RXFIR
Receive FIFO full raw interrupt status
RO
0x0
3
RXOIR
Receive FIFO overflow raw interrupt status
RO
0x0
2
RXUIR
Receive FIFO underflow raw interrupt status
RO
0x0
1
TXOIR
Transmit FIFO overflow raw interrupt status
RO
0x0
0
TXEIR
Transmit FIFO empty raw interrupt status
RO
0x0
SSI: TXOICR Register
Offset: 0x38
Description
TX FIFO overflow interrupt clear
Table 596. TXOICR
Register
Bits
Description
Type
Reset
31:1
Reserved.
-
-
0
Clear-on-read transmit FIFO overflow interrupt
RO
0x0
SSI: RXOICR Register
Offset: 0x3c
Description
RX FIFO overflow interrupt clear
Table 597. RXOICR
Register
Bits
Description
Type
Reset
31:1
Reserved.
-
-
0
Clear-on-read receive FIFO overflow interrupt
RO
0x0
SSI: RXUICR Register
Offset: 0x40
Description
RX FIFO underflow interrupt clear
4.10. SSI
604
RP2040 Datasheet
Table 598. RXUICR
Register
Bits
Description
Type
Reset
31:1
Reserved.
-
-
0
Clear-on-read receive FIFO underflow interrupt
RO
0x0
SSI: MSTICR Register
Offset: 0x44
Description
Multi-master interrupt clear
Table 599. MSTICR
Register
Bits
Description
Type
Reset
31:1
Reserved.
-
-
0
Clear-on-read multi-master contention interrupt
RO
0x0
SSI: ICR Register
Offset: 0x48
Description
Interrupt clear
Table 600. ICR
Register
Bits
Description
Type
Reset
31:1
Reserved.
-
-
0
Clear-on-read all active interrupts
RO
0x0
SSI: DMACR Register
Offset: 0x4c
Description
DMA control
Table 601. DMACR
Register
Bits
Name
Description
Type
Reset
31:2
Reserved.
-
-
-
1
TDMAE
Transmit DMA enable
RW
0x0
0
RDMAE
Receive DMA enable
RW
0x0
SSI: DMATDLR Register
Offset: 0x50
Description
DMA TX data level
Table 602. DMATDLR
Register
Bits
Name
Description
Type
Reset
31:8
Reserved.
-
-
-
7:0
DMATDL
Transmit data watermark level
RW
0x00
SSI: DMARDLR Register
Offset: 0x54
4.10. SSI
605
RP2040 Datasheet
Description
DMA RX data level
Table 603. DMARDLR
Register
Bits
Name
Description
Type
Reset
31:8
Reserved.
-
-
-
7:0
DMARDL
Receive data watermark level (DMARDLR+1)
RW
0x00
SSI: IDR Register
Offset: 0x58
Description
Identification register
Table 604. IDR
Register
Bits
Name
Description
Type
Reset
31:0
IDCODE
Peripheral dentification code
RO
0x51535049
Type
Reset
RO
0x3430312a
SSI: SSI_VERSION_ID Register
Offset: 0x5c
Description
Version ID
Table 605.
SSI_VERSION_ID
Register
Bits
Name
Description
31:0
SSI_COMP_VERSI SNPS component version (format X.YY)
ON
SSI: DR0 Register
Offset: 0x60
Description
Data Register 0 (of 36)
Table 606. DR0
Register
Bits
Name
Description
Type
Reset
31:0
DR
First data register of 36
RW
0x00000000
SSI: RX_SAMPLE_DLY Register
Offset: 0xf0
Description
RX sample delay
Table 607.
RX_SAMPLE_DLY
Register
Bits
Name
Description
Type
Reset
31:8
Reserved.
-
-
-
7:0
RSD
RXD sample delay (in SCLK cycles)
RW
0x00
SSI: SPI_CTRLR0 Register
Offset: 0xf4
4.10. SSI
606
RP2040 Datasheet
Description
SPI control
Table 608.
SPI_CTRLR0 Register
Bits
Name
Description
Type
Reset
31:24
XIP_CMD
SPI Command to send in XIP mode (INST_L = 8-bit) or to
RW
0x03
append to Address (INST_L = 0-bit)
23:19
Reserved.
-
-
-
18
SPI_RXDS_EN
Read data strobe enable
RW
0x0
17
INST_DDR_EN
Instruction DDR transfer enable
RW
0x0
16
SPI_DDR_EN
SPI DDR transfer enable
RW
0x0
15:11
WAIT_CYCLES
Wait cycles between control frame transmit and data
RW
0x00
reception (in SCLK cycles)
10
Reserved.
-
-
-
9:8
INST_L
Instruction length (0/4/8/16b)
RW
0x0
0x0 → No instruction
0x1 → 4-bit instruction
0x2 → 8-bit instruction
0x3 → 16-bit instruction
7:6
Reserved.
-
-
-
5:2
ADDR_L
Address length (0b-60b in 4b increments)
RW
0x0
1:0
TRANS_TYPE
Address and instruction transfer format
RW
0x0
0x0 → Command and address both in standard SPI frame
format
0x1 → Command in standard SPI format, address in
format specified by FRF
0x2 → Command and address both in format specified by
FRF (e.g. Dual-SPI)
SSI: TXD_DRIVE_EDGE Register
Offset: 0xf8
Description
TX drive edge
Table 609.
TXD_DRIVE_EDGE
Register
4.10. SSI
Bits
Name
Description
Type
Reset
31:8
Reserved.
-
-
-
7:0
TDE
TXD drive edge
RW
0x00
607
RP2040 Datasheet
Chapter 5. Electrical and Mechanical
Physical and electrical details of the RP2040 chip.
5.1. Package
Figure 166. Top down
view (left, top) and
side view (right, top),
along with bottom
view (left, bottom) of
the RP2040 QFN-56
package
PIN 1
NOTE
There is no standard size for the central GND pad (or ePad) with QFNs. However, the one on RP2040 is smaller than
most. This means that standard 0.4mm QFN-56 footprints provided with CAD tools may need adjusting. This gives
the opportunity to route between the central pad and the ones on the periphery, which can help with maintaining
power and ground integrity on cheaper PCBs. See Minimal Design Example for an example.
5.1.1. Recommended PCB Footprint
5.1. Package
608
RP2040 Datasheet
Figure 167.
Recommended PCB
7.75
Footprint for the
6.00
RP2040 QFN-56
3.20
package
0.20
7.75
6.00
3.20
5.40
0.20
1.175
0.875
0.40
5.40
Dimensions in mm
5.2. Solder profile
RP2040 is a Pb-free part, with a Tp value of 260°C.
All temperatures refer to the center of the package, measured on the package body surface that is facing up during
assembly reflow (live-bug orientation). If parts are reflowed in other than the normal live-bug assembly reflow
orientation (i.e., dead-bug), Tp shall be within ±2°C of the live-bug Tp and still meet the Tc requirements; otherwise, the
profile shall be adjusted to achieve the latter.
5.2. Solder profile
609
RP2040 Datasheet
Figure 168.
Classification profile
Supplier T p ≥ Tc
(not to scale)
User T p ≤ Tc
Tc
Tc -5°C
Supplier t p
User t p
Tp
tp
Max. Ramp Up Rate = 3°C/s
Max. Ramp Down Rate = 6°C/s
Tc -5°C
TL
t
Temperature
Tsmax
Preheat Area
Tsmin
ts
25
Time 25°C to Peak
Time
NOTE
Reflow profiles in this document are for classification/preconditioning, and are not meant to specify board assembly
profiles. Actual board assembly profiles should be developed based on specific process needs and board designs,
and should not exceed the parameters in Table 610.
Table 610. Solder
profile values
Profile feature
Value
Temperature min (Tsmin)
150°C
Temperature max (Tsmax)
200°C
Time (ts) from (Tsmin to Tsmax)
60 — 120 seconds
Ramp-up rate (TL to Tp)
3°C/second max.
Liquidous temperature (TL)
217°C
Time (tL) maintained above TL
60 to 150 seconds
Peak package body temperature (Tp)
260°C
Classification temperature (Tc)
260°C
Time (tp) within 5°C of the specified classification temperature (Tc)
30 seconds
Ramp-down rate (Tp to TL)
6°C/second max.
Time 25°C to peak temperature
8 minutes max.
5.2. Solder profile
610
RP2040 Datasheet
5.2.1. Compliance
RP2040 is compliant to Moisture Sensitivity Level 1.
RP2040 is compliant to the requirement of REACH Substances of Very High Concern (SVHC) that ECHA announced on
25 June 2020.
RP2040 is compliant to the requirement and standard of Controlled Environment-related Substance of RoHS directive
(EU) 2011/65/EU and directive (EU) 2015/863.
5.3. Pinout
5.3.1. Pin Locations
Figure 169. RP2040
QFN-56 package
pinout
5.3.2. Pin Definitions
5.3.2.1. Pin Types
In the following GPIO Pin table (Table 612), the pin types are defined as shown below.
Table 611. Pin Types
5.3. Pinout
Pin Type
Direction
Description
Digital In
Input only
Standard Digital. Programmable Pull-Up, Pull-Down, Slew Rate,
Digital IO
Bi-directional
Schmitt Trigger and Drive Strength. Default Drive Strength is 4mA.
611
RP2040 Datasheet
Pin Type
Direction
Description
Digital In (FT)
Input only
Fault Tolerant Digital. These pins are described as Fault Tolerant,
which in this case means that very little current flows into the pin
whilst it is below 3.63V and IOVDD is 0V. There is also enhanced ESD
Digital IO (FT)
Bi-directional
protection on these pins. Programmable Pull-Up, Pull-Down, Slew Rate,
Schmitt Trigger and Drive Strength. Default Drive Strength is 4mA.
Digital IO / Analogue
Bi-directional (digital), Standard Digital and ADC input. Programmable Pull-Up, Pull-Down,
Input (Analogue)
Slew Rate, Schmitt Trigger and Drive Strength. Default Drive Strength
is 4mA.
USB IO
Bi-directional
These pins are for USB use, and contain internal pull-up and pull-down
resistors, as per the USB specification. Note that external 27Ω series
resistors are required for USB operation.
Analogue (XOSC)
Oscillator input pins for attaching a 12MHz crystal. Alternatively, XIN
may be driven by a square wave.
5.3.2.2. Pin List
Table 612. GPIO pins
5.3. Pinout
Name
Number
Type
Power Domain
Reset State
Description
GPIO0
2
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO1
3
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO2
4
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO3
5
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO4
6
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO5
7
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO6
8
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO7
9
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO8
11
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO9
12
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO10
13
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO11
14
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO12
15
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO13
16
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO14
17
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO15
18
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO16
27
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO17
28
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO18
29
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO19
30
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO20
31
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO21
32
Digital IO (FT)
IOVDD
Pull-Down
User IO
612
RP2040 Datasheet
Name
Number
Type
Power Domain
Reset State
Description
GPIO22
34
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO23
35
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO24
36
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO25
37
Digital IO (FT)
IOVDD
Pull-Down
User IO
GPIO26 / ADC0
38
Digital IO /
IOVDD /
Pull-Down
User IO or ADC
Analogue
ADC_AVDD
Digital IO /
IOVDD /
Analogue
ADC_AVDD
GPIO27 / ADC1
GPIO28 / ADC2
GPIO29 / ADC3
Table 613. QSPI pins
Table 614. Crystal
oscillator pins
39
40
IOVDD /
Analogue
ADC_AVDD
Pull-Down
User IO or ADC
input
Pull-Down
User IO or ADC
input
Digital IO /
IOVDD /
Analogue
ADC_AVDD
Number
Type
Power Domain
QSPI_SD3
51
Digital IO
IOVDD
QSPI_SCLK
52
Digital IO
IOVDD
QSPI_SD0
53
Digital IO
IOVDD
QSPI data
QSPI_SD2
54
Digital IO
IOVDD
QSPI data
QSPI_SD1
55
Digital IO
IOVDD
QSPI data
QSPI_CSn
56
Digital IO
IOVDD
Name
41
Digital IO /
input
Name
Pull-Down
input
Reset State
Description
QSPI data
Pull-Down
Pull-Up
Number
Type
Power Domain
20
Analogue (XOSC)
IOVDD
XIN
User IO or ADC
QSPI clock
QSPI chip select
Description
Crystal oscillator. XIN
may also be driven by
a square wave.
XOUT
Table 615. Serial wire
debug pins
Table 616.
Miscellaneous pins
Name
21
Analogue (XOSC)
IOVDD
Crystal oscillator.
Number
Type
Power Domain
Reset State
Description
SWCLK
24
Digital In (FT)
IOVDD
Pull-Up
Debug clock
SWD
25
Digital IO (FT)
IOVDD
Pull-Up
Debug data
Name
Number
Type
Power Domain
Reset State
Description
RUN
26
Digital In (FT)
IOVDD
Pull-Up
Chip enable /
reset
TESTEN
19
Digital In
IOVDD
Pull-Down
Test enable
(connect to Gnd)
5.3. Pinout
613
RP2040 Datasheet
Table 617. USB pins
Name
Number
Type
Power Domain
Description
47
USB IO
USB_VDD
USB Data +ve. 27Ω
USB_DP
series resistor
required for USB
operation
USB_DM
46
USB IO
USB_VDD
USB Data -ve. 27Ω
series resistor
required for USB
operation
Table 618. Power
supply pins
Name
Number(s)
Description
IOVDD
1, 10, 22, 33, 42, 49
IO supply
DVDD
23, 50
Core supply
VREG_VIN
44
Voltage regulator input supply
VREG_VOUT
45
Voltage regulator output
USB_VDD
48
USB supply
ADC_AVDD
43
ADC supply
GND
57
Common ground connection via
central pad
5.3.3. Pin Specifications
The following electrical specifications are obtained from characterisation over the specified temperature and voltage
ranges, as well as process variation, unless the specification is marked as 'Simulated'. In this case, the data is for
information purposes only, and is not guaranteed.
5.3.3.1. Absolute Maximum Ratings
Table 619. Absolute
maximum ratings for
digital IO (Standard
and Fault Tolerant)
Parameter
Symbol
Minimum
Maximum
Units
I/O Supply Voltage
IOVDD
-0.5
3.63
V
VPIN
-0.5
IOVDD + 0.5
V
Voltage at IO
Comment
5.3.3.2. ESD Performance
Table 620. ESD
performance for all
pins, unless otherwise
stated
Parameter
Human Body Model
Symbol
Maximum
Units
Comment
HBM
2
kV
Compliant with JEDEC
specification JS-0012012 (April 2012)
Human Body Model
HBM
4
kV
Digital (FT) pins only
Compliant with JEDEC
specification JS-0012012 (April 2012)
Charged Device Model
CDM
500
V
Compliant with
JESD22-C101E
(December 2009)
5.3. Pinout
614
RP2040 Datasheet
5.3.3.3. Thermal Performance
Table 621. Thermal
Performance
Parameter
Case
Symbol
Minimum
TC
-40
Typical
Maximum
Units
85
°C
Comment
Temperature
5.3.3.4. IO Electrical Characteristics
Table 622. Digital IO
characteristics Standard and FT
unless otherwise
stated
Parameter
Pin Input Leakage
Symbol
Minimum
IIN
Maximum
Units
1
μA
Comment
Current
Input Voltage High
VIH
0.65 * IOVDD
IOVDD + 0.3
V
VIH
1.7
IOVDD + 0.3
V
VIH
2
IOVDD + 0.3
V
VIL
-0.3
0.35 * IOVDD
V
VIL
-0.3
0.7
V
VIL
-0.3
0.8
V
VHYS
0.1 * IOVDD
@ IOVDD=1.8V
Input Voltage High
@ IOVDD=2.5V
Input Voltage High
@ IOVDD=3.3V
Input Voltage Low
@ IOVDD=1.8V
Input Voltage Low
@ IOVDD=2.5V
Input Voltage Low
@ IOVDD=3.3V
Input Hysteresis
V
Voltage @
Schmitt Trigger
enabled
IOVDD=1.8V
Input Hysteresis
VHYS
0.2
V
Voltage @
Schmitt Trigger
enabled
IOVDD=2.5V
Input Hysteresis
VHYS
0.2
V
Voltage @
Schmitt Trigger
enabled
IOVDD=3.3V
Output Voltage
VOH
1.24
IOVDD
V
High @
12mA depending
IOVDD=1.8V
Output Voltage
on setting
VOH
1.78
IOVDD
V
High @
on setting
VOH
2.62
IOVDD
V
High @
Low @
IOVDD=1.8V
5.3. Pinout
IOH = 2, 4, 8 or
12mA depending
IOVDD=3.3V
Output Voltage
IOH = 2, 4, 8 or
12mA depending
IOVDD=2.5V
Output Voltage
IOH = 2, 4, 8 or
on setting
VOL
0
0.3
V
IOL = 2, 4, 8 or
12mA depending
on setting
615
RP2040 Datasheet
Parameter
Output Voltage
Symbol
Minimum
Maximum
Units
VOL
0
0.4
V
Low @
IOL = 2, 4, 8 or
12mA depending
IOVDD=2.5V
Output Voltage
Comment
on setting
VOL
0
0.5
V
Low @
IOL = 2, 4, 8 or
12mA depending
IOVDD=3.3V
on setting
Pull-Up Resistance
RPU
50
80
kΩ
Pull-Down
RPD
50
80
kΩ
50
mA
Resistance
Maximum Total
IIOVDD_MAX
IOVDD current
Sum of all current
being sourced by
GPIO and QSPI
pins
Maximum Total
IIOVSS_MAX
50
mA
Sum of all current
VSS current due to
being sunk into
IO (IOVSS)
GPIO and QSPI
pins
Table 623. USB IO
characteristics
Parameter
Pin Input Leakage
Symbol
Minimum
IIN
Maximum
Units
1
μA
Comment
Current
Single Ended Input
VIHSE
2
V
Voltage High
Single Ended Input
VILSE
0.8
V
Voltage Low
Differential Input
VIHDIFF
0.2
V
Voltage High
Differential Input
VILDIFF
-0.2
V
Voltage Low
Output Voltage
VOH
2.8
USB_VDD
V
VOL
0
0.3
V
RPU2
0.873
1.548
kΩ
RPU1&2
1.398
3.063
kΩ
RPD
14.25
15.75
kΩ
Parameter
Symbol
Minimum
Maximum
Units
ADC Input Voltage
VPIN_ADC
0
ADC_AVDD
V
High
Output Voltage
Low
Pull-Up Resistance
- RPU2
Pull-Up Resistance
- RPU1&2
Pull-Down
Resistance
Table 624. ADC
characteristics
Comment
Range
5.3. Pinout
616
RP2040 Datasheet
Parameter
Symbol
Minimum
Effective Number
ENOB
8.7
Maximum
Units
Comment
bits
See Section 4.9.3
of Bits
Resolved Bits
ADC Input
12
bits
RIN_ADC
100
kΩ
Symbol
Minimum
Maximum
Units
Comment
VIH
0.65*IOVDD
IOVDD + 0.3
V
XIN only. XOUT
Impedance
Table 625. Oscillator
pin characteristics
when using a Square
Wave input
Parameter
Input Voltage High
floating
Input Voltage Low
VIL
0
0.35*IOVDD
V
XIN only. XOUT
floating
See Section 2.16 for more details on the Oscillator, and Minimal Design Example for information on crystal usage.
5.3.3.5. Interpreting GPIO output voltage specifications
The GPIOs on RP2040 have four different output drive strengths, which are nominally called 2, 4, 8 and 12mA modes.
These are not hard limits, nor do they mean that they will always be sourcing (or sinking) the selected amount of
milliamps. The amount of current a GPIO sources or sinks is dependant on the load attached to it. It will attempt to drive
the output to the IOVDD level (or 0V in the case of a logic 0), but the amount of current it is able to source is limited,
which will be dependant on the selected drive strength. Therefore the higher the current load is, the lower the voltage
will be at the pin. At some point, the GPIO will be sourcing so much current, that the voltage is so low, it won’t be
recognised as a logic 1 by the input of a connected device. The purpose of the output specifications in Table 622 are to
try and quantify how much lower the voltage can be expected to be, when drawing specified amounts of current from
the pin.
The Output High Voltage (VOH) is defined as the lowest voltage the output pin can be when driven to a logic 1 with a
particular selected drive strength; e.g., 4mA being sourced by the pin whilst in 4mA drive strength mode. The Output
Low Voltage is similar, but with a logic 0 being driven.
In addition to this, the sum of all the IO currents being sourced (i.e. when outputs are being driven high) from the IOVDD
bank (essentially the GPIO and QSPI pins), must not exceed IIOVDD_MAX. Similarly, the sum of all the IO currents being sunk
(i.e. when the outputs are being driven low) must not exceed IIOVSS_MAX.
5.3. Pinout
617
RP2040 Datasheet
Figure 170. Typical
Current vs Voltage
curves of a GPIO
output.
Figure 170 shows the effect on the output voltage as the current load on the pin increases. You can clearly see the
effect of the different drive strengths; the higher the drive strength, the closer the output voltage is to IOVDD (or 0V) for
a given current. The minimum VOH and maximum VOL limits are shown in red. You can see that at the specified current
for each drive strength, the voltage is well within the allowed limits, meaning that this particular device could drive a lot
more current and still be within VOH/VOL specification. This is a typical part at room temperature, there will be a spread of
other devices which will have voltages much closer to this limit. Of course, if your application doesn’t need such tightly
controlled voltages, then you can source or sink more current from the GPIO than the selected drive strength setting, but
experimentation will be required to determine if it indeed safe to do so in your application, as it will be outside the scope
of this specification.
5.4. Power Supplies
Table 626. Power
Power Supply
Supply Specifications
Supplies
Min
Typ
Max
Units
Digital IO
1.62
1.8 / 3.3
3.63
V
Digital core
0.99
1.1
1.21
V
VREG_VIN
Voltage regulator
1.62
1.8 / 3.3
3.63
V
USB_VDD
USB PHY
3.135
3.3
3.63
V
ADC
1.62
3.3
3.63
V
IOVDDa
DVDD
ADC_AVDDb
a
If IOVDD