diff options
45 files changed, 3602 insertions, 1595 deletions
@@ -1,320 +1,24 @@ -Introduction ------------- - -This repository contains reStructuredText (reST) source files used to -generate the documentation for LeafLabs' libmaple and Maple IDE -projects. For more information on these projects, see their GitHub -pages: - - https://github.com/leaflabs/libmaple - https://github.com/leaflabs/maple-ide - -While the two projects are developed separately, they are released in -lockstep, and Maple IDE depends upon libmaple. (libmaple doesn't -depend on Maple IDE). - -The generated documentation for the latest libmaple and Maple IDE -release is available online in HTML form: +This repository contains source files used to generate the +documentation for LeafLabs' libmaple and Maple IDE projects [*]. The +HTML documentation generated from these sources is available online: http://leaflabs.com/docs/ -The web interface is the recommended way for users to read the -documentation. Older versions are available as well: - - http://static.leaflabs.com/pub/leaflabs/maple-docs/ - -This file contains instructions for generating the HTML files. It -also contains guidelines for the documentation's maintainers. - -About the Documentation ------------------------ - -The docs are written in Sphinx's extensions to reStructuredText -(reST). You can read more about Sphinx here: - - http://sphinx.pocoo.org/tutorial.html - -Much of the documentation is pulled out of the libmaple source code. -libmaple documents itself using Doxygen: - - http://doxygen.org - -We use a Sphinx plugin called Breathe to parse Doxygen's XML output -into a form usable by Sphinx. You can read more about Breathe here: - - http://michaeljones.github.com/breathe/ - -Documentation Build Steps -------------------------- - -First, you will need to install some dependencies (Doxygen, Sphinx, -and Breathe). - -1. You need a recent-ish version of Doxygen in your PATH: - - http://www.stack.nl/~dimitri/doxygen/download.html#latestsrc - -2. Install Breathe, which does Doxygen-to-Sphinx conversion: - - Read/write version (for LeafLabs developers): - - $ git clone git@github.com:leaflabs/breathe.git - - Read-only version (for non-LeafLabs developers): - - $ git clone git://github.com/leaflabs/breathe.git - - After that's done, set an environment variable BREATHE_HOME to - point to where you downloaded it. Something like this on bash: - - $ export BREATHE_HOME=/path/to/breathe/repo/ - - (You'll want to put this in your shell startup script). - -3. Install Sphinx. - - From source or .egg: - - http://pypi.python.org/pypi/Sphinx#downloads - - Via easy_install: - - $ sudo easy_install -U Sphinx - - You need Sphinx version >= 1.0.6. - -You are now ready to build the documentation. First, you'll produce -Doxygen XML output, then you can generate the HTML documentation. - -1. Before the first time you run Sphinx (and any time the Doxygen - comments in the libmaple source code are changed), you'll need to - rebuild libmaple's Doxygen XML output. That is, from within the - libmaple repository (i.e., NOT THIS REPOSITORY), run: - - $ make doxygen - -2. Finally, you can build the documentation (in this folder): - - $ make html - - On Windows, use the batch file make.bat instead. - - As of 8 September 2011, building the docs generates a bunch of - errors/warnings. Most of these are spurious and appear to be - Breathe's fault. C'est la vie. - -Reading and Modifying the Documentation ---------------------------------------- - -Just point your web browser at the file - - build/html/index.html - -It corresponds to the Sphinx file - - source/index.rst - -Read more about Sphinx and use the existing docs source as an example -when writing yours. The directory tmpl/ contains template ReST files -you should modify when creating a new page, in order to keep the style -consistent. - -The file source/conf.py is the Sphinx configuration file; you can go -read it for more information about our setup. - -All of the documentation which isn't pulled out of source code -comments lives in source/. The directory source/_static/ is for -static content (like style sheets); source/_templates/ is meant to -contain Sphinx templates. - -The remaining sections describe what to do under various circumstances -when modifying or building the docs. - -Adding a New Board ------------------- - -Adding documentation for a new board is not just a matter of shoving a -file for it into source/hardware/! - -- Various places in the docs link to particular kinds of pin maps for - each board. When you add a new board, you must update these as - well. Here's the list; please keep it current (files are relative - to the source/ directory): - - * external-interrupts.rst: EXTI line pin maps - * timers.rst: timer pin maps - * adc.rst: low-noise ADC banks - * usart.rst: USART pin maps - * gpio.rst: master pin maps - * bootloader.rst: flashing a custom bootloader +The above URL is the recommended way for users to read the +documentation. The docs for the latest release are always available +there. -- The quickstart document may not explain how to use the new board. - If the board is different enough, a new, special-purpose quickstart - may need to be written for it. Therefore, read the quickstart in - its entirety and update it appropriately. +Older versions are here: - Take this step seriously. The quickstart is the first thing users - read when starting out, and first impressions matter. - -Building Documentation for a Release ------------------------------------- - -This is the procedure to follow when building the documentation for a -versioned release (as such, it's mostly intended for LeafLabs people). - -Read the following "Background" section if you've never done this -before (or haven't done it in a while; things change). Then do the -steps in the "Preparation" and "Cutting the Release" sections that -follow it. - -If you're bugfixing the docs for a release that's already been -shipped, skip to "Maintaining a Release", below. - - ~~~~~~~~~~ - Background - ~~~~~~~~~~ - -As a lightweight form of issue tracking, the documentation sources are -sprinkled (not to say "littered") with comments that begin with FIXME -or TODO, optionally followed by [milestone]. - -Here's a hypothetical example: - - .. TODO [1.4.0] Replace this section; new API is incompatible with 1.3.7 - -This means you should replace the docs section following the comment -before you build the HTML for version 1.4.0. - -Here's a command line you can use on OS X and Linux to list the TODOs -in the documentation sources (run it from the same directory as this -README): - - $ find . -name '*.rst' | xargs egrep --color=auto -n '(FIXME|TODO)' - -You can use the following to temporarily alias the above mouthful to -'todos': - - $ alias todos="find . -name '*.rst' | xargs egrep --color=auto -n '(FIXME|TODO)'" - -Then you can just run - - $ todos - -to measure the joy that awaits you. - -Windows users: I'm not sure what the equivalent of grep is on your -system. If you're using Git, I presume you've got a Bash shell -available to you due to msysgit; try running the above commands there. - -BE ADVISED: that only finds the comments embedded within .rst files. -You also need to check for these in source/conf.py; there may be -others. If you have ack (which might be called "ack-grep" on your -system) installed, you can instead use - - $ ack --type-set rst=.rst --type-set txt=.txt --ignore-dir=build '(FIXME|TODO)' - -to get the same output, but for all the file types we care about. - - ~~~~~~~~~~~ - Preparation - ~~~~~~~~~~~ - -- FINISH THE FIXMEs/TODOs FOR THE CURRENT RELEASE! - - You may violate assumptions made elsewhere in the documentation if - you don't. This can lead to incoherent or incorrect documentation, - which is usually worse than none at all. - - If the release you're building is vA.B.C, you can see the relevant - TODOs with: - - $ todos | grep A\.B\.C - - If you find that you really can't finish the TODO, you should bump - the version number in the comment. Don't do this out of laziness. - Seriously, don't. We may have made promises to the users about what - would happen when, and you might be breaking them. - -- Pick the low-hanging fruit on any other FIXMEs/TODOs. - -- Ask Git to tell you what's happened since the most recent libmaple - release, and make sure that any major, potentially - backwards-incompatible, etc. changes are appropriately documented. - - You can use three dots ("...") between the git tags for those - releases in concert with "git log --oneline" to do this. - - For instance, from the libmaple repository, you can use the - following to tell you what happened in between 0.0.9 and 0.0.10: - - $ git log --oneline 0.0.9...0.0.10 - - As an example of what the output might cause you to do, consider the - following line (which appears in the output for 0.0.9...0.0.10): - - 4941335 Adding rcc_dev_clk(), an accessor for a peripheral's clock line. - - Did the author of that commit (or some other interested party) - remember to pull in the documentation for rcc_dev_clk() into the - libmaple API page for rcc.h? Go check! - -- Do something similar for Maple IDE. The IDE changes a lot more - slowly, so there should be less to do. - - ~~~~~~~~~~~~~~~~~~~ - Cutting the Release - ~~~~~~~~~~~~~~~~~~~ - -- Make a release branch in Git. For release A.B.C, call it - vA.B.C-maintenance. You spell that - - $ git checkout -b vA.B.C-maintenance - - DON'T MAKE A TAG. There are inevitably mistakes in the docs, some - of which will be noticed and corrected, making a fixed tag useless. - When you correct the errors, you'll need to update this branch, - possibly also cherry-picking or otherwise adding into master. See - "Maintaining the Release", below. - -- Do all the TODOs which must happen for _every_ release. (These are - distinct from the ones that must happen for some _particular_ - release). You can find most of these with - - $ todos | grep RELEASE - - However, you'll also need to check source/conf.py, as e.g. a - release's configuration file needs to have a version entered into - it. - - Don't forget to commit your changes. - -- Run "$ make mrproper" from the libmaple directory, and "$ make - clean" from this directory, in order to wipe out old docs. - -- Finally, you can actually build the docs. "$ make doxygen" from - libmaple followed by "$ make html" from here. The sources you want - will be in build/html. Wooo! You're done! Distribute the results - appropriately (e.g. by bundling them with the IDE release). - - Don't forget to push the release branch to the leaflabs-docs repo on - GitHub. - -Maintaining a Release ---------------------- - -So a released version's documentation contains unforgivable lies, huh? -It needs to be updated RIGHT AWAY, you say? Here's what you do: - -- Check out the release branch for the version of the docs you care - about (see "Cutting the Release", above). - -- Make your changes. + http://static.leaflabs.com/pub/leaflabs/maple-docs/ -- Rebuild the docs (see the last two steps in "Cutting the Release"). +The file README-building.txt explains how to build the HTML docs. -- If your changes need to happen on the master branch, make them - appropriately. +The file README-maintainers.txt contains important information for +maintainers of the documentation (e.g. how to add docs for a new +board, how to cut a release version of the docs, etc.). -- Push your fixes to GitHub. +[*] libmaple and Maple IDE themselves are in separate repositories: -- Distribute the updated docs. + https://github.com/leaflabs/libmaple + https://github.com/leaflabs/maple-ide diff --git a/README-building.txt b/README-building.txt new file mode 100644 index 0000000..de4a7f7 --- /dev/null +++ b/README-building.txt @@ -0,0 +1,105 @@ +This file explains how to build the HTML documentation. As such, it's +probably only useful to LeafLabs developers. Users can read the HTML +for the latest release here: + + http://leaflabs.com/docs/ + +Install Dependencies +-------------------- + +First, you will need to install some dependencies (Doxygen, Sphinx, +and Breathe). + +1. Much of the documentation is pulled out of the libmaple source + code's Doxygen comments, so you need a recent-ish version of + Doxygen in your PATH: + + http://www.stack.nl/~dimitri/doxygen/download.html#latestsrc + +2. Documentation not taken from the libmaple sources is written in + Sphinx's extensions to the reStructuredText (reST) markup language. + (More about Sphinx: http://sphinx.pocoo.org/tutorial.html). + + These are your choices for how to install Sphinx: + + - From source or .egg: + http://pypi.python.org/pypi/Sphinx#downloads + + - Via easy_install: + $ sudo easy_install -U Sphinx + + You need Sphinx version >= 1.0.6. + +3. We use a Sphinx plugin called Breathe to parse Doxygen's XML output + into a form usable by Sphinx. (More about Breathe: + http://michaeljones.github.com/breathe/). + + LeafLabs sometimes patches Breathe for the purposes of building our + docs, so clone the LeafLabs Breathe tree from GitHub (somewhere + else on your system, NOT in the leaflabs-docs repo): + + - LeafLabs developers, clone with push permissions: + $ git clone git@github.com:leaflabs/breathe.git + + - Everyone else, clone without them: + $ git clone git://github.com/leaflabs/breathe.git + +4. After that's done, set environment variables LIB_MAPLE_HOME to + point to libmaple, and BREATHE_HOME to point to Breathe. Something + like this in Bash: + + $ export LIB_MAPLE_HOME=/path/to/libmaple/repo/ + $ export BREATHE_HOME=/path/to/breathe/repo/ + + (You'll want this in your shell startup script.) + +Build the Docs +-------------- + +You are finally ready to build the documentation. First, you'll +produce Doxygen XML output, then you can generate the final HTML docs. + +1. Before the first time you run Sphinx (and any time the Doxygen + comments in the libmaple source code are changed), you'll need to + re-run doxygen on libmaple. + + $ cd /path/to/libmaple + $ make doxygen + + Doxygen will yell at you a lot; it's generally safe to ignore it. + +2. Finally, you can build the HTML (in the leaflabs-docs repository): + + $ cd /path/to/leaflabs-docs + $ make html + + On Windows, you can supposedly use the batch file make.bat instead. + + Breathe will yell at you a lot; it's often safe to ignore this, + too. C'est la vie. + +Read and Modify the Docs +------------------------ + +Point your web browser at the file + + build/html/index.html + +For the most part, the file build/html/foo.html is built from +source/foo.rst. (The index is an exception, because we needed to +hand-hack the HTML to get the "Contents at a Glance" section to look +nice). + +All of the documentation which isn't pulled out of libmaple's Doxygen +comments lives in source/. The directory source/_static/ is for +static content (like style sheets); source/_templates/ is meant to +contain Sphinx templates. + +Read more about Sphinx and use the existing leaflabs-docs source for +examples when writing new docs. The directory tmpl/ contains template +ReST files you should sometimes use when creating a page that follows +a pattern (like a libmaple API page), in order to keep the style +consistent. + +The file source/conf.py is the Sphinx configuration file; you can go +read it for more information about our setup. diff --git a/README-maintainers.txt b/README-maintainers.txt new file mode 100644 index 0000000..90ebfb5 --- /dev/null +++ b/README-maintainers.txt @@ -0,0 +1,209 @@ +This file contains information useful for the documentation's +maintainers. As such, it's probably only useful to LeafLabs +developers. Users can read the HTML for the latest release here: + + http://leaflabs.com/docs/ + +Things you can learn how to do from this file: + +- Cut a release version +- Fix errors in/otherwise maintain the current docs release +- Add docs for a new board + +Building Documentation for a Release +------------------------------------ + +This is the procedure to follow when building the documentation for a +versioned release. + +Read the following "Background" section if you've never done this +before (or haven't done it in a while; things change). Then do the +steps in the "Preparation" and "Cutting the Release" sections that +follow it. + +If you're bugfixing the docs for a release that's already been +shipped, skip to "Maintaining a Release", below. + + ~~~~~~~~~~ + Background + ~~~~~~~~~~ + +As a lightweight form of issue tracking, the documentation sources are +sprinkled (not to say "littered") with comments that begin with FIXME +or TODO, optionally followed by [milestone]. + +Here's a hypothetical example: + + .. TODO [1.4.0] Replace this section; new API is incompatible with 1.3.7 + +This means you should replace the docs section following the comment +before you build the HTML for version 1.4.0. + +Here's a command line you can use to list the TODOs in the +documentation sources (run it from the top-level directory in the +repository): + + $ git grep -n 'FIXME\|TODO' + +You can use the following to temporarily alias the above mouthful to +'todos': + + $ alias todos="git grep -n 'FIXME\|TODO'" + +Then you can just run + + $ todos + +to measure the joy that awaits you. + + ~~~~~~~~~~~ + Preparation + ~~~~~~~~~~~ + +- FINISH THE FIXMEs/TODOs FOR THE CURRENT RELEASE! + + You may violate assumptions made elsewhere in the documentation if + you don't. This can lead to incoherent or incorrect documentation, + which is usually worse than none at all. + + If the release you're building is vA.B.C, you can see the relevant + TODOs with: + + $ todos | grep A\.B\.C + + If you find that you really can't finish the TODO, you should bump + the version number in the comment. Don't do this out of laziness. + Seriously, don't. We may have made promises to the users about what + would happen when, and you might be breaking them. + +- Pick the low-hanging fruit on any other FIXMEs/TODOs. + +- Ask Git to tell you what's happened since the most recent libmaple + release, and make sure that any major, potentially + backwards-incompatible, etc. changes are appropriately documented. + + You can use three dots ("...") between the git tags for those + releases in concert with "git log --oneline" to do this. + + For instance, from the libmaple repository, you can use the + following to tell you what happened in between 0.0.9 and 0.0.10: + + $ git log --oneline 0.0.9...0.0.10 + + As an example of what the output might cause you to do, consider the + following line (which appears in the output for 0.0.9...0.0.10): + + 4941335 Adding rcc_dev_clk(), an accessor for a peripheral's clock line. + + Did the author of that commit (or some other interested party) + remember to pull in the documentation for rcc_dev_clk() into the + libmaple API page for rcc.h? Go check! + +- Do something similar for Maple IDE. The IDE changes a lot more + slowly, so there should be less to do. + + ~~~~~~~~~~~~~~~~~~~ + Cutting the Release + ~~~~~~~~~~~~~~~~~~~ + +- Make a release branch in Git. For release A.B.C, call it + vA.B.C-maintenance. You spell that + + $ git checkout -b vA.B.C-maintenance + + DON'T MAKE A TAG. There are inevitably mistakes in the docs, some + of which will be noticed and corrected, making a fixed tag useless. + When you correct the errors, you'll need to update this branch, + possibly also cherry-picking or otherwise adding into master. See + "Maintaining the Release", below. + +- Do all the TODOs which must happen for _every_ release. (These are + distinct from the ones that must happen for some _particular_ + release). You can find most of these with + + $ todos | grep RELEASE + + However, you'll also need to check source/conf.py, as e.g. a + release's configuration file needs to have a version entered into + it. + + DON'T FORGET TO COMMIT YOUR CHANGES. + +- Run "$ make mrproper" from the libmaple directory, and "$ make + clean" from this directory, in order to wipe out existing old docs. + +- Finally, you can actually build the docs. (See README-building.txt + for instructions if you've never done this before.) + + DON'T FORGET TO PUSH THE RELEASE BRANCH TO GITHUB. + +Maintaining a Release +--------------------- + +So a released version's documentation contains unforgivable lies, huh? +It needs to be updated RIGHT AWAY, you say? Here's what you do: + +- Check out the release branch for the version of the docs you care + about (see "Cutting the Release", above). + +- Make your changes. + +- Rebuild the docs (see the last two steps in "Cutting the Release") + and look at the changed pages. + +- If your changes also need to happen on the master branch, make them + appropriately. + + Advice: git cherry-pick is your friend. Let's say you're on branch + "vX.Y.Z-maintenance", and you want to get commit C onto master: + + o---C vX.Y.Z-maintenance + / + -o---o---o---o master + + The recipe is: + + $ git checkout master + $ git cherry-pick C + + Which (if there are no conflicts) will result in: + + o---C vX.Y.Z-maintenance + / + -o---o---o---o---C' master + + Where C' performs the same changes as C. + +- Push your fixes to GitHub. + +- Distribute the updated docs. These are world-visible here: + + http://static.leaflabs.com/pub/leaflabs/maple-docs/ + +Adding a New Board +------------------ + +Adding documentation for a new board is not just a matter of shoving a +file for it into source/hardware/! + +Other things you must consider: + +- Various places in the docs link to particular kinds of pin maps for + each board. When you add a new board, you must update these as + well. Here's the list; please keep it current (files are relative + to the source/ directory): + + * external-interrupts.rst: EXTI line pin maps + * timers.rst: timer pin maps + * adc.rst: low-noise ADC banks + * usart.rst: USART pin maps + * gpio.rst: master pin maps + * bootloader.rst: flashing a custom bootloader + +- The quickstart document may not explain how to use the new board. + If the board is different enough, a new, special-purpose quickstart + may need to be written for it. Therefore, read the quickstart in + its entirety and update it appropriately. + + Take this step seriously. The quickstart is the first thing users + read when starting out, and first impressions matter. diff --git a/source/_static/apilist.html b/source/_static/apilist.html deleted file mode 100644 index 556fcc9..0000000 --- a/source/_static/apilist.html +++ /dev/null @@ -1,5 +0,0 @@ -{# Filename: .static/apilist.html #} -{% set parents = parents.pop() %} -{% if parents %} -<a href="{{ parents.link|e }}">{{ parents.title }}</a> -{% endif %} diff --git a/source/_static/index-style.css b/source/_static/index-style.css new file mode 100644 index 0000000..d7c42b3 --- /dev/null +++ b/source/_static/index-style.css @@ -0,0 +1,19 @@ +/* Contents style */ + +.contents-table { + font-size: large; +} + +.contents-table ul, .contents-table li { + display: inline; +} + +.contents-table td { + padding: 0em 1em 0em; +} + +.contents-table ul { + list-style-type: none; + margin: 0em; + padding-left: 0px; +} diff --git a/source/_static/leaflabs-docs.css b/source/_static/leaflabs-docs.css new file mode 100644 index 0000000..18f5bcc --- /dev/null +++ b/source/_static/leaflabs-docs.css @@ -0,0 +1 @@ +/* Any custom CSS you want applied goes here */ diff --git a/source/_templates/indexcontent.html b/source/_templates/indexcontent.html new file mode 100644 index 0000000..a043f8a --- /dev/null +++ b/source/_templates/indexcontent.html @@ -0,0 +1,117 @@ +{# This file generates the top-level index.html file. We are very + obviously stealing from the Python docs' style ;). +#} + +<!-- Extend our layout.html. So inheritance hierarchy is Sphinx's + layout, then our layout.html, then this file. --> +{% extends "layout.html" %} + +<!-- Pull in extra index stylesheet --> +{% set css_files = css_files + ["_static/index-style.css"] %} + +<!-- Separator for contents lists --> +{% set content_sep = "·" %} + +<!-- Content --> +{% block body %} +<h1>Hi!</h1> + +This is the documentation for the LeafLabs Maple boards, version {{ +release }}. + +<h2>Read This First</h2> + +<p>Just getting started? Try the <a href="{{ +pathto("maple-quickstart") }}">Quickstart</a>. Having problems? Check +out <a href="{{ pathto("troubleshooting") }}">Troubleshooting</a> and +the <a href="{{ pathto("faq") }}">FAQ</a>. Can't find what you want +here? Look on the <a href="http://wiki.leaflabs.com/">LeafLabs +wiki</a>. +</p> + +<p>See the <a href="{{ pathto("whats-new") }}">What's New</a> page for +changes that are new in {{ release }}.</p> + +<h2>Contents at a Glance</h2> + +<table class="contents-table"> + <tr> + <td><p><strong>Getting Started</strong></p> + <ul> + <li><a href="{{ pathto("maple-quickstart") }}">Quickstart</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("maple-ide-install") }}">Installing Maple IDE</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("ide") }}">Using Maple IDE</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("unix-toolchain") }}">Command-Line + Toolchain</a></li> + </ul> + </td> + <td><p><strong>Boards</strong></p> + <ul> + <li><a href="{{ pathto("hardware/maple") }}">Maple</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("hardware/maple-ret6") }}">Maple RET6 Edition</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("hardware/maple-mini") }}">Maple Mini</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("hardware/maple-native-beta") }}">Maple + Native β</a></li> + </ul> + </td> + </tr> + <tr> + <td><p><strong>Programming</strong></p> + <ul> + <li><a href="{{ pathto("language") }}">Language Reference</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("troubleshooting") }}">Troubleshooting</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("faq") }}">FAQ</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("libraries") }}">Libraries</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("libmaple") }}"><tt>libmaple</tt></a> + {{ content_sep }}</li> + <li><a href="{{ pathto("bootloader") }}">Bootloader</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("arm-gcc") }}">GCC and libc</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("arduino-compatibility") }}">Arduino + Compatibility</a></li> + </ul> + </td> + <td><p><strong>Hardware and Peripherals</strong></p> + <ul> + <li><a href="{{ pathto("stm32") }}">STM32</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("adc") }}">ADC</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("external-interrupts") }}">External + Interrupts</a> {{ content_sep }}</li> + <li><a href="{{ pathto("fsmc") }}">FSMC</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("gpio") }}">GPIO</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("i2c") }}">I<sup>2</sup>C</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("jtag") }}">JTAG</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("pwm") }}">PWM</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("spi") }}">SPI</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("systick") }}">SysTick</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("timers") }}">Timers</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("usart") }}">USART</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("usb") }}">USB</a></li> + </ul> + </td> + </tr> +</table> + +{% endblock %} diff --git a/source/_templates/layout.html b/source/_templates/layout.html index 4d92d33..2fd81ce 100644 --- a/source/_templates/layout.html +++ b/source/_templates/layout.html @@ -1,5 +1,11 @@ {% extends "!layout.html" %} + +{% set css_files = css_files + ["_static/leaflabs-docs.css"] %} + {% block rootrellink %} - <li><a href="http://leaflabs.com/">LeafLabs</a> |</li> - {{ super() }} + <li><a href="http://leaflabs.com/"> + <img width="16px" src="_static/img/round_logo_32x32.ico"></img> + leaflabs.com + </a>·</li> + <li><a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}</li> {% endblock %} diff --git a/source/arm-gcc.rst b/source/arm-gcc.rst index 1d55d07..30667a2 100644 --- a/source/arm-gcc.rst +++ b/source/arm-gcc.rst @@ -1,8 +1,8 @@ .. _arm-gcc: -GCC for Maple -============= +GCC and libc +============ This document provides notes on using ``arm-none-eabi-gcc``, the `CodeSourcery <http://www.codesourcery.com/>`_ version of the GNU `GCC diff --git a/source/bootloader.rst b/source/bootloader.rst index e3eb65e..23b0448 100644 --- a/source/bootloader.rst +++ b/source/bootloader.rst @@ -584,8 +584,6 @@ DFU pipe and bringing up the USB serial port. Flashing A Custom Bootloader ---------------------------- -.. FIXME [0.0.13] Update for Maple Native - .. warning:: This section is for users who want to put a fresh or custom bootloader on their board. It's possible to make a mistake in this process and e.g. render your Maple unable to communicate @@ -601,9 +599,6 @@ This means that you can **always** follow these instructions to put a new bootloader program on your board; it **doesn't matter** if there's already a copy of the Maple bootloader on it or not. -This section applies to Maple Rev 3 (or higher), Maple Mini, and Maple -RET6 Edition. - If you have a Maple Rev 1; you don't have a BUT button, and won't be able to follow these directions. A workaround is detailed in `this forum posting <http://forums.leaflabs.com/topic.php?id=32#post-126>`_. @@ -629,6 +624,7 @@ In order to follow these instructions, you will need: - `Maple <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_boot.bin>`_ - `Maple Mini <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_mini_boot.bin>`_ - `Maple RET6 Edition <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_RET6_boot.bin>`_ +- `Maple Native <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_native_boot.bin>`_ To flash a customized version of a LeafLabs bootloader, you can run (on a :ref:`suitably configured system <unix-toolchain>`) the diff --git a/source/conf.py b/source/conf.py index 7380f8e..5b8f2d8 100644 --- a/source/conf.py +++ b/source/conf.py @@ -14,7 +14,6 @@ import sys, os - # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. @@ -37,7 +36,7 @@ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.coverage', 'breathe'] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates', '_static'] +templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' @@ -46,7 +45,7 @@ source_suffix = '.rst' #source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = 'contents' # General information about the project. project = u'Maple' @@ -132,11 +131,11 @@ html_theme_options = { 'relbarbgcolor' : 'green', 'headlinkcolor' : '#000000', 'linkcolor' : 'green', - 'visitedlinkcolor' : 'green', + #'visitedlinkcolor' : 'green', ## Font 'headfont' : 'Georgia', - 'bodyfont' : 'Lucidia' + 'bodyfont' : 'Lucida' } # Add any paths that contain custom themes here, relative to this directory. @@ -144,14 +143,14 @@ html_theme_options = { # The name for this set of Sphinx documents. If None, it defaults to # "<project> v<release> documentation". -html_title = project + ' v' + release + ' Documentation' +html_title = project + ' v' + release # A shorter title for the navigation bar. Default is the same as html_title. html_short_title = 'Index' # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = '_static/img/round_logo_60x60.png' +# html_logo = '_static/img/round_logo_60x60.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -172,16 +171,15 @@ html_last_updated_fmt = '%b %d, %Y' #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -# re-add commented line when custom template for api finished html_sidebars = { '**': ['globaltoc.html', 'searchbox.html'], - #'lang/api**':['searchbox.html', 'apilist.html'], } - # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +html_additional_pages = { + 'index': 'indexcontent.html' +} # If false, no module index is generated. #html_domain_indices = True @@ -263,7 +261,7 @@ man_pages = [ # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'http://docs.python.org/': None} +#intersphinx_mapping = {'http://docs.python.org/': None} # -- Options for breathe integration ------------------------------------------ diff --git a/source/contents.rst b/source/contents.rst new file mode 100644 index 0000000..7bb60b8 --- /dev/null +++ b/source/contents.rst @@ -0,0 +1,70 @@ +.. _index: + +Contents in Full +================ + +.. _index-usage: + +**Getting Started** + +.. toctree:: + :maxdepth: 2 + + maple-quickstart + maple-ide-install + ide + unix-toolchain + whats-new + +.. _index-maple-programming: + +**Programming** + +.. toctree:: + :maxdepth: 2 + + language + libraries + arduino-compatibility + libmaple + bootloader + troubleshooting + FAQ <faq> + arm-gcc + language-index + +.. _index-hardware: + +**Hardware and Peripherals** + +.. toctree:: + :maxdepth: 2 + + stm32 + adc + external-interrupts + fsmc + gpio + i2c + jtag + pwm + spi + timers + systick + usb + usart + +.. _index-boards: + +**Boards** + +.. toctree:: + :maxdepth: 2 + + hardware/maple.rst + hardware/maple-ret6.rst + hardware/maple-mini.rst + hardware/maple-native-beta.rst + +.. TODO [Maple Native] write/include upon finished Native release +.. hardware/maple-native.rst diff --git a/source/faq.rst b/source/faq.rst index 937eae8..bd155ae 100644 --- a/source/faq.rst +++ b/source/faq.rst @@ -11,16 +11,16 @@ .. _faq-atoi: -How can I use ``atoi()``, ``strol()``, etc.? --------------------------------------------- +Can I use ``atoi()``, ``strol()``, etc.? +---------------------------------------- Just ``#include <stdlib.h>``. See :ref:`arm-gcc-libc` for more information. .. _faq-dynamic-memory: -How can I use ``malloc()``/``new``? ------------------------------------ +Can I use ``malloc()``/``new``? +------------------------------- For ``malloc()``, just ``#include <stdlib.h>``, and everything should work fine. Be careful, though! This isn't like C programming on a @@ -107,3 +107,9 @@ featuring a `detailed discussion on pin capability writes. And finally, `another thread <http://forums.leaflabs.com/topic.php?id=895>`_ on the subject which summarizes a variety of other threads on doing I/O quickly. + +Can I use Maple without Maple IDE? +---------------------------------- + +Yes. See :ref:`unix-toolchain` for the details. + diff --git a/source/hardware/maple-mini.rst b/source/hardware/maple-mini.rst index 986ab4b..36702dd 100644 --- a/source/hardware/maple-mini.rst +++ b/source/hardware/maple-mini.rst @@ -15,7 +15,7 @@ breadboard. Technical Specifications ------------------------ -* MCU: :ref:`STM32F103RCBT6 <maple-mini-stdocs>`, a 32-bit ARM Cortex +* MCU: :ref:`STM32F103CBT6 <maple-mini-stdocs>`, a 32-bit ARM Cortex M3 microprocessor * Clock Speed: **72 MHz** * **128 KB Flash** and **20 KB SRAM** @@ -50,9 +50,40 @@ directly. .. warning:: The silkscreen on the Maple Mini suggests it will accept an input voltage up to 16 V. We recommend applying **no greater - than 12 V**. - - See :ref:`this erratum <maple-mini-vin>` for more information. + than 12 V**, and potentially even lower depending upon the current + draw requirements of the application. Please see :ref:`Power + Regulation on the Maple Mini <maple-mini-power-regulation>` for + more information. + +.. _maple-mini-power-regulation: + +Power Regulation on the Maple Mini +---------------------------------- + +Power regulation on the Maple is provided by two low dropout linear +voltage regulators. (The part is the MCP1703 from Microchip, in the +SOT-23A package. You can download the datasheet `here +<http://ww1.microchip.com/downloads/en/DeviceDoc/22049a.pdf>`_ ). One +of the regulators supplies power to the digital voltage plane; the +other supplies power to the analog voltage plane. + +These voltage regulators nominally take an input of up to 16V. In +addition, while the maximum continuous output current for the board is +250mA, if you are powering the board off higher voltages the amount +off current it can supply goes down, due to the regulators needing to +dissipate the extra power. So if you are powering the board off 12V, +the max current is about 40mA at room temperature. In general (again, +at room temperature) the max power dissipation (PD) for the chip is +about .37W, and output current = PD/(Vin-Vout). For exact max current +calculations, please refer to the datasheet linked above. + +If you are planning to draw a lot of current from the Maple board, it +is necessary to provide input power as close to 3.3V as +possible. Powering the microcontroller circuitry and LEDs on the board +alone takes approximately 30mA, so if you are powering the board with +12V that leaves only 10mA (at best) available for powering any user +circuitry. Attempting to draw more than 10mA runs the risk of shorting +out the power regulators and bricking your board. .. _maple-mini-gpios: @@ -339,14 +370,12 @@ This section lists known issues and warnings for the Maple Mini Rev 2 .. _maple-mini-vin: * **Silkscreen Vin voltage mistake**: The silkscreen on the Maple Mini - falsely indicates that Vin may be supplied with up to 16 V. We - recommend an input voltage **no greater than 12 V**. - - The voltage regulator on the Mini is rated up to 16 V. However, our - tests indicate that as its input voltage approaches 16 V, its output - begins to rise to levels higher than those recommended by ST for - supplying the STM32F103CB. The limit of 12 V keeps the voltage - supplied to the processor at safe levels. + falsely indicates that Vin may be supplied with up to 16V. We + recommend an input voltage **no greater than 12V**, and potentially + even lower depending upon the current draw requirements of the + application. Please see :ref:`Power Regulation on the Maple Mini + <maple-mini-power-regulation>` for more information. + Recommended Reading ------------------- diff --git a/source/hardware/maple-native-beta.rst b/source/hardware/maple-native-beta.rst index f120c05..f1b2284 100644 --- a/source/hardware/maple-native-beta.rst +++ b/source/hardware/maple-native-beta.rst @@ -46,20 +46,57 @@ Technical Specifications Powering the Maple Native ------------------------- -The Maple Native may be powered from the barrel jack connector, USB, -or a LiPo battery. The power source is determined by the header -labeled "PWRSEL" on the silkscreen. Boards are shipped with a jumper -on the USB selector. In order to power it off of an alternative -source, unplug the Maple Native, then move the jumper to the desired -selector before reconnecting power. - -You can also power the Maple Native via the pin labeled "Vin" on the -vertical header to the right of the PWRSEL header. This pin feeds -into both the digital and analog voltage regulators. However, don't -do this while simultaneously powering the board from another source, -or you could damage it. - -We recommend an input voltage no greater than 12 V. +The power source is determined by the header labeled "PWRSEL" on the +silkscreen. The Maple Native may be powered from USB (marked "USB" on +the PWRSEL header), a LiPo battery (marked "BAT"), or one of the two +"Vin" pins (marked "EXT"). Boards are shipped with a jumper on the +USB selector. In order to power it off of an alternative source, +unplug the Maple Native, then move the jumper to the desired selector +before reconnecting power. + +The "Vin" line is available on the pin labeled "Vin" on the vertical +header to the right of the PWRSEL header, as well as on the +unpopulated two-pin connector on the upper left corner of the +board. On this latter connector, polarity was accidentally left +unmarked: the leftmost, round pin should be power, while the square +pin should be ground. + +When powering the Maple Native board from a battery or the Vin lines, +care must be taken not to over-voltage the board. In general, an upper +limit of 12V input is acceptable, but this may vary depending upon the +current draw requirements of the application. Please see :ref:`Power +Regulation on the Maple Native <maple-native-b-power-regulation>` for +more information. + +.. _maple-native-b-power-regulation: + +Power Regulation on the Maple Native +------------------------------------ + +Power regulation on the Maple Native is provided by two low dropout +linear voltage regulators. (The part is the MCP1703 from Microchip, in +the SOT-23A package. You can download the datasheet `here +<http://ww1.microchip.com/downloads/en/DeviceDoc/22049a.pdf>`_). One +of the regulators supplies power to the digital voltage plane; the +other supplies power to the analog voltage plane. + +These voltage regulators nominally take an input of up to 16V. In +addition, while the maximum continuous output current for the board is +250mA, if you are powering the board off higher voltages the amount +off current it can supply goes down, due to the regulators needing to +dissipate the extra power. So if you are powering the board off 12V, +the max current is about 40mA at room temperature. In general (again, +at room temperature) the max power dissipation (PD) for the chip is +about .37W, and output current = PD/(Vin-Vout). For exact max current +calculations, please refer to the datasheet linked above. + +If you are planning to draw a lot of current from the Maple Native +board, it is necessary to provide input power as close to 3.3V as +possible. Powering the microcontroller circuitry and LEDs on the board +alone takes approximately 30mA, so if you are powering the board with +12V that leaves only 10mA (at best) available for powering any user +circuitry. Attempting to draw more than 10mA runs the risk of shorting +out the power regulators and bricking your board. Using the Built-in Battery Charger ---------------------------------- diff --git a/source/hardware/maple-ret6.rst b/source/hardware/maple-ret6.rst index d5bf049..21c033b 100644 --- a/source/hardware/maple-ret6.rst +++ b/source/hardware/maple-ret6.rst @@ -58,9 +58,20 @@ standard Maple <maple-powering>`. .. warning:: The RET6 Edition silkscreen falsely indicates that the barrel jack accepts up to 18 V. We recommend a barrel jack input - voltage **no greater than 12 V**. + voltage **no greater than 12V**, and potentially even lower + depending upon the current draw requirements of the + application. The same goes for powering off LiPo batteries. - See :ref:`this erratum <maple-barrel-jack>` for more information. + Please see :ref:`Power Regulation on the Maple + <maple-power-regulation>` for more information. + +.. _maple-ret6power-regulation: + +Power Regulation on the Maple RET6 +---------------------------------- + +Power regulation on the Maple RET6 works in the :ref:`same way as the +standard Maple <maple-power-regulation>`. Using the Built-in Battery Charger ---------------------------------- @@ -373,11 +384,17 @@ features only available on the STM32F103RET6. .. _maple-ret6-barrel-jack: -* **Barrel jack power supply voltage mistake**: The silkscreen next to - the barrel jack connector incorrectly indicates that up to an 18 V - input voltage is allowed. **We do not recommend exceeding 12 V**. - - See this :ref:`Maple erratum <maple-barrel-jack>` for more +* **Barrel jack power supply voltage mistake**: The acceptable voltage + range given next to the barrel jack on the Maple RET6 is + **incorrect**. The given range is 7V — 18V. In fact, **18V is too + high** and should not be supplied to your board. The original + voltage regulators used on the Maple were rated up to 18V. However, + the voltage regulators on current Maple Revs are rated up to only + 16V, and due to the current draw requirements of the board, operate + properly only up to 12V. The recommended maximum voltage you should + apply is **12V**, and potentially even lower depending upon the + current draw requirements of the application. Please see :ref:`Power + Regulation on the Maple <maple-power-regulation>` for more information. * **Power supply marketing mistake**: We originally sold the Maple diff --git a/source/hardware/maple.rst b/source/hardware/maple.rst index 610fdfc..aff64d5 100644 --- a/source/hardware/maple.rst +++ b/source/hardware/maple.rst @@ -103,15 +103,50 @@ header. This pin feeds into both the digital and analog voltage regulators. However, don't do this while simultaneously powering the board from another source, or you could damage it. +When powering the board from a barrel jack, **double check the +polarity of the barrel.** The appropriate polarity is noted on the +silkscreen right next to the connector. + .. warning:: Silkscreens on Maples up through Rev 5s manufactured in Spring 2011 falsely indicated that the barrel jack could be - supplied by up to 18 V. We recommend a barrel jack input voltage - **no greater than 12 V**. - - Rev5s manufactured after Spring 2011 may still have this error on - the silk, but it has been marked over. - - See :ref:`this erratum <maple-barrel-jack>` for more information. + supplied by up to 18V. (Rev5s manufactured after Spring 2011 may + still have this error on the silk, but it has been marked over.) We + recommend a barrel jack input voltage **no greater than 12V**, and + potentially even lower depending upon the current draw requirements + of the application. The same goes for powering off LiPo batteries. + + Please see :ref:`Power Regulation on the Maple + <maple-power-regulation>` for more information. + +.. _maple-power-regulation: + +Power Regulation on the Maple +----------------------------- + +Power regulation on the Maple is provided by two low dropout linear +voltage regulators. (The part is the MCP1703 from Microchip, in the +SOT-23A package. You can download the datasheet `here +<http://ww1.microchip.com/downloads/en/DeviceDoc/22049a.pdf>`_ ). One +of the regulators supplies power to the digital voltage plane; the +other supplies power to the analog voltage plane. + +These voltage regulators nominally take an input of up to 16V. In +addition, while the maximum continuous output current for the board is +250mA, if you are powering the board off higher voltages the amount +off current it can supply goes down, due to the regulators needing to +dissipate the extra power. So if you are powering the board off 12V, +the max current is about 40mA at room temperature. In general (again, +at room temperature) the max power dissipation (PD) for the chip is +about .37W, and output current = PD/(Vin-Vout). For exact max current +calculations, please refer to the datasheet linked above. + +If you are planning to draw a lot of current from the Maple board, it +is necessary to provide input power as close to 3.3V as +possible. Powering the microcontroller circuitry and LEDs on the board +alone takes approximately 30mA, so if you are powering the board with +12V that leaves only 10mA (at best) available for powering any user +circuitry. Attempting to draw more than 10mA runs the risk of shorting +out the power regulators and bricking your board. Using the Built-in Battery Charger ---------------------------------- @@ -423,15 +458,16 @@ General * **Barrel jack power supply voltage mistake**: The acceptable voltage range given next to the barrel jack on the Maple through Rev 5s - manufactured in Spring 2011 is **incorrect**. The given range is 7 - V — 18 V. In fact, **18 V is too high** and should not be supplied - to your board. The recommended maximum voltage you should apply is - **12 V**. - - The original voltage regulators used on the Maple were rated up to - 18 V. However, the voltage regulators on current Maple Revs are - rated up to 16 V. Our tests indicate that they operate correctly - through 12 V. We do not recommend higher input voltages. + manufactured in Spring 2011 is **incorrect**. The given range is 7V + — 18V. In fact, **18V is too high** and should not be supplied to + your board. The original voltage regulators used on the Maple were + rated up to 18V. However, the voltage regulators on current Maple + Revs are rated up to only 16V, and due to the current draw + requirements of the board, operate properly only up to 12V. The + recommended maximum voltage you should apply is **12V**, and + potentially even lower depending upon the current draw requirements + of the application. Please see :ref:`Power Regulation on the Maple + <maple-power-regulation>` for more information. .. _maple-nrst-pb4: diff --git a/source/ide.rst b/source/ide.rst index 6e36e47..e6d49fc 100644 --- a/source/ide.rst +++ b/source/ide.rst @@ -1,7 +1,7 @@ .. _ide: -Maple IDE -========= +Using Maple IDE +=============== This page documents the basic functionality of the Maple IDE. Specifically, it describes the operation of the buttons on the main diff --git a/source/index.rst b/source/index.rst deleted file mode 100644 index e8f0277..0000000 --- a/source/index.rst +++ /dev/null @@ -1,78 +0,0 @@ -.. _index: - -LeafLabs Documentation Index -============================ - -Welcome to the LeafLabs documentation! - -If you're setting up a board for the first time, try the -:ref:`quickstart <maple-quickstart>`. If you're having problems, -check out the :ref:`troubleshooting <troubleshooting>` and :ref:`FAQ -<faq>` pages. - -If you can't find what you're looking for here, try the `LeafLabs wiki -<http://wiki.leaflabs.com/index.php?title=Main_Page>`_. - -.. _index-usage: - -**Usage Guides:** - -.. toctree:: - :maxdepth: 1 - - Quickstart <maple-quickstart> - IDE Installation <maple-ide-install> - IDE Usage <ide> - Command-Line Toolchain <unix-toolchain> - -.. _index-maple-programming: - -**Maple Programming:** - -.. toctree:: - :maxdepth: 1 - - Language <language> - Libraries <libraries> - Arduino Compatibility <arduino-compatibility> - libmaple - Bootloader <bootloader> - Troubleshooting <troubleshooting> - FAQ <faq> - GCC and libc for Maple <arm-gcc> - Language Index <language-index> - -.. _index-hardware: - -**Hardware Peripherals:** - -.. toctree:: - :maxdepth: 1 - - adc - external-interrupts - fsmc - gpio - i2c - jtag - pwm - spi - timers - systick - usb - usart - -.. _index-boards: - -**Board Hardware Documentation:** - -.. toctree:: - :maxdepth: 1 - - hardware/maple.rst - hardware/maple-ret6.rst - hardware/maple-mini.rst - hardware/maple-native-beta.rst - -.. TODO [Maple Native] write/include upon finished Native release -.. hardware/maple-native.rst diff --git a/source/lang/api/serial.rst b/source/lang/api/serial.rst index 8c9ebc7..e287015 100644 --- a/source/lang/api/serial.rst +++ b/source/lang/api/serial.rst @@ -1,3 +1,4 @@ +.. FIXME [0.0.13] This doesn't include UART4/5, or USART6 .. highlight:: cpp .. _lang-serial: diff --git a/source/lang/cpp/built-in-types.rst b/source/lang/cpp/built-in-types.rst index 28e8cdc..f14dce5 100644 --- a/source/lang/cpp/built-in-types.rst +++ b/source/lang/cpp/built-in-types.rst @@ -86,8 +86,8 @@ Floating-Point Types 64-bit, IEEE-754 double-precision floating-point type. -Other Types ------------ +Miscellaneous Types +------------------- .. cpp:type:: voidFuncPtr @@ -98,3 +98,11 @@ Other Types .. cpp:type:: bool Boolean type. + +Other +----- + +.. cpp:type:: void + + Not really a type. To be honest with you, this only exists here to + silence warnings from our documentation build system. diff --git a/source/language-index.rst b/source/language-index.rst index 6c20605..5e4c609 100644 --- a/source/language-index.rst +++ b/source/language-index.rst @@ -16,11 +16,7 @@ programmers familiar with the Arduino language. with different kinds of hardware. - If you're looking for something from the C standard library (like - ``atoi()``, for instance): the :ref:`CodeSourcery GCC compiler - <arm-gcc>` used to compile your programs is configured to link - against `newlib <http://sourceware.org/newlib/>`_, and allows the - use of any of its header files. However, dynamic memory allocation - (``malloc()``, etc.) is not available. + ``atoi()``, for instance), see :ref:`this FAQ <faq-atoi>`. - If you're looking for pointers to low-level details, see the :ref:`Language Recommended Reading diff --git a/source/language.rst b/source/language.rst index 1a8ef30..a24bb5f 100644 --- a/source/language.rst +++ b/source/language.rst @@ -2,9 +2,9 @@ .. _language: -========================== - Maple Language Reference -========================== +==================== + Language Reference +==================== The Maple can be programmed in the `Wiring <http://www.wiring.org.co/reference/>`_ language, which is the same @@ -15,17 +15,18 @@ C or C++ programmers who are new to Wiring may wish to skip to the .. contents:: Contents :local: -.. admonition:: **Looking for Something Else?** +.. admonition:: Looking for something else? Try these - See the :ref:`libraries` for extra built-in libraries. - - If you prefer C or C++ over Wiring, see the :ref:`unix-toolchain`. + - If you prefer C or C++ over Wiring, see :ref:`libmaple` and the + :ref:`unix-toolchain`. - If you're looking for something from the C standard library (like ``atoi()``, for instance), see :ref:`this FAQ <faq-atoi>`. - - Low-level details are in :ref:`libmaple` and this page's - :ref:`Recommended Reading <language-recommended-reading>`. + - An :ref:`stm32` and other :ref:`language-recommended-reading` are + also available. .. _language-lang-docs: @@ -272,7 +273,7 @@ the Maple can be programmed using a :ref:`standard Unix toolchain <unix-toolchain>`, so if you'd rather stick with :command:`gcc`, :command:`make`, and friends, you can. If you're using the Unix toolchain and want to skip past the Wiring conveniences and get -straight to registers, you are encouraged to move on to the +straight to the details, you are encouraged to move on to the :ref:`libmaple` documentation. A *sketch* is the IDE's notion of a project; it consists of one or @@ -419,21 +420,12 @@ Which could plausibly be turned into the final source file :: Recommended Reading ------------------- -* :ref:`libmaple Documentation <libmaple>` -* Your board's :ref:`Board Hardware Documentation <index-boards>` page -* ST Documentation: - * Reference Manual `RM0008 - <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ - (PDF). This is the most important reference work on the STM32 - line, and covers the low-level hardware capabilities and - interfaces in great detail. - * `Programming Manual - <http://www.st.com/stonline/products/literature/pm/15491.pdf>`_ - (PDF). This is an assembly language and register reference for - the STM32 line. -* ARM Documentation: - * `Cortex-M3 Technical Reference Manual, Revision r1p1 - <http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337e/DDI0337E_cortex_m3_r1p1_trm.pdf>`_ - (PDF). This ARM manual specifies much of the the Cortex M3 - Architecture, including instruction timings. -* `newlib Documentation <http://sourceware.org/newlib/>`_ +* :ref:`Your board's documentation <index-boards>` page, which + includes references to the relevant ST materials (reference manual, + datashseet, etc.) for your board. +* `ARM Cortex-M3 Technical Reference Manual, Revision r1p1 <http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337e/DDI0337E_cortex_m3_r1p1_trm.pdf>`_ + (PDF). This ARM manual specifies the Cortex-M3 architecture, + including instruction timings. +* :ref:`libmaple` +* `newlib's Documentation <http://sourceware.org/newlib/>`_ + (see :ref:`arm-gcc-libc`) diff --git a/source/libmaple.rst b/source/libmaple.rst index b06e73e..458241e 100644 --- a/source/libmaple.rst +++ b/source/libmaple.rst @@ -5,33 +5,39 @@ ``libmaple`` ============ -LeafLabs' libmaple (`source code on GitHub -<https://github.com/leaflabs/libmaple>`_) is the library we have -developed for the `STM32 <http://www.st.com/stonline>`_ line of ARM -Cortex M3 microcontrollers. Its high-level interfaces are -:ref:`largely compatible <arduino-compatibility>` with the AVR -libraries written for the `Arduino <http://arduino.cc>`_ and `Wiring -<http://wiring.org.co/>`_ development boards. +LeafLabs' libmaple is the open source library we have developed for +programming the `STM32 <http://www.st.com/stonline>`_ line of +microcontrollers. Libmaple's `source is on GitHub +<https://github.com/leaflabs/libmaple>`_; :ref:`patches are welcome +<libmaple-contributing>`. .. _libmaple-vs-wirish: -libmaple is split into two pieces: a lower level layer written in pure -C, which we call *libmaple proper* (in the `libmaple/ -<https://github.com/leaflabs/libmaple/tree/master/libmaple>`_ -directory of the source repository), and the Wiring-style C++ API -written on top of it, called *Wirish* (in `wirish/ -<https://github.com/leaflabs/libmaple/tree/master/wirish>`_; the -wirish APIs are :ref:`summarized here <language>`, with an :ref:`index -here <language-index>`). +Libmaple is split into two pieces: -libmaple is bundled with the :ref:`Maple IDE <ide>`. However, we -develop it separately, and :ref:`release it standalone -<unix-toolchain>` for advanced users who might chafe at the "sketch" -programming model of the IDE. +- A low-level layer, written in C, called *libmaple proper*, located + in the `libmaple/ + <https://github.com/leaflabs/libmaple/tree/master/libmaple>`_ + subdirectory of the source repository. + +- A high-level layer, written in C++, called *wirish*, in the `wirish/ + <https://github.com/leaflabs/libmaple/tree/master/wirish>`_ + subdirectory. -As always, :ref:`patches are welcome <libmaple-contributing>`. +Wirish is :ref:`largely compatible <arduino-compatibility>` with the +AVR libraries written for the `Arduino <http://arduino.cc>`_ and +`Wiring <http://wiring.org.co/>`_ development boards. The Wirish +:ref:`language` page is a good summary of what Wirish provides; a +:ref:`complete Wirish API index <language-index>` is also +available. :ref:`Wirish libraries <libraries>` are documented +separately. -**Contents:** +libmaple is bundled with the :ref:`Maple IDE <ide>`. However, we +develop it separately, and :ref:`release it standalone +<unix-toolchain>` for users who might chafe at the "sketch" +programming model of the IDE. The following pages document libmaple +proper. As such, they're intended for advanced users who know how to +write C. .. toctree:: :maxdepth: 1 @@ -40,4 +46,3 @@ As always, :ref:`patches are welcome <libmaple-contributing>`. libmaple/apis libmaple/contributing libmaple/coding-standard - diff --git a/source/libmaple/api/adc.rst b/source/libmaple/api/adc.rst index fecaece..2f06926 100644 --- a/source/libmaple/api/adc.rst +++ b/source/libmaple/api/adc.rst @@ -1,24 +1,31 @@ .. highlight:: c .. _libmaple-adc: -``adc.h`` -========= +``<libmaple/adc.h>`` +==================== :ref:`Analog to Digital Conversion <adc>` (ADC) support. +A common API for basic ADC functionality is available, but the +characteristics of the ADC peripherals vary slightly across +targets. To manage this, each target defines a small set of datatypes +expressing its capabilities (namely :ref:`adc_extsel_event +<adc-adc_extsel_event>`, :ref:`adc_smp_rate <adc-adc_smp_rate>`, and +:ref:`adc_prescaler <adc-adc_prescaler>`). + .. contents:: Contents :local: + :depth: 2 -Types ------ +Devices +------- + +The individual ADC peripherals have the following device struct. .. doxygenstruct:: adc_dev -.. doxygenstruct:: adc_reg_map -.. doxygenenum:: adc_extsel_event -.. doxygenenum:: adc_smp_rate -Devices -------- +The available ADC peripherals vary by target. The complete list is +``ADC1``, ``ADC2``, and ``ADC3``. .. doxygenvariable:: ADC1 .. doxygenvariable:: ADC2 @@ -27,189 +34,198 @@ Devices Functions --------- +Activation and Deactivation +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``adc_enable_single_swstart()`` is simple, portable function, which +enables an ADC and sets it up for its basic usage: performing single +conversions using :ref:`adc_read() <adc-adc_read>`. + +.. _adc-adc_enable_single_swstart: +.. doxygenfunction:: adc_enable_single_swstart + +The precise software sequence used varies by target, so this is a good +function to use if your program needs to support multiple MCUs. By +default, Wirish calls ``adc_enable_single_swstart()`` on all available +ADCs at ``init()`` time, so Wirish users don't have to call this +function. + +There are several other lower-level routines used for activating and +deactivating ADCs: + +.. _adc-adc_init: .. doxygenfunction:: adc_init -.. doxygenfunction:: adc_calibrate -.. doxygenfunction:: adc_set_extsel +.. _adc-adc_enable: .. doxygenfunction:: adc_enable +.. _adc-adc_disable: .. doxygenfunction:: adc_disable +.. _adc-adc_disable_all: .. doxygenfunction:: adc_disable_all -.. doxygenfunction:: adc_foreach -.. doxygenfunction:: adc_set_sample_rate + +ADC Conversion +~~~~~~~~~~~~~~ + +``adc_read()`` is a simple function which starts conversion on a +single ADC channel, blocks until it has completed, and returns the +converted result. Don't use the ADC device for any other purpose while +it's running. + +.. _adc-adc_read: .. doxygenfunction:: adc_read + +To use ``adc_read()``, the device must be configured appropriately. +You can do this with :ref:`adc_enable_single_swstart() +<adc-adc_enable_single_swstart>`. + +Note that for an ADC device to perform conversion on a GPIO input +(which is the usual case; the notable exception being taking +temperature reading), the pin must be configured for analog +conversion. Do this with :ref:`adc_config_gpio() +<adc-adc_config_gpio>`. + +Other routines helpful for ADC conversion: + +.. _adc-adc_set_reg_seqlen: .. doxygenfunction:: adc_set_reg_seqlen -.. doxygenfunction:: adc_set_exttrig +.. _adc-adc_set_extsel: +.. doxygenfunction:: adc_set_extsel -Register Map Base Pointers --------------------------- +.. _adc-adc_extsel_event: -.. doxygendefine:: ADC1_BASE -.. doxygendefine:: ADC2_BASE -.. doxygendefine:: ADC3_BASE +The last of these, :ref:`adc_set_extsel() <adc-adc_set_extsel>`, takes +a target-dependent ``adc_extsel_event`` argument. -Register Bit Definitions ------------------------- +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::adc_extsel_event + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::adc_extsel_event + +ADC Clock Prescaler +~~~~~~~~~~~~~~~~~~~ + +``adc_set_prescaler()`` is available for setting the prescaler which +determines the common ADC clock rate. (Wirish sets a sensible default +for this, so Wirish users ordinarily don't need to call this +function.) + +.. warning:: Increasing the ADC clock rate does speed conversion time, + but the ADC peripherals have a maximum clock rate which must not be + exceeded. Make sure to configure your system and ADC clocks to + respect your device's maximum rate. + +.. _adc_adc_set_prescaler: +.. doxygenfunction:: adc_set_prescaler -Status register +.. _adc-adc_prescaler: + +ADC prescaler values are target-dependent. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::adc_prescaler + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::adc_prescaler + +.. _adc-adc_set_sample_rate: + +ADC Sample Time ~~~~~~~~~~~~~~~ -.. doxygendefine:: ADC_SR_AWD_BIT -.. doxygendefine:: ADC_SR_EOC_BIT -.. doxygendefine:: ADC_SR_JEOC_BIT -.. doxygendefine:: ADC_SR_JSTRT_BIT -.. doxygendefine:: ADC_SR_STRT_BIT - -.. doxygendefine:: ADC_SR_AWD -.. doxygendefine:: ADC_SR_EOC -.. doxygendefine:: ADC_SR_JEOC -.. doxygendefine:: ADC_SR_JSTRT -.. doxygendefine:: ADC_SR_STRT - -Control register 1 -~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: ADC_CR1_EOCIE_BIT -.. doxygendefine:: ADC_CR1_AWDIE_BIT -.. doxygendefine:: ADC_CR1_JEOCIE_BIT -.. doxygendefine:: ADC_CR1_SCAN_BIT -.. doxygendefine:: ADC_CR1_AWDSGL_BIT -.. doxygendefine:: ADC_CR1_JAUTO_BIT -.. doxygendefine:: ADC_CR1_DISCEN_BIT -.. doxygendefine:: ADC_CR1_JDISCEN_BIT -.. doxygendefine:: ADC_CR1_JAWDEN_BIT -.. doxygendefine:: ADC_CR1_AWDEN_BIT - -.. doxygendefine:: ADC_CR1_AWDCH -.. doxygendefine:: ADC_CR1_EOCIE -.. doxygendefine:: ADC_CR1_AWDIE -.. doxygendefine:: ADC_CR1_JEOCIE -.. doxygendefine:: ADC_CR1_SCAN -.. doxygendefine:: ADC_CR1_AWDSGL -.. doxygendefine:: ADC_CR1_JAUTO -.. doxygendefine:: ADC_CR1_DISCEN -.. doxygendefine:: ADC_CR1_JDISCEN -.. doxygendefine:: ADC_CR1_DISCNUM -.. doxygendefine:: ADC_CR1_JAWDEN -.. doxygendefine:: ADC_CR1_AWDEN - -Control register 2 -~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: ADC_CR2_ADON_BIT -.. doxygendefine:: ADC_CR2_CONT_BIT -.. doxygendefine:: ADC_CR2_CAL_BIT -.. doxygendefine:: ADC_CR2_RSTCAL_BIT -.. doxygendefine:: ADC_CR2_DMA_BIT -.. doxygendefine:: ADC_CR2_ALIGN_BIT -.. doxygendefine:: ADC_CR2_JEXTTRIG_BIT -.. doxygendefine:: ADC_CR2_EXTTRIG_BIT -.. doxygendefine:: ADC_CR2_JSWSTART_BIT -.. doxygendefine:: ADC_CR2_SWSTART_BIT -.. doxygendefine:: ADC_CR2_TSEREFE_BIT - -.. doxygendefine:: ADC_CR2_ADON -.. doxygendefine:: ADC_CR2_CONT -.. doxygendefine:: ADC_CR2_CAL -.. doxygendefine:: ADC_CR2_RSTCAL -.. doxygendefine:: ADC_CR2_DMA -.. doxygendefine:: ADC_CR2_ALIGN -.. doxygendefine:: ADC_CR2_JEXTSEL -.. doxygendefine:: ADC_CR2_JEXTTRIG -.. doxygendefine:: ADC_CR2_EXTSEL -.. doxygendefine:: ADC_CR2_EXTTRIG -.. doxygendefine:: ADC_CR2_JSWSTART -.. doxygendefine:: ADC_CR2_SWSTART -.. doxygendefine:: ADC_CR2_TSEREFE - -Sample time register 1 -~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: ADC_SMPR1_SMP17 -.. doxygendefine:: ADC_SMPR1_SMP16 -.. doxygendefine:: ADC_SMPR1_SMP15 -.. doxygendefine:: ADC_SMPR1_SMP14 -.. doxygendefine:: ADC_SMPR1_SMP13 -.. doxygendefine:: ADC_SMPR1_SMP12 -.. doxygendefine:: ADC_SMPR1_SMP11 -.. doxygendefine:: ADC_SMPR1_SMP10 - -Sample time register 2 -~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: ADC_SMPR2_SMP9 -.. doxygendefine:: ADC_SMPR2_SMP8 -.. doxygendefine:: ADC_SMPR2_SMP7 -.. doxygendefine:: ADC_SMPR2_SMP6 -.. doxygendefine:: ADC_SMPR2_SMP5 -.. doxygendefine:: ADC_SMPR2_SMP4 -.. doxygendefine:: ADC_SMPR2_SMP3 -.. doxygendefine:: ADC_SMPR2_SMP2 -.. doxygendefine:: ADC_SMPR2_SMP1 -.. doxygendefine:: ADC_SMPR2_SMP0 - -Injected channel data offset register -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: ADC_JOFR_JOFFSET - -Watchdog high threshold register -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: ADC_HTR_HT - -Watchdog low threshold register -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: ADC_LTR_LT - -Regular sequence register 1 -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You can control the sampling time (in ADC cycles) for an entire ADC +device using ``adc_set_sample_rate()`` [#fchansamp]_. This function +**only controls the sample rate**; the total conversion time is equal +to the sample time plus an additional number of ADC cycles. Consult +the reference manual for your chip for more details. -.. doxygendefine:: ADC_SQR1_L -.. doxygendefine:: ADC_SQR1_SQ16 -.. doxygendefine:: ADC_SQR1_SQ15 -.. doxygendefine:: ADC_SQR1_SQ14 -.. doxygendefine:: ADC_SQR1_SQ13 +.. warning:: Decreasing ADC sample time speeds conversion, but it also + decreases the maximum allowable impedance of the voltage source you + are measuring. If your voltage source has a high impedance + (e.g. you're measuring Vcc through a potentiometer), and your + sample time is too low, you will get inaccurate results. Consult + the datasheet for your target for more details. -Regular sequence register 2 -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. note:: Wirish sets a sensible default sample rate to allow for + high-impedance inputs at ``init()`` time, but Wirish users who know + what they're doing may want to call this function to speed up ADC + conversion. -.. doxygendefine:: ADC_SQR2_SQ12 -.. doxygendefine:: ADC_SQR2_SQ11 -.. doxygendefine:: ADC_SQR2_SQ10 -.. doxygendefine:: ADC_SQR2_SQ9 -.. doxygendefine:: ADC_SQR2_SQ8 -.. doxygendefine:: ADC_SQR2_SQ7 +.. doxygenfunction:: adc_set_sample_rate -Regular sequence register 3 -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _adc-adc_smp_rate: + +The ``adc_smp_rate`` argument to :ref:`adc_set_sample_rate() +<adc-adc_set_sample_rate>` is target-dependent. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::adc_smp_rate + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::adc_smp_rate + +Miscellaneous +~~~~~~~~~~~~~ -.. doxygendefine:: ADC_SQR3_SQ6 -.. doxygendefine:: ADC_SQR3_SQ5 -.. doxygendefine:: ADC_SQR3_SQ4 -.. doxygendefine:: ADC_SQR3_SQ3 -.. doxygendefine:: ADC_SQR3_SQ2 -.. doxygendefine:: ADC_SQR3_SQ1 +.. FIXME [0.0.13] why don't adc_config_gpio()'s docs show up? -Injected sequence register -~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _adc-adc_foreach: +.. doxygenfunction:: adc_foreach + +.. _adc-adc_config_gpio: +.. doxygenfunction:: adc_config_gpio + +STM32F1 only +~~~~~~~~~~~~ + +The following routines are available only on STM32F1 targets. + +.. _adc-adc_set_exttrig: +.. doxygenfunction:: adc_set_exttrig + +``adc_calibrate()`` performs calibration necessary on STM32F1 before +using an ADC. Note that on STM32F1 targets, +:ref:`adc_enable_single_swstart() <adc-adc_enable_single_swstart>` +calls ``adc_calibrate()``, so there's no need to do it separately. + +.. _adc-adc_calibrate: +.. doxygenfunction:: adc_calibrate -.. doxygendefine:: ADC_JSQR_JL -.. doxygendefine:: ADC_JSQR_JL_1CONV -.. doxygendefine:: ADC_JSQR_JL_2CONV -.. doxygendefine:: ADC_JSQR_JL_3CONV -.. doxygendefine:: ADC_JSQR_JL_4CONV -.. doxygendefine:: ADC_JSQR_JSQ4 -.. doxygendefine:: ADC_JSQR_JSQ3 -.. doxygendefine:: ADC_JSQR_JSQ2 -.. doxygendefine:: ADC_JSQR_JSQ1 +Register Maps +------------- + +Individual ADC peripherals have the following register map. The base +pointers are ``ADC1_BASE``, ``ADC2_BASE``, and ``ADC3_BASE``. + +.. _adc-adc_reg_map: +.. doxygenstruct:: adc_reg_map + +On **STM32F2 targets**, there is an additional common set of registers +shared by all ADC peripherals. Its base pointer is +``ADC_COMMON_BASE``. + +.. _adc-adc_common_reg_map: +.. doxygenstruct:: stm32f2::adc_common_reg_map + +Register Bit Definitions +------------------------ -Injected data registers -~~~~~~~~~~~~~~~~~~~~~~~ +.. TODO [0.0.13] -.. doxygendefine:: ADC_JDR_JDATA +TODO -Regular data register -~~~~~~~~~~~~~~~~~~~~~ +.. rubric:: Footnotes -.. doxygendefine:: ADC_DR_ADC2DATA -.. doxygendefine:: ADC_DR_DATA +.. [#fchansamp] Per-channel sample time configuration is possible, + but currently unsupported. diff --git a/source/libmaple/api/bitband.rst b/source/libmaple/api/bitband.rst index 5251015..768f678 100644 --- a/source/libmaple/api/bitband.rst +++ b/source/libmaple/api/bitband.rst @@ -1,8 +1,8 @@ .. highlight:: c .. _libmaple-bitband: -``bitband.h`` -============= +``<libmaple/bitband.h>`` +======================== Bit-banding support. diff --git a/source/libmaple/api/delay.rst b/source/libmaple/api/delay.rst index 5d0397d..d11496b 100644 --- a/source/libmaple/api/delay.rst +++ b/source/libmaple/api/delay.rst @@ -1,12 +1,11 @@ .. highlight:: c .. _libmaple-delay: -``delay.h`` -=========== +``<libmaple/delay.h>`` +====================== -Simple busy-loop delaying. - -Functions ---------- +Provides a simple busy-loop delay function. Note that this function +does not account for time spent in interrupts, so actual delay times +may vary depending on your application. .. doxygenfunction:: delay_us diff --git a/source/libmaple/api/flash.rst b/source/libmaple/api/flash.rst index 8a7e79b..52ff4d2 100644 --- a/source/libmaple/api/flash.rst +++ b/source/libmaple/api/flash.rst @@ -1,97 +1,249 @@ .. highlight:: c .. _libmaple-flash: -``flash.h`` -=========== +``<libmaple/flash.h>`` +====================== -Flash support. +Flash memory support. + +The built-in Flash on different STM32 MCUs varies in terms of its +eraseable page/sector size and read/write protections. There isn't +currently much support for dealing with this. This header is mostly +useful for its functions that control Flash features which affect +system performance, like wait states and prefetch buffers. .. contents:: Contents :local: -Types ------ +Devices +------- -.. doxygenstruct:: flash_reg_map +None at this time. Functions --------- -.. doxygenfunction:: flash_enable_prefetch +The following functions can be used to portably manipulate Flash memory. + .. doxygenfunction:: flash_set_latency +.. doxygenfunction:: flash_enable_features +.. doxygenfunction:: flash_enable_prefetch -Register Map Base Pointers --------------------------- +Register Maps +------------- + +Register maps vary by target. The base pointer is always ``FLASH_BASE``. + +Base Pointer +~~~~~~~~~~~~ .. doxygendefine:: FLASH_BASE +STM32F1 targets +~~~~~~~~~~~~~~~ + +.. doxygenstruct:: stm32f1::flash_reg_map + +STM32F2 targets +~~~~~~~~~~~~~~~ + +.. doxygenstruct:: stm32f2::flash_reg_map + Register Bit Definitions ------------------------ -Access control register -~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: FLASH_ACR_PRFTBS_BIT -.. doxygendefine:: FLASH_ACR_PRFTBE_BIT -.. doxygendefine:: FLASH_ACR_HLFCYA_BIT +These are given as source code. Available register bit definitions +vary by target. -.. doxygendefine:: FLASH_ACR_PRFTBS -.. doxygendefine:: FLASH_ACR_PRFTBE -.. doxygendefine:: FLASH_ACR_HLFCYA -.. doxygendefine:: FLASH_ACR_LATENCY +STM32F1 Targets +~~~~~~~~~~~~~~~ -Status register +:: + + /* Access control register */ + + #define FLASH_ACR_PRFTBS_BIT 5 + #define FLASH_ACR_PRFTBE_BIT 4 + #define FLASH_ACR_HLFCYA_BIT 3 + + #define FLASH_ACR_PRFTBS (1U << FLASH_ACR_PRFTBS_BIT) + #define FLASH_ACR_PRFTBE (1U << FLASH_ACR_PRFTBE_BIT) + #define FLASH_ACR_HLFCYA (1U << FLASH_ACR_HLFCYA_BIT) + #define FLASH_ACR_LATENCY 0x7 + + /* Status register */ + + #define FLASH_SR_EOP_BIT 5 + #define FLASH_SR_WRPRTERR_BIT 4 + #define FLASH_SR_PGERR_BIT 2 + #define FLASH_SR_BSY_BIT 0 + + #define FLASH_SR_EOP (1U << FLASH_SR_EOP_BIT) + #define FLASH_SR_WRPRTERR (1U << FLASH_SR_WRPRTERR_BIT) + #define FLASH_SR_PGERR (1U << FLASH_SR_PGERR_BIT) + #define FLASH_SR_BSY (1U << FLASH_SR_BSY_BIT) + + /* Control register */ + + #define FLASH_CR_EOPIE_BIT 12 + #define FLASH_CR_ERRIE_BIT 10 + #define FLASH_CR_OPTWRE_BIT 9 + #define FLASH_CR_LOCK_BIT 7 + #define FLASH_CR_STRT_BIT 6 + #define FLASH_CR_OPTER_BIT 5 + #define FLASH_CR_OPTPG_BIT 4 + #define FLASH_CR_MER_BIT 2 + #define FLASH_CR_PER_BIT 1 + #define FLASH_CR_PG_BIT 0 + + #define FLASH_CR_EOPIE (1U << FLASH_CR_EOPIE_BIT) + #define FLASH_CR_ERRIE (1U << FLASH_CR_ERRIE_BIT) + #define FLASH_CR_OPTWRE (1U << FLASH_CR_OPTWRE_BIT) + #define FLASH_CR_LOCK (1U << FLASH_CR_LOCK_BIT) + #define FLASH_CR_STRT (1U << FLASH_CR_STRT_BIT) + #define FLASH_CR_OPTER (1U << FLASH_CR_OPTER_BIT) + #define FLASH_CR_OPTPG (1U << FLASH_CR_OPTPG_BIT) + #define FLASH_CR_MER (1U << FLASH_CR_MER_BIT) + #define FLASH_CR_PER (1U << FLASH_CR_PER_BIT) + #define FLASH_CR_PG (1U << FLASH_CR_PG_BIT) + + /* Option byte register */ + + #define FLASH_OBR_nRST_STDBY_BIT 4 + #define FLASH_OBR_nRST_STOP_BIT 3 + #define FLASH_OBR_WDG_SW_BIT 2 + #define FLASH_OBR_RDPRT_BIT 1 + #define FLASH_OBR_OPTERR_BIT 0 + + #define FLASH_OBR_DATA1 (0xFF << 18) + #define FLASH_OBR_DATA0 (0xFF << 10) + #define FLASH_OBR_USER 0x3FF + #define FLASH_OBR_nRST_STDBY (1U << FLASH_OBR_nRST_STDBY_BIT) + #define FLASH_OBR_nRST_STOP (1U << FLASH_OBR_nRST_STOP_BIT) + #define FLASH_OBR_WDG_SW (1U << FLASH_OBR_WDG_SW_BIT) + #define FLASH_OBR_RDPRT (1U << FLASH_OBR_RDPRT_BIT) + #define FLASH_OBR_OPTERR (1U << FLASH_OBR_OPTERR_BIT) + +STM32F2 Targets ~~~~~~~~~~~~~~~ -.. doxygendefine:: FLASH_SR_EOP_BIT -.. doxygendefine:: FLASH_SR_WRPRTERR_BIT -.. doxygendefine:: FLASH_SR_PGERR_BIT -.. doxygendefine:: FLASH_SR_BSY_BIT - -.. doxygendefine:: FLASH_SR_EOP -.. doxygendefine:: FLASH_SR_WRPRTERR -.. doxygendefine:: FLASH_SR_PGERR -.. doxygendefine:: FLASH_SR_BSY - -Control register -~~~~~~~~~~~~~~~~ - -.. doxygendefine:: FLASH_CR_EOPIE_BIT -.. doxygendefine:: FLASH_CR_ERRIE_BIT -.. doxygendefine:: FLASH_CR_OPTWRE_BIT -.. doxygendefine:: FLASH_CR_LOCK_BIT -.. doxygendefine:: FLASH_CR_STRT_BIT -.. doxygendefine:: FLASH_CR_OPTER_BIT -.. doxygendefine:: FLASH_CR_OPTPG_BIT -.. doxygendefine:: FLASH_CR_MER_BIT -.. doxygendefine:: FLASH_CR_PER_BIT -.. doxygendefine:: FLASH_CR_PG_BIT - -.. doxygendefine:: FLASH_CR_EOPIE -.. doxygendefine:: FLASH_CR_ERRIE -.. doxygendefine:: FLASH_CR_OPTWRE -.. doxygendefine:: FLASH_CR_LOCK -.. doxygendefine:: FLASH_CR_STRT -.. doxygendefine:: FLASH_CR_OPTER -.. doxygendefine:: FLASH_CR_OPTPG -.. doxygendefine:: FLASH_CR_MER -.. doxygendefine:: FLASH_CR_PER -.. doxygendefine:: FLASH_CR_PG - -Option byte register -~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: FLASH_OBR_nRST_STDBY_BIT -.. doxygendefine:: FLASH_OBR_nRST_STOP_BIT -.. doxygendefine:: FLASH_OBR_WDG_SW_BIT -.. doxygendefine:: FLASH_OBR_RDPRT_BIT -.. doxygendefine:: FLASH_OBR_OPTERR_BIT - -.. doxygendefine:: FLASH_OBR_DATA1 -.. doxygendefine:: FLASH_OBR_DATA0 -.. doxygendefine:: FLASH_OBR_USER -.. doxygendefine:: FLASH_OBR_nRST_STDBY -.. doxygendefine:: FLASH_OBR_nRST_STOP -.. doxygendefine:: FLASH_OBR_WDG_SW -.. doxygendefine:: FLASH_OBR_RDPRT -.. doxygendefine:: FLASH_OBR_OPTERR +:: + + /* Access control register */ + + #define FLASH_ACR_DCRST_BIT 12 + #define FLASH_ACR_ICRST_BIT 11 + #define FLASH_ACR_DCEN_BIT 10 + #define FLASH_ACR_ICEN_BIT 9 + #define FLASH_ACR_PRFTEN_BIT 8 + + #define FLASH_ACR_DCRST (1U << FLASH_ACR_DCRST_BIT) + #define FLASH_ACR_ICRST (1U << FLASH_ACR_ICRST_BIT) + #define FLASH_ACR_DCEN (1U << FLASH_ACR_DCEN_BIT) + #define FLASH_ACR_ICEN (1U << FLASH_ACR_ICEN_BIT) + #define FLASH_ACR_PRFTEN (1U << FLASH_ACR_PRFTEN_BIT) + #define FLASH_ACR_LATENCY 0x7 + #define FLASH_ACR_LATENCY_0WS 0x0 + #define FLASH_ACR_LATENCY_1WS 0x1 + #define FLASH_ACR_LATENCY_2WS 0x2 + #define FLASH_ACR_LATENCY_3WS 0x3 + #define FLASH_ACR_LATENCY_4WS 0x4 + #define FLASH_ACR_LATENCY_5WS 0x5 + #define FLASH_ACR_LATENCY_6WS 0x6 + #define FLASH_ACR_LATENCY_7WS 0x7 + + /* Key register */ + + #define FLASH_KEYR_KEY1 0x45670123 + #define FLASH_KEYR_KEY2 0xCDEF89AB + + /* Option key register */ + + #define FLASH_OPTKEYR_OPTKEY1 0x08192A3B + #define FLASH_OPTKEYR_OPTKEY2 0x4C5D6E7F + + /* Status register */ + + #define FLASH_SR_BSY_BIT 16 + #define FLASH_SR_PGSERR_BIT 7 + #define FLASH_SR_PGPERR_BIT 6 + #define FLASH_SR_PGAERR_BIT 5 + #define FLASH_SR_WRPERR_BIT 4 + #define FLASH_SR_OPERR_BIT 1 + #define FLASH_SR_EOP_BIT 0 + + #define FLASH_SR_BSY (1U << FLASH_SR_BSY_BIT) + #define FLASH_SR_PGSERR (1U << FLASH_SR_PGSERR_BIT) + #define FLASH_SR_PGPERR (1U << FLASH_SR_PGPERR_BIT) + #define FLASH_SR_PGAERR (1U << FLASH_SR_PGAERR_BIT) + #define FLASH_SR_WRPERR (1U << FLASH_SR_WRPERR_BIT) + #define FLASH_SR_OPERR (1U << FLASH_SR_OPERR_BIT) + #define FLASH_SR_EOP (1U << FLASH_SR_EOP_BIT) + + /* Control register */ + + #define FLASH_CR_LOCK_BIT 31 + #define FLASH_CR_ERRIE_BIT 25 + #define FLASH_CR_EOPIE_BIT 24 + #define FLASH_CR_STRT_BIT 16 + #define FLASH_CR_MER_BIT 2 + #define FLASH_CR_SER_BIT 1 + #define FLASH_CR_PG_BIT 0 + + #define FLASH_CR_LOCK (1U << FLASH_CR_LOCK_BIT) + #define FLASH_CR_ERRIE (1U << FLASH_CR_ERRIE_BIT) + #define FLASH_CR_EOPIE (1U << FLASH_CR_EOPIE_BIT) + #define FLASH_CR_STRT (1U << FLASH_CR_STRT_BIT) + + #define FLASH_CR_PSIZE (0x3 << 8) + #define FLASH_CR_PSIZE_MUL8 (0x0 << 8) + #define FLASH_CR_PSIZE_MUL16 (0x1 << 8) + #define FLASH_CR_PSIZE_MUL32 (0x2 << 8) + #define FLASH_CR_PSIZE_MUL64 (0x3 << 8) + + #define FLASH_CR_SNB (0xF << 3) + #define FLASH_CR_SNB_0 (0x0 << 3) + #define FLASH_CR_SNB_1 (0x1 << 3) + #define FLASH_CR_SNB_2 (0x2 << 3) + #define FLASH_CR_SNB_3 (0x3 << 3) + #define FLASH_CR_SNB_4 (0x4 << 3) + #define FLASH_CR_SNB_5 (0x5 << 3) + #define FLASH_CR_SNB_6 (0x6 << 3) + #define FLASH_CR_SNB_7 (0x7 << 3) + #define FLASH_CR_SNB_8 (0x8 << 3) + #define FLASH_CR_SNB_9 (0x9 << 3) + #define FLASH_CR_SNB_10 (0xA << 3) + #define FLASH_CR_SNB_11 (0xB << 3) + + #define FLASH_CR_MER (1U << FLASH_CR_MER_BIT) + #define FLASH_CR_SER (1U << FLASH_CR_SER_BIT) + #define FLASH_CR_PG (1U << FLASH_CR_PG_BIT) + + /* Option control register */ + + #define FLASH_OPTCR_NRST_STDBY_BIT 7 + #define FLASH_OPTCR_NRST_STOP_BIT 6 + #define FLASH_OPTCR_WDG_SW_BIT 5 + #define FLASH_OPTCR_OPTSTRT_BIT 1 + #define FLASH_OPTCR_OPTLOCK_BIT 0 + + #define FLASH_OPTCR_NWRP (0x3FF << 16) + + /* Excluded: The many level 1 values */ + #define FLASH_OPTCR_RDP (0xFF << 8) + #define FLASH_OPTCR_RDP_LEVEL0 (0xAA << 8) + #define FLASH_OPTCR_RDP_LEVEL2 (0xCC << 8) + + #define FLASH_OPTCR_USER (0x7 << 5) + #define FLASH_OPTCR_nRST_STDBY (1U << FLASH_OPTCR_nRST_STDBY_BIT) + #define FLASH_OPTCR_nRST_STOP (1U << FLASH_OPTCR_nRST_STOP_BIT) + #define FLASH_OPTCR_WDG_SW (1U << FLASH_OPTCR_WDG_SW_BIT) + + #define FLASH_OPTCR_BOR_LEV (0x3 << 2) + #define FLASH_OPTCR_BOR_LEVEL3 (0x0 << 2) + #define FLASH_OPTCR_BOR_LEVEL2 (0x1 << 2) + #define FLASH_OPTCR_BOR_LEVEL1 (0x2 << 2) + #define FLASH_OPTCR_BOR_OFF (0x3 << 2) + + #define FLASH_OPTCR_OPTSTRT (1U << FLASH_OPTCR_OPTSTRT_BIT) + #define FLASH_OPTCR_OPTLOCK (1U << FLASH_OPTCR_OPTLOCK_BIT) diff --git a/source/libmaple/api/fsmc.rst b/source/libmaple/api/fsmc.rst index 3b356cc..e2bf87a 100644 --- a/source/libmaple/api/fsmc.rst +++ b/source/libmaple/api/fsmc.rst @@ -1,19 +1,43 @@ .. highlight:: c .. _libmaple-fsmc: -``fsmc.h`` -========== +``<libmaple/fsmc.h>`` +===================== -Flexible Static Memory Controller (FSMC) support. +Flexible Static Memory Controller (FSMC) support. The FSMC peripheral +is only available on some targets. Including this header on a target +without an FSMC will cause a compilation error. Check your target's +documentation to determine if it's available. You can also use +:ref:`STM32_HAVE_FSMC <libmaple-stm32-STM32_HAVE_FSMC>` from +``<libmaple/stm32.h>`` to determine whether your target has an FSMC at +build time. + +All functionality documented here is portable. .. contents:: Contents :local: -Types ------ +Usage Note +---------- -.. doxygenstruct:: fsmc_reg_map -.. doxygenstruct:: fsmc_nor_psram_reg_map +FSMC support is fairly limited at this time. Current Leaflabs boards +only use the FSMC to interface with external SRAM chips, so that's +what there's the most support for (:ref:`patches welcome! +<libmaple-contributing>`). Even for use with SRAM, you will still need +to program some registers directly. + +To use the FSMC with an SRAM chip, first call +:ref:`fsmc_sram_init_gpios() <libmaple-fsmc-fsmc_sram_init_gpios>` to +configure its data, address, and control lines. Then, turn on the +FSMC clock (by calling :ref:`rcc_clk_enable(RCC_FSMC) +<libmaple-rcc-rcc_clk_enable>`). You can then configure the relevant +:ref:`fsmc_nor_psram_reg_map <libmaple-fsmc-fsmc_nor_psram_reg_map>` +``BCR`` register yourself for the SRAM chip you are using. + +You can additionally use :ref:`fsmc_nor_psram_set_datast() +<libmaple-fsmc-fsmc_nor_psram_set_datast>` and +:ref:`fsmc_nor_psram_set_datast() <libmaple-fsmc-fsmc_nor_psram_set_datast>` +to control read/write timing. Devices ------- @@ -23,13 +47,49 @@ None at this time. Functions --------- +.. _libmaple-fsmc-fsmc_sram_init_gpios: .. doxygenfunction:: fsmc_sram_init_gpios +.. _libmaple-fsmc-fsmc_nor_psram_set_datast: .. doxygenfunction:: fsmc_nor_psram_set_datast +.. _libmaple-fsmc-fsmc_nor_psram_set_addset: .. doxygenfunction:: fsmc_nor_psram_set_addset +Register Maps +------------- + +The general purpose register map type is ``fsmc_reg_map``; its base +pointer is ``FSMC_BASE``. The ``fsmc_nor_psram_reg_map`` type is for +use configuring the registers for an individual NOR/PSRAM region +(``FSMC_BCRx``, ``FSMC_BTRx``, and ``FSMC_BWTRx``); the relevant base +pointers are ``FSMC_NOR_PSRAM_REGION1`` through +``FSMC_NOR_PSRAM_REGION4``. + +.. doxygendefine:: FSMC_BASE + +.. doxygendefine:: FSMC_NOR_PSRAM1_BASE +.. doxygendefine:: FSMC_NOR_PSRAM2_BASE +.. doxygendefine:: FSMC_NOR_PSRAM3_BASE +.. doxygendefine:: FSMC_NOR_PSRAM4_BASE + +.. doxygenstruct:: fsmc_reg_map +.. _libmaple-fsmc-fsmc_nor_psram_reg_map: +.. doxygenstruct:: fsmc_nor_psram_reg_map + Memory Bank Boundary Addresses ------------------------------ +Reading and writing data on an external memory chip using FSMC is done +by reading and writing from addresses in special memory-mapped +sections of the address space called *memory banks*. + +This is convenient, since it implies that the usual load and store +instructions used for I/O with the internal SRAM are also used to +perform bus transactions with the external memory chip. (Which means +you can use ``memcpy()`` etc. on external memory.) + +Pointers to the memory banks' base addresses are given by the +following macros. + .. doxygendefine:: FSMC_BANK1 .. doxygendefine:: FSMC_BANK2 .. doxygendefine:: FSMC_BANK3 @@ -40,150 +100,136 @@ Memory Bank Boundary Addresses .. doxygendefine:: FSMC_NOR_PSRAM_REGION3 .. doxygendefine:: FSMC_NOR_PSRAM_REGION4 -Register Map Base Pointers --------------------------- - -.. doxygendefine:: FSMC_BASE - -.. doxygendefine:: FSMC_NOR_PSRAM1_BASE -.. doxygendefine:: FSMC_NOR_PSRAM2_BASE -.. doxygendefine:: FSMC_NOR_PSRAM3_BASE -.. doxygendefine:: FSMC_NOR_PSRAM4_BASE - Register Bit Definitions ------------------------ -NOR/PSRAM Chip-Select Control Registers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: FSMC_BCR_CBURSTRW_BIT -.. doxygendefine:: FSMC_BCR_ASYNCWAIT_BIT -.. doxygendefine:: FSMC_BCR_EXTMOD_BIT -.. doxygendefine:: FSMC_BCR_WAITEN_BIT -.. doxygendefine:: FSMC_BCR_WREN_BIT -.. doxygendefine:: FSMC_BCR_WAITCFG_BIT -.. doxygendefine:: FSMC_BCR_WRAPMOD_BIT -.. doxygendefine:: FSMC_BCR_WAITPOL_BIT -.. doxygendefine:: FSMC_BCR_BURSTEN_BIT -.. doxygendefine:: FSMC_BCR_FACCEN_BIT -.. doxygendefine:: FSMC_BCR_MUXEN_BIT -.. doxygendefine:: FSMC_BCR_MBKEN_BIT - -.. doxygendefine:: FSMC_BCR_CBURSTRW -.. doxygendefine:: FSMC_BCR_ASYNCWAIT -.. doxygendefine:: FSMC_BCR_EXTMOD -.. doxygendefine:: FSMC_BCR_WAITEN -.. doxygendefine:: FSMC_BCR_WREN -.. doxygendefine:: FSMC_BCR_WAITCFG -.. doxygendefine:: FSMC_BCR_WRAPMOD -.. doxygendefine:: FSMC_BCR_WAITPOL -.. doxygendefine:: FSMC_BCR_BURSTEN -.. doxygendefine:: FSMC_BCR_FACCEN -.. doxygendefine:: FSMC_BCR_MWID -.. doxygendefine:: FSMC_BCR_MWID_8BITS -.. doxygendefine:: FSMC_BCR_MWID_16BITS -.. doxygendefine:: FSMC_BCR_MTYP -.. doxygendefine:: FSMC_BCR_MTYP_SRAM -.. doxygendefine:: FSMC_BCR_MTYP_PSRAM -.. doxygendefine:: FSMC_BCR_MTYP_NOR_FLASH -.. doxygendefine:: FSMC_BCR_MUXEN -.. doxygendefine:: FSMC_BCR_MBKEN - -SRAM/NOR-Flash Chip-Select Timing Registers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: FSMC_BTR_ACCMOD -.. doxygendefine:: FSMC_BTR_ACCMOD_A -.. doxygendefine:: FSMC_BTR_ACCMOD_B -.. doxygendefine:: FSMC_BTR_ACCMOD_C -.. doxygendefine:: FSMC_BTR_ACCMOD_D -.. doxygendefine:: FSMC_BTR_DATLAT -.. doxygendefine:: FSMC_BTR_CLKDIV -.. doxygendefine:: FSMC_BTR_BUSTURN -.. doxygendefine:: FSMC_BTR_DATAST -.. doxygendefine:: FSMC_BTR_ADDHLD -.. doxygendefine:: FSMC_BTR_ADDSET - -SRAM/NOR-Flash Write Timing Registers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: FSMC_BWTR_ACCMOD -.. doxygendefine:: FSMC_BWTR_ACCMOD_A -.. doxygendefine:: FSMC_BWTR_ACCMOD_B -.. doxygendefine:: FSMC_BWTR_ACCMOD_C -.. doxygendefine:: FSMC_BWTR_ACCMOD_D -.. doxygendefine:: FSMC_BWTR_DATLAT -.. doxygendefine:: FSMC_BWTR_CLKDIV -.. doxygendefine:: FSMC_BWTR_DATAST -.. doxygendefine:: FSMC_BWTR_ADDHLD -.. doxygendefine:: FSMC_BWTR_ADDSET - -NAND Flash/PC Card Controller Registers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: FSMC_PCR_ECCEN_BIT -.. doxygendefine:: FSMC_PCR_PTYP_BIT -.. doxygendefine:: FSMC_PCR_PBKEN_BIT -.. doxygendefine:: FSMC_PCR_PWAITEN_BIT - -.. doxygendefine:: FSMC_PCR_ECCPS -.. doxygendefine:: FSMC_PCR_ECCPS_256B -.. doxygendefine:: FSMC_PCR_ECCPS_512B -.. doxygendefine:: FSMC_PCR_ECCPS_1024B -.. doxygendefine:: FSMC_PCR_ECCPS_2048B -.. doxygendefine:: FSMC_PCR_ECCPS_4096B -.. doxygendefine:: FSMC_PCR_ECCPS_8192B -.. doxygendefine:: FSMC_PCR_TAR -.. doxygendefine:: FSMC_PCR_TCLR -.. doxygendefine:: FSMC_PCR_ECCEN -.. doxygendefine:: FSMC_PCR_PWID -.. doxygendefine:: FSMC_PCR_PWID_8BITS -.. doxygendefine:: FSMC_PCR_PWID_16BITS -.. doxygendefine:: FSMC_PCR_PTYP -.. doxygendefine:: FSMC_PCR_PTYP_PC_CF_PCMCIA -.. doxygendefine:: FSMC_PCR_PTYP_NAND -.. doxygendefine:: FSMC_PCR_PBKEN -.. doxygendefine:: FSMC_PCR_PWAITEN - -FIFO Status And Interrupt Registers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: FSMC_SR_FEMPT_BIT -.. doxygendefine:: FSMC_SR_IFEN_BIT -.. doxygendefine:: FSMC_SR_ILEN_BIT -.. doxygendefine:: FSMC_SR_IREN_BIT -.. doxygendefine:: FSMC_SR_IFS_BIT -.. doxygendefine:: FSMC_SR_ILS_BIT -.. doxygendefine:: FSMC_SR_IRS_BIT - -.. doxygendefine:: FSMC_SR_FEMPT -.. doxygendefine:: FSMC_SR_IFEN -.. doxygendefine:: FSMC_SR_ILEN -.. doxygendefine:: FSMC_SR_IREN -.. doxygendefine:: FSMC_SR_IFS -.. doxygendefine:: FSMC_SR_ILS -.. doxygendefine:: FSMC_SR_IRS - -Common Memory Space Timing Registers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: FSMC_PMEM_MEMHIZ -.. doxygendefine:: FSMC_PMEM_MEMHOLD -.. doxygendefine:: FSMC_PMEM_MEMWAIT -.. doxygendefine:: FSMC_PMEM_MEMSET - -Attribute Memory Space Timing Registers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: FSMC_PATT_ATTHIZ -.. doxygendefine:: FSMC_PATT_ATTHOLD -.. doxygendefine:: FSMC_PATT_ATTWAIT -.. doxygendefine:: FSMC_PATT_ATTSET - -I/O Space Timing Register 4 -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: FSMC_PIO_IOHIZ -.. doxygendefine:: FSMC_PIO_IOHOLD -.. doxygendefine:: FSMC_PIO_IOWAIT -.. doxygendefine:: FSMC_PIO_IOSET +These are given as source code. + +:: + + /* NOR/PSRAM chip-select control registers */ + + #define FSMC_BCR_CBURSTRW_BIT 19 + #define FSMC_BCR_ASYNCWAIT_BIT 15 + #define FSMC_BCR_EXTMOD_BIT 14 + #define FSMC_BCR_WAITEN_BIT 13 + #define FSMC_BCR_WREN_BIT 12 + #define FSMC_BCR_WAITCFG_BIT 11 + #define FSMC_BCR_WRAPMOD_BIT 10 + #define FSMC_BCR_WAITPOL_BIT 9 + #define FSMC_BCR_BURSTEN_BIT 8 + #define FSMC_BCR_FACCEN_BIT 6 + #define FSMC_BCR_MUXEN_BIT 1 + #define FSMC_BCR_MBKEN_BIT 0 + + #define FSMC_BCR_CBURSTRW (1U << FSMC_BCR_CBURSTRW_BIT) + #define FSMC_BCR_ASYNCWAIT (1U << FSMC_BCR_ASYNCWAIT_BIT) + #define FSMC_BCR_EXTMOD (1U << FSMC_BCR_EXTMOD_BIT) + #define FSMC_BCR_WAITEN (1U << FSMC_BCR_WAITEN_BIT) + #define FSMC_BCR_WREN (1U << FSMC_BCR_WREN_BIT) + #define FSMC_BCR_WAITCFG (1U << FSMC_BCR_WAITCFG_BIT) + #define FSMC_BCR_WRAPMOD (1U << FSMC_BCR_WRAPMOD_BIT) + #define FSMC_BCR_WAITPOL (1U << FSMC_BCR_WAITPOL_BIT) + #define FSMC_BCR_BURSTEN (1U << FSMC_BCR_BURSTEN_BIT) + #define FSMC_BCR_FACCEN (1U << FSMC_BCR_FACCEN_BIT) + #define FSMC_BCR_MWID (0x3 << 4) + #define FSMC_BCR_MWID_8BITS (0x0 << 4) + #define FSMC_BCR_MWID_16BITS (0x1 << 4) + #define FSMC_BCR_MTYP (0x3 << 2) + #define FSMC_BCR_MTYP_SRAM (0x0 << 2) + #define FSMC_BCR_MTYP_PSRAM (0x1 << 2) + #define FSMC_BCR_MTYP_NOR_FLASH (0x2 << 2) + #define FSMC_BCR_MUXEN (1U << FSMC_BCR_MUXEN_BIT) + #define FSMC_BCR_MBKEN (1U << FSMC_BCR_MBKEN_BIT) + + /* SRAM/NOR-Flash chip-select timing registers */ + + #define FSMC_BTR_ACCMOD (0x3 << 28) + #define FSMC_BTR_ACCMOD_A (0x0 << 28) + #define FSMC_BTR_ACCMOD_B (0x1 << 28) + #define FSMC_BTR_ACCMOD_C (0x2 << 28) + #define FSMC_BTR_ACCMOD_D (0x3 << 28) + #define FSMC_BTR_DATLAT (0xF << 24) + #define FSMC_BTR_CLKDIV (0xF << 20) + #define FSMC_BTR_BUSTURN (0xF << 16) + #define FSMC_BTR_DATAST (0xFF << 8) + #define FSMC_BTR_ADDHLD (0xF << 4) + #define FSMC_BTR_ADDSET 0xF + + /* SRAM/NOR-Flash write timing registers */ + + #define FSMC_BWTR_ACCMOD (0x3 << 28) + #define FSMC_BWTR_ACCMOD_A (0x0 << 28) + #define FSMC_BWTR_ACCMOD_B (0x1 << 28) + #define FSMC_BWTR_ACCMOD_C (0x2 << 28) + #define FSMC_BWTR_ACCMOD_D (0x3 << 28) + #define FSMC_BWTR_DATLAT (0xF << 24) + #define FSMC_BWTR_CLKDIV (0xF << 20) + #define FSMC_BWTR_DATAST (0xFF << 8) + #define FSMC_BWTR_ADDHLD (0xF << 4) + #define FSMC_BWTR_ADDSET 0xF + + /* NAND Flash/PC Card controller registers */ + + #define FSMC_PCR_ECCEN_BIT 6 + #define FSMC_PCR_PTYP_BIT 3 + #define FSMC_PCR_PBKEN_BIT 2 + #define FSMC_PCR_PWAITEN_BIT 1 + + #define FSMC_PCR_ECCPS (0x7 << 17) + #define FSMC_PCR_ECCPS_256B (0x0 << 17) + #define FSMC_PCR_ECCPS_512B (0x1 << 17) + #define FSMC_PCR_ECCPS_1024B (0x2 << 17) + #define FSMC_PCR_ECCPS_2048B (0x3 << 17) + #define FSMC_PCR_ECCPS_4096B (0x4 << 17) + #define FSMC_PCR_ECCPS_8192B (0x5 << 17) + #define FSMC_PCR_TAR (0xF << 13) + #define FSMC_PCR_TCLR (0xF << 9) + #define FSMC_PCR_ECCEN (1U << FSMC_PCR_ECCEN_BIT) + #define FSMC_PCR_PWID (0x3 << 4) + #define FSMC_PCR_PWID_8BITS (0x0 << 4) + #define FSMC_PCR_PWID_16BITS (0x1 << 4) + #define FSMC_PCR_PTYP (1U << FSMC_PCR_PTYP_BIT) + #define FSMC_PCR_PTYP_PC_CF_PCMCIA (0x0 << FSMC_PCR_PTYP_BIT) + #define FSMC_PCR_PTYP_NAND (0x1 << FSMC_PCR_PTYP_BIT) + #define FSMC_PCR_PBKEN (1U << FSMC_PCR_PBKEN_BIT) + #define FSMC_PCR_PWAITEN (1U << FSMC_PCR_PWAITEN_BIT) + + /* FIFO status and interrupt registers */ + + #define FSMC_SR_FEMPT_BIT 6 + #define FSMC_SR_IFEN_BIT 5 + #define FSMC_SR_ILEN_BIT 4 + #define FSMC_SR_IREN_BIT 3 + #define FSMC_SR_IFS_BIT 2 + #define FSMC_SR_ILS_BIT 1 + #define FSMC_SR_IRS_BIT 0 + + #define FSMC_SR_FEMPT (1U << FSMC_SR_FEMPT_BIT) + #define FSMC_SR_IFEN (1U << FSMC_SR_IFEN_BIT) + #define FSMC_SR_ILEN (1U << FSMC_SR_ILEN_BIT) + #define FSMC_SR_IREN (1U << FSMC_SR_IREN_BIT) + #define FSMC_SR_IFS (1U << FSMC_SR_IFS_BIT) + #define FSMC_SR_ILS (1U << FSMC_SR_ILS_BIT) + #define FSMC_SR_IRS (1U << FSMC_SR_IRS_BIT) + + /* Common memory space timing registers */ + + #define FSMC_PMEM_MEMHIZ (0xFF << 24) + #define FSMC_PMEM_MEMHOLD (0xFF << 16) + #define FSMC_PMEM_MEMWAIT (0xFF << 8) + #define FSMC_PMEM_MEMSET 0xFF + + /* Attribute memory space timing registers */ + + #define FSMC_PATT_ATTHIZ (0xFF << 24) + #define FSMC_PATT_ATTHOLD (0xFF << 16) + #define FSMC_PATT_ATTWAIT (0xFF << 8) + #define FSMC_PATT_ATTSET 0xFF + + /* I/O space timing register 4 */ + + #define FSMC_PIO_IOHIZ (0xFF << 24) + #define FSMC_PIO_IOHOLD (0xFF << 16) + #define FSMC_PIO_IOWAIT (0xFF << 8) + #define FSMC_PIO_IOSET 0xF diff --git a/source/libmaple/api/iwdg.rst b/source/libmaple/api/iwdg.rst index 06691f8..65f9f7b 100644 --- a/source/libmaple/api/iwdg.rst +++ b/source/libmaple/api/iwdg.rst @@ -1,10 +1,11 @@ .. highlight:: c .. _libmaple-iwdg: -``iwdg.h`` -========== +``<libmaple/iwdg.h>`` +===================== -Independent Watchdog (IWDG) support. +Independent Watchdog (IWDG) support. The IWDG peripheral is common +across supported targets, so everything documented here is portable. .. contents:: Contents :local: @@ -12,20 +13,15 @@ Independent Watchdog (IWDG) support. Usage Note ---------- -To use the independent watchdog, first call :c:func:`iwdg_init()` with -the appropriate prescaler and IWDG counter reload values for your -application. Afterwards, you must periodically call -:c:func:`iwdg_feed()` before the IWDG counter reaches 0 to reset the -counter to its reload value. If you do not, the chip will reset. +To use the independent watchdog, first call :ref:`iwdg_init() +<libmaple-iwdg-iwdg_init>` with the appropriate prescaler and IWDG +counter reload values for your application. Afterwards, you must +periodically call :ref:`iwdg_feed() <libmaple-iwdg-iwdg_feed>` before +the IWDG counter reaches zero to reset the counter to its reload +value. If you do not, the chip will reset. Once started, the independent watchdog cannot be turned off. -Types ------ - -.. doxygenstruct:: iwdg_reg_map -.. doxygenenum:: iwdg_prescaler - Devices ------- @@ -34,40 +30,51 @@ None at this time. Functions --------- +.. _libmaple-iwdg-iwdg_init: .. doxygenfunction:: iwdg_init +.. _libmaple-iwdg-iwdg_feed: .. doxygenfunction:: iwdg_feed -Register Map Base Pointers --------------------------- +Types +----- + +.. doxygenenum:: iwdg_prescaler + + +Register Maps +------------- .. doxygendefine:: IWDG_BASE +.. doxygenstruct:: iwdg_reg_map + Register Bit Definitions ------------------------ -Key register -~~~~~~~~~~~~ +These are given as source code. + +:: + + /* Key register */ -.. doxygendefine:: IWDG_KR_UNLOCK -.. doxygendefine:: IWDG_KR_FEED -.. doxygendefine:: IWDG_KR_START + #define IWDG_KR_UNLOCK 0x5555 + #define IWDG_KR_FEED 0xAAAA + #define IWDG_KR_START 0xCCCC -Prescaler register -~~~~~~~~~~~~~~~~~~ + /* Prescaler register */ -.. doxygendefine:: IWDG_PR_DIV_4 -.. doxygendefine:: IWDG_PR_DIV_8 -.. doxygendefine:: IWDG_PR_DIV_16 -.. doxygendefine:: IWDG_PR_DIV_32 -.. doxygendefine:: IWDG_PR_DIV_64 -.. doxygendefine:: IWDG_PR_DIV_128 -.. doxygendefine:: IWDG_PR_DIV_256 + #define IWDG_PR_DIV_4 0x0 + #define IWDG_PR_DIV_8 0x1 + #define IWDG_PR_DIV_16 0x2 + #define IWDG_PR_DIV_32 0x3 + #define IWDG_PR_DIV_64 0x4 + #define IWDG_PR_DIV_128 0x5 + #define IWDG_PR_DIV_256 0x6 -Status register -~~~~~~~~~~~~~~~ + /* Status register */ -.. doxygendefine:: IWDG_SR_RVU_BIT -.. doxygendefine:: IWDG_SR_PVU_BIT + #define IWDG_SR_RVU_BIT 1 + #define IWDG_SR_PVU_BIT 0 -.. doxygendefine:: IWDG_SR_RVU -.. doxygendefine:: IWDG_SR_PVU + #define IWDG_SR_RVU (1U << IWDG_SR_RVU_BIT) + #define IWDG_SR_PVU (1U << IWDG_SR_PVU_BIT) diff --git a/source/libmaple/api/libmaple.rst b/source/libmaple/api/libmaple.rst index c230cef..7deb659 100644 --- a/source/libmaple/api/libmaple.rst +++ b/source/libmaple/api/libmaple.rst @@ -1,8 +1,8 @@ .. highlight:: c .. _libmaple-libmaple: -``libmaple.h`` -============== +``<libmaple/libmaple.h>`` +========================= Base include file for libmaple. diff --git a/source/libmaple/api/libmaple_types.rst b/source/libmaple/api/libmaple_types.rst index 7fed5dc..5ca446e 100644 --- a/source/libmaple/api/libmaple_types.rst +++ b/source/libmaple/api/libmaple_types.rst @@ -1,12 +1,15 @@ .. highlight:: c .. _libmaple-libmaple_types: -``libmaple_types.h`` -==================== +``<libmaple/libmaple_types.h>`` +=============================== Defines the base types and type-related macros used throughout the rest of libmaple. +.. contents:: Contents + :local: + Integral Types -------------- @@ -22,22 +25,61 @@ Integral Types Attributes and Type Qualifiers ------------------------------ +In the case of macros for GCC's ``__attribute__``\ s, we have our own +macros mostly to save typing, but also in hopes that they might be +expressible using different compiler extensions, or to give them +different interpretations when running e.g. Doxygen on libmaple. + +.. c:macro:: __always_inline + + Macro for ``inline __attribute__((always_inline))``. This can be + used to defeat GCC's ``-Os`` when you Really Mean Inline. + +.. c:macro:: __attr_flash + + Macro for a GCC ``__attribute__`` which (when using libmaple's + linker scripts) will cause the variable being marked to be stored + in Flash, rather than SRAM. It's useful for read-only variables + like look-up tables. + +.. c:macro:: __deprecated + + Macro for ``__attribute__((deprecated))``. Its use causes GCC to + emit deprecation warnings when the deprecated functionality is + used. It's not used for everything that gets deprecated, so don't + rely on it to catch all uses of deprecated APIs. + +.. c:macro:: __packed + + Macro for ``__attribute__((packed))``. + .. c:macro:: __io - This is a macro for ``volatile`` which is used to denote that the - variable whose type is being qualified is IO-mapped. Its most - common use is in the individual members of each :ref:`register map + Macro for ``volatile`` which denotes that the variable whose type + is being qualified is IO-mapped. Its most common use is in the + individual members of each :ref:`register map <libmaple-overview-regmaps>` struct. -.. c:macro:: __attr_flash +.. c:macro:: __weak - This is a macro for a GCC ``__attribute__`` which (when using the - linker scripts provided with libmaple) will cause the variable - being marked to be stored in Flash, rather than SRAM. The - variable's value may be read like that of any other variable, but - it may not be written. + Macro for ``__attribute__((weak))``. -Other typedefs --------------- +.. c:macro:: __unused + + Macro for ``__attribute__((unused))``. This can be used + (sparingly!) to silence unused function warnings when GCC is + mistaken. + +Miscellaneous +------------- .. doxygentypedef:: voidFuncPtr + +.. c:macro:: offsetof(type, member) + + If left undefined, this is defined to ``__builtin_ofsetof(type, + member)``. + +.. c:macro:: NULL + + If left undefined, this is defined to ``0``. diff --git a/source/libmaple/api/nvic.rst b/source/libmaple/api/nvic.rst index b22c94b..505e36e 100644 --- a/source/libmaple/api/nvic.rst +++ b/source/libmaple/api/nvic.rst @@ -1,25 +1,44 @@ .. highlight:: c .. _libmaple-nvic: -``nvic.h`` -========== +``<libmaple/nvic.h>`` +===================== Nested Vector Interrupt Controller (NVIC) support. +The same API is used on all targets, but the available interrupts are +target-dependent. To manage this, each target series defines an +:ref:`nvic_irq_num <libmaple-nvic-nvic_irq_num>` enumerator for each +available interrupt. + .. contents:: Contents :local: -Types ------ - -.. doxygenstruct:: nvic_reg_map -.. doxygenenum:: nvic_irq_num - Devices ------- None at this time. +.. _libmaple-nvic-nvic_irq_num: + +``nvic_irq_num`` +---------------- + +This target-dependent enum is used to identify an interrupt vector +number. Interrupts which are common across series have the same token +(though not necessarily the same value) for their ``nvic_irq_num``\ s. +The available values on each supported target series are as follows. + +STM32F1 Targets +~~~~~~~~~~~~~~~ + +.. doxygenenum:: stm32f1::nvic_irq_num + +STM32F2 Targets +~~~~~~~~~~~~~~~ + +.. doxygenenum:: stm32f2::nvic_irq_num + Functions --------- @@ -33,10 +52,14 @@ Functions .. doxygenfunction:: nvic_irq_disable_all .. doxygenfunction:: nvic_sys_reset -Register Map Base Pointers --------------------------- +Register Maps +------------- + +Since the NVIC is part of the ARM core, its registers and base pointer +are common across all targes. .. doxygendefine:: NVIC_BASE +.. doxygenstruct:: nvic_reg_map Register Bit Definitions ------------------------ diff --git a/source/libmaple/api/rcc-reg-bits.txt b/source/libmaple/api/rcc-reg-bits.txt new file mode 100644 index 0000000..6b1133d --- /dev/null +++ b/source/libmaple/api/rcc-reg-bits.txt @@ -0,0 +1,1017 @@ +STM32F1 Targets +~~~~~~~~~~~~~~~ + +Clock control register +++++++++++++++++++++++ + +:: + + #define RCC_CR_PLLRDY_BIT 25 + #define RCC_CR_PLLON_BIT 24 + #define RCC_CR_CSSON_BIT 19 + #define RCC_CR_HSEBYP_BIT 18 + #define RCC_CR_HSERDY_BIT 17 + #define RCC_CR_HSEON_BIT 16 + #define RCC_CR_HSIRDY_BIT 1 + #define RCC_CR_HSION_BIT 0 + + #define RCC_CR_PLLRDY (1U << RCC_CR_PLLRDY_BIT) + #define RCC_CR_PLLON (1U << RCC_CR_PLLON_BIT) + #define RCC_CR_CSSON (1U << RCC_CR_CSSON_BIT) + #define RCC_CR_HSEBYP (1U << RCC_CR_HSEBYP_BIT) + #define RCC_CR_HSERDY (1U << RCC_CR_HSERDY_BIT) + #define RCC_CR_HSEON (1U << RCC_CR_HSEON_BIT) + #define RCC_CR_HSICAL (0xFF << 8) + #define RCC_CR_HSITRIM (0x1F << 3) + #define RCC_CR_HSIRDY (1U << RCC_CR_HSIRDY_BIT) + #define RCC_CR_HSION (1U << RCC_CR_HSION_BIT) + +Clock configuration register +++++++++++++++++++++++++++++ + +:: + + #define RCC_CFGR_USBPRE_BIT 22 + #define RCC_CFGR_PLLXTPRE_BIT 17 + #define RCC_CFGR_PLLSRC_BIT 16 + + #define RCC_CFGR_MCO (0x3 << 24) + #define RCC_CFGR_USBPRE (1U << RCC_CFGR_USBPRE_BIT) + #define RCC_CFGR_PLLMUL (0xF << 18) + #define RCC_CFGR_PLLXTPRE (1U << RCC_CFGR_PLLXTPRE_BIT) + #define RCC_CFGR_PLLSRC (1U << RCC_CFGR_PLLSRC_BIT) + #define RCC_CFGR_ADCPRE (0x3 << 14) + #define RCC_CFGR_PPRE2 (0x7 << 11) + #define RCC_CFGR_PPRE1 (0x7 << 8) + #define RCC_CFGR_HPRE (0xF << 4) + #define RCC_CFGR_SWS (0x3 << 2) + #define RCC_CFGR_SWS_PLL (0x2 << 2) + #define RCC_CFGR_SWS_HSE (0x1 << 2) + #define RCC_CFGR_SW 0x3 + #define RCC_CFGR_SW_PLL 0x2 + #define RCC_CFGR_SW_HSE 0x1 + +Clock interrupt register +++++++++++++++++++++++++ + +:: + + #define RCC_CIR_CSSC_BIT 23 + #define RCC_CIR_PLLRDYC_BIT 20 + #define RCC_CIR_HSERDYC_BIT 19 + #define RCC_CIR_HSIRDYC_BIT 18 + #define RCC_CIR_LSERDYC_BIT 17 + #define RCC_CIR_LSIRDYC_BIT 16 + #define RCC_CIR_PLLRDYIE_BIT 12 + #define RCC_CIR_HSERDYIE_BIT 11 + #define RCC_CIR_HSIRDYIE_BIT 10 + #define RCC_CIR_LSERDYIE_BIT 9 + #define RCC_CIR_LSIRDYIE_BIT 8 + #define RCC_CIR_CSSF_BIT 7 + #define RCC_CIR_PLLRDYF_BIT 4 + #define RCC_CIR_HSERDYF_BIT 3 + #define RCC_CIR_HSIRDYF_BIT 2 + #define RCC_CIR_LSERDYF_BIT 1 + #define RCC_CIR_LSIRDYF_BIT 0 + + #define RCC_CIR_CSSC (1U << RCC_CIR_CSSC_BIT) + #define RCC_CIR_PLLRDYC (1U << RCC_CIR_PLLRDYC_BIT) + #define RCC_CIR_HSERDYC (1U << RCC_CIR_HSERDYC_BIT) + #define RCC_CIR_HSIRDYC (1U << RCC_CIR_HSIRDYC_BIT) + #define RCC_CIR_LSERDYC (1U << RCC_CIR_LSERDYC_BIT) + #define RCC_CIR_LSIRDYC (1U << RCC_CIR_LSIRDYC_BIT) + #define RCC_CIR_PLLRDYIE (1U << RCC_CIR_PLLRDYIE_BIT) + #define RCC_CIR_HSERDYIE (1U << RCC_CIR_HSERDYIE_BIT) + #define RCC_CIR_HSIRDYIE (1U << RCC_CIR_HSIRDYIE_BIT) + #define RCC_CIR_LSERDYIE (1U << RCC_CIR_LSERDYIE_BIT) + #define RCC_CIR_LSIRDYIE (1U << RCC_CIR_LSIRDYIE_BIT) + #define RCC_CIR_CSSF (1U << RCC_CIR_CSSF_BIT) + #define RCC_CIR_PLLRDYF (1U << RCC_CIR_PLLRDYF_BIT) + #define RCC_CIR_HSERDYF (1U << RCC_CIR_HSERDYF_BIT) + #define RCC_CIR_HSIRDYF (1U << RCC_CIR_HSIRDYF_BIT) + #define RCC_CIR_LSERDYF (1U << RCC_CIR_LSERDYF_BIT) + #define RCC_CIR_LSIRDYF (1U << RCC_CIR_LSIRDYF_BIT) + +Peripheral reset registers +++++++++++++++++++++++++++ + +:: + + #define RCC_APB2RSTR_TIM11RST_BIT 21 + #define RCC_APB2RSTR_TIM10RST_BIT 20 + #define RCC_APB2RSTR_TIM9RST_BIT 19 + #define RCC_APB2RSTR_ADC3RST_BIT 15 + #define RCC_APB2RSTR_USART1RST_BIT 14 + #define RCC_APB2RSTR_TIM8RST_BIT 13 + #define RCC_APB2RSTR_SPI1RST_BIT 12 + #define RCC_APB2RSTR_TIM1RST_BIT 11 + #define RCC_APB2RSTR_ADC2RST_BIT 10 + #define RCC_APB2RSTR_ADC1RST_BIT 9 + #define RCC_APB2RSTR_IOPGRST_BIT 8 + #define RCC_APB2RSTR_IOPFRST_BIT 7 + #define RCC_APB2RSTR_IOPERST_BIT 6 + #define RCC_APB2RSTR_IOPDRST_BIT 5 + #define RCC_APB2RSTR_IOPCRST_BIT 4 + #define RCC_APB2RSTR_IOPBRST_BIT 3 + #define RCC_APB2RSTR_IOPARST_BIT 2 + #define RCC_APB2RSTR_AFIORST_BIT 0 + + #define RCC_APB2RSTR_TIM11RST (1U << RCC_APB2RSTR_TIM11RST_BIT) + #define RCC_APB2RSTR_TIM10RST (1U << RCC_APB2RSTR_TIM10RST_BIT) + #define RCC_APB2RSTR_TIM9RST (1U << RCC_APB2RSTR_TIM9RST_BIT) + #define RCC_APB2RSTR_ADC3RST (1U << RCC_APB2RSTR_ADC3RST_BIT) + #define RCC_APB2RSTR_USART1RST (1U << RCC_APB2RSTR_USART1RST_BIT) + #define RCC_APB2RSTR_TIM8RST (1U << RCC_APB2RSTR_TIM8RST_BIT) + #define RCC_APB2RSTR_SPI1RST (1U << RCC_APB2RSTR_SPI1RST_BIT) + #define RCC_APB2RSTR_TIM1RST (1U << RCC_APB2RSTR_TIM1RST_BIT) + #define RCC_APB2RSTR_ADC2RST (1U << RCC_APB2RSTR_ADC2RST_BIT) + #define RCC_APB2RSTR_ADC1RST (1U << RCC_APB2RSTR_ADC1RST_BIT) + #define RCC_APB2RSTR_IOPGRST (1U << RCC_APB2RSTR_IOPGRST_BIT) + #define RCC_APB2RSTR_IOPFRST (1U << RCC_APB2RSTR_IOPFRST_BIT) + #define RCC_APB2RSTR_IOPERST (1U << RCC_APB2RSTR_IOPERST_BIT) + #define RCC_APB2RSTR_IOPDRST (1U << RCC_APB2RSTR_IOPDRST_BIT) + #define RCC_APB2RSTR_IOPCRST (1U << RCC_APB2RSTR_IOPCRST_BIT) + #define RCC_APB2RSTR_IOPBRST (1U << RCC_APB2RSTR_IOPBRST_BIT) + #define RCC_APB2RSTR_IOPARST (1U << RCC_APB2RSTR_IOPARST_BIT) + #define RCC_APB2RSTR_AFIORST (1U << RCC_APB2RSTR_AFIORST_BIT) + + #define RCC_APB1RSTR_DACRST_BIT 29 + #define RCC_APB1RSTR_PWRRST_BIT 28 + #define RCC_APB1RSTR_BKPRST_BIT 27 + #define RCC_APB1RSTR_CANRST_BIT 25 + #define RCC_APB1RSTR_USBRST_BIT 23 + #define RCC_APB1RSTR_I2C2RST_BIT 22 + #define RCC_APB1RSTR_I2C1RST_BIT 21 + #define RCC_APB1RSTR_UART5RST_BIT 20 + #define RCC_APB1RSTR_UART4RST_BIT 19 + #define RCC_APB1RSTR_USART3RST_BIT 18 + #define RCC_APB1RSTR_USART2RST_BIT 17 + #define RCC_APB1RSTR_SPI3RST_BIT 15 + #define RCC_APB1RSTR_SPI2RST_BIT 14 + #define RCC_APB1RSTR_WWDRST_BIT 11 + #define RCC_APB1RSTR_TIM14RST_BIT 8 + #define RCC_APB1RSTR_TIM13RST_BIT 7 + #define RCC_APB1RSTR_TIM12RST_BIT 6 + #define RCC_APB1RSTR_TIM7RST_BIT 5 + #define RCC_APB1RSTR_TIM6RST_BIT 4 + #define RCC_APB1RSTR_TIM5RST_BIT 3 + #define RCC_APB1RSTR_TIM4RST_BIT 2 + #define RCC_APB1RSTR_TIM3RST_BIT 1 + #define RCC_APB1RSTR_TIM2RST_BIT 0 + + #define RCC_APB1RSTR_DACRST (1U << RCC_APB1RSTR_DACRST_BIT) + #define RCC_APB1RSTR_PWRRST (1U << RCC_APB1RSTR_PWRRST_BIT) + #define RCC_APB1RSTR_BKPRST (1U << RCC_APB1RSTR_BKPRST_BIT) + #define RCC_APB1RSTR_CANRST (1U << RCC_APB1RSTR_CANRST_BIT) + #define RCC_APB1RSTR_USBRST (1U << RCC_APB1RSTR_USBRST_BIT) + #define RCC_APB1RSTR_I2C2RST (1U << RCC_APB1RSTR_I2C2RST_BIT) + #define RCC_APB1RSTR_I2C1RST (1U << RCC_APB1RSTR_I2C1RST_BIT) + #define RCC_APB1RSTR_UART5RST (1U << RCC_APB1RSTR_UART5RST_BIT) + #define RCC_APB1RSTR_UART4RST (1U << RCC_APB1RSTR_UART4RST_BIT) + #define RCC_APB1RSTR_USART3RST (1U << RCC_APB1RSTR_USART3RST_BIT) + #define RCC_APB1RSTR_USART2RST (1U << RCC_APB1RSTR_USART2RST_BIT) + #define RCC_APB1RSTR_SPI3RST (1U << RCC_APB1RSTR_SPI3RST_BIT) + #define RCC_APB1RSTR_SPI2RST (1U << RCC_APB1RSTR_SPI2RST_BIT) + #define RCC_APB1RSTR_WWDRST (1U << RCC_APB1RSTR_WWDRST_BIT) + #define RCC_APB1RSTR_TIM14RST (1U << RCC_APB1RSTR_TIM14RST_BIT) + #define RCC_APB1RSTR_TIM13RST (1U << RCC_APB1RSTR_TIM13RST_BIT) + #define RCC_APB1RSTR_TIM12RST (1U << RCC_APB1RSTR_TIM12RST_BIT) + #define RCC_APB1RSTR_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT) + #define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_BIT) + #define RCC_APB1RSTR_TIM5RST (1U << RCC_APB1RSTR_TIM5RST_BIT) + #define RCC_APB1RSTR_TIM4RST (1U << RCC_APB1RSTR_TIM4RST_BIT) + #define RCC_APB1RSTR_TIM3RST (1U << RCC_APB1RSTR_TIM3RST_BIT) + #define RCC_APB1RSTR_TIM2RST (1U << RCC_APB1RSTR_TIM2RST_BIT) + +Peripheral clock enable registers ++++++++++++++++++++++++++++++++++ + +:: + + #define RCC_AHBENR_SDIOEN_BIT 10 + #define RCC_AHBENR_FSMCEN_BIT 8 + #define RCC_AHBENR_CRCEN_BIT 7 + #define RCC_AHBENR_FLITFEN_BIT 4 + #define RCC_AHBENR_SRAMEN_BIT 2 + #define RCC_AHBENR_DMA2EN_BIT 1 + #define RCC_AHBENR_DMA1EN_BIT 0 + + #define RCC_AHBENR_SDIOEN (1U << RCC_AHBENR_SDIOEN_BIT) + #define RCC_AHBENR_FSMCEN (1U << RCC_AHBENR_FSMCEN_BIT) + #define RCC_AHBENR_CRCEN (1U << RCC_AHBENR_CRCEN_BIT) + #define RCC_AHBENR_FLITFEN (1U << RCC_AHBENR_FLITFEN_BIT) + #define RCC_AHBENR_SRAMEN (1U << RCC_AHBENR_SRAMEN_BIT) + #define RCC_AHBENR_DMA2EN (1U << RCC_AHBENR_DMA2EN_BIT) + #define RCC_AHBENR_DMA1EN (1U << RCC_AHBENR_DMA1EN_BIT) + + #define RCC_APB2ENR_TIM11EN_BIT 21 + #define RCC_APB2ENR_TIM10EN_BIT 20 + #define RCC_APB2ENR_TIM9EN_BIT 19 + #define RCC_APB2ENR_ADC3EN_BIT 15 + #define RCC_APB2ENR_USART1EN_BIT 14 + #define RCC_APB2ENR_TIM8EN_BIT 13 + #define RCC_APB2ENR_SPI1EN_BIT 12 + #define RCC_APB2ENR_TIM1EN_BIT 11 + #define RCC_APB2ENR_ADC2EN_BIT 10 + #define RCC_APB2ENR_ADC1EN_BIT 9 + #define RCC_APB2ENR_IOPGEN_BIT 8 + #define RCC_APB2ENR_IOPFEN_BIT 7 + #define RCC_APB2ENR_IOPEEN_BIT 6 + #define RCC_APB2ENR_IOPDEN_BIT 5 + #define RCC_APB2ENR_IOPCEN_BIT 4 + #define RCC_APB2ENR_IOPBEN_BIT 3 + #define RCC_APB2ENR_IOPAEN_BIT 2 + #define RCC_APB2ENR_AFIOEN_BIT 0 + + #define RCC_APB2ENR_TIM11EN (1U << RCC_APB2ENR_TIM11EN_BIT) + #define RCC_APB2ENR_TIM10EN (1U << RCC_APB2ENR_TIM10EN_BIT) + #define RCC_APB2ENR_TIM9EN (1U << RCC_APB2ENR_TIM9EN_BIT) + #define RCC_APB2ENR_ADC3EN (1U << RCC_APB2ENR_ADC3EN_BIT) + #define RCC_APB2ENR_USART1EN (1U << RCC_APB2ENR_USART1EN_BIT) + #define RCC_APB2ENR_TIM8EN (1U << RCC_APB2ENR_TIM8EN_BIT) + #define RCC_APB2ENR_SPI1EN (1U << RCC_APB2ENR_SPI1EN_BIT) + #define RCC_APB2ENR_TIM1EN (1U << RCC_APB2ENR_TIM1EN_BIT) + #define RCC_APB2ENR_ADC2EN (1U << RCC_APB2ENR_ADC2EN_BIT) + #define RCC_APB2ENR_ADC1EN (1U << RCC_APB2ENR_ADC1EN_BIT) + #define RCC_APB2ENR_IOPGEN (1U << RCC_APB2ENR_IOPGEN_BIT) + #define RCC_APB2ENR_IOPFEN (1U << RCC_APB2ENR_IOPFEN_BIT) + #define RCC_APB2ENR_IOPEEN (1U << RCC_APB2ENR_IOPEEN_BIT) + #define RCC_APB2ENR_IOPDEN (1U << RCC_APB2ENR_IOPDEN_BIT) + #define RCC_APB2ENR_IOPCEN (1U << RCC_APB2ENR_IOPCEN_BIT) + #define RCC_APB2ENR_IOPBEN (1U << RCC_APB2ENR_IOPBEN_BIT) + #define RCC_APB2ENR_IOPAEN (1U << RCC_APB2ENR_IOPAEN_BIT) + #define RCC_APB2ENR_AFIOEN (1U << RCC_APB2ENR_AFIOEN_BIT) + + #define RCC_APB1ENR_DACEN_BIT 29 + #define RCC_APB1ENR_PWREN_BIT 28 + #define RCC_APB1ENR_BKPEN_BIT 27 + #define RCC_APB1ENR_CANEN_BIT 25 + #define RCC_APB1ENR_USBEN_BIT 23 + #define RCC_APB1ENR_I2C2EN_BIT 22 + #define RCC_APB1ENR_I2C1EN_BIT 21 + #define RCC_APB1ENR_UART5EN_BIT 20 + #define RCC_APB1ENR_UART4EN_BIT 19 + #define RCC_APB1ENR_USART3EN_BIT 18 + #define RCC_APB1ENR_USART2EN_BIT 17 + #define RCC_APB1ENR_SPI3EN_BIT 15 + #define RCC_APB1ENR_SPI2EN_BIT 14 + #define RCC_APB1ENR_WWDEN_BIT 11 + #define RCC_APB1ENR_TIM14EN_BIT 8 + #define RCC_APB1ENR_TIM13EN_BIT 7 + #define RCC_APB1ENR_TIM12EN_BIT 6 + #define RCC_APB1ENR_TIM7EN_BIT 5 + #define RCC_APB1ENR_TIM6EN_BIT 4 + #define RCC_APB1ENR_TIM5EN_BIT 3 + #define RCC_APB1ENR_TIM4EN_BIT 2 + #define RCC_APB1ENR_TIM3EN_BIT 1 + #define RCC_APB1ENR_TIM2EN_BIT 0 + + #define RCC_APB1ENR_DACEN (1U << RCC_APB1ENR_DACEN_BIT) + #define RCC_APB1ENR_PWREN (1U << RCC_APB1ENR_PWREN_BIT) + #define RCC_APB1ENR_BKPEN (1U << RCC_APB1ENR_BKPEN_BIT) + #define RCC_APB1ENR_CANEN (1U << RCC_APB1ENR_CANEN_BIT) + #define RCC_APB1ENR_USBEN (1U << RCC_APB1ENR_USBEN_BIT) + #define RCC_APB1ENR_I2C2EN (1U << RCC_APB1ENR_I2C2EN_BIT) + #define RCC_APB1ENR_I2C1EN (1U << RCC_APB1ENR_I2C1EN_BIT) + #define RCC_APB1ENR_UART5EN (1U << RCC_APB1ENR_UART5EN_BIT) + #define RCC_APB1ENR_UART4EN (1U << RCC_APB1ENR_UART4EN_BIT) + #define RCC_APB1ENR_USART3EN (1U << RCC_APB1ENR_USART3EN_BIT) + #define RCC_APB1ENR_USART2EN (1U << RCC_APB1ENR_USART2EN_BIT) + #define RCC_APB1ENR_SPI3EN (1U << RCC_APB1ENR_SPI3EN_BIT) + #define RCC_APB1ENR_SPI2EN (1U << RCC_APB1ENR_SPI2EN_BIT) + #define RCC_APB1ENR_WWDEN (1U << RCC_APB1ENR_WWDEN_BIT) + #define RCC_APB1ENR_TIM14EN (1U << RCC_APB1ENR_TIM14EN_BIT) + #define RCC_APB1ENR_TIM13EN (1U << RCC_APB1ENR_TIM13EN_BIT) + #define RCC_APB1ENR_TIM12EN (1U << RCC_APB1ENR_TIM12EN_BIT) + #define RCC_APB1ENR_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT) + #define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_BIT) + #define RCC_APB1ENR_TIM5EN (1U << RCC_APB1ENR_TIM5EN_BIT) + #define RCC_APB1ENR_TIM4EN (1U << RCC_APB1ENR_TIM4EN_BIT) + #define RCC_APB1ENR_TIM3EN (1U << RCC_APB1ENR_TIM3EN_BIT) + #define RCC_APB1ENR_TIM2EN (1U << RCC_APB1ENR_TIM2EN_BIT) + +Backup domain control register +++++++++++++++++++++++++++++++ + +:: + + #define RCC_BDCR_BDRST_BIT 16 + #define RCC_BDCR_RTCEN_BIT 15 + #define RCC_BDCR_LSEBYP_BIT 2 + #define RCC_BDCR_LSERDY_BIT 1 + #define RCC_BDCR_LSEON_BIT 0 + + #define RCC_BDCR_BDRST (1U << RCC_BDCR_BDRST_BIT) + #define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTC_BIT) + #define RCC_BDCR_RTCSEL (0x3 << 8) + #define RCC_BDCR_RTCSEL_NONE (0x0 << 8) + #define RCC_BDCR_RTCSEL_LSE (0x1 << 8) + #define RCC_BDCR_RTCSEL_HSE (0x3 << 8) + #define RCC_BDCR_LSEBYP (1U << RCC_BDCR_LSEBYP_BIT) + #define RCC_BDCR_LSERDY (1U << RCC_BDCR_LSERDY_BIT) + #define RCC_BDCR_LSEON (1U << RCC_BDCR_LSEON_BIT) + +Control/status register ++++++++++++++++++++++++ + +:: + + #define RCC_CSR_LPWRRSTF_BIT 31 + #define RCC_CSR_WWDGRSTF_BIT 30 + #define RCC_CSR_IWDGRSTF_BIT 29 + #define RCC_CSR_SFTRSTF_BIT 28 + #define RCC_CSR_PORRSTF_BIT 27 + #define RCC_CSR_PINRSTF_BIT 26 + #define RCC_CSR_RMVF_BIT 24 + #define RCC_CSR_LSIRDY_BIT 1 + #define RCC_CSR_LSION_BIT 0 + + #define RCC_CSR_LPWRRSTF (1U << RCC_CSR_LPWRRSTF_BIT) + #define RCC_CSR_WWDGRSTF (1U << RCC_CSR_WWDGRSTF_BIT) + #define RCC_CSR_IWDGRSTF (1U << RCC_CSR_IWDGRSTF_BIT) + #define RCC_CSR_SFTRSTF (1U << RCC_CSR_SFTRSTF_BIT) + #define RCC_CSR_PORRSTF (1U << RCC_CSR_PORRSTF_BIT) + #define RCC_CSR_PINRSTF (1U << RCC_CSR_PINRSTF_BIT) + #define RCC_CSR_RMVF (1U << RCC_CSR_RMVF_BIT) + #define RCC_CSR_LSIRDY (1U << RCC_CSR_LSIRDY_BIT) + #define RCC_CSR_LSION (1U << RCC_CSR_LSION_BIT) + +STM32F2 Targets +~~~~~~~~~~~~~~~ + +Clock control register +++++++++++++++++++++++ + +:: + + #define RCC_CR_PLLI2SRDY_BIT 27 + #define RCC_CR_PLLI2SON_BIT 26 + #define RCC_CR_PLLRDY_BIT 25 + #define RCC_CR_PLLON_BIT 24 + #define RCC_CR_CSSON_BIT 19 + #define RCC_CR_HSEBYP_BIT 18 + #define RCC_CR_HSERDY_BIT 17 + #define RCC_CR_HSEON_BIT 16 + #define RCC_CR_HSIRDY_BIT 1 + #define RCC_CR_HSION_BIT 0 + + #define RCC_CR_PLLI2SRDY (1U << RCC_CR_PLLI2SRDY_BIT) + #define RCC_CR_PLLI2SON (1U << RCC_CR_PLLI2SON_BIT) + #define RCC_CR_PLLRDY (1U << RCC_CR_PLLRDY_BIT) + #define RCC_CR_PLLON (1U << RCC_CR_PLLON_BIT) + #define RCC_CR_CSSON (1U << RCC_CR_CSSON_BIT) + #define RCC_CR_HSEBYP (1U << RCC_CR_HSEBYP_BIT) + #define RCC_CR_HSERDY (1U << RCC_CR_HSERDY_BIT) + #define RCC_CR_HSEON (1U << RCC_CR_HSEON_BIT) + #define RCC_CR_HSICAL (0xFF << 8) + #define RCC_CR_HSITRIM (0x1F << 3) + #define RCC_CR_HSIRDY (1U << RCC_CR_HSIRDY_BIT) + #define RCC_CR_HSION (1U << RCC_CR_HSION_BIT) + +PLL configuration register +++++++++++++++++++++++++++ + +:: + + #define RCC_PLLCFGR_PLLSRC_BIT 22 + + #define RCC_PLLCFGR_PLLQ (0xF << 24) + #define RCC_PLLCFGR_PLLSRC (1U << RCC_PLLCFGR_PLLSRC_BIT) + #define RCC_PLLCFGR_PLLSRC_HSI (0x0 << RCC_PLLCFGR_PLLSRC_BIT) + #define RCC_PLLCFGR_PLLSRC_HSE (0x1 << RCC_PLLCFGR_PLLSRC_BIT) + #define RCC_PLLCFGR_PLLP (0x3 << 16) + #define RCC_PLLCFGR_PLLN (0x1FF << 6) + #define RCC_PLLCFGR_PLLM 0x1F + +Clock configuration register +++++++++++++++++++++++++++++ + +:: + + #define RCC_CFGR_I2SSRC_BIT 23 + + #define RCC_CFGR_MCO2 (0x3 << 30) + #define RCC_CFGR_MCO2_SYSCLK (0x0 << 30) + #define RCC_CFGR_MCO2_PLLI2S (0x1 << 30) + #define RCC_CFGR_MCO2_HSE (0x2 << 30) + #define RCC_CFGR_MCO2_PLL (0x3 << 30) + + #define RCC_CFGR_MCO2PRE (0x7 << 27) + #define RCC_CFGR_MCO2PRE_DIV_1 (0x0 << 27) + #define RCC_CFGR_MCO2PRE_DIV_2 (0x4 << 27) + #define RCC_CFGR_MCO2PRE_DIV_3 (0x5 << 27) + #define RCC_CFGR_MCO2PRE_DIV_4 (0x6 << 27) + #define RCC_CFGR_MCO2PRE_DIV_5 (0x7 << 27) + + #define RCC_CFGR_MCO1PRE (0x7 << 24) + #define RCC_CFGR_MCO1PRE_DIV_1 (0x0 << 24) + #define RCC_CFGR_MCO1PRE_DIV_2 (0x4 << 24) + #define RCC_CFGR_MCO1PRE_DIV_3 (0x5 << 24) + #define RCC_CFGR_MCO1PRE_DIV_4 (0x6 << 24) + #define RCC_CFGR_MCO1PRE_DIV_5 (0x7 << 24) + + #define RCC_CFGR_I2SSRC (1U << RCC_CFGR_I2SSRC_BIT) + #define RCC_CFGR_I2SSRC_PLLI2S (0 << RCC_CFGR_I2SSRC_BIT) + #define RCC_CFGR_I2SSRC_I2S_CKIN (1 << RCC_CFGR_I2SSRC_BIT) + + #define RCC_CFGR_MCO1 (0x3 << 21) + #define RCC_CFGR_MCO1_HSI (0x0 << 21) + #define RCC_CFGR_MCO1_LSE (0x1 << 21) + #define RCC_CFGR_MCO1_HSE (0x2 << 21) + #define RCC_CFGR_MCO1_PLL (0x3 << 21) + + #define RCC_CFGR_RTCPRE (0x1F << 16) + + /* Skipped: all the 0b0xx values meaning "not divided" */ + #define RCC_CFGR_PPRE2 (0x7 << 13) + #define RCC_CFGR_PPRE2_AHB_DIV_2 (0x4 << 13) + #define RCC_CFGR_PPRE2_AHB_DIV_4 (0x5 << 13) + #define RCC_CFGR_PPRE2_AHB_DIV_8 (0x6 << 13) + #define RCC_CFGR_PPRE2_AHB_DIV_16 (0x7 << 13) + + /* Skipped: all the 0b0xx values meaning "not divided" */ + #define RCC_CFGR_PPRE1 (0x7 << 10) + #define RCC_CFGR_PPRE1_AHB_DIV_2 (0x4 << 10) + #define RCC_CFGR_PPRE1_AHB_DIV_4 (0x5 << 10) + #define RCC_CFGR_PPRE1_AHB_DIV_8 (0x6 << 10) + #define RCC_CFGR_PPRE1_AHB_DIV_16 (0x7 << 10) + + /* Skipped: all the 0b0xxx values meaning "not divided" */ + #define RCC_CFGR_HPRE (0xF << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_2 (0x8 << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_4 (0x9 << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_8 (0xA << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_16 (0xB << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_64 (0xC << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_128 (0xD << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_256 (0xE << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_512 (0xF << 4) + + #define RCC_CFGR_SWS (0x3 << 2) + #define RCC_CFGR_SWS_HSI (0x0 << 2) + #define RCC_CFGR_SWS_HSE (0x1 << 2) + #define RCC_CFGR_SWS_PLL (0x2 << 2) + + #define RCC_CFGR_SW 0x3 + #define RCC_CFGR_SW_HSI 0x0 + #define RCC_CFGR_SW_HSE 0x1 + #define RCC_CFGR_SW_PLL 0x2 + +Clock interrupt register +++++++++++++++++++++++++ + +:: + + #define RCC_CIR_CSSC_BIT 23 + + #define RCC_CIR_PLLI2SRDYC_BIT 21 + #define RCC_CIR_PLLRDYC_BIT 20 + #define RCC_CIR_HSERDYC_BIT 19 + #define RCC_CIR_HSIRDYC_BIT 18 + #define RCC_CIR_LSERDYC_BIT 17 + #define RCC_CIR_LSIRDYC_BIT 16 + + #define RCC_CIR_PLLI2SRDYIE_BIT 13 + #define RCC_CIR_PLLRDYIE_BIT 12 + #define RCC_CIR_HSERDYIE_BIT 11 + #define RCC_CIR_HSIRDYIE_BIT 10 + #define RCC_CIR_LSERDYIE_BIT 9 + #define RCC_CIR_LSIRDYIE_BIT 8 + + #define RCC_CIR_CSSF_BIT 7 + + #define RCC_CIR_PLLI2SRDYF_BIT 5 + #define RCC_CIR_PLLRDYF_BIT 4 + #define RCC_CIR_HSERDYF_BIT 3 + #define RCC_CIR_HSIRDYF_BIT 2 + #define RCC_CIR_LSERDYF_BIT 1 + #define RCC_CIR_LSIRDYF_BIT 0 + + #define RCC_CIR_CSSC (1U << RCC_CIR_CSSC_BIT) + + #define RCC_CIR_PLLI2SRDYC (1U << RCC_CIR_PLLI2SRDYC_BIT) + #define RCC_CIR_PLLRDYC (1U << RCC_CIR_PLLRDYC_BIT) + #define RCC_CIR_HSERDYC (1U << RCC_CIR_HSERDYC_BIT) + #define RCC_CIR_HSIRDYC (1U << RCC_CIR_HSIRDYC_BIT) + #define RCC_CIR_LSERDYC (1U << RCC_CIR_LSERDYC_BIT) + #define RCC_CIR_LSIRDYC (1U << RCC_CIR_LSIRDYC_BIT) + + #define RCC_CIR_PLLI2SRDYIE (1U << RCC_CIR_PLLI2SRDYIE_BIT) + #define RCC_CIR_PLLRDYIE (1U << RCC_CIR_PLLRDYIE_BIT) + #define RCC_CIR_HSERDYIE (1U << RCC_CIR_HSERDYIE_BIT) + #define RCC_CIR_HSIRDYIE (1U << RCC_CIR_HSIRDYIE_BIT) + #define RCC_CIR_LSERDYIE (1U << RCC_CIR_LSERDYIE_BIT) + #define RCC_CIR_LSIRDYIE (1U << RCC_CIR_LSIRDYIE_BIT) + + #define RCC_CIR_CSSF (1U << RCC_CIR_CSSF_BIT) + + #define RCC_CIR_PLLI2SRDYF (1U << RCC_CIR_PLLI2SRDYF_BIT) + #define RCC_CIR_PLLRDYF (1U << RCC_CIR_PLLRDYF_BIT) + #define RCC_CIR_HSERDYF (1U << RCC_CIR_HSERDYF_BIT) + #define RCC_CIR_HSIRDYF (1U << RCC_CIR_HSIRDYF_BIT) + #define RCC_CIR_LSERDYF (1U << RCC_CIR_LSERDYF_BIT) + #define RCC_CIR_LSIRDYF (1U << RCC_CIR_LSIRDYF_BIT) + +Peripheral reset registers +++++++++++++++++++++++++++ + +:: + + /* AHB1 */ + + #define RCC_AHB1RSTR_OTGHSRST_BIT 29 + #define RCC_AHB1RSTR_ETHMACRST_BIT 25 + #define RCC_AHB1RSTR_DMA2RST_BIT 22 + #define RCC_AHB1RSTR_DMA1RST_BIT 21 + #define RCC_AHB1RSTR_CRCRST_BIT 12 + #define RCC_AHB1RSTR_GPIOIRST_BIT 8 + #define RCC_AHB1RSTR_GPIOHRST_BIT 7 + #define RCC_AHB1RSTR_GPIOGRST_BIT 6 + #define RCC_AHB1RSTR_GPIOFRST_BIT 5 + #define RCC_AHB1RSTR_GPIOERST_BIT 4 + #define RCC_AHB1RSTR_GPIODRST_BIT 3 + #define RCC_AHB1RSTR_GPIOCRST_BIT 2 + #define RCC_AHB1RSTR_GPIOBRST_BIT 1 + #define RCC_AHB1RSTR_GPIOARST_BIT 0 + + #define RCC_AHB1RSTR_OTGHSRST (1U << RCC_AHB1RSTR_OTGHSRST_BIT) + #define RCC_AHB1RSTR_ETHMACRST (1U << RCC_AHB1RSTR_ETHMACRST_BIT) + #define RCC_AHB1RSTR_DMA2RST (1U << RCC_AHB1RSTR_DMA2RST_BIT) + #define RCC_AHB1RSTR_DMA1RST (1U << RCC_AHB1RSTR_DMA1RST_BIT) + #define RCC_AHB1RSTR_CRCRST (1U << RCC_AHB1RSTR_CRCRST_BIT) + #define RCC_AHB1RSTR_GPIOIRST (1U << RCC_AHB1RSTR_GPIOIRST_BIT) + #define RCC_AHB1RSTR_GPIOHRST (1U << RCC_AHB1RSTR_GPIOHRST_BIT) + #define RCC_AHB1RSTR_GPIOGRST (1U << RCC_AHB1RSTR_GPIOGRST_BIT) + #define RCC_AHB1RSTR_GPIOFRST (1U << RCC_AHB1RSTR_GPIOFRST_BIT) + #define RCC_AHB1RSTR_GPIOERST (1U << RCC_AHB1RSTR_GPIOERST_BIT) + #define RCC_AHB1RSTR_GPIODRST (1U << RCC_AHB1RSTR_GPIODRST_BIT) + #define RCC_AHB1RSTR_GPIOCRST (1U << RCC_AHB1RSTR_GPIOCRST_BIT) + #define RCC_AHB1RSTR_GPIOBRST (1U << RCC_AHB1RSTR_GPIOBRST_BIT) + #define RCC_AHB1RSTR_GPIOARST (1U << RCC_AHB1RSTR_GPIOARST_BIT) + + /* AHB2 */ + + #define RCC_AHB2RSTR_OTGFSRST_BIT 7 + #define RCC_AHB2RSTR_RNGRST_BIT 6 + #define RCC_AHB2RSTR_HASHRST_BIT 5 + #define RCC_AHB2RSTR_CRYPRST_BIT 4 + #define RCC_AHB2RSTR_DCMIRST_BIT 0 + + #define RCC_AHB2RSTR_OTGFSRST (1U << RCC_AHB2RSTR_OTGFSRST_BIT) + #define RCC_AHB2RSTR_RNGRST (1U << RCC_AHB2RSTR_RNGRST_BIT) + #define RCC_AHB2RSTR_HASHRST (1U << RCC_AHB2RSTR_HASHRST_BIT) + #define RCC_AHB2RSTR_CRYPRST (1U << RCC_AHB2RSTR_CRYPRST_BIT) + #define RCC_AHB2RSTR_DCMIRST (1U << RCC_AHB2RSTR_DCMIRST_BIT) + + /* AHB3 */ + + #define RCC_AHB3RSTR_FSMCRST_BIT 0 + + #define RCC_AHB3RSTR_FSMCRST (1U << RCC_AHB3RSTR_FSMCRST_BIT) + + /* APB1 */ + + #define RCC_APB1RSTR_DACRST_BIT 29 + #define RCC_APB1RSTR_PWRRST_BIT 28 + #define RCC_APB1RSTR_CAN2RST_BIT 26 + #define RCC_APB1RSTR_CAN1RST_BIT 25 + #define RCC_APB1RSTR_I2C3RST_BIT 23 + #define RCC_APB1RSTR_I2C2RST_BIT 22 + #define RCC_APB1RSTR_I2C1RST_BIT 21 + #define RCC_APB1RSTR_UART5RST_BIT 20 + #define RCC_APB1RSTR_UART4RST_BIT 19 + #define RCC_APB1RSTR_UART3RST_BIT 18 + #define RCC_APB1RSTR_UART2RST_BIT 17 + #define RCC_APB1RSTR_SPI3RST_BIT 15 + #define RCC_APB1RSTR_SPI2RST_BIT 14 + #define RCC_APB1RSTR_WWDGRST_BIT 11 + #define RCC_APB1RSTR_TIM14RST_BIT 8 + #define RCC_APB1RSTR_TIM13RST_BIT 7 + #define RCC_APB1RSTR_TIM12RST_BIT 6 + #define RCC_APB1RSTR_TIM7RST_BIT 5 + #define RCC_APB1RSTR_TIM6RST_BIT 4 + #define RCC_APB1RSTR_TIM5RST_BIT 3 + #define RCC_APB1RSTR_TIM4RST_BIT 2 + #define RCC_APB1RSTR_TIM3RST_BIT 1 + #define RCC_APB1RSTR_TIM2RST_BIT 0 + + #define RCC_APB1RSTR_DACRST (1U << RCC_APB1RSTR_DACRST_BIT) + #define RCC_APB1RSTR_PWRRST (1U << RCC_APB1RSTR_PWRRST_BIT) + #define RCC_APB1RSTR_CAN2RST (1U << RCC_APB1RSTR_CAN2RST_BIT) + #define RCC_APB1RSTR_CAN1RST (1U << RCC_APB1RSTR_CAN1RST_BIT) + #define RCC_APB1RSTR_I2C3RST (1U << RCC_APB1RSTR_I2C3RST_BIT) + #define RCC_APB1RSTR_I2C2RST (1U << RCC_APB1RSTR_I2C2RST_BIT) + #define RCC_APB1RSTR_I2C1RST (1U << RCC_APB1RSTR_I2C1RST_BIT) + #define RCC_APB1RSTR_UART5RST (1U << RCC_APB1RSTR_UART5RST_BIT) + #define RCC_APB1RSTR_UART4RST (1U << RCC_APB1RSTR_UART4RST_BIT) + #define RCC_APB1RSTR_UART3RST (1U << RCC_APB1RSTR_UART3RST_BIT) + #define RCC_APB1RSTR_UART2RST (1U << RCC_APB1RSTR_UART2RST_BIT) + #define RCC_APB1RSTR_SPI3RST (1U << RCC_APB1RSTR_SPI3RST_BIT) + #define RCC_APB1RSTR_SPI2RST (1U << RCC_APB1RSTR_SPI2RST_BIT) + #define RCC_APB1RSTR_WWDGRST (1U << RCC_APB1RSTR_WWDGRST_BIT) + #define RCC_APB1RSTR_TIM14RST (1U << RCC_APB1RSTR_TIM14RST_BIT) + #define RCC_APB1RSTR_TIM13RST (1U << RCC_APB1RSTR_TIM13RST_BIT) + #define RCC_APB1RSTR_TIM12RST (1U << RCC_APB1RSTR_TIM12RST_BIT) + #define RCC_APB1RSTR_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT) + #define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_BIT) + #define RCC_APB1RSTR_TIM5RST (1U << RCC_APB1RSTR_TIM5RST_BIT) + #define RCC_APB1RSTR_TIM4RST (1U << RCC_APB1RSTR_TIM4RST_BIT) + #define RCC_APB1RSTR_TIM3RST (1U << RCC_APB1RSTR_TIM3RST_BIT) + #define RCC_APB1RSTR_TIM2RST (1U << RCC_APB1RSTR_TIM2RST_BIT) + + /* APB2 */ + + #define RCC_APB2RSTR_TIM11RST_BIT 18 + #define RCC_APB2RSTR_TIM10RST_BIT 17 + #define RCC_APB2RSTR_TIM9RST_BIT 16 + #define RCC_APB2RSTR_SYSCFGRST_BIT 14 + #define RCC_APB2RSTR_SPI1RST_BIT 12 + #define RCC_APB2RSTR_SDIORST_BIT 11 + #define RCC_APB2RSTR_ADCRST_BIT 8 + #define RCC_APB2RSTR_USART6RST_BIT 5 + #define RCC_APB2RSTR_USART1RST_BIT 4 + #define RCC_APB2RSTR_TIM8RST_BIT 1 + #define RCC_APB2RSTR_TIM1RST_BIT 0 + + #define RCC_APB2RSTR_TIM11RST (1U << RCC_APB2RSTR_TIM11RST_BIT) + #define RCC_APB2RSTR_TIM10RST (1U << RCC_APB2RSTR_TIM10RST_BIT) + #define RCC_APB2RSTR_TIM9RST (1U << RCC_APB2RSTR_TIM9RST_BIT) + #define RCC_APB2RSTR_SYSCFGRST (1U << RCC_APB2RSTR_SYSCFGRST_BIT) + #define RCC_APB2RSTR_SPI1RST (1U << RCC_APB2RSTR_SPI1RST_BIT) + #define RCC_APB2RSTR_SDIORST (1U << RCC_APB2RSTR_SDIORST_BIT) + #define RCC_APB2RSTR_ADCRST (1U << RCC_APB2RSTR_ADCRST_BIT) + #define RCC_APB2RSTR_USART6RST (1U << RCC_APB2RSTR_USART6RST_BIT) + #define RCC_APB2RSTR_USART1RST (1U << RCC_APB2RSTR_USART1RST_BIT) + #define RCC_APB2RSTR_TIM8RST (1U << RCC_APB2RSTR_TIM8RST_BIT) + #define RCC_APB2RSTR_TIM1RST (1U << RCC_APB2RSTR_TIM1RST_BIT) + +Peripheral clock enable registers ++++++++++++++++++++++++++++++++++ + +:: + + /* AHB1 */ + + #define RCC_AHB1ENR_OTGHSULPIEN_BIT 30 + #define RCC_AHB1ENR_OTGHSEN_BIT 29 + #define RCC_AHB1ENR_ETHMACPTPEN_BIT 28 + #define RCC_AHB1ENR_ETHMACRXEN_BIT 27 + #define RCC_AHB1ENR_ETHMACTXEN_BIT 26 + #define RCC_AHB1ENR_ETHMACEN_BIT 25 + #define RCC_AHB1ENR_DMA2EN_BIT 22 + #define RCC_AHB1ENR_DMA1EN_BIT 21 + #define RCC_AHB1ENR_BKPSRAMEN_BIT 18 + #define RCC_AHB1ENR_CRCEN_BIT 12 + #define RCC_AHB1ENR_GPIOIEN_BIT 8 + #define RCC_AHB1ENR_GPIOHEN_BIT 7 + #define RCC_AHB1ENR_GPIOGEN_BIT 6 + #define RCC_AHB1ENR_GPIOFEN_BIT 5 + #define RCC_AHB1ENR_GPIOEEN_BIT 4 + #define RCC_AHB1ENR_GPIODEN_BIT 3 + #define RCC_AHB1ENR_GPIOCEN_BIT 2 + #define RCC_AHB1ENR_GPIOBEN_BIT 1 + #define RCC_AHB1ENR_GPIOAEN_BIT 0 + + #define RCC_AHB1ENR_OTGHSULPIEN (1U << RCC_AHB1ENR_OTGHSULPIEN_BIT) + #define RCC_AHB1ENR_OTGHSEN (1U << RCC_AHB1ENR_OTGHSEN_BIT) + #define RCC_AHB1ENR_ETHMACPTPEN (1U << RCC_AHB1ENR_ETHMACPTPEN_BIT) + #define RCC_AHB1ENR_ETHMACRXEN (1U << RCC_AHB1ENR_ETHMACRXEN_BIT) + #define RCC_AHB1ENR_ETHMACTXEN (1U << RCC_AHB1ENR_ETHMACTXEN_BIT) + #define RCC_AHB1ENR_ETHMACEN (1U << RCC_AHB1ENR_ETHMACEN_BIT) + #define RCC_AHB1ENR_DMA2EN (1U << RCC_AHB1ENR_DMA2EN_BIT) + #define RCC_AHB1ENR_DMA1EN (1U << RCC_AHB1ENR_DMA1EN_BIT) + #define RCC_AHB1ENR_BKPSRAMEN (1U << RCC_AHB1ENR_BKPSRAMEN_BIT) + #define RCC_AHB1ENR_CRCEN (1U << RCC_AHB1ENR_CRCEN_BIT) + #define RCC_AHB1ENR_GPIOIEN (1U << RCC_AHB1ENR_GPIOIEN_BIT) + #define RCC_AHB1ENR_GPIOHEN (1U << RCC_AHB1ENR_GPIOHEN_BIT) + #define RCC_AHB1ENR_GPIOGEN (1U << RCC_AHB1ENR_GPIOGEN_BIT) + #define RCC_AHB1ENR_GPIOFEN (1U << RCC_AHB1ENR_GPIOFEN_BIT) + #define RCC_AHB1ENR_GPIOEEN (1U << RCC_AHB1ENR_GPIOEEN_BIT) + #define RCC_AHB1ENR_GPIODEN (1U << RCC_AHB1ENR_GPIODEN_BIT) + #define RCC_AHB1ENR_GPIOCEN (1U << RCC_AHB1ENR_GPIOCEN_BIT) + #define RCC_AHB1ENR_GPIOBEN (1U << RCC_AHB1ENR_GPIOBEN_BIT) + #define RCC_AHB1ENR_GPIOAEN (1U << RCC_AHB1ENR_GPIOAEN_BIT) + + /* AHB2 */ + + #define RCC_AHB2ENR_OTGFSEN_BIT 7 + #define RCC_AHB2ENR_RNGEN_BIT 6 + #define RCC_AHB2ENR_HASHEN_BIT 5 + #define RCC_AHB2ENR_CRYPEN_BIT 4 + #define RCC_AHB2ENR_DCMIEN_BIT 0 + + #define RCC_AHB2ENR_OTGFSEN (1U << RCC_AHB2ENR_OTGFSEN_BIT) + #define RCC_AHB2ENR_RNGEN (1U << RCC_AHB2ENR_RNGEN_BIT) + #define RCC_AHB2ENR_HASHEN (1U << RCC_AHB2ENR_HASHEN_BIT) + #define RCC_AHB2ENR_CRYPEN (1U << RCC_AHB2ENR_CRYPEN_BIT) + #define RCC_AHB2ENR_DCMIEN (1U << RCC_AHB2ENR_DCMIEN_BIT) + + /* AHB3 */ + + #define RCC_AHB3ENR_FSMCEN_BIT 0 + + #define RCC_AHB3ENR_FSMCEN (1U << RCC_AHB3ENR_FSMCEN_BIT) + + /* APB1 */ + + #define RCC_APB1ENR_DACEN_BIT 29 + #define RCC_APB1ENR_PWREN_BIT 28 + #define RCC_APB1ENR_CAN2EN_BIT 26 + #define RCC_APB1ENR_CAN1EN_BIT 25 + #define RCC_APB1ENR_I2C3EN_BIT 23 + #define RCC_APB1ENR_I2C2EN_BIT 22 + #define RCC_APB1ENR_I2C1EN_BIT 21 + #define RCC_APB1ENR_UART5EN_BIT 20 + #define RCC_APB1ENR_UART4EN_BIT 19 + #define RCC_APB1ENR_USART3EN_BIT 18 + #define RCC_APB1ENR_USART2EN_BIT 17 + #define RCC_APB1ENR_SPI3EN_BIT 15 + #define RCC_APB1ENR_SPI2EN_BIT 14 + #define RCC_APB1ENR_WWDGEN_BIT 11 + #define RCC_APB1ENR_TIM14EN_BIT 8 + #define RCC_APB1ENR_TIM13EN_BIT 7 + #define RCC_APB1ENR_TIM12EN_BIT 6 + #define RCC_APB1ENR_TIM7EN_BIT 5 + #define RCC_APB1ENR_TIM6EN_BIT 4 + #define RCC_APB1ENR_TIM5EN_BIT 3 + #define RCC_APB1ENR_TIM4EN_BIT 2 + #define RCC_APB1ENR_TIM3EN_BIT 1 + #define RCC_APB1ENR_TIM2EN_BIT 0 + + #define RCC_APB1ENR_DACEN (1U << RCC_APB1ENR_DACEN_BIT) + #define RCC_APB1ENR_PWREN (1U << RCC_APB1ENR_PWREN_BIT) + #define RCC_APB1ENR_CAN2EN (1U << RCC_APB1ENR_CAN2EN_BIT) + #define RCC_APB1ENR_CAN1EN (1U << RCC_APB1ENR_CAN1EN_BIT) + #define RCC_APB1ENR_I2C3EN (1U << RCC_APB1ENR_I2C3EN_BIT) + #define RCC_APB1ENR_I2C2EN (1U << RCC_APB1ENR_I2C2EN_BIT) + #define RCC_APB1ENR_I2C1EN (1U << RCC_APB1ENR_I2C1EN_BIT) + #define RCC_APB1ENR_UART5EN (1U << RCC_APB1ENR_UART5EN_BIT) + #define RCC_APB1ENR_UART4EN (1U << RCC_APB1ENR_UART4EN_BIT) + #define RCC_APB1ENR_USART3EN (1U << RCC_APB1ENR_USART3EN_BIT) + #define RCC_APB1ENR_USART2EN (1U << RCC_APB1ENR_USART2EN_BIT) + #define RCC_APB1ENR_SPI3EN (1U << RCC_APB1ENR_SPI3EN_BIT) + #define RCC_APB1ENR_SPI2EN (1U << RCC_APB1ENR_SPI2EN_BIT) + #define RCC_APB1ENR_WWDGEN (1U << RCC_APB1ENR_WWDGEN_BIT) + #define RCC_APB1ENR_TIM14EN (1U << RCC_APB1ENR_TIM14EN_BIT) + #define RCC_APB1ENR_TIM13EN (1U << RCC_APB1ENR_TIM13EN_BIT) + #define RCC_APB1ENR_TIM12EN (1U << RCC_APB1ENR_TIM12EN_BIT) + #define RCC_APB1ENR_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT) + #define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_BIT) + #define RCC_APB1ENR_TIM5EN (1U << RCC_APB1ENR_TIM5EN_BIT) + #define RCC_APB1ENR_TIM4EN (1U << RCC_APB1ENR_TIM4EN_BIT) + #define RCC_APB1ENR_TIM3EN (1U << RCC_APB1ENR_TIM3EN_BIT) + #define RCC_APB1ENR_TIM2EN (1U << RCC_APB1ENR_TIM2EN_BIT) + + /* APB2 */ + + #define RCC_APB2ENR_TIM11EN_BIT 18 + #define RCC_APB2ENR_TIM10EN_BIT 17 + #define RCC_APB2ENR_TIM9EN_BIT 16 + #define RCC_APB2ENR_SYSCFGEN_BIT 14 + #define RCC_APB2ENR_SPI1EN_BIT 12 + #define RCC_APB2ENR_SDIOEN_BIT 11 + #define RCC_APB2ENR_ADC3EN_BIT 10 + #define RCC_APB2ENR_ADC2EN_BIT 9 + #define RCC_APB2ENR_ADC1EN_BIT 8 + #define RCC_APB2ENR_USART6EN_BIT 5 + #define RCC_APB2ENR_USART1EN_BIT 4 + #define RCC_APB2ENR_TIM8EN_BIT 1 + #define RCC_APB2ENR_TIM1EN_BIT 0 + + #define RCC_APB2ENR_TIM11EN (1U << RCC_APB2ENR_TIM11EN_BIT) + #define RCC_APB2ENR_TIM10EN (1U << RCC_APB2ENR_TIM10EN_BIT) + #define RCC_APB2ENR_TIM9EN (1U << RCC_APB2ENR_TIM9EN_BIT) + #define RCC_APB2ENR_SYSCFGEN (1U << RCC_APB2ENR_SYSCFGEN_BIT) + #define RCC_APB2ENR_SPI1EN (1U << RCC_APB2ENR_SPI1EN_BIT) + #define RCC_APB2ENR_SDIOEN (1U << RCC_APB2ENR_SDIOEN_BIT) + #define RCC_APB2ENR_ADC3EN (1U << RCC_APB2ENR_ADC3EN_BIT) + #define RCC_APB2ENR_ADC2EN (1U << RCC_APB2ENR_ADC2EN_BIT) + #define RCC_APB2ENR_ADC1EN (1U << RCC_APB2ENR_ADC1EN_BIT) + #define RCC_APB2ENR_USART6EN (1U << RCC_APB2ENR_USART6EN_BIT) + #define RCC_APB2ENR_USART1EN (1U << RCC_APB2ENR_USART1EN_BIT) + #define RCC_APB2ENR_TIM8EN (1U << RCC_APB2ENR_TIM8EN_BIT) + #define RCC_APB2ENR_TIM1EN (1U << RCC_APB2ENR_TIM1EN_BIT) + +Peripheral clock enable in low power mode registers ++++++++++++++++++++++++++++++++++++++++++++++++++++ + +:: + + /* AHB1 */ + + #define RCC_AHB1LPENR_OTGHSULPILPEN_BIT 30 + #define RCC_AHB1LPENR_OTGHSLPEN_BIT 29 + #define RCC_AHB1LPENR_ETHMACPTPLPEN_BIT 28 + #define RCC_AHB1LPENR_ETHMACRXLPEN_BIT 27 + #define RCC_AHB1LPENR_ETHMACTXLPEN_BIT 26 + #define RCC_AHB1LPENR_ETHMACLPEN_BIT 25 + #define RCC_AHB1LPENR_DMA2LPEN_BIT 22 + #define RCC_AHB1LPENR_DMA1LPEN_BIT 21 + #define RCC_AHB1LPENR_BKPSRAMLPEN_BIT 18 + #define RCC_AHB1LPENR_SRAM2LPEN_BIT 17 + #define RCC_AHB1LPENR_SRAM1LPEN_BIT 16 + #define RCC_AHB1LPENR_FLITFLPEN_BIT 15 + #define RCC_AHB1LPENR_CRCLPEN_BIT 12 + #define RCC_AHB1LPENR_GPIOILPEN_BIT 8 + #define RCC_AHB1LPENR_GPIOGLPEN_BIT 6 + #define RCC_AHB1LPENR_GPIOFLPEN_BIT 5 + #define RCC_AHB1LPENR_GPIOELPEN_BIT 4 + #define RCC_AHB1LPENR_GPIODLPEN_BIT 3 + #define RCC_AHB1LPENR_GPIOCLPEN_BIT 2 + #define RCC_AHB1LPENR_GPIOBLPEN_BIT 1 + #define RCC_AHB1LPENR_GPIOALPEN_BIT 0 + + #define RCC_AHB1LPENR_OTGHSULPILPEN (1U << RCC_AHB1LPENR_OTGHSULPILPEN_BIT) + #define RCC_AHB1LPENR_OTGHSLPEN (1U << RCC_AHB1LPENR_OTGHSLPEN_BIT) + #define RCC_AHB1LPENR_ETHMACPTPLPEN (1U << RCC_AHB1LPENR_ETHMACPTPLPEN_BIT) + #define RCC_AHB1LPENR_ETHMACRXLPEN (1U << RCC_AHB1LPENR_ETHMACRXLPEN_BIT) + #define RCC_AHB1LPENR_ETHMACTXLPEN (1U << RCC_AHB1LPENR_ETHMACTXLPEN_BIT) + #define RCC_AHB1LPENR_ETHMACLPEN (1U << RCC_AHB1LPENR_ETHMACLPEN_BIT) + #define RCC_AHB1LPENR_DMA2LPEN (1U << RCC_AHB1LPENR_DMA2LPEN_BIT) + #define RCC_AHB1LPENR_DMA1LPEN (1U << RCC_AHB1LPENR_DMA1LPEN_BIT) + #define RCC_AHB1LPENR_BKPSRAMLPEN (1U << RCC_AHB1LPENR_BKPSRAMLPEN_BIT) + #define RCC_AHB1LPENR_SRAM2LPEN (1U << RCC_AHB1LPENR_SRAM2LPEN_BIT) + #define RCC_AHB1LPENR_SRAM1LPEN (1U << RCC_AHB1LPENR_SRAM1LPEN_BIT) + #define RCC_AHB1LPENR_FLITFLPEN (1U << RCC_AHB1LPENR_FLITFLPEN_BIT) + #define RCC_AHB1LPENR_CRCLPEN (1U << RCC_AHB1LPENR_CRCLPEN_BIT) + #define RCC_AHB1LPENR_GPIOILPEN (1U << RCC_AHB1LPENR_GPIOILPEN_BIT) + #define RCC_AHB1LPENR_GPIOGLPEN (1U << RCC_AHB1LPENR_GPIOGLPEN_BIT) + #define RCC_AHB1LPENR_GPIOFLPEN (1U << RCC_AHB1LPENR_GPIOFLPEN_BIT) + #define RCC_AHB1LPENR_GPIOELPEN (1U << RCC_AHB1LPENR_GPIOELPEN_BIT) + #define RCC_AHB1LPENR_GPIODLPEN (1U << RCC_AHB1LPENR_GPIODLPEN_BIT) + #define RCC_AHB1LPENR_GPIOCLPEN (1U << RCC_AHB1LPENR_GPIOCLPEN_BIT) + #define RCC_AHB1LPENR_GPIOBLPEN (1U << RCC_AHB1LPENR_GPIOBLPEN_BIT) + #define RCC_AHB1LPENR_GPIOALPEN (1U << RCC_AHB1LPENR_GPIOALPEN_BIT) + + /* AHB2 */ + + #define RCC_AHB2LPENR_OTGFSLPEN_BIT 7 + #define RCC_AHB2LPENR_RNGLPEN_BIT 6 + #define RCC_AHB2LPENR_HASHLPEN_BIT 5 + #define RCC_AHB2LPENR_CRYPLPEN_BIT 4 + #define RCC_AHB2LPENR_DCMILPEN_BIT 0 + + #define RCC_AHB2LPENR_OTGFSLPEN (1U << RCC_AHB2LPENR_OTGFSLPEN_BIT) + #define RCC_AHB2LPENR_RNGLPEN (1U << RCC_AHB2LPENR_RNGLPEN_BIT) + #define RCC_AHB2LPENR_HASHLPEN (1U << RCC_AHB2LPENR_HASHLPEN_BIT) + #define RCC_AHB2LPENR_CRYPLPEN (1U << RCC_AHB2LPENR_CRYPLPEN_BIT) + #define RCC_AHB2LPENR_DCMILPEN (1U << RCC_AHB2LPENR_DCMILPEN_BIT) + + /* AHB3 */ + + #define RCC_AHB3LPENR_FSMCLPEN_BIT 0 + + #define RCC_AHB3LPENR_FSMCLPEN (1U << RCC_AHB3LPENR_FSMCLPEN_BIT) + + /* APB1 */ + + #define RCC_APB1LPENR_DACLPEN_BIT 29 + #define RCC_APB1LPENR_PWRLPEN_BIT 28 + #define RCC_APB1LPENR_CAN2LPEN_BIT 26 + #define RCC_APB1LPENR_CAN1LPEN_BIT 25 + #define RCC_APB1LPENR_I2C3LPEN_BIT 23 + #define RCC_APB1LPENR_I2C2LPEN_BIT 22 + #define RCC_APB1LPENR_I2C1LPEN_BIT 21 + #define RCC_APB1LPENR_UART5LPEN_BIT 20 + #define RCC_APB1LPENR_UART4LPEN_BIT 19 + #define RCC_APB1LPENR_USART3LPEN_BIT 18 + #define RCC_APB1LPENR_USART2LPEN_BIT 17 + #define RCC_APB1LPENR_SPI3LPEN_BIT 15 + #define RCC_APB1LPENR_SPI2LPEN_BIT 14 + #define RCC_APB1LPENR_WWDGLPEN_BIT 11 + #define RCC_APB1LPENR_TIM14LPEN_BIT 8 + #define RCC_APB1LPENR_TIM13LPEN_BIT 7 + #define RCC_APB1LPENR_TIM12LPEN_BIT 6 + #define RCC_APB1LPENR_TIM7LPEN_BIT 5 + #define RCC_APB1LPENR_TIM6LPEN_BIT 4 + #define RCC_APB1LPENR_TIM5LPEN_BIT 3 + #define RCC_APB1LPENR_TIM4LPEN_BIT 2 + #define RCC_APB1LPENR_TIM3LPEN_BIT 1 + #define RCC_APB1LPENR_TIM2LPEN_BIT 0 + + #define RCC_APB1LPENR_DACLPEN (1U << RCC_APB1LPENR_DACLPEN_BIT) + #define RCC_APB1LPENR_PWRLPEN (1U << RCC_APB1LPENR_PWRLPEN_BIT) + #define RCC_APB1LPENR_CAN2LPEN (1U << RCC_APB1LPENR_CAN2LPEN_BIT) + #define RCC_APB1LPENR_CAN1LPEN (1U << RCC_APB1LPENR_CAN1LPEN_BIT) + #define RCC_APB1LPENR_I2C3LPEN (1U << RCC_APB1LPENR_I2C3LPEN_BIT) + #define RCC_APB1LPENR_I2C2LPEN (1U << RCC_APB1LPENR_I2C2LPEN_BIT) + #define RCC_APB1LPENR_I2C1LPEN (1U << RCC_APB1LPENR_I2C1LPEN_BIT) + #define RCC_APB1LPENR_UART5LPEN (1U << RCC_APB1LPENR_UART5LPEN_BIT) + #define RCC_APB1LPENR_UART4LPEN (1U << RCC_APB1LPENR_UART4LPEN_BIT) + #define RCC_APB1LPENR_USART3LPEN (1U << RCC_APB1LPENR_USART3LPEN_BIT) + #define RCC_APB1LPENR_USART2LPEN (1U << RCC_APB1LPENR_USART2LPEN_BIT) + #define RCC_APB1LPENR_SPI3LPEN (1U << RCC_APB1LPENR_SPI3LPEN_BIT) + #define RCC_APB1LPENR_SPI2LPEN (1U << RCC_APB1LPENR_SPI2LPEN_BIT) + #define RCC_APB1LPENR_WWDGLPEN (1U << RCC_APB1LPENR_WWDGLPEN_BIT) + #define RCC_APB1LPENR_TIM14LPEN (1U << RCC_APB1LPENR_TIM14LPEN_BIT) + #define RCC_APB1LPENR_TIM13LPEN (1U << RCC_APB1LPENR_TIM13LPEN_BIT) + #define RCC_APB1LPENR_TIM12LPEN (1U << RCC_APB1LPENR_TIM12LPEN_BIT) + #define RCC_APB1LPENR_TIM7LPEN (1U << RCC_APB1LPENR_TIM7LPEN_BIT) + #define RCC_APB1LPENR_TIM6LPEN (1U << RCC_APB1LPENR_TIM6LPEN_BIT) + #define RCC_APB1LPENR_TIM5LPEN (1U << RCC_APB1LPENR_TIM5LPEN_BIT) + #define RCC_APB1LPENR_TIM4LPEN (1U << RCC_APB1LPENR_TIM4LPEN_BIT) + #define RCC_APB1LPENR_TIM3LPEN (1U << RCC_APB1LPENR_TIM3LPEN_BIT) + #define RCC_APB1LPENR_TIM2LPEN (1U << RCC_APB1LPENR_TIM2LPEN_BIT) + + /* APB2 */ + + #define RCC_APB2LPENR_TIM11LPEN_BIT 18 + #define RCC_APB2LPENR_TIM10LPEN_BIT 17 + #define RCC_APB2LPENR_TIM9LPEN_BIT 16 + #define RCC_APB2LPENR_SYSCFGLPEN_BIT 14 + #define RCC_APB2LPENR_SPI1LPEN_BIT 12 + #define RCC_APB2LPENR_SDIOLPEN_BIT 11 + #define RCC_APB2LPENR_ADC3LPEN_BIT 10 + #define RCC_APB2LPENR_ADC2LPEN_BIT 9 + #define RCC_APB2LPENR_ADC1LPEN_BIT 8 + #define RCC_APB2LPENR_USART6LPEN_BIT 5 + #define RCC_APB2LPENR_USART1LPEN_BIT 4 + #define RCC_APB2LPENR_TIM8LPEN_BIT 1 + #define RCC_APB2LPENR_TIM1LPEN_BIT 0 + + #define RCC_APB2LPENR_TIM11LPEN (1U << RCC_APB2LPENR_TIM11LPEN_BIT) + #define RCC_APB2LPENR_TIM10LPEN (1U << RCC_APB2LPENR_TIM10LPEN_BIT) + #define RCC_APB2LPENR_TIM9LPEN (1U << RCC_APB2LPENR_TIM9LPEN_BIT) + #define RCC_APB2LPENR_SYSCFGLPEN (1U << RCC_APB2LPENR_SYSCFGLPEN_BIT) + #define RCC_APB2LPENR_SPI1LPEN (1U << RCC_APB2LPENR_SPI1LPEN_BIT) + #define RCC_APB2LPENR_SDIOLPEN (1U << RCC_APB2LPENR_SDIOLPEN_BIT) + #define RCC_APB2LPENR_ADC3LPEN (1U << RCC_APB2LPENR_ADC3LPEN_BIT) + #define RCC_APB2LPENR_ADC2LPEN (1U << RCC_APB2LPENR_ADC2LPEN_BIT) + #define RCC_APB2LPENR_ADC1LPEN (1U << RCC_APB2LPENR_ADC1LPEN_BIT) + #define RCC_APB2LPENR_USART6LPEN (1U << RCC_APB2LPENR_USART6LPEN_BIT) + #define RCC_APB2LPENR_USART1LPEN (1U << RCC_APB2LPENR_USART1LPEN_BIT) + #define RCC_APB2LPENR_TIM8LPEN (1U << RCC_APB2LPENR_TIM8LPEN_BIT) + #define RCC_APB2LPENR_TIM1LPEN (1U << RCC_APB2LPENR_TIM1LPEN_BIT) + +Backup domain control register +++++++++++++++++++++++++++++++ + +:: + + #define RCC_BDCR_BDRST_BIT 16 + #define RCC_BDCR_RTCEN_BIT 15 + #define RCC_BDCR_LSEBYP_BIT 2 + #define RCC_BDCR_LSERDY_BIT 1 + #define RCC_BDCR_LSEON_BIT 0 + + #define RCC_BDCR_BDRST (1U << RCC_BDCR_BDRST_BIT) + #define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTCEN_BIT) + #define RCC_BDCR_RTCSEL (0x3 << 8) + #define RCC_BDCR_RTCSEL_NOCLOCK (0x0 << 8) + #define RCC_BDCR_RTCSEL_LSE (0x1 << 8) + #define RCC_BDCR_RTCSEL_LSI (0x2 << 8) + #define RCC_BDCR_RTCSEL_HSE_DIV (0x3 << 8) + #define RCC_BDCR_LSEBYP (1U << RCC_BDCR_LSEBYP_BIT) + #define RCC_BDCR_LSERDY (1U << RCC_BDCR_LSERDY_BIT) + #define RCC_BDCR_LSEON (1U << RCC_BDCR_LSEON_BIT) + +Clock control and status register ++++++++++++++++++++++++++++++++++ + +:: + + #define RCC_CSR_LPWRRSTF_BIT 31 + #define RCC_CSR_WWDGRSTF_BIT 30 + #define RCC_CSR_IWDGRSTF_BIT 29 + #define RCC_CSR_SFTRSTF_BIT 28 + #define RCC_CSR_PORRSTF_BIT 27 + #define RCC_CSR_PINRSTF_BIT 26 + #define RCC_CSR_BORRSTF_BIT 25 + #define RCC_CSR_RMVF_BIT 24 + #define RCC_CSR_LSIRDY_BIT 1 + #define RCC_CSR_LSION_BIT 0 + + #define RCC_CSR_LPWRRSTF (1U << RCC_CSR_LPWRRSTF_BIT) + #define RCC_CSR_WWDGRSTF (1U << RCC_CSR_WWDGRSTF_BIT) + #define RCC_CSR_IWDGRSTF (1U << RCC_CSR_IWDGRSTF_BIT) + #define RCC_CSR_SFTRSTF (1U << RCC_CSR_SFTRSTF_BIT) + #define RCC_CSR_PORRSTF (1U << RCC_CSR_PORRSTF_BIT) + #define RCC_CSR_PINRSTF (1U << RCC_CSR_PINRSTF_BIT) + #define RCC_CSR_BORRSTF (1U << RCC_CSR_BORRSTF_BIT) + #define RCC_CSR_RMVF (1U << RCC_CSR_RMVF_BIT) + #define RCC_CSR_LSIRDY (1U << RCC_CSR_LSIRDY_BIT) + #define RCC_CSR_LSION (1U << RCC_CSR_LSION_BIT) + +Spread spectrum clock generation register ++++++++++++++++++++++++++++++++++++++++++ + +:: + + #define RCC_SSCGR_SSCGEN_BIT 31 + #define RCC_SSCGR_SPREADSEL_BIT 30 + + #define RCC_SSCGR_SSCGEN (1U << RCC_SSCGR_SSCGEN_BIT) + #define RCC_SSCGR_SPREADSEL (1U << RCC_SSCGR_SPREADSEL_BIT) + #define RCC_SSCGR_SPREADSEL_CENTER (0x0 << RCC_SSCGR_SPREADSEL_BIT) + #define RCC_SSCGR_SPREADSEL_DOWN (0x1 << RCC_SSCGR_SPREADSEL_BIT) + #define RCC_SSCGR_INCSTEP (0xFFF << 16) + #define RCC_SSCGR_MODPER 0xFFFF + +PLLI2S configuration register ++++++++++++++++++++++++++++++ + +:: + + #define RCC_PLLI2SCFGR_PLLI2SR (0x7 << 28) + #define RCC_PLLI2SCFGR_PLLI2SN (0x1FF << 6) + diff --git a/source/libmaple/api/rcc.rst b/source/libmaple/api/rcc.rst index 4b96c00..ce58ec8 100644 --- a/source/libmaple/api/rcc.rst +++ b/source/libmaple/api/rcc.rst @@ -1,377 +1,360 @@ .. highlight:: c .. _libmaple-rcc: -``rcc.h`` -========= +``<libmaple/rcc.h>`` +==================== Reset and Clock Control (RCC) support. +The RCC is responsible for managing the MCU's various clocks. This +includes the core clock SYSCLK, which determines the CPU clock +frequency, as well as the clock lines that drive peripherals. + +Because of this, the available RCC functionality varies by target. +There are a :ref:`variety of abstractions <libmaple-rcc-core-types>` +in place to make managing this more convenient. + .. contents:: Contents :local: + :depth: 2 + +.. _libmaple-rcc-core-types: + +Core Types +---------- + +The core abstractions in place are +:ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`, +:ref:`rcc_clk <libmaple-rcc-rcc_clk>`, +:ref:`rcc_sysclk_src <libmaple-rcc-rcc_sysclk_src>`, +:ref:`rcc_clk_domain <libmaple-rcc-rcc_clk_domain>`, and +:ref:`rcc_prescaler <libmaple-rcc-rcc_prescaler>`. + +.. _libmaple-rcc-rcc_clk_id: + +Peripheral Identifiers: ``rcc_clk_id`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``rcc_clk_id`` is an enum used to identify peripherals. The RCC +back-ends use them to look up a peripheral's bus and clock line, but +they are also generally useful as unique identifiers for each +peripheral. You can manage peripherals using their ``rcc_clk_id``\ s +with :ref:`these functions <libmaple-rcc-clk-id-funcs>`. + +Peripherals which are common across targets have the same token +(though not necessarily the same value) for their ``rcc_clk_id`` +across different targets. For example, the ``rcc_clk_id`` for the ADC1 +peripheral is always ``RCC_ADC1`` regardless of the target. +Additionally, as explained in :ref:`libmaple-overview-devices`, each +peripheral device type struct contains the ``rcc_clk_id`` for that +peripheral in a ``clk_id`` field. + +The available ``rcc_clk_id``\ s on each supported target series are as +follows. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::rcc_clk_id -Types ------ +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::rcc_clk_id + +.. _libmaple-rcc-rcc_sysclk_src: + +System Clock (SYSCLK) Sources: ``rcc_sysclk_src`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +SYSCLK is the core system clock. It determines the CPU clock rate, and +it's the base clock which is used to drive (most of) the peripherals +on the STM32. ``rcc_sysclk_src`` is an enum for the possible SYSCLK +sources. Switch the SYSCLK source with :ref:`rcc_switch_sysclk() +<libmaple-rcc-rcc_switch_sysclk>`. -.. doxygenstruct:: rcc_reg_map .. doxygenenum:: rcc_sysclk_src -.. doxygenenum:: rcc_pllsrc -.. doxygenenum:: rcc_pll_multiplier -.. doxygenenum:: rcc_clk_id -.. doxygenenum:: rcc_clk_domain -.. doxygenenum:: rcc_prescaler -.. doxygenenum:: rcc_adc_divider -.. doxygenenum:: rcc_apb1_divider -.. doxygenenum:: rcc_apb2_divider -.. doxygenenum:: rcc_ahb_divider -Devices -------- +As a special case, you can configure the PLL with a call to +:ref:`rcc_configure_pll() <libmaple-rcc-rcc_configure_pll>`. + +.. _libmaple-rcc-rcc_clk: + +System and Secondary Clock Sources: ``rcc_clk`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``rcc_clk`` type gives available system and secondary clock +sources (e.g. HSI, HSE, LSE). As with :ref:`rcc_clk_id +<libmaple-rcc-rcc_clk_id>`, clock sources which are common across +targets have the same token, but not necessarily the same value, for +their ``rcc_clk`` on each target. A variety of :ref:`clock management +functions <libmaple-rcc-clk-funcs>` are available. + +Note that the inclusion of secondary clock sources, like LSI and LSE, +makes ``rcc_clk`` different from the SYSCLK sources, which are managed +using :ref:`rcc_sysclk_src <libmaple-rcc-rcc_sysclk_src>`. + +The available ``rcc_clk``\ s for each supported target series are as +follows. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::rcc_clk -None. +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::rcc_clk + +.. _libmaple-rcc-rcc_clk_domain: + +Clock Domains: ``rcc_clk_domain`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These specify the available clock domains. For example, each AHB and +APB is a clock domain. + +This type mostly exists to enable asking devices what bus they're on, +which, given knowledge of your system's clock configuration, can be +useful when making decisions about prescalers, etc. + +Given an :ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`, you can get the +peripheral's clock domain with :ref:`rcc_dev_clk() +<libmaple-rcc-rcc_dev_clk>`. Clock domains that are common across +series have the same token (but not necessarily the same value) for +their corresponding ``rcc_clk_domain``. + +The available ``rcc_clk_domain``\ s for each supported target series +are as follows. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::rcc_clk_domain + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::rcc_clk_domain + +.. _libmaple-rcc-rcc_prescaler: + +Prescalers: ``rcc_prescaler`` and Friends +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Available prescalers are managed via the ``rcc_prescaler`` type, the +``rcc_set_prescaler()`` function, and a variety of related prescaler +divider types. See :ref:`libmaple-rcc-prescalers` for more +information and usage notes. Functions --------- -.. doxygenfunction:: rcc_clk_init +.. _libmaple-rcc-sysclk-funcs: +.. _libmaple-rcc-rcc_switch_sysclk: + +SYSCLK Management +~~~~~~~~~~~~~~~~~ + +Change the SYSCLK source with ``rcc_switch_sysclk()``. + +.. doxygenfunction:: rcc_switch_sysclk + +.. _libmaple-rcc-rcc_configure_pll: + +PLL Configuration +~~~~~~~~~~~~~~~~~ + +You can configure the PLL with ``rcc_configure_pll()``. This takes an +``rcc_pll_cfg`` struct as its argument. Though the definition of +``rcc_pll_cfg`` is common across series, its contents are entirely +target-dependent. + +.. doxygenstruct:: rcc_pll_cfg +.. _rcc-rcc_configure_pll: +.. doxygenfunction:: rcc_configure_pll + +The fields in an ``rcc_pll_cfg`` on each target are as follows. + +rcc_pll_cfg on STM32F1 Targets +++++++++++++++++++++++++++++++ + +The ``pllsrc`` field is chosen from the following. + +.. doxygenenum:: stm32f1::rcc_pllsrc + +.. FIXME [0.0.13] We've got plans to redo this; make sure you watch +.. libmaple for changes here. + +The ``data`` field must point to a ``struct stm32f1_rcc_pll_data``. +This just contains an ``rcc_pll_multiplier``. + +.. doxygenenum:: stm32f1::rcc_pll_multiplier + +.. doxygenstruct:: stm32f1::stm32f1_rcc_pll_data + +rcc_pll_cfg on STM32F2 Targets +++++++++++++++++++++++++++++++ + +The ``pllsrc`` field is chosen from the following. + +.. doxygenenum:: stm32f2::rcc_pllsrc + +The ``data`` field must point to a ``struct stm32f2_rcc_pll_data``. + +.. doxygenstruct:: stm32f2::stm32f2_rcc_pll_data + +.. _libmaple-rcc-clk-funcs: + +System and Secondary Clock Management +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These functions are useful for managing clocks via their :ref:`rcc_clk +<libmaple-rcc-rcc_clk>`. + +.. doxygenfunction:: rcc_turn_on_clk +.. doxygenfunction:: rcc_turn_off_clk +.. doxygenfunction:: rcc_is_clk_on +.. doxygenfunction:: rcc_is_clk_ready + +.. _libmaple-rcc-clk-id-funcs: + +Peripheral Management +~~~~~~~~~~~~~~~~~~~~~ + +These functions are useful for managing peripherals via their +:ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`. + +.. _libmaple-rcc-rcc_clk_enable: .. doxygenfunction:: rcc_clk_enable .. doxygenfunction:: rcc_reset_dev +.. _libmaple-rcc-rcc_dev_clk: .. doxygenfunction:: rcc_dev_clk + +.. _libmaple-rcc-prescalers: + +Prescaler Management +~~~~~~~~~~~~~~~~~~~~ + +All clock prescalers managed by RCC can be controlled with a single +function, ``rcc_set_prescaler()``. + .. doxygenfunction:: rcc_set_prescaler -Register Map Base Pointers --------------------------- +The arguments to ``rcc_set_prescaler()`` are target-dependent, but +follow a common pattern: + +- The first argument is the prescaler to set, so there's one for each + peripheral clock domain, etc. These have names like + ``RCC_PRESCALER_FOO``, e.g. ``RCC_PRESCALER_APB1``. Choose the + prescaler from the ``rcc_prescaler``\ s on your target (see below). + +- The second argument is the actual clock divider to use; it's chosen + based on the first argument. The dividers for ``RCC_PRESCALER_FOO`` + are given by the type ``rcc_foo_divider``, and have values like + ``RCC_FOO_xxx_DIV_y``. This means that the foo clock will be the + ``xxx`` clock divided by ``y``. + +For example, calling ``rcc_set_prescaler(RCC_PRESCALER_APB1, +RCC_APB1_HCLK_DIV_1)`` would set the APB1 clock to HCLK divided by 1. + +Prescalers which are common across targets have the same token, though +not necessarily the same value, for their ``rcc_prescaler`` (for +example, ``RCC_PRESCALER_APB1`` is available on both STM32F1 and +STM32F2 targets). The available prescalers and dividers on each +supported target series are as follows. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::rcc_prescaler +.. doxygenenum:: stm32f1::rcc_adc_divider +.. doxygenenum:: stm32f1::rcc_apb1_divider +.. doxygenenum:: stm32f1::rcc_apb2_divider +.. doxygenenum:: stm32f1::rcc_ahb_divider + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::rcc_prescaler +.. doxygenenum:: stm32f2::rcc_mco2_divider +.. doxygenenum:: stm32f2::rcc_mco1_divider +.. doxygenenum:: stm32f2::rcc_rtc_divider +.. doxygenenum:: stm32f2::rcc_apb2_divider +.. doxygenenum:: stm32f2::rcc_apb1_divider +.. doxygenenum:: stm32f2::rcc_ahb_divider + +Register Maps +------------- + +These vary by target. The base pointer is always ``RCC_BASE``. .. doxygendefine:: RCC_BASE +STM32F1 Targets +~~~~~~~~~~~~~~~ + +.. doxygenstruct:: stm32f1::rcc_reg_map + +STM32F2 Targets +~~~~~~~~~~~~~~~ + +.. doxygenstruct:: stm32f2::rcc_reg_map + Register Bit Definitions ------------------------ -Clock control register -~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: RCC_CR_PLLRDY_BIT -.. doxygendefine:: RCC_CR_PLLON_BIT -.. doxygendefine:: RCC_CR_CSSON_BIT -.. doxygendefine:: RCC_CR_HSEBYP_BIT -.. doxygendefine:: RCC_CR_HSERDY_BIT -.. doxygendefine:: RCC_CR_HSEON_BIT -.. doxygendefine:: RCC_CR_HSIRDY_BIT -.. doxygendefine:: RCC_CR_HSION_BIT - -.. doxygendefine:: RCC_CR_PLLRDY -.. doxygendefine:: RCC_CR_PLLON -.. doxygendefine:: RCC_CR_CSSON -.. doxygendefine:: RCC_CR_HSEBYP -.. doxygendefine:: RCC_CR_HSERDY -.. doxygendefine:: RCC_CR_HSEON -.. doxygendefine:: RCC_CR_HSICAL -.. doxygendefine:: RCC_CR_HSITRIM -.. doxygendefine:: RCC_CR_HSIRDY -.. doxygendefine:: RCC_CR_HSION - -Clock configuration register -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: RCC_CFGR_USBPRE_BIT -.. doxygendefine:: RCC_CFGR_PLLXTPRE_BIT -.. doxygendefine:: RCC_CFGR_PLLSRC_BIT - -.. doxygendefine:: RCC_CFGR_MCO -.. doxygendefine:: RCC_CFGR_USBPRE -.. doxygendefine:: RCC_CFGR_PLLMUL -.. doxygendefine:: RCC_CFGR_PLLXTPRE -.. doxygendefine:: RCC_CFGR_PLLSRC -.. doxygendefine:: RCC_CFGR_ADCPRE -.. doxygendefine:: RCC_CFGR_PPRE2 -.. doxygendefine:: RCC_CFGR_PPRE1 -.. doxygendefine:: RCC_CFGR_HPRE -.. doxygendefine:: RCC_CFGR_SWS -.. doxygendefine:: RCC_CFGR_SWS_PLL -.. doxygendefine:: RCC_CFGR_SWS_HSE -.. doxygendefine:: RCC_CFGR_SW -.. doxygendefine:: RCC_CFGR_SW_PLL -.. doxygendefine:: RCC_CFGR_SW_HSE - -Clock interrupt register -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: RCC_CIR_CSSC_BIT -.. doxygendefine:: RCC_CIR_PLLRDYC_BIT -.. doxygendefine:: RCC_CIR_HSERDYC_BIT -.. doxygendefine:: RCC_CIR_HSIRDYC_BIT -.. doxygendefine:: RCC_CIR_LSERDYC_BIT -.. doxygendefine:: RCC_CIR_LSIRDYC_BIT -.. doxygendefine:: RCC_CIR_PLLRDYIE_BIT -.. doxygendefine:: RCC_CIR_HSERDYIE_BIT -.. doxygendefine:: RCC_CIR_HSIRDYIE_BIT -.. doxygendefine:: RCC_CIR_LSERDYIE_BIT -.. doxygendefine:: RCC_CIR_LSIRDYIE_BIT -.. doxygendefine:: RCC_CIR_CSSF_BIT -.. doxygendefine:: RCC_CIR_PLLRDYF_BIT -.. doxygendefine:: RCC_CIR_HSERDYF_BIT -.. doxygendefine:: RCC_CIR_HSIRDYF_BIT -.. doxygendefine:: RCC_CIR_LSERDYF_BIT -.. doxygendefine:: RCC_CIR_LSIRDYF_BIT - -.. doxygendefine:: RCC_CIR_CSSC -.. doxygendefine:: RCC_CIR_PLLRDYC -.. doxygendefine:: RCC_CIR_HSERDYC -.. doxygendefine:: RCC_CIR_HSIRDYC -.. doxygendefine:: RCC_CIR_LSERDYC -.. doxygendefine:: RCC_CIR_LSIRDYC -.. doxygendefine:: RCC_CIR_PLLRDYIE -.. doxygendefine:: RCC_CIR_HSERDYIE -.. doxygendefine:: RCC_CIR_HSIRDYIE -.. doxygendefine:: RCC_CIR_LSERDYIE -.. doxygendefine:: RCC_CIR_LSIRDYIE -.. doxygendefine:: RCC_CIR_CSSF -.. doxygendefine:: RCC_CIR_PLLRDYF -.. doxygendefine:: RCC_CIR_HSERDYF -.. doxygendefine:: RCC_CIR_HSIRDYF -.. doxygendefine:: RCC_CIR_LSERDYF -.. doxygendefine:: RCC_CIR_LSIRDYF - -APB2 peripheral reset register -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: RCC_APB2RSTR_TIM11RST_BIT -.. doxygendefine:: RCC_APB2RSTR_TIM10RST_BIT -.. doxygendefine:: RCC_APB2RSTR_TIM9RST_BIT -.. doxygendefine:: RCC_APB2RSTR_ADC3RST_BIT -.. doxygendefine:: RCC_APB2RSTR_USART1RST_BIT -.. doxygendefine:: RCC_APB2RSTR_TIM8RST_BIT -.. doxygendefine:: RCC_APB2RSTR_SPI1RST_BIT -.. doxygendefine:: RCC_APB2RSTR_TIM1RST_BIT -.. doxygendefine:: RCC_APB2RSTR_ADC2RST_BIT -.. doxygendefine:: RCC_APB2RSTR_ADC1RST_BIT -.. doxygendefine:: RCC_APB2RSTR_IOPGRST_BIT -.. doxygendefine:: RCC_APB2RSTR_IOPFRST_BIT -.. doxygendefine:: RCC_APB2RSTR_IOPERST_BIT -.. doxygendefine:: RCC_APB2RSTR_IOPDRST_BIT -.. doxygendefine:: RCC_APB2RSTR_IOPCRST_BIT -.. doxygendefine:: RCC_APB2RSTR_IOPBRST_BIT -.. doxygendefine:: RCC_APB2RSTR_IOPARST_BIT -.. doxygendefine:: RCC_APB2RSTR_AFIORST_BIT - -.. doxygendefine:: RCC_APB2RSTR_TIM11RST -.. doxygendefine:: RCC_APB2RSTR_TIM10RST -.. doxygendefine:: RCC_APB2RSTR_TIM9RST -.. doxygendefine:: RCC_APB2RSTR_ADC3RST -.. doxygendefine:: RCC_APB2RSTR_USART1RST -.. doxygendefine:: RCC_APB2RSTR_TIM8RST -.. doxygendefine:: RCC_APB2RSTR_SPI1RST -.. doxygendefine:: RCC_APB2RSTR_TIM1RST -.. doxygendefine:: RCC_APB2RSTR_ADC2RST -.. doxygendefine:: RCC_APB2RSTR_ADC1RST -.. doxygendefine:: RCC_APB2RSTR_IOPGRST -.. doxygendefine:: RCC_APB2RSTR_IOPFRST -.. doxygendefine:: RCC_APB2RSTR_IOPERST -.. doxygendefine:: RCC_APB2RSTR_IOPDRST -.. doxygendefine:: RCC_APB2RSTR_IOPCRST -.. doxygendefine:: RCC_APB2RSTR_IOPBRST -.. doxygendefine:: RCC_APB2RSTR_IOPARST -.. doxygendefine:: RCC_APB2RSTR_AFIORST - -APB1 peripheral reset register -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: RCC_APB1RSTR_DACRST_BIT -.. doxygendefine:: RCC_APB1RSTR_PWRRST_BIT -.. doxygendefine:: RCC_APB1RSTR_BKPRST_BIT -.. doxygendefine:: RCC_APB1RSTR_CANRST_BIT -.. doxygendefine:: RCC_APB1RSTR_USBRST_BIT -.. doxygendefine:: RCC_APB1RSTR_I2C2RST_BIT -.. doxygendefine:: RCC_APB1RSTR_I2C1RST_BIT -.. doxygendefine:: RCC_APB1RSTR_UART5RST_BIT -.. doxygendefine:: RCC_APB1RSTR_UART4RST_BIT -.. doxygendefine:: RCC_APB1RSTR_USART3RST_BIT -.. doxygendefine:: RCC_APB1RSTR_USART2RST_BIT -.. doxygendefine:: RCC_APB1RSTR_SPI3RST_BIT -.. doxygendefine:: RCC_APB1RSTR_SPI2RST_BIT -.. doxygendefine:: RCC_APB1RSTR_WWDRST_BIT -.. doxygendefine:: RCC_APB1RSTR_TIM14RST_BIT -.. doxygendefine:: RCC_APB1RSTR_TIM13RST_BIT -.. doxygendefine:: RCC_APB1RSTR_TIM12RST_BIT -.. doxygendefine:: RCC_APB1RSTR_TIM7RST_BIT -.. doxygendefine:: RCC_APB1RSTR_TIM6RST_BIT -.. doxygendefine:: RCC_APB1RSTR_TIM5RST_BIT -.. doxygendefine:: RCC_APB1RSTR_TIM4RST_BIT -.. doxygendefine:: RCC_APB1RSTR_TIM3RST_BIT -.. doxygendefine:: RCC_APB1RSTR_TIM2RST_BIT - -.. doxygendefine:: RCC_APB1RSTR_DACRST -.. doxygendefine:: RCC_APB1RSTR_PWRRST -.. doxygendefine:: RCC_APB1RSTR_BKPRST -.. doxygendefine:: RCC_APB1RSTR_CANRST -.. doxygendefine:: RCC_APB1RSTR_USBRST -.. doxygendefine:: RCC_APB1RSTR_I2C2RST -.. doxygendefine:: RCC_APB1RSTR_I2C1RST -.. doxygendefine:: RCC_APB1RSTR_UART5RST -.. doxygendefine:: RCC_APB1RSTR_UART4RST -.. doxygendefine:: RCC_APB1RSTR_USART3RST -.. doxygendefine:: RCC_APB1RSTR_USART2RST -.. doxygendefine:: RCC_APB1RSTR_SPI3RST -.. doxygendefine:: RCC_APB1RSTR_SPI2RST -.. doxygendefine:: RCC_APB1RSTR_WWDRST -.. doxygendefine:: RCC_APB1RSTR_TIM14RST -.. doxygendefine:: RCC_APB1RSTR_TIM13RST -.. doxygendefine:: RCC_APB1RSTR_TIM12RST -.. doxygendefine:: RCC_APB1RSTR_TIM7RST -.. doxygendefine:: RCC_APB1RSTR_TIM6RST -.. doxygendefine:: RCC_APB1RSTR_TIM5RST -.. doxygendefine:: RCC_APB1RSTR_TIM4RST -.. doxygendefine:: RCC_APB1RSTR_TIM3RST -.. doxygendefine:: RCC_APB1RSTR_TIM2RST - -AHB peripheral clock enable register -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: RCC_AHBENR_SDIOEN_BIT -.. doxygendefine:: RCC_AHBENR_FSMCEN_BIT -.. doxygendefine:: RCC_AHBENR_CRCEN_BIT -.. doxygendefine:: RCC_AHBENR_FLITFEN_BIT -.. doxygendefine:: RCC_AHBENR_SRAMEN_BIT -.. doxygendefine:: RCC_AHBENR_DMA2EN_BIT -.. doxygendefine:: RCC_AHBENR_DMA1EN_BIT - -.. doxygendefine:: RCC_AHBENR_SDIOEN -.. doxygendefine:: RCC_AHBENR_FSMCEN -.. doxygendefine:: RCC_AHBENR_CRCEN -.. doxygendefine:: RCC_AHBENR_FLITFEN -.. doxygendefine:: RCC_AHBENR_SRAMEN -.. doxygendefine:: RCC_AHBENR_DMA2EN -.. doxygendefine:: RCC_AHBENR_DMA1EN - -APB2 peripheral clock enable register -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +These are given as source code. Available register bit definitions +vary by target. -.. doxygendefine:: RCC_APB2ENR_TIM11EN_BIT -.. doxygendefine:: RCC_APB2ENR_TIM10EN_BIT -.. doxygendefine:: RCC_APB2ENR_TIM9EN_BIT -.. doxygendefine:: RCC_APB2ENR_ADC3EN_BIT -.. doxygendefine:: RCC_APB2ENR_USART1EN_BIT -.. doxygendefine:: RCC_APB2ENR_TIM8EN_BIT -.. doxygendefine:: RCC_APB2ENR_SPI1EN_BIT -.. doxygendefine:: RCC_APB2ENR_TIM1EN_BIT -.. doxygendefine:: RCC_APB2ENR_ADC2EN_BIT -.. doxygendefine:: RCC_APB2ENR_ADC1EN_BIT -.. doxygendefine:: RCC_APB2ENR_IOPGEN_BIT -.. doxygendefine:: RCC_APB2ENR_IOPFEN_BIT -.. doxygendefine:: RCC_APB2ENR_IOPEEN_BIT -.. doxygendefine:: RCC_APB2ENR_IOPDEN_BIT -.. doxygendefine:: RCC_APB2ENR_IOPCEN_BIT -.. doxygendefine:: RCC_APB2ENR_IOPBEN_BIT -.. doxygendefine:: RCC_APB2ENR_IOPAEN_BIT -.. doxygendefine:: RCC_APB2ENR_AFIOEN_BIT - -.. doxygendefine:: RCC_APB2ENR_TIM11EN -.. doxygendefine:: RCC_APB2ENR_TIM10EN -.. doxygendefine:: RCC_APB2ENR_TIM9EN -.. doxygendefine:: RCC_APB2ENR_ADC3EN -.. doxygendefine:: RCC_APB2ENR_USART1EN -.. doxygendefine:: RCC_APB2ENR_TIM8EN -.. doxygendefine:: RCC_APB2ENR_SPI1EN -.. doxygendefine:: RCC_APB2ENR_TIM1EN -.. doxygendefine:: RCC_APB2ENR_ADC2EN -.. doxygendefine:: RCC_APB2ENR_ADC1EN -.. doxygendefine:: RCC_APB2ENR_IOPGEN -.. doxygendefine:: RCC_APB2ENR_IOPFEN -.. doxygendefine:: RCC_APB2ENR_IOPEEN -.. doxygendefine:: RCC_APB2ENR_IOPDEN -.. doxygendefine:: RCC_APB2ENR_IOPCEN -.. doxygendefine:: RCC_APB2ENR_IOPBEN -.. doxygendefine:: RCC_APB2ENR_IOPAEN -.. doxygendefine:: RCC_APB2ENR_AFIOEN - -APB1 peripheral clock enable register -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. We need this include to avoid crashing Emacs's ReST parser. Yuck. + +.. include:: rcc-reg-bits.txt + +Deprecated Functionality +------------------------ -.. doxygendefine:: RCC_APB1ENR_DACEN_BIT -.. doxygendefine:: RCC_APB1ENR_PWREN_BIT -.. doxygendefine:: RCC_APB1ENR_BKPEN_BIT -.. doxygendefine:: RCC_APB1ENR_CANEN_BIT -.. doxygendefine:: RCC_APB1ENR_USBEN_BIT -.. doxygendefine:: RCC_APB1ENR_I2C2EN_BIT -.. doxygendefine:: RCC_APB1ENR_I2C1EN_BIT -.. doxygendefine:: RCC_APB1ENR_UART5EN_BIT -.. doxygendefine:: RCC_APB1ENR_UART4EN_BIT -.. doxygendefine:: RCC_APB1ENR_USART3EN_BIT -.. doxygendefine:: RCC_APB1ENR_USART2EN_BIT -.. doxygendefine:: RCC_APB1ENR_SPI3EN_BIT -.. doxygendefine:: RCC_APB1ENR_SPI2EN_BIT -.. doxygendefine:: RCC_APB1ENR_WWDEN_BIT -.. doxygendefine:: RCC_APB1ENR_TIM14EN_BIT -.. doxygendefine:: RCC_APB1ENR_TIM13EN_BIT -.. doxygendefine:: RCC_APB1ENR_TIM12EN_BIT -.. doxygendefine:: RCC_APB1ENR_TIM7EN_BIT -.. doxygendefine:: RCC_APB1ENR_TIM6EN_BIT -.. doxygendefine:: RCC_APB1ENR_TIM5EN_BIT -.. doxygendefine:: RCC_APB1ENR_TIM4EN_BIT -.. doxygendefine:: RCC_APB1ENR_TIM3EN_BIT -.. doxygendefine:: RCC_APB1ENR_TIM2EN_BIT - -.. doxygendefine:: RCC_APB1ENR_DACEN -.. doxygendefine:: RCC_APB1ENR_PWREN -.. doxygendefine:: RCC_APB1ENR_BKPEN -.. doxygendefine:: RCC_APB1ENR_CANEN -.. doxygendefine:: RCC_APB1ENR_USBEN -.. doxygendefine:: RCC_APB1ENR_I2C2EN -.. doxygendefine:: RCC_APB1ENR_I2C1EN -.. doxygendefine:: RCC_APB1ENR_UART5EN -.. doxygendefine:: RCC_APB1ENR_UART4EN -.. doxygendefine:: RCC_APB1ENR_USART3EN -.. doxygendefine:: RCC_APB1ENR_USART2EN -.. doxygendefine:: RCC_APB1ENR_SPI3EN -.. doxygendefine:: RCC_APB1ENR_SPI2EN -.. doxygendefine:: RCC_APB1ENR_WWDEN -.. doxygendefine:: RCC_APB1ENR_TIM14EN -.. doxygendefine:: RCC_APB1ENR_TIM13EN -.. doxygendefine:: RCC_APB1ENR_TIM12EN -.. doxygendefine:: RCC_APB1ENR_TIM7EN -.. doxygendefine:: RCC_APB1ENR_TIM6EN -.. doxygendefine:: RCC_APB1ENR_TIM5EN -.. doxygendefine:: RCC_APB1ENR_TIM4EN -.. doxygendefine:: RCC_APB1ENR_TIM3EN -.. doxygendefine:: RCC_APB1ENR_TIM2EN - -Backup domain control register -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: RCC_BDCR_BDRST_BIT -.. doxygendefine:: RCC_BDCR_RTCEN_BIT -.. doxygendefine:: RCC_BDCR_LSEBYP_BIT -.. doxygendefine:: RCC_BDCR_LSERDY_BIT -.. doxygendefine:: RCC_BDCR_LSEON_BIT - -.. doxygendefine:: RCC_BDCR_BDRST -.. doxygendefine:: RCC_BDCR_RTCEN -.. doxygendefine:: RCC_BDCR_RTCSEL -.. doxygendefine:: RCC_BDCR_RTCSEL_NONE -.. doxygendefine:: RCC_BDCR_RTCSEL_LSE -.. doxygendefine:: RCC_BDCR_RTCSEL_HSE -.. doxygendefine:: RCC_BDCR_LSEBYP -.. doxygendefine:: RCC_BDCR_LSERDY -.. doxygendefine:: RCC_BDCR_LSEON - -Control/status register -~~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygendefine:: RCC_CSR_LPWRRSTF_BIT -.. doxygendefine:: RCC_CSR_WWDGRSTF_BIT -.. doxygendefine:: RCC_CSR_IWDGRSTF_BIT -.. doxygendefine:: RCC_CSR_SFTRSTF_BIT -.. doxygendefine:: RCC_CSR_PORRSTF_BIT -.. doxygendefine:: RCC_CSR_PINRSTF_BIT -.. doxygendefine:: RCC_CSR_RMVF_BIT -.. doxygendefine:: RCC_CSR_LSIRDY_BIT -.. doxygendefine:: RCC_CSR_LSION_BIT - -.. doxygendefine:: RCC_CSR_LPWRRSTF -.. doxygendefine:: RCC_CSR_WWDGRSTF -.. doxygendefine:: RCC_CSR_IWDGRSTF -.. doxygendefine:: RCC_CSR_SFTRSTF -.. doxygendefine:: RCC_CSR_PORRSTF -.. doxygendefine:: RCC_CSR_PINRSTF -.. doxygendefine:: RCC_CSR_RMVF -.. doxygendefine:: RCC_CSR_LSIRDY -.. doxygendefine:: RCC_CSR_LSION +.. _rcc-rcc_clk_init: +.. doxygenfunction:: stm32f1::rcc_clk_init + +To replace a call to ``rcc_clk_init()`` in order to set SYSCLK to PLL +driven by an external oscillator, you can use something like this, +which is portable except for the initialization of ``your_pll_cfg``:: + + /* You need to make this point to something valid for your target; see + * the documentation for rcc_configure_pll() for more details. */ + extern rcc_pll_cfg *your_pll_cfg; + + void pll_reconfigure() { + /* Turn on HSI using rcc_turn_on_clk() and wait for it to + * become ready by busy-waiting on rcc_is_clk_ready(). + * + * Switch to HSI to ensure we're not using the PLL while we + * reconfigure it. */ + rcc_turn_on_clk(RCC_CLK_HSI); + while (!rcc_is_clk_ready(RCC_CLK_HSI)) + ; + rcc_switch_sysclk(RCC_CLKSRC_HSI); + + /* Turn off HSE and the PLL, or we can't reconfigure it. */ + rcc_turn_off_clk(RCC_CLK_PLL); + rcc_turn_off_clk(RCC_CLK_HSE); + + /* Reconfigure the PLL. You can also perform any other + * prescaler management here. */ + rcc_configure_pll(your_pll_cfg); + + /* Turn on RCC_CLK_HSE. */ + rcc_turn_on_clk(RCC_CLK_HSE); + while (!rcc_is_clk_ready(RCC_CLK_HSE)) + ; + + /* Turn on RCC_CLK_PLL. */ + rcc_turn_on_clk(RCC_CLK_PLL); + while (!rcc_is_clk_ready(RCC_CLK_PLL)) + ; + + /* Finally, switch to the PLL. */ + rcc_switch_sysclk(RCC_CLKSRC_PLL); + } diff --git a/source/libmaple/api/ring_buffer.rst b/source/libmaple/api/ring_buffer.rst index e9b6637..ef082dd 100644 --- a/source/libmaple/api/ring_buffer.rst +++ b/source/libmaple/api/ring_buffer.rst @@ -1,8 +1,8 @@ .. highlight:: c .. _libmaple-ring_buffer: -``ring_buffer.h`` -================= +``<libmaple/ring_buffer.h>`` +============================ Simple circular byte buffer. This implementation is not thread-safe. In particular, none of these functions is guaranteed to be re-entrant. diff --git a/source/libmaple/api/stm32.rst b/source/libmaple/api/stm32.rst index 6e631b0..335bda4 100644 --- a/source/libmaple/api/stm32.rst +++ b/source/libmaple/api/stm32.rst @@ -1,26 +1,118 @@ .. highlight:: c .. _libmaple-stm32: -``stm32.h`` -=========== +``<libmaple/stm32.h>`` +====================== -General STM32-specific definitions. This file is currently somewhat -incomplete, but it will form the future basis for MCU-specific (rather -than board-specific, which belongs in :ref:`Wirish -<libmaple-vs-wirish>`) configuration. +STM32 chip header. This header supplies various series-specific and +chip-specific macros for the current build target. It's useful both +to abstract away hardware details (e.g. through use of +:ref:`STM32_NR_INTERRUPTS <libmaple-stm32-STM32_NR_INTERRUPTS>`) and +to decide what to do when you want something nonportable (e.g. by +checking :ref:`STM32_MCU_SERIES <libmaple-stm32-STM32_MCU_SERIES>`). -Defines -------- +.. contents:: Contents + :local: + +Determining the Target Series +----------------------------- + +The STM32 series (e.g. STM32F1, STM32F2, etc.) of the current target +can be inspected with ``STM32_MCU_SERIES``. + +.. _libmaple-stm32-STM32_MCU_SERIES: +.. doxygendefine:: STM32_MCU_SERIES + +Allowed values for ``STM32_MCU_SERIES`` are the following. This set is +expected to grow over time. + +.. doxygendefine:: STM32_SERIES_F1 +.. doxygendefine:: STM32_SERIES_F2 +.. doxygendefine:: STM32_SERIES_L1 +.. doxygendefine:: STM32_SERIES_F4 + +Series-Specific Characteristics +------------------------------- + +The macros in this section are only available on some STM32 series. + +STM32F1 +~~~~~~~ + +.. note:: These macros are only available when the current target is + an STM32F1 series MCU (i.e., when :ref:`STM32_MCU_SERIES + <libmaple-stm32-STM32_MCU_SERIES>` is ``STM32_SERIES_F1``). + +The STM32F1 series is further subdivided into :ref:`lines +<stm32-series-f1-lines>`. The line of the current target can be +inspected with ``STM32_F1_LINE``. + +.. doxygendefine:: STM32_F1_LINE + +There are five STM32F1 lines. The corresponding values +``STM32_F1_LINE`` can take are the following, though libmaple doesn't +currently support all of them. + +.. doxygendefine:: STM32_F1_LINE_VALUE +.. doxygendefine:: STM32_F1_LINE_ACCESS +.. doxygendefine:: STM32_F1_LINE_USB_ACCESS +.. doxygendefine:: STM32_F1_LINE_PERFORMANCE +.. doxygendefine:: STM32_F1_LINE_CONNECTIVITY + +MCU Feature Tests +----------------- + +The following defines can be used to determine if the target MCU has +a particular feature. + +.. _libmaple-stm32-STM32_HAVE_FSMC: +.. doxygendefine:: STM32_HAVE_FSMC +.. doxygendefine:: STM32_HAVE_USB + +MCU Characteristics +------------------- + +The following defines give salient characteristics of the target MCU. + +.. doxygendefine:: STM32_NR_GPIO_PORTS +.. _libmaple-stm32-STM32_NR_INTERRUPTS: +.. doxygendefine:: STM32_NR_INTERRUPTS +.. doxygendefine:: STM32_SRAM_END + +Clock Speeds +------------ + +The macros in this section are related to clock rates. As such, they +are really part of the configuration of the MCU, rather than inherent +characteristics of the MCU itself. For instance, it's possible to +change the PCLK1 and PCLK2 clock rates by reconfiguring the :ref:`RCC +<libmaple-rcc>`. libmaple proper never changes any clock rates, but it +does have APIs for doing so (such as :ref:`rcc_configure_pll() +<libmaple-rcc-rcc_configure_pll>`). Because of this, be careful when +using the macros in this section, as they assume that some values are +constant which in fact may be changed. + +The values these macros actually take are typically the maximum values +supported by the MCU. Since these are their actual values in practice +(at least in LeafLabs' current use cases, which have the chips running +as fast as possible), they're still considered useful. .. doxygendefine:: STM32_PCLK1 .. doxygendefine:: STM32_PCLK2 -.. doxygendefine:: STM32_NR_INTERRUPTS -.. doxygendefine:: STM32_NR_GPIO_PORTS + +The following macro, ``STM32_DELAY_US_MULT``, is a libmaple +implementation detail. It was included in this public API page in a +previous release by mistake, and is not deprecated, but using it in +your own code is a bad idea. + .. doxygendefine:: STM32_DELAY_US_MULT -.. doxygendefine:: STM32_SRAM_END -Deprecated Defines ------------------- +Deprecated Macros +----------------- + +.. warning:: The macros in this section are deprecated, and are + available for backwards compatibility only. Do not use + them in new code. .. doxygendefine:: PCLK1 .. doxygendefine:: PCLK2 diff --git a/source/libmaple/api/usart.rst b/source/libmaple/api/usart.rst index 1575a8f..68f2c37 100644 --- a/source/libmaple/api/usart.rst +++ b/source/libmaple/api/usart.rst @@ -34,6 +34,7 @@ Functions .. doxygenfunction:: usart_disable .. doxygenfunction:: usart_disable_all .. doxygenfunction:: usart_foreach +.. doxygenfunction:: usart_rx .. doxygenfunction:: usart_tx .. doxygenfunction:: usart_putudec .. doxygenfunction:: usart_putc diff --git a/source/libmaple/api/util.rst b/source/libmaple/api/util.rst index 06c9246..54377c0 100644 --- a/source/libmaple/api/util.rst +++ b/source/libmaple/api/util.rst @@ -1,8 +1,8 @@ .. highlight:: c .. _libmaple-util: -``util.h`` -========== +``<libmaple/util.h>`` +===================== .. TODO [0.2.0?] clean this up. @@ -14,17 +14,20 @@ Miscellaneous utility macros and procedures. Bit Manipulation ---------------- -:: +The following macros are useful for bit manipulation. - #define BIT(shift) (1UL << (shift)) - #define BIT_MASK_SHIFT(mask, shift) ((mask) << (shift)) - /** Gets bits m to n of x */ - #define GET_BITS(x, m, n) ((((uint32)x) << (31 - (n))) >> ((31 - (n)) + (m))) - #define IS_POWER_OF_TWO(v) (v && !(v & (v - 1))) +.. doxygendefine:: BIT +.. doxygendefine:: BIT_MASK_SHIFT +.. doxygendefine:: GET_BITS +.. doxygendefine:: IS_POWER_OF_TWO Failure Routines ---------------- +``throb()`` is called by various routines to throb a built-in +LED. **Usually, you shouldn't call it yourself**; use something like +``ASSERT(0)`` (or the libc ``abort()`` function) instead. + .. doxygenfunction:: throb Asserts and Debug Levels diff --git a/source/libmaple/apis.rst b/source/libmaple/apis.rst index f493406..31f4902 100644 --- a/source/libmaple/apis.rst +++ b/source/libmaple/apis.rst @@ -1,7 +1,7 @@ .. _libmaple-apis: -APIs -==== +``libmaple`` API Index +====================== This is the master index for libmaple proper's APIs. diff --git a/source/libmaple/overview.rst b/source/libmaple/overview.rst index 21d1a72..006f1d8 100644 --- a/source/libmaple/overview.rst +++ b/source/libmaple/overview.rst @@ -5,9 +5,12 @@ Overview ======== -This page is a general overview of libmaple proper. It provides a -general perspective of the library's goals and design. Examples are -given from libmaple's sources. +This page is a general overview of :ref:`libmaple proper +<libmaple-vs-wirish>`. It describes libmaple's design, and names +implementation patterns to look for when using it. General +familiarity with the :ref:`STM32 <stm32>` is assumed; beginners should +start with the high-level :ref:`Wirish interface <language>` instead. +Examples are given from libmaple's sources. .. contents:: Contents :local: @@ -15,170 +18,321 @@ given from libmaple's sources. Design Goals ------------ -The central goal of the libmaple project is to provide a pleasant, -consistent set of interfaces for dealing with the various peripherals -on the STM32 line. - -Let's start with the basics. If you're interested in low-level details -on the STM32, then you're going to spend a lot of quality time wading -through `ST RM0008 -<http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf>`_. -That document is the single most important tool in your toolbox. It -is the authoritative documentation for the capabilities and register -interfaces of the STM32 line. - -Perhaps you haven't read it in detail, but maybe you've at least -thumbed through a few of the sections, trying to gain some -understanding of what's going on. If you've done that (and if you -haven't, just take our word for it), then you know that underneath the -covers, *everything* is controlled by messing with bits in the -seemingly endless collections of registers specific to every -peripheral. The :ref:`USARTs <usart>` have data registers; (some of -the) the :ref:`timers <timers>` have capture/compare registers, the -:ref:`GPIOs <gpio>` have output data registers, etc. - -For the most part, Wirish does everything it can to hide this truth -from you. That's because when you really just want to get your robot -to fly, your LEDs to blink, or your `FM synthesizer -<https://github.com/Ixox/preen>`_ to, well, `synthesize -<http://xhosxe.free.fr/IxoxFMSynth.mp3>`_, you probably couldn't care -less about messing with registers. - -That's fine! In fact, it's our explicit goal for Wirish to be good -enough that most people never need to know libmaple proper even -exists. We want to make programming our boards as easy as possible, -after all. But the day may come when you want to add a library for an -as-yet unsupported peripheral, or you want to do something we didn't -anticipate, or you'd like to squeeze a little more speed out of a -critical section in your program. Or maybe you're just curious! - -If anything in the above paragraph describes you, then you'll find -that you need a way to translate your knowledge of RM0008 into -software. We imagine (if you're anything like us) you want to spend -the least amount of time you possibly can doing that -translation. Ideally, once you've finished your design, you want some -way to start reading and writing code right away, without having to -bushwhack your way through a thicket of clunky APIs. - -The central abstractions we've chosen to accomplish the above goals -are *register maps* and *devices*. Register maps are just structs -which encapsulate the layout of the IO-mapped memory regions -corresponding to a peripheral's registers. Devices encapsulate a -peripheral's register map as well as any other necessary information -needed to operate on it. Peripheral support routines generally -operate on devices rather than register maps. - -Devices -------- - -At the highest level, you'll be dealing with *devices*, where a -"device" is a general term for any particular piece of hardware you -might encounter. So, for example, an analog to digital converter is a -device. So is a USART. So is a GPIO port. In this section, we'll -consider some hypothetical "xxx" device. - -The first thing you need to know is that the header file for dealing -with xxx devices is, naturally enough, called ``xxx.h``. So if you -want to interface with the :ref:`ADCs <adc>`, just ``#include -"adc.h"``. - -Inside of ``xxx.h``, there will be a declaration for a ``struct -xxx_dev`` type. This type encapsulates all of the information we keep -track of for that xxx. So, for example, in ``adc.h``, there's a -``struct adc_dev``:: - - /** ADC device type. */ +The central goal for libmaple proper is to provide a pleasant, +portable, and consistent set of interfaces for dealing with the +various series of STM32 microcontrollers. + +Portability in particular can be a problem when programming for the +STM32. While the various STM32 series are largely pin-compatible with +one another, the peripheral register maps between series often change +drastically, even when the functionality provided by the peripheral +doesn't change very much. This means that code which accesses +registers directly often needs to change when porting a program to a +different series MCU. + +ST's solution to this problem thus far has been to `issue +<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32l1_stdperiph_lib.zip>`_ +`separate +<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f10x_stdperiph_lib.zip>`_ +`firmware +<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f2xx_stdperiph_lib.zip>`_ +`libraries +<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4_dsp_stdperiph_lib.zip>`_; +one for each STM32 series. Along with these, they have released a +`number +<http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00024853.pdf>`_ +of `application +<http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00033267.pdf>`_ +`notes +<http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00032987.pdf>`_ +describing the compatibility issues and how to migrate between series +by switching firmware libraries. Often, the migration advice is +essentially "rewrite your code"; this occurs, for example, with any +code involving GPIO or DMA being migrated between STM32F1 and STM32F2. + +Needless to say, this can be very annoying. (Didn't we solve this +sort of problem years ago?) When you just want your robot to fly, +your `LEDs to blink <http://www.youtube.com/watch?v=J845L45zqfk>`_, or +your `FM synthesizer <https://github.com/Ixox/preen>`_ to, well, +`synthesize <http://xhosxe.free.fr/IxoxFMSynth.mp3>`_, you probably +couldn't care less about dealing with a new set of registers. + +We want to make it easier to write portable STM32 code. To enable +that, libmaple abstracts away many hardware details behind portable +interfaces. We also want to make it easy for you to get your hands +dirty when need or desire arises. To that end, libmaple makes as few +assumptions as possible, and does its best to get out of your way when +you want it to leave. + +.. _libmaple-overview-devices: + +Libmaple's Device Model +----------------------- + +The libmaple device model is simple and stupid. This is a feature. + +*Device types* are the central libmaple abstraction; they exist to +provide portable interfaces to common peripherals, but they still let +you do nonportable things easily if you want to. + +The rules for device types are: + +- Device types are structs representing peripherals. The name of the + device type for peripheral "foo" is ``struct foo_dev`` (so for + foo=ADC, it's ``struct adc_dev``. For foo=DMA, it's ``struct + dma_dev``; etc.). These are always ``typedef``\ ed to ``foo_dev``. + +- Each device type contains any information needed or used by libmaple + for operating on the peripheral the type represents. Device types + are defined alongside declarations for portable support routines in + the header ``<libmaple/foo.h>`` (examples: :ref:`libmaple-adc`, + :ref:`libmaple-dma`). + +- Direct :ref:`register access <libmaple-overview-regmaps>` is + possible via the ``regs`` field in each device type. (Given a + ``foo_dev *foo``, you can read and write the BAR register + ``FOO_BAR`` with ``foo->regs->BAR``.) + +- An :ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>` for the device is + available in the ``clk_id`` field; this is an opaque type that can + be used to uniquely identifies the peripheral. (Given ``foo_dev + *foo``, you can check which foo you have by looking at + ``foo->clk_id``.) + +- The backend for each supported STM32 series statically initializes + devices as appropriate, and ensures that the peripheral support + header includes declarations for pointers to these statically + allocated devices. + +- Peripheral support functions usually expect a pointer to a device as + their first argument. These functions' implementations may vary + with the particular microcontroller you're targeting, but their + semantics try to stay the same. To migrate to a different target, + you'll often be able to simply recompile your program (and libmaple) + for the new target. + +- When complete portability is not possible, libmaple tries to keep + the nonportable bits in data, rather than code. + +Example: ``adc_dev`` +~~~~~~~~~~~~~~~~~~~~ + +These rules are best explained by example. The device type for ADC +peripherals is ``struct adc_dev``. Its definition is provided by +``<libmaple/adc.h>``:: + typedef struct adc_dev { - adc_reg_map *regs; /**< Register map */ - rcc_clk_id clk_id; /**< RCC clock information */ + adc_reg_map *regs; + rcc_clk_id clk_id; } adc_dev; -The ADCs aren't particularly complicated. All we keep track of for an -ADC device is a pointer to its register map (which keeps track of all -of its registers' bits; see :ref:`below <libmaple-overview-regmaps>` -for more details), and an identifying piece of information which tells -the RCC (reset and clock control) interface how to turn the ADC on and -reset its registers to their default values. - -The timers on the STM32 line are more involved than the ADCs, so a -``timer_dev`` has to keep track of a bit more information:: - - /** Timer device type */ - typedef struct timer_dev { - timer_reg_map regs; /**< Register map */ - rcc_clk_id clk_id; /**< RCC clock information */ - timer_type type; /**< Timer's type */ - voidFuncPtr handlers[]; /**< User IRQ handlers */ - } timer_dev; - -However, as you can see, both ADC and timer devices are named -according to a single scheme, and store similar information. - -``xxx.h`` will also declare pointers to the actual devices you need to -deal with, called ``XXX1``, ``XXX2``, etc. (or just ``XXX``, if -there's only one) [#fgpio]_. For instance, on the Maple's -microcontroller (the STM32F103RBT6), there are two ADCs. -Consequently, in ``adc.h``, there are declarations for dealing with -ADC devices one and two:: - - extern const adc_dev *ADC1; - extern const adc_dev *ADC2; - -In general, each device needs to be initialized before it can be used. -libmaple provides this initialization routine for each peripheral -``xxx``; its name is ``xxx_init()``. These initialization routines -turn on the clock to a device, and restore its register values to -their default settings. Here are a few examples:: - - /* From dma.h */ - void dma_init(dma_dev *dev); - - /* From gpio.h */ - void gpio_init(gpio_dev *dev); - void gpio_init_all(void); - -Note that, sometimes, there will be an additional initialization -routine for all available peripherals of a certain kind. - -Many peripherals also need additional configuration before they can be -used. These functions are usually called something along the lines of -``xxx_enable()``, and often take additional arguments which specify a -particular configuration for the peripheral. Some examples:: +An ``adc_dev`` contains a pointer to its register map in the ``regs`` +field. This ``regs`` field is available on all device types. Its value +is a :ref:`register map base pointer +<libmaple-overview-regmaps-base-pts>` (like ``ADC1_BASE``, etc.) for +the peripheral, as determined by the current target. For example, two +equivalent expressions for reading the ADC1 regular data register are +``ADC1_BASE->DR`` and ``ADC1->regs->DR`` (though the first one is +faster). Manipulating registers directly via ``->regs`` is thus +always possible, but can be nonportable, and should you choose to do +this, it's up to you to get it right. + +An ``adc_dev`` also contains an ``rcc_clk_id`` for the ADC peripheral +it represents in the ``clk_id`` field. The ``rcc_clk_id`` enum type +has an enumerator for each peripheral supported by your series. For +example, the ADC peripherals' ``rcc_clk_id`` enumerators are +``RCC_ADC1``, ``RCC_ADC2``, and ``RCC_ADC3``. In general, an +``rcc_clk_id`` is useful not only for managing the clock line to a +peripheral, but also as a unique identifier for that peripheral. + +(Device types can be more complicated than this; ``adc_dev`` was +chosen as a simple example of the minimum you can expect.) + +Rather than have you define your own ``adc_dev``\ s, libmaple defines +them for you as appropriate for your target STM32 series. For example, +on STM32F1, the file libmaple/stm32f1/adc.c contains the following:: + + static adc_dev adc1 = { + .regs = ADC1_BASE, + .clk_id = RCC_ADC1, + }; + /** ADC1 device. */ + const adc_dev *ADC1 = &adc1; + + static adc_dev adc2 = { + .regs = ADC2_BASE, + .clk_id = RCC_ADC2, + }; + /** ADC2 device. */ + const adc_dev *ADC2 = &adc2; + + #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) + static adc_dev adc3 = { + .regs = ADC3_BASE, + .clk_id = RCC_ADC3, + }; + /** ADC3 device. */ + const adc_dev *ADC3 = &adc3; + #endif + +Since all supported STM32F1 targets support ADC1 and ADC2, libmaple +predefines corresponding ``adc_dev`` instances for you. To save space, +it avoids defining an ``adc_dev`` for ADC3 unless you are targeting a +high- or XL-density STM32F1, as medium- and lower density MCUs don't +have ADC3. + +Note that the structs themselves are static and are exposed only via +pointers. These pointers are declared in a series-specific ADC +header, ``<series/adc.h>`` which is included by ``<libmaple/adc.h>`` +based on the MCU you're targeting. (**Never include <series/foo.h> +directly**. Instead, include ``<libmaple/foo.h>`` and let it take +care of that for you.) On STM32F1, the series ADC header contains the +following:: + + extern const struct adc_dev *ADC1; + extern const struct adc_dev *ADC2; + #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) + extern const struct adc_dev *ADC3; + #endif + +In general, you access the predefined devices via these pointers. As +illustrated by the ADC example, the variables for these pointers +follow the naming scheme used in ST's reference manuals -- the pointer +to ADC1's ``adc_dev`` is named ``ADC1``, and so on. + +The :ref:`API documentation <libmaple-apis>` for the peripherals +you're interested in will list the available devices on each target. + +Using Devices +~~~~~~~~~~~~~ + +Peripheral support routines usually expect pointers to their device +types as their first arguments. Here are some ADC examples:: + + uint16 adc_read(const adc_dev *dev, uint8 channel); + static inline void adc_enable(const adc_dev *dev); + static inline void adc_disable(const adc_dev *dev); + +So, to read channel 2 of ADC1, you could call ``adc_read(ADC1, 2)``. +To disable ADC2, call ``adc_disable(ADC2)``; etc. + +That's it; there's nothing complicated here. In general, just follow +links from the :ref:`libmaple-apis` page to the header for the +peripheral you're interested in. It will explain the supported +functionality, both portable and series-specific. + +Segregating Non-portable Functionality into Data +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As mentioned previously, when total portability isn't possible, +libmaple tries to do the right thing and segregate the nonportable +portions into data rather than code. The function +``adc_set_sample_rate()`` is a good example of how this works, and why +it's useful:: - /* From usart.h */ - void usart_enable(usart_dev *dev); - - /* From i2c.h */ - void i2c_master_enable(i2c_dev *dev, uint32 flags); + void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate); -After you've initialized, and potentially enabled, your peripheral, it -is now time to begin using it. The file ``xxx.h`` contains other -convenience functions for dealing with xxx devices. For instance, -here are a few from ``adc.h``:: +For example, while both STM32F1 and STM32F2 support setting the ADC +sample time via the same register interface, the actual sample times +supported are different. For instance, on STM32F1, available sample +times include 1.5, 7.5, and 13.5 ADC cycles. On STM32F2, none of these +are available, but 3, 15, and 28 ADC cycles are supported (which is +not true for STM32F1). To work with this, libmaple provides a single +function, ``adc_set_sample_rate()``, for setting an ADC controller's +channel sampling time, but the actual sample rates it takes are given +by the ``adc_smp_rate`` type, which is different on STM32F1 and +STM32F2. + +This is the STM32F1 implementation of adc_smp_rate:: + + typedef enum adc_smp_rate { + ADC_SMPR_1_5, /**< 1.5 ADC cycles */ + ADC_SMPR_7_5, /**< 7.5 ADC cycles */ + ADC_SMPR_13_5, /**< 13.5 ADC cycles */ + ADC_SMPR_28_5, /**< 28.5 ADC cycles */ + ADC_SMPR_41_5, /**< 41.5 ADC cycles */ + ADC_SMPR_55_5, /**< 55.5 ADC cycles */ + ADC_SMPR_71_5, /**< 71.5 ADC cycles */ + ADC_SMPR_239_5, /**< 239.5 ADC cycles */ + } adc_smp_rate; + +And here is the STM32F2 implementation:: + + typedef enum adc_smp_rate { + ADC_SMPR_3, /**< 3 ADC cycles */ + ADC_SMPR_15, /**< 15 ADC cycles */ + ADC_SMPR_28, /**< 28 ADC cycles */ + ADC_SMPR_56, /**< 56 ADC cycles */ + ADC_SMPR_84, /**< 84 ADC cycles */ + ADC_SMPR_112, /**< 112 ADC cycles */ + ADC_SMPR_144, /**< 144 ADC cycles */ + ADC_SMPR_480, /**< 480 ADC cycles */ + } adc_smp_rate; + +So, on F1, you could call ``adc_set_sample_rate(ADC1, ADC_SMPR_1_5)``, +and on F2, you could call ``adc_set_sample_rate(ADC1, +ADC_SMPR_3)``. If you're only interested in one of those series, then +that's all you need to know. + +However, if you're targeting multiple series, then this is useful +because it lets you put the actual sample time for the MCU you're +targeting into a variable (or macro, etc.), whose value depends on the +target you're compiling for. This lets you have a single codebase to +test and maintain, and lets you add support for a new target by simply +adding some new data. + +To continue the example, one easy way is to pick an ``adc_smp_rate`` +for each of STM32F1 and STM32F2 is with conditional compilation. Using +the :ref:`STM32_MCU_SERIES <libmaple-stm32-STM32_MCU_SERIES>` define +from :ref:`libmaple-stm32`, you can write:: + + #include <libmaple/adc.h> + #include <libmaple/stm32.h> + + #if STM32_MCU_SERIES == STM32_SERIES_F1 + /* Target is an STM32F1 */ + adc_smp_rate smp_rate = ADC_SMPR_1_5; + #elif STM32_MCU_SERIES == STM32_SERIES_F2 + /* Target is an STM32F2 */ + adc_smp_rate smp_rate = ADC_SMPR_3; + #else + #error "Unsupported STM32 target; can't pick a sample rate" + #endif + + void setup(void) { + adc_set_smp_rate(ADC1, smp_rate); + } - void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate); - uint32 adc_read(const adc_dev *dev, uint8 channel); +Adding support for e.g. STM32F4 would only require adding a new +``#elif`` for that series. This is simple, but hackish, and can get +out of control if you're not careful. -We aim to enable libmaple's users to interact with peripherals through -devices as much as possible, rather than having to break the -abstraction and consider individual registers. However, there will -always be a need for low-level access. To allow for that, libmaple -provides *register maps* as a consistent set of names and abstractions -for dealing with registers and their bits. +Another way to get the job done is to declare an ``extern adc_smp_rate +smp_rate``, and use the build system to compile a file defining +``smp_rate`` depending on your target. As was discussed earlier, this +is what libmaple does when choosing which files to use for defining +the appropriate ``adc_dev``\ s for your target. How to do this is +outside the scope of this overview, however. .. _libmaple-overview-regmaps: Register Maps ------------- -A *register map* is just a C struct which names and provides access to -a peripheral's registers. These registers are usually mapped to -contiguous regions of memory (though at times unusable or reserved -regions exist between a peripheral's registers). Here's an example -register map, from ``dac.h`` (``__io`` is just libmaple's way of -saying ``volatile`` when referring to register values):: +Though we aim to enable libmaple's users to interact with the more +portable :ref:`device interface <libmaple-overview-devices>` as much +as possible, there will always be a need for efficient direct register +access. To allow for that, libmaple provides *register maps* as a +consistent set of names and abstractions for dealing with peripheral +registers and their bits. + +A *register map type* is a struct which names and provides access to a +peripheral's registers (we can use a struct because registers are +usually mapped into contiguous regions of memory). Here's an example +register map for the DAC peripheral on STM32F1 series MCUs (``__io`` +is just libmaple's way of saying ``volatile`` when referring to +register values):: - /** DAC register map. */ typedef struct dac_reg_map { __io uint32 CR; /**< Control register */ __io uint32 SWTRIGR; /**< Software trigger register */ @@ -204,89 +358,87 @@ saying ``volatile`` when referring to register values):: __io uint32 DOR2; /**< Channel 2 data output register */ } dac_reg_map; +There are two things to notice here. First, if the chip reference +manual (for STM32F1, that's RM0008) names a register ``DAC_FOO``, then +``dac_reg_map`` has a field named ``FOO``. So, the Channel 1 12-bit +right-aligned data register (DAC_DHR12R1) is the ``DHR12R1`` field in +a ``dac_reg_map``. Second, if the reference manual describes a +register as "Foo bar register", the documentation for the +corresponding field has the same description. This consistency makes +it easy to search for a particular register, and, if you see one used +in a source file, to feel sure about what's going on just based on its +name. -There are two things to notice here. First, if RM0008 names a -register ``DAC_FOO``, then ``dac_reg_map`` has a field named ``FOO``. -So, the Channel 1 12-bit right-aligned data register (RM0008: -DAC_DHR12R1) is the ``DHR12R1`` field in a ``dac_reg_map``. Second, -if RM0008 describes a register as "Foo bar register", the -documentation for the corresponding field has the same description. -This consistency makes it easy to search for a particular register, -and, if you see one used in a source file, to feel sure about what's -going on just based on its name. +.. _libmaple-overview-regmaps-base-pts: -So let's say you've included ``xxx.h``, and you want to mess with some -particular register. What's the name of the ``xxx_reg_map`` variable -you want? That depends on if there's more than one xxx or not. If -there's only one xxx, then libmaple guarantees there will be a -``#define`` that looks like like this:: +So let's say you've included ``<libmaple/foo.h>``, and you want to +mess with some particular register. You'll do this using *register map +base pointers*, which are pointers to ``struct foo_reg_map``. What's +the name of the base pointer you want? That depends on if there's +more than one foo or not. If there's only one foo, then libmaple +guarantees there will be a ``#define`` that looks like like this:: - #define XXX_BASE ((struct xxx_reg_map*)0xDEADBEEF) + #define FOO_BASE ((struct foo_reg_map*)0xDEADBEEF) That is, you're guaranteed there will be a pointer to the (only) -``xxx_reg_map`` you want, and it will be called -``XXX_BASE``. (``0xDEADBEEF`` is the register map's *base address*, or -the fixed location in memory where the register map begins). Here's a -concrete example from ``dac.h``:: +``foo_reg_map`` you want, and it will be called +``FOO_BASE``. (``0xDEADBEEF`` is the register map's *base address*, or +the fixed location in memory where the register map begins). Here's +an example for STM32F1:: - #define DAC_BASE ((struct dac_reg_map*)0x40007400) + #define DAC_BASE ((struct dac_reg_map*)0x40007400) -How can you use these? This is perhaps best explained by example. +Here are some examples for how to read and write to registers using +register map base pointers. * In order to write 2048 to the channel 1 12-bit left-aligned data - holding register (RM0008: DAC_DHR12L1), you could write:: + holding register (DAC_DHR12L1), you would write:: DAC_BASE->DHR12L1 = 2048; -* In order to read the DAC control register, you could write:: +* In order to read the DAC control register, you would write:: uint32 cr = DAC_BASE->CR; -The microcontroller takes care of converting reads and writes from a -register's IO-mapped memory regions into reads and writes to the -corresponding hardware registers. - -That covers the case where there's a single xxx peripheral. If -there's more than one (say, if there are *n*), then ``xxx.h`` provides -the following:: +That covers the case where there's a single foo peripheral. If +there's more than one (say, if there are *n*), then +``<libmaple/foo.h>`` provides the following:: - #define XXX1_BASE ((struct xxx_reg_map*)0xDEADBEEF) - #define XXX2_BASE ((struct xxx_reg_map*)0xF00DF00D) + #define FOO1_BASE ((struct foo_reg_map*)0xDEADBEEF) + #define FOO2_BASE ((struct foo_reg_map*)0xF00DF00D) ... - #define XXXn_BASE ((struct xxx_reg_map*)0x13AF1AB5) + #define FOOn_BASE ((struct foo_reg_map*)0x1EAF1AB5) -Here are some examples from ``adc.h``:: +Here are some examples for the ADCs on STM32F1:: - #define ADC1_BASE ((struct adc_reg_map*)0x40012400) - #define ADC2_BASE ((struct adc_reg_map*)0x40012800) + #define ADC1_BASE ((struct adc_reg_map*)0x40012400) + #define ADC2_BASE ((struct adc_reg_map*)0x40012800) In order to read from the ADC1's regular data register (where the -results of ADC conversion are stored), you might write:: +results of ADC conversion are stored), you would write:: uint32 converted_result = ADC1_BASE->DR; Register Bit Definitions ------------------------ -In ``xxx.h``, there will also be a variety of #defines for dealing -with interesting bits in the xxx registers, called *register bit -definitions*. These are named according to the scheme -``XXX_REG_FIELD``, where "``REG``" refers to the register, and -"``FIELD``" refers to the bit or bits in ``REG`` that are special. - -.. TODO image of the bit layout of a DMA_CCR register - -Again, this is probably best explained by example. Each Direct Memory -Access (DMA) controller's register map has a certain number of channel -configuration registers (RM0008: DMA_CCRx). In each of these channel -configuration registers, bit 14 is called the ``MEM2MEM`` bit, and -bits 13 and 12 are the priority level (``PL``) bits. Here are the -register bit definitions for those fields:: - - /* From dma.h */ +In ``<libmaple/foo.h>``, there will also be a variety of ``#define``\ +s for dealing with interesting bits in the xxx registers, called +*register bit definitions*. In keeping with the ST reference manuals, +these are named according to the scheme ``FOO_REG_FIELD``, where +"``REG``" refers to the register, and "``FIELD``" refers to the bit or +bits in ``REG`` that are special. + +Again, this is probably best explained by example. On STM32F1, each +Direct Memory Access (DMA) controller's register map has a certain +number of channel configuration registers (DMA_CCRx). In each of +these channel configuration registers, bit 14 is called the +``MEM2MEM`` bit, and bits 13 and 12 are the priority level (``PL``) +bits. Here are the register bit definitions for those fields on +STM32F1:: #define DMA_CCR_MEM2MEM_BIT 14 - #define DMA_CCR_MEM2MEM BIT(DMA_CCR_MEM2MEM_BIT) + #define DMA_CCR_MEM2MEM (1U << DMA_CCR_MEM2MEM_BIT) #define DMA_CCR_PL (0x3 << 12) #define DMA_CCR_PL_LOW (0x0 << 12) #define DMA_CCR_PL_MEDIUM (0x1 << 12) @@ -294,7 +446,7 @@ register bit definitions for those fields:: #define DMA_CCR_PL_VERY_HIGH (0x3 << 12) Thus, to check if the ``MEM2MEM`` bit is set in DMA controller 1's -channel configuration register 2 (RM0008: DMA_CCR2), you can write:: +channel configuration register 2 (DMA_CCR2), you can write:: if (DMA1_BASE->CCR2 & DMA_CCR_MEM2MEM) { /* MEM2MEM is set */ @@ -304,33 +456,61 @@ Certain register values occupy multiple bits. For example, the priority level (PL) of a DMA channel is determined by bits 13 and 12 of the corresponding channel configuration register. As shown above, libmaple provides several register bit definitions for masking out the -individual PL bits and determining their meaning. For example, to -check the priority level of a DMA transfer, you can write:: - - switch (DMA1_BASE->CCR2 & DMA_CCR_PL) { - case DMA_CCR_PL_LOW: - /* handle low priority case */ - case DMA_CCR_PL_MEDIUM: - /* handle medium priority case */ - case DMA_CCR_PL_HIGH: - /* handle high priority case */ - case DMA_CCR_PL_VERY_HIGH: - /* handle very high priority case */ - } +individual PL bits and determining their meaning. For example, to set +the priority level of a DMA transfer to "high priority", you can +do a read-modify-write sequence on the DMA_CCR_PL bits like so:: + + uint32 ccr = DMA1_BASE->CCR2; + ccr &= ~DMA_CCR_PL; + ccr |= DMA_CCR_PL_HIGH; + DMA1_BASE->CCR2 = ccr; Of course, before doing that, you should check to make sure there's -not already a device-level function for performing the same task! +not already a device-level function for performing the same task! (In +this case, there is. It's called :c:func:`dma_set_priority()`; see +:ref:`libmaple-dma`.) For instance, **none of the above code is +portable** to STM32F4, which uses DMA streams instead of channels for +this purpose. + +Peripheral Support Routines +--------------------------- + +This section describes patterns to look for in peripheral support +routines. + +In general, each device needs to be initialized before it can be used. +libmaple provides this initialization routine for each peripheral +``foo``; its name is ``foo_init()``. These initialization routines +turn on the clock to a device, and restore its register values to +their default settings. Here are a few examples:: -What Next? ----------- + /* From <libmaple/dma.h> */ + void dma_init(dma_dev *dev); -After you've read this page, you can proceed to the :ref:`libmaple API -listing <libmaple-apis>`. From there, you can read documentation and -follow links to the current source code for those files on `libmaple's -GitHub page <https://github.com/leaflabs/libmaple>`_. + /* From <libmaple/gpio.h> */ + void gpio_init(gpio_dev *dev); + void gpio_init_all(void); + +Note that, sometimes, there will be an additional initialization +routine for all available peripherals of a certain kind. + +Many peripherals also need additional configuration before they can be +used. These functions are usually called something along the lines of +``foo_enable()``, and often take additional arguments which specify a +particular configuration for the peripheral. Some examples:: + + /* From <libmaple/usart.h> */ + void usart_enable(usart_dev *dev); + + /* From <libmaple/i2c.h> */ + void i2c_master_enable(i2c_dev *dev, uint32 flags); + +After you've initialized, and potentially enabled, your peripheral, it +is now time to begin using it. The :ref:`libmaple API pages +<libmaple-apis>` are your friends here. .. rubric:: Footnotes -.. [#fgpio] For consistency with RM0008, GPIO ports are given letters - instead of numbers (``GPIOA`` and ``GPIOB`` instead of - ``GPIO1`` and ``GPIO2``, etc.). +.. [#fgpio] As an exception, GPIO ports are given letters instead of + numbers (``GPIOA`` and ``GPIOB`` instead of ``GPIO1`` and + ``GPIO2``, etc.). diff --git a/source/libraries.rst b/source/libraries.rst index 44a72f7..1ae0e87 100644 --- a/source/libraries.rst +++ b/source/libraries.rst @@ -73,7 +73,7 @@ bugs, and reported on the forums. Wire ---- -.. FIXME [0.1.0] Update with hard Wire implementation info +.. FIXME [0.0.13] Update with crenn's info We currently provide a soft (bit-banged) implementation of the :ref:`Wire <libs-wire>` I2C library. A hardware version is planned diff --git a/source/stm32.rst b/source/stm32.rst new file mode 100644 index 0000000..d918655 --- /dev/null +++ b/source/stm32.rst @@ -0,0 +1,87 @@ +.. _stm32: + +Introduction to STM32 +===================== + +.. FIXME [v0.0.13] Stub page. + +Every Maple board is powered by an STM32 microcontroller (the chip +which controls all of the pins). Once you're comfortable using your +Maple, you'll probably start to get curious about what's going on +under the hood. This page is a good place to begin. It includes an +overview of the STM32, and helps you make sense of the sometimes +dizzying array of features, libraries, and documentation that are +available to you. + +The world of the STM32 is a big one, and it's only getting bigger. +With literally thousands of pages of manuals, datasheets, application +notes, etc. available for every STM32 microcontroller, and a huge +variety of categories and subcategories of STM32s available to choose +from, it's easy to get confused or feel daunted about getting started. +Don't panic! We've got `your towel +<http://en.wikipedia.org/wiki/Know_where_one%27s_towel_is#Knowing_where_one.27s_towel_is>`_ +right here. + +.. contents:: Contents + :local: + +.. _stm32-general: + +General Information +------------------- + +- Description of the history and present state of the STM32 line. ARM + Cortex-M series etc. + +- Introduction and pointers to ARM Cortex-M docs and other good books + on the subject. + +- Pointers to ST reference manuals. Note that the appropriate + reference manual for each board is always documented in that board's + hardware page. + +.. _stm32-series: +.. _stm32-series-f1-lines: + +STM32 Series +------------ + +- Describe families, F1 lines, etc. + +- Describe how a product name tells you what you need + +ST's Documentation +------------------ + +- Classes of documentation: product flyer, datasheet, reference + manual, programming manual, application note. + +.. _stm32-registers: + +Registers and Register Maps +--------------------------- + +- General purpose registers vs. peripheral registers. + +Perhaps you haven't read it in detail, but maybe you've at least +thumbed through a few of the sections, trying to gain some +understanding of what's going on. If you've done that (and if you +haven't, just take our word for it), then you know that underneath the +covers, *everything* is controlled by messing with bits in the +seemingly endless collections of registers specific to every +peripheral. The :ref:`USARTs <usart>` have data registers; (some of +the) the :ref:`timers <timers>` have capture/compare registers, the +:ref:`GPIOs <gpio>` have output data registers, etc. + +- Peripheral register maps; how they're duplicated for each peripheral + +- Portability concerns across series + +.. _stm32-libmaple-support: + +``libmaple`` STM32 support +-------------------------- + +- Descriptions of libmaple's present support for the STM32 line + (i.e. currently performance-line only; update when the F2 branch is + ready to merge into master etc.). diff --git a/source/unix-toolchain.rst b/source/unix-toolchain.rst index a397cc1..4fc21ea 100644 --- a/source/unix-toolchain.rst +++ b/source/unix-toolchain.rst @@ -67,14 +67,21 @@ The following are **mandatory**: the `OpenMoko`_ project. It is used to upload programs to the Maple over USB. +.. warning:: Due to firmware bugs in our :ref:`bootloader + <bootloader>`, you must use recent versions of ``dfu-util``, or + uploads will not work. ``dfu-util`` versions 0.6 and greater + should work. + +.. _OpenMoko: http://openmoko.com/ + * `make <http://www.gnu.org/software/make/>`_ is used to direct compilation. * `Python <http://python.org>`_ is a programming language. Our reset script, which sends control signals to the board which cause it to to reset and enter the :ref:`bootloader <bootloader>`, is written in - Python. (Most Linux distributions these days include Python by - default). + Python (and works with Python 2 or 3). Most Linux distributions + these days include Python by default. * `PySerial`_ is a Python library for interacting with serial port devices. It's needed by our reset script. PySerial can also be @@ -176,6 +183,11 @@ You will need the following tools\ [#fpackman]_ to get started: * `dfu-util <http://wiki.openmoko.org/wiki/Dfu-util>`_: A tool from `OpenMoko`_ that we use to upload programs to the Maple over USB. + .. warning:: Due to firmware bugs in our :ref:`bootloader + <bootloader>`, you must use recent versions of ``dfu-util``, or + uploads will not work. ``dfu-util`` versions 0.6 and greater + should work. + If you prefer to compile from source, OpenMoko provides instructions for `building dfu-util on OS X <http://wiki.openmoko.org/wiki/Dfu-util#Mac>`_. diff --git a/source/whats-new.rst b/source/whats-new.rst new file mode 100644 index 0000000..c1f0bd5 --- /dev/null +++ b/source/whats-new.rst @@ -0,0 +1,78 @@ +.. highlight:: c + +What's New +========== + +.. FIXME [RELEASE] finish. + +This page tracks updates to libmaple and MapleIDE. + +.. contents:: + :local: + :depth: 1 + +v0.0.13 +------- + +**General Changes** + +.. We started doing this as we updated the docs on 29 Jun 2012, so +.. updates before then need to be pulled from libmaple's Git logs. + +- Additional STM32 support: for this release, libmaple was taught + how to target STM32F1 value line (thanks to Anton Eltchaninov) and + STM32F2 series microcontrollers. It learned a huge bag of new + tricks as a result, so this list is only a summary of the most + important changes. + +- New include style: You should now include libmaple and Wirish + headers like this (respectively):: + + #include <libmaple/libmaple.h> + #include <wirish/wirish.h> + + The old include style (e.g. ``#include "libmaple.h"``) is now + **deprecated**, and will **break in the next release**. This is more + standard usage for libraries, and was necessary to e.g. allow for + implementing a Wiring/Arduino-style SPI library (which is included + as ``#include "SPI.h"`` and clashes with :ref:`libmaple-spi` on + case-insensitive filesystems like OS X's). + +**Wirish** + +- Wire I2C library: New, improved, and more Arduino-compatible + :ref:`Wire <libs-wire>` library, thanks to Trystan Jones. + +**libmaple proper** + +Better documentation: The old documentation for libmaple's C layer did +little more than list the Doxygen comments in the source code. It now +includes explanatory material and usage notes. See +:ref:`libmaple-apis`. + +.. FIXME [0.0.13] this is ugly + +Changes by header follow. + +.. list-table:: + :header-rows: 1 + :widths: 1 10 + + * - Header + - Changes + + * - :ref:`libmaple-rcc` + - :ref:`rcc_clk_init() <rcc-rcc_clk_init>` is deprecated. Use + :ref:`rcc_configure_pll() <libmaple-rcc-rcc_configure_pll>` as + the basis for a portable replacement; see the + ``rcc_clk_init()`` docs for a porting guide. + + * - :ref:`libmaple-libmaple_types` + - Various new attributes and type qualifiers. + + * - :ref:`libmaple-adc` + - New :ref:`adc_enable_single_swstart() + <adc-adc_enable_single_swstart>` and :ref:`adc_config_gpio() + <adc-adc_config_gpio>`, for portably enabling ADC peripherals + and their associated pins for use with :ref:`adc_read() + <adc-adc_read>`. |