mirror of
https://github.com/lupyuen/lupyuen.github.io.git
synced 2025-01-13 09:08:30 +08:00
663 lines
No EOL
51 KiB
HTML
663 lines
No EOL
51 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="generator" content="rustdoc">
|
||
<title>Connect PineCone BL602 to OpenOCD</title>
|
||
|
||
|
||
<!-- Begin scripts/articles/*-header.html: Article Header for Custom Markdown files processed by rustdoc, like chip8.md -->
|
||
<meta property="og:title"
|
||
content="Connect PineCone BL602 to OpenOCD"
|
||
data-rh="true">
|
||
<meta property="og:description"
|
||
content="How we connect PineCone BL602 Evaluation Board to OpenOCD... For flashing and debugging RISC-V firmware"
|
||
data-rh="true">
|
||
<meta property="og:image"
|
||
content="https://lupyuen.github.io/images/openocd-title.jpg">
|
||
<meta property="og:type"
|
||
content="article" data-rh="true">
|
||
<link rel="canonical" href="https://lupyuen.org/articles/openocd.html" />
|
||
<!-- End scripts/articles/*-header.html -->
|
||
<!-- Begin scripts/rustdoc-header.html: Header for Custom Markdown files processed by rustdoc, like chip8.md -->
|
||
<link rel="alternate" type="application/rss+xml" title="RSS Feed for lupyuen" href="/rss.xml" />
|
||
<link rel="stylesheet" type="text/css" href="../normalize.css">
|
||
<link rel="stylesheet" type="text/css" href="../rustdoc.css" id="mainThemeStyle">
|
||
<link rel="stylesheet" type="text/css" href="../dark.css">
|
||
<link rel="stylesheet" type="text/css" href="../light.css" id="themeStyle">
|
||
<link rel="stylesheet" type="text/css" href="../prism.css">
|
||
<script src="../storage.js"></script><noscript>
|
||
<link rel="stylesheet" href="../noscript.css"></noscript>
|
||
<link rel="shortcut icon" href="../favicon.ico">
|
||
<style type="text/css">
|
||
#crate-search {
|
||
background-image: url("../down-arrow.svg");
|
||
}
|
||
</style>
|
||
<!-- End scripts/rustdoc-header.html -->
|
||
|
||
|
||
</head>
|
||
<body class="rustdoc">
|
||
<!--[if lte IE 8]>
|
||
<div class="warning">
|
||
This old browser is unsupported and will most likely display funky
|
||
things.
|
||
</div>
|
||
<![endif]-->
|
||
|
||
|
||
<!-- Begin scripts/rustdoc-before.html: Pre-HTML for Custom Markdown files processed by rustdoc, like chip8.md -->
|
||
|
||
<!-- Begin Theme Picker -->
|
||
<div class="theme-picker" style="left: 0"><button id="theme-picker" aria-label="Pick another theme!"><img src="../brush.svg"
|
||
width="18" alt="Pick another theme!"></button>
|
||
<div id="theme-choices"></div>
|
||
</div>
|
||
<!-- Theme Picker -->
|
||
|
||
<!-- End scripts/rustdoc-before.html -->
|
||
|
||
|
||
<h1 class="title">Connect PineCone BL602 to OpenOCD</h1>
|
||
<nav id="rustdoc"><ul>
|
||
<li><a href="#what-is-openocd" title="What is OpenOCD?">1 What is OpenOCD?</a><ul>
|
||
<li><a href="#openocd-vs-uart-flashing" title="OpenOCD vs UART Flashing">1.1 OpenOCD vs UART Flashing</a><ul></ul></li>
|
||
<li><a href="#openocd-alternatives" title="OpenOCD Alternatives">1.2 OpenOCD Alternatives</a><ul></ul></li></ul></li>
|
||
<li><a href="#what-is-jtag" title="What is JTAG?">2 What is JTAG?</a><ul>
|
||
<li><a href="#jtag-vs-swd" title="JTAG vs SWD">2.1 JTAG vs SWD</a><ul></ul></li></ul></li>
|
||
<li><a href="#wheres-the-jtag-port" title="Where’s the JTAG Port?">3 Where’s the JTAG Port?</a><ul></ul></li>
|
||
<li><a href="#connect-jtag-debugger-to-pinecone" title="Connect JTAG Debugger to PineCone">4 Connect JTAG Debugger to PineCone</a><ul></ul></li>
|
||
<li><a href="#download-and-run-openocd" title="Download and run OpenOCD">5 Download and run OpenOCD</a><ul>
|
||
<li><a href="#download-openocd" title="Download OpenOCD">5.1 Download OpenOCD</a><ul></ul></li>
|
||
<li><a href="#download-openocd-script" title="Download OpenOCD Script">5.2 Download OpenOCD Script</a><ul></ul></li>
|
||
<li><a href="#run-openocd" title="Run OpenOCD">5.3 Run OpenOCD</a><ul></ul></li>
|
||
<li><a href="#openocd-output" title="OpenOCD Output">5.4 OpenOCD Output</a><ul></ul></li>
|
||
<li><a href="#troubleshoot-openocd" title="Troubleshoot OpenOCD">5.5 Troubleshoot OpenOCD</a><ul></ul></li></ul></li>
|
||
<li><a href="#openocd-script" title="OpenOCD Script">6 OpenOCD Script</a><ul>
|
||
<li><a href="#debug-logging" title="Debug Logging">6.1 Debug Logging</a><ul></ul></li>
|
||
<li><a href="#openocd-driver" title="OpenOCD Driver">6.2 OpenOCD Driver</a><ul></ul></li>
|
||
<li><a href="#ftdi-channel" title="FTDI Channel">6.3 FTDI Channel</a><ul></ul></li>
|
||
<li><a href="#jtag-speed" title="JTAG Speed">6.4 JTAG Speed</a><ul></ul></li>
|
||
<li><a href="#cpu-id" title="CPU ID">6.5 CPU ID</a><ul></ul></li>
|
||
<li><a href="#restart-pinecone" title="Restart PineCone">6.6 Restart PineCone</a><ul></ul></li>
|
||
<li><a href="#wait-for-gdb-and-tcl-commands" title="Wait for GDB and TCL Commands">6.7 Wait for GDB and TCL Commands</a><ul></ul></li></ul></li>
|
||
<li><a href="#if-you-love-the-led-set-it-free" title="If you love the LED… Set it free!">7 If you love the LED… Set it free!</a><ul>
|
||
<li><a href="#free-the-led-from-jtag-port" title="Free the LED from JTAG Port">7.1 Free the LED from JTAG Port</a><ul></ul></li></ul></li>
|
||
<li><a href="#remap-the-jtag-port" title="Remap the JTAG Port">8 Remap the JTAG Port</a><ul>
|
||
<li><a href="#before-and-after" title="Before and After">8.1 Before and After</a><ul></ul></li></ul></li>
|
||
<li><a href="#test-the-remapped-jtag-port" title="Test the Remapped JTAG Port">9 Test the Remapped JTAG Port</a><ul>
|
||
<li><a href="#connect-the-remapped-jtag-port" title="Connect the Remapped JTAG Port">9.1 Connect the Remapped JTAG Port</a><ul></ul></li>
|
||
<li><a href="#download-the-remap-firmware" title="Download the Remap Firmware">9.2 Download the Remap Firmware</a><ul></ul></li>
|
||
<li><a href="#flash-the-remap-firmware" title="Flash the Remap Firmware">9.3 Flash the Remap Firmware</a><ul></ul></li>
|
||
<li><a href="#start-the-remap-firmware" title="Start the Remap Firmware">9.4 Start the Remap Firmware</a><ul></ul></li>
|
||
<li><a href="#run-openocd-1" title="Run OpenOCD">9.5 Run OpenOCD</a><ul></ul></li>
|
||
<li><a href="#remove-the-remap-firmware" title="Remove the Remap Firmware">9.6 Remove the Remap Firmware</a><ul></ul></li></ul></li>
|
||
<li><a href="#how-to-fix-the-jtag-port" title="How to fix the JTAG Port">10 How to fix the JTAG Port</a><ul>
|
||
<li><a href="#redesign-the-pinecone-hardware" title="Redesign the PineCone Hardware">10.1 Redesign the PineCone Hardware</a><ul></ul></li>
|
||
<li><a href="#keep-pinecone-as-is" title="Keep PineCone as is">10.2 Keep PineCone as is</a><ul></ul></li>
|
||
<li><a href="#integrate-jtag-debugger-with-pinecone" title="Integrate JTAG Debugger with PineCone">10.3 Integrate JTAG Debugger with PineCone</a><ul></ul></li></ul></li>
|
||
<li><a href="#whats-next" title="What’s Next">11 What’s Next</a><ul></ul></li></ul></nav><p><img src="https://lupyuen.github.io/images/openocd-title.jpg" alt="PineCone BL602 RISC-V Evaluation Board connected to Sipeed JTAG Debugger" /></p>
|
||
<p><em>PineCone BL602 RISC-V Evaluation Board connected to Sipeed JTAG Debugger</em></p>
|
||
<p>📝 <em>11 Dec 2020</em></p>
|
||
<p>Today we’ll learn to connect the <a href="https://lupyuen.github.io/articles/pinecone"><strong>PineCone BL602 RISC-V Evaluation Board</strong></a> to OpenOCD for loading and debugging PineCone firmware.</p>
|
||
<p><a href="https://lupyuen.github.io/articles/pinecone#other-flashing-tools">(JTAG and OpenOCD won’t work for flashing BL602)</a></p>
|
||
<p><a href="https://github.com/bouffalolab/bl_docs/tree/main/BL602_Openocd&GDB/en">(UPDATE: There’s a new doc on BL602, OpenOCD and GDB. Check it out here</a></p>
|
||
<h1 id="what-is-openocd"><a class="doc-anchor" href="#what-is-openocd">§</a>1 What is OpenOCD?</h1>
|
||
<p><strong>OpenOCD</strong> is the open source software that runs on our computer and connects to microcontrollers (like PineCone) to…</p>
|
||
<ol>
|
||
<li>
|
||
<p><strong>Load our firmware</strong> to the microcontroller’s RAM</p>
|
||
<p><a href="https://lupyuen.github.io/articles/pinecone#other-flashing-tools">(JTAG and OpenOCD won’t work for flashing BL602)</a></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Debug our firmware</strong>: Set breakpoints, step through code, examine the variables</p>
|
||
</li>
|
||
</ol>
|
||
<p>Most development tools (like VSCode) work with OpenOCD for loading and debugging firmware.</p>
|
||
<p>Thus it’s important to get PineCone talking to OpenOCD, so that our development tools will work with PineCone.</p>
|
||
<p>(<a href="https://github.com/lupyuen/bl602-rust-guide">Rust for PineCone</a> also uses OpenOCD for loading and debugging)</p>
|
||
<p>PineCone exposes a <strong>JTAG Port</strong> that works with OpenOCD for loading and debugging firmware.</p>
|
||
<p><a href="https://lupyuen.github.io/articles/pinecone#other-flashing-tools">(JTAG and OpenOCD won’t work for flashing BL602)</a></p>
|
||
<p>This is similar to the SWD Port that’s found in PineTime, STM32 Blue Pill and other Arm microcontrollers.</p>
|
||
<p>We’ll learn about JTAG in the next section.</p>
|
||
<h2 id="openocd-vs-uart-flashing"><a class="doc-anchor" href="#openocd-vs-uart-flashing">§</a>1.1 OpenOCD vs UART Flashing</h2>
|
||
<p><em>Doesn’t PineCone support UART flashing? Why use OpenOCD and JTAG?</em></p>
|
||
<p>Yes we may flash our firmware to PineCone via a Serial USB connection to PineCone’s UART Port. <a href="https://lupyuen.github.io/articles/pinecone">More about this</a></p>
|
||
<p>However it uses a flashing protocol that’s designed specifically for BL602 devices. The flashing protocol is not supported by popular tools like VSCode.</p>
|
||
<p>BL602 doesn’t support debugging over UART. For serious firmware coding on BL602, OpenOCD is the best option.</p>
|
||
<p><a href="https://lupyuen.github.io/articles/pinecone#other-flashing-tools">(JTAG and OpenOCD won’t work for flashing BL602)</a></p>
|
||
<h2 id="openocd-alternatives"><a class="doc-anchor" href="#openocd-alternatives">§</a>1.2 OpenOCD Alternatives</h2>
|
||
<p><em>OpenOCD has been around for a while. Are there newer tools for loading and debugging firmware?</em></p>
|
||
<p>There’s a newer alternative to OpenOCD that’s built with Rust: <a href="https://probe.rs/">probe.rs</a></p>
|
||
<p>It has beta support for JTAG. Hopefully we can use it with PineCone someday.</p>
|
||
<p>But for today, we’ll learn to use OpenOCD and JTAG with PineCone.</p>
|
||
<p><img src="https://lupyuen.github.io/images/pinecone-sipeed.jpg" alt="Sipeed JTAG Debugger" /></p>
|
||
<p><em>Sipeed JTAG Debugger with the JTAG Pins: TMS, TCK, TDI, TDO, GND</em></p>
|
||
<h1 id="what-is-jtag"><a class="doc-anchor" href="#what-is-jtag">§</a>2 What is JTAG?</h1>
|
||
<p>PineCone’s <strong>JTAG Port</strong> is a standard port for loading and debugging firmware, available on most RISC-V microcontrollers (like SiFive FE310 and GigaDevice GD32 VF103).</p>
|
||
<p>JTAG uses these pins…</p>
|
||
<ol>
|
||
<li><strong>TMS (Test Mode Select)</strong>: Select the JTAG operation to be executed</li>
|
||
<li><strong>TCK (Test Clock)</strong>: Synchronise the serial input/output bits</li>
|
||
<li><strong>TDI (Test Data Input)</strong>: Serial data input</li>
|
||
<li><strong>TDO (Test Data Output)</strong>: Serial data output</li>
|
||
<li><strong>GND (Ground)</strong>: Always connect the Ground Pin, or JTAG will get wonky</li>
|
||
</ol>
|
||
<p>(If you stare at it… Yep JTAG looks like SPI!)</p>
|
||
<p>We’ll connect the JTAG Port on PineCone to our computer with a JTAG Debugger, like the <a href="https://www.seeedstudio.com/Sipeed-USB-JTAG-TTL-RISC-V-Debugger-p-2910.html">Sipeed JTAG Debugger</a> shown above.</p>
|
||
<p><em>Why are the JTAG Pins named “Test”?</em></p>
|
||
<p>Because JTAG was originally created for testing Printed Circuit Boards. JTAG stands for Joint Test Action Group, the maintainers of the JTAG standard.</p>
|
||
<p><a href="https://www.allaboutcircuits.com/technical-articles/introduction-to-jtag-test-access-port-tap/">More about JTAG</a></p>
|
||
<h2 id="jtag-vs-swd"><a class="doc-anchor" href="#jtag-vs-swd">§</a>2.1 JTAG vs SWD</h2>
|
||
<p><em>Is SWD supported for flashing and debugging firmware on PineCone?</em></p>
|
||
<p>Sorry no. SWD is available only on Arm Microcontrollers. <a href="https://lupyuen.github.io/articles/openocd-on-raspberry-pi-better-with-swd-on-spi">(SWD was created by Arm)</a></p>
|
||
<p>SWD is derived from JTAG… It takes the 4 pins from JTAG and smashes them into 2 pins SWDCLK (Clock) and SWDIO (Birectional Data). <a href="https://en.wikipedia.org/wiki/JTAG#Similar_interface_standards">More details</a></p>
|
||
<p>Let’s go deep into the JTAG Port on PineCone…</p>
|
||
<p><img src="https://lupyuen.github.io/images/pinecone-jtag.png" alt="Default JTAG Port on PineCone" /></p>
|
||
<p><em>Default JTAG Port on PineCone</em></p>
|
||
<h1 id="wheres-the-jtag-port"><a class="doc-anchor" href="#wheres-the-jtag-port">§</a>3 Where’s the JTAG Port?</h1>
|
||
<p>BL602 is an interesting microcontroller… Each pin may be remapped to various functions: GPIO, SPI, I2C, UART, PWM, ADC, SDIO, even JTAG!</p>
|
||
<p>To find the default JTAG Pins, we refer to…</p>
|
||
<ul>
|
||
<li>
|
||
<p><a href="https://github.com/bouffalolab/bl_docs/blob/main/BL602_RM/en/BL602_BL604_RM_1.2_en.pdf">BL602 Reference Manual</a></p>
|
||
<p>Section 3.2.8, “GPIO Function” (Pages 27 to 40)</p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://github.com/pine64/bl602-docs/blob/main/mirrored/Pine64%20BL602%20EVB%20Schematic%20ver%201.1.pdf">PineCone Schematics</a></p>
|
||
<p>“Module Interface”</p>
|
||
</li>
|
||
</ul>
|
||
<p>(See the pic above)</p>
|
||
<p>Based on the above docs, the JTAG Port is located at the following pins whenever we boot or reset PineCone…</p>
|
||
<div><table><thead><tr><th style="text-align: center">JTAG Pin</th><th style="text-align: left">PineCone Pin</th></tr></thead><tbody>
|
||
<tr><td style="text-align: center"><strong><code>TDO</code></strong></td><td style="text-align: left"><code>IO 11</code></td></tr>
|
||
<tr><td style="text-align: center"><strong><code>TMS</code></strong></td><td style="text-align: left"><code>IO 12</code></td></tr>
|
||
<tr><td style="text-align: center"><strong><code>TCK</code></strong></td><td style="text-align: left"><code>IO 14</code></td></tr>
|
||
<tr><td style="text-align: center"><strong><code>TDI</code></strong></td><td style="text-align: left"><code>IO 17</code></td></tr>
|
||
<tr><td style="text-align: center"><strong><code>GND</code></strong></td><td style="text-align: left"><code>GND</code></td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<p>Before connecting PineCone to our JTAG Debugger, we need to <a href="https://lupyuen.github.io/images/pinecone-solder.jpg">solder the headers</a> to the PineCone board and expose the above JTAG Pins.</p>
|
||
<p><img src="https://lupyuen.github.io/images/pinecone-headers.jpg" alt="Default JTAG Port connected to JTAG Debugger" /></p>
|
||
<p><em>Default JTAG Port connected to JTAG Debugger. Jumper is set to H, for Bootloader Mode. LED is lit with multiple colours when JTAG is active.</em></p>
|
||
<h1 id="connect-jtag-debugger-to-pinecone"><a class="doc-anchor" href="#connect-jtag-debugger-to-pinecone">§</a>4 Connect JTAG Debugger to PineCone</h1>
|
||
<p>The instructions here will work with <a href="https://www.seeedstudio.com/Sipeed-USB-JTAG-TTL-RISC-V-Debugger-p-2910.html">Sipeed JTAG Debugger</a> and other JTAG Debuggers based on FTDI FT2232.</p>
|
||
<ul>
|
||
<li>
|
||
<p><a href="https://mcuoneclipse.com/2019/10/20/jtag-debugging-the-esp32-with-ft2232-and-openocd/">Make your own JTAG Debugger with FT2232</a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://tang.sipeed.com/en/hardware-overview/rv-debugger/?utm_source=platformio&utm_medium=docs">Compare with Schematics of Sipeed JTAG Debugger</a></p>
|
||
</li>
|
||
</ul>
|
||
<p>Now we connect the JTAG Debugger to PineCone…</p>
|
||
<ol>
|
||
<li>
|
||
<p>Connect our JTAG Debugger to the PineCone Pins</p>
|
||
<div><table><thead><tr><th style="text-align: center">JTAG Debugger</th><th style="text-align: left">PineCone Pin</th><th style="text-align: left">Wire Colour</th></tr></thead><tbody>
|
||
<tr><td style="text-align: center"><strong><code>TDO</code></strong></td><td style="text-align: left"><code>IO 11</code></td><td style="text-align: left">Blue</td></tr>
|
||
<tr><td style="text-align: center"><strong><code>TMS</code></strong></td><td style="text-align: left"><code>IO 12</code></td><td style="text-align: left">Yellow</td></tr>
|
||
<tr><td style="text-align: center"><strong><code>TCK</code></strong></td><td style="text-align: left"><code>IO 14</code></td><td style="text-align: left">Green</td></tr>
|
||
<tr><td style="text-align: center"><strong><code>TDI</code></strong></td><td style="text-align: left"><code>IO 17</code></td><td style="text-align: left">Red</td></tr>
|
||
<tr><td style="text-align: center"><strong><code>GND</code></strong></td><td style="text-align: left"><code>GND</code></td><td style="text-align: left">Black</td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<p>(See pic above)</p>
|
||
</li>
|
||
<li>
|
||
<p>Connect the JTAG Debugger to our computer’s USB Port</p>
|
||
</li>
|
||
<li>
|
||
<p>Connect PineCone to our computer’s USB Port</p>
|
||
<p>(Yes we’ll need two USB ports on our computer)</p>
|
||
</li>
|
||
<li>
|
||
<p>Follow these instructions to install the FT2232 drivers for Linux, macOS and Windows…</p>
|
||
<ul>
|
||
<li>
|
||
<p><a href="https://docs.platformio.org/en/latest/plus/debug-tools/sipeed-rv-debugger.html#drivers">Install FT2232 Drivers on Linux, macOS and Windows</a></p>
|
||
</li>
|
||
<li>
|
||
<p>For Windows: Follow the steps above. Then use the Zadig Tool to install the WinUSB Driver for BOTH <code>Dual RS232 (Interface 0)</code> and <code>Dual RS232 (Interface 1)</code></p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ol>
|
||
<p>We’re ready to download and run OpenOCD…</p>
|
||
<p><img src="https://lupyuen.github.io/images/pinecone-jtag-ftdi.jpg" alt="Sipeed JTAG Debugger is powered by FTDI FT2232D" /></p>
|
||
<p><em>Sipeed JTAG Debugger is powered by FTDI FT2232D</em></p>
|
||
<h1 id="download-and-run-openocd"><a class="doc-anchor" href="#download-and-run-openocd">§</a>5 Download and run OpenOCD</h1>
|
||
<p>Here are the steps to download and run OpenOCD with PineCone on Linux, macOS and Windows…</p>
|
||
<h2 id="download-openocd"><a class="doc-anchor" href="#download-openocd">§</a>5.1 Download OpenOCD</h2>
|
||
<p>Download OpenOCD from the <a href="https://github.com/xpack-dev-tools/openocd-xpack/releases/tag/v0.10.0-15/">xPack OpenOCD site</a>… (Other variants of OpenOCD may not work with PineCone)</p>
|
||
<ul>
|
||
<li>
|
||
<p><a href="https://github.com/xpack-dev-tools/openocd-xpack/releases/download/v0.10.0-15/xpack-openocd-0.10.0-15-linux-x64.tar.gz">xPack OpenOCD for Linux x64</a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://github.com/xpack-dev-tools/openocd-xpack/releases/download/v0.10.0-15/xpack-openocd-0.10.0-15-linux-arm64.tar.gz">xPack OpenOCD for Linux Arm64</a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://github.com/xpack-dev-tools/openocd-xpack/releases/download/v0.10.0-15/xpack-openocd-0.10.0-15-darwin-x64.tar.gz">xPack OpenOCD for macOS x64</a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://github.com/xpack-dev-tools/openocd-xpack/releases/download/v0.10.0-15/xpack-openocd-0.10.0-15-win32-x64.zip">xPack OpenOCD for Windows x64</a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://github.com/xpack-dev-tools/openocd-xpack/releases/tag/v0.10.0-15/">Other builds of xPack OpenOCD</a></p>
|
||
</li>
|
||
</ul>
|
||
<p>Extract the downloaded file. On Windows: <a href="https://www.7-zip.org/">Use 7-Zip</a></p>
|
||
<h2 id="download-openocd-script"><a class="doc-anchor" href="#download-openocd-script">§</a>5.2 Download OpenOCD Script</h2>
|
||
<p>Open a command prompt and enter…</p>
|
||
<div class="example-wrap"><pre class="language-bash"><code>git clone --recursive https://github.com/lupyuen/pinecone-rust</code></pre></div>
|
||
<p>If we will be coding Rust Firmware for PineCone, enter these commands too…</p>
|
||
<div class="example-wrap"><pre class="language-bash"><code>git clone --recursive https://github.com/sipeed/bl602-pac
|
||
git clone --recursive https://github.com/sipeed/bl602-hal</code></pre></div><h2 id="run-openocd"><a class="doc-anchor" href="#run-openocd">§</a>5.3 Run OpenOCD</h2>
|
||
<p>At the command prompt, enter…</p>
|
||
<div class="example-wrap"><pre class="language-bash"><code>cd pinecone-rust
|
||
OPENOCD_DIRECTORY/bin/openocd</code></pre></div>
|
||
<p>For Windows: Enter…</p>
|
||
<div class="example-wrap"><pre class="language-cmd"><code>cd pinecone-rust
|
||
OPENOCD_DIRECTORY\bin\openocd</code></pre></div>
|
||
<p>Change <code>OPENOCD_DIRECTORY</code> to the directory that contains the extracted xPack OpenOCD files.</p>
|
||
<h2 id="openocd-output"><a class="doc-anchor" href="#openocd-output">§</a>5.4 OpenOCD Output</h2>
|
||
<p>We should see this output in OpenOCD…</p>
|
||
<div class="example-wrap"><pre class="language-text"><code>xPack OpenOCD, x86_64 Open On-Chip Debugger 0.10.0+dev-00378-ge5be992df (2020-06-26-12:31)
|
||
Licensed under GNU GPL v2
|
||
For bug reports, read
|
||
http://openocd.org/doc/doxygen/bugs.html
|
||
Ready for Remote Connections
|
||
Info : clock speed 100 kHz
|
||
Info : JTAG tap: riscv.cpu tap/device found: 0x20000c05 (mfg: 0x602 (<unknown>), part: 0x0000, ver: 0x2)</code></pre></div>
|
||
<p>Notice the mysterious number <code>0x20000c05</code>?</p>
|
||
<p>This is very important… <code>0x20000c05</code> is the CPU ID that identifies the BL602 Microcontroller. It shows that our JTAG connection is OK.</p>
|
||
<p>If we see any CPU ID other than <code>0x20000c05</code>, it probably means that our JTAG connection is loose. Or that we have connected our JTAG Debugger to the incorrect PineCone Pins.</p>
|
||
<div class="example-wrap"><pre class="language-text"><code>Info : datacount=1 progbufsize=2
|
||
Info : Disabling abstract command reads from CSRs.
|
||
Info : Examined RISC-V core; found 1 harts
|
||
Info : hart 0: XLEN=32, misa=0x40801125
|
||
Info : starting gdb server for riscv.cpu.0 on 3333
|
||
Info : Listening on port 3333 for gdb connections</code></pre></div>
|
||
<p>Then we see some info about PineCone’s BL602 Microcontroller. And we see that OpenOCD is ready to accept debugging commands from GDB.</p>
|
||
<div class="example-wrap"><pre class="language-text"><code>Info : JTAG tap: riscv.cpu tap/device found: 0x20000c05 (mfg: 0x602 (<unknown>), part: 0x0000, ver: 0x2)
|
||
reset-assert-pre
|
||
reset-deassert-post
|
||
Info : Disabling abstract command writes to CSRs.
|
||
reset-init
|
||
Info : Listening on port 6666 for tcl connections</code></pre></div>
|
||
<p>Finally OpenOCD restarts the JTAG connection. And it listens for OpenOCD (TCL) commands.</p>
|
||
<p>If we see CPU ID <code>0x20000c05</code> and the messages above… Congratulations OpenOCD is now connected to PineCone’s JTAG Port!</p>
|
||
<p>OpenOCD is all ready to load and debug PineCone firmware. <a href="https://lupyuen.github.io/articles/debug">(Which we’ll cover in the next article)</a></p>
|
||
<p>To stop OpenOCD and disconnect from PineCone, press <code>Ctrl-C</code>.</p>
|
||
<h2 id="troubleshoot-openocd"><a class="doc-anchor" href="#troubleshoot-openocd">§</a>5.5 Troubleshoot OpenOCD</h2>
|
||
<p>If we see…</p>
|
||
<div class="example-wrap"><pre class="language-text"><code>Error: unable to open ftdi device with vid 0403, pid 6010, description '*', serial '*' at bus location '*'</code></pre></div>
|
||
<p>It means that OpenOCD couldn’t detect the JTAG Debugger. Check that the FT2232 drivers are installed correctly.</p>
|
||
<p>If we see…</p>
|
||
<div class="example-wrap"><pre class="language-text"><code>Error: failed read at 0x11, status=1
|
||
Error: Hart 0 is unavailable.
|
||
Error: Hart 0 doesn't exist.
|
||
Info : Hart 0 unexpectedly reset!
|
||
Error: failed read at 0x11, status=1</code></pre></div>
|
||
<p>Check that the <code>GND</code> Pin is connected from the JTAG Debugger to PineCone.</p>
|
||
<p><a href="https://mcuoneclipse.com/2019/10/20/jtag-debugging-the-esp32-with-ft2232-and-openocd/">More tips on connecting OpenOCD to FT2232</a></p>
|
||
<h1 id="openocd-script"><a class="doc-anchor" href="#openocd-script">§</a>6 OpenOCD Script</h1>
|
||
<p>The OpenOCD connection to PineCone is controlled by the OpenOCD Script <a href="https://github.com/lupyuen/pinecone-rust/blob/main/openocd.cfg"><code>pinecone-rust/openocd.cfg</code></a>.</p>
|
||
<p>Our OpenOCD Script is based on the one kindly contributed by the <a href="https://github.com/sipeed/bl602-rust-guide">Sipeed BL602 Community</a>.</p>
|
||
<p>Let’s study the important bits of our OpenOCD Script: <a href="https://github.com/lupyuen/pinecone-rust/blob/main/openocd.cfg"><code>pinecone-rust/openocd.cfg</code></a></p>
|
||
<h2 id="debug-logging"><a class="doc-anchor" href="#debug-logging">§</a>6.1 Debug Logging</h2><div class="example-wrap"><pre class="language-text"><code>## Uncomment to enable debug messages
|
||
## debug_level 4</code></pre></div>
|
||
<p>To show debug messages in OpenOCD, uncomment the <code>debug_level</code> line. (Remove the leading “<code>#</code>”)</p>
|
||
<p>This is useful for troubleshooting the OpenOCD connection to PineCone. OpenOCD will show every single JTAG packet transmitted between our computer and PineCone.</p>
|
||
<h2 id="openocd-driver"><a class="doc-anchor" href="#openocd-driver">§</a>6.2 OpenOCD Driver</h2><div class="example-wrap"><pre class="language-text"><code>adapter driver ftdi
|
||
|
||
ftdi_vid_pid 0x0403 0x6010</code></pre></div>
|
||
<p>Here we tell OpenOCD to use the FT2232 debugger that’s connected to USB.</p>
|
||
<p><code>0x0403</code> is the USB Vendor ID for FT2232. <code>0x6010</code> is the USB Product ID.</p>
|
||
<h2 id="ftdi-channel"><a class="doc-anchor" href="#ftdi-channel">§</a>6.3 FTDI Channel</h2><div class="example-wrap"><pre class="language-text"><code>## Sipeed JTAG Debugger uses FTDI Channel 0, not 1
|
||
ftdi_channel 0
|
||
## Previously: ftdi_channel 1</code></pre></div>
|
||
<p>According to the <a href="https://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232D.pdf">FT2232 Specs</a>, the FT2232 module supports two Serial Channels: 0 and 1.</p>
|
||
<p>For Sipeed JTAG Debugger: The FTDI Channel must be 0. <a href="https://tang.sipeed.com/en/hardware-overview/rv-debugger/?utm_source=platformio&utm_medium=docs">See the schematics</a></p>
|
||
<p>For other JTAG Debuggers: Set the FTDI Channel to 0 if PineCone is connected to the first Serial Channel, and to 1 for the second Serial Channel.</p>
|
||
<h2 id="jtag-speed"><a class="doc-anchor" href="#jtag-speed">§</a>6.4 JTAG Speed</h2><div class="example-wrap"><pre class="language-text"><code>transport select jtag
|
||
|
||
## TODO: Increase the adapter speed (now 100 kHz)
|
||
adapter speed 100
|
||
## Previously: adapter speed 2000</code></pre></div>
|
||
<p>Here we select JTAG as the communication protocol for talking to PineCone.</p>
|
||
<p>Our OpenOCD Script talks to PineCone at 100 kbps, which is a safe (but slow) data rate that works with most JTAG Debuggers.</p>
|
||
<p>We should increase the Adapter Speed to speed up the data transfer. (After lots of testing, of course)</p>
|
||
<h2 id="cpu-id"><a class="doc-anchor" href="#cpu-id">§</a>6.5 CPU ID</h2><div class="example-wrap"><pre class="language-text"><code>set _CHIPNAME riscv
|
||
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000c05</code></pre></div>
|
||
<p>This is the part that verifies BL602’s CPU ID: <code>0x20000c05</code></p>
|
||
<p>This should never be changed. (Unless we’re connecting to a different microcontroller)</p>
|
||
<h2 id="restart-pinecone"><a class="doc-anchor" href="#restart-pinecone">§</a>6.6 Restart PineCone</h2><div class="example-wrap"><pre class="language-text"><code>init
|
||
reset init</code></pre></div>
|
||
<p>The <code>init</code> command initiates the JTAG connection to PineCone, and verifies the CPU ID of our BL602 Microcontroller.</p>
|
||
<p><code>reset init</code> triggers a reboot of PineCone. (Similar to pressing the <code>RST</code> button on PineCone)</p>
|
||
<h2 id="wait-for-gdb-and-tcl-commands"><a class="doc-anchor" href="#wait-for-gdb-and-tcl-commands">§</a>6.7 Wait for GDB and TCL Commands</h2>
|
||
<p>After executing our script, OpenOCD waits to receive GDB Debugging commands and OpenOCD TCL commands.</p>
|
||
<p>For some OpenOCD Scripts (like for loading firmware), we don’t need OpenOCD to wait for further commands. In such scripts, we terminate OpenOCD with the <code>exit</code> command…</p>
|
||
<div class="example-wrap"><pre class="language-text"><code># Terminate OpenOCD
|
||
exit</code></pre></div>
|
||
<p>See the complete OpenOCD Script: <a href="https://github.com/lupyuen/pinecone-rust/blob/main/openocd.cfg"><code>pinecone-rust/openocd.cfg</code></a></p>
|
||
<p><a href="https://twitter.com/gamelaster/status/1335997851151835140?s=20">Check out the awesome work on PineCone OpenOCD by @gamelaster</a></p>
|
||
<p><a href="http://openocd.org/doc/html/index.html">More about OpenOCD</a></p>
|
||
<p><img src="https://lupyuen.github.io/images/pinecone-led.png" alt="PineCone LED uses GPIO 11, 14, 17" /></p>
|
||
<p><em>PineCone LED uses GPIO 11, 14, 17</em></p>
|
||
<h1 id="if-you-love-the-led-set-it-free"><a class="doc-anchor" href="#if-you-love-the-led-set-it-free">§</a>7 If you love the LED… Set it free!</h1>
|
||
<p><em>Why does the PineCone LED light up in colour when the JTAG Port is active?</em></p>
|
||
<p>To solve this mystery, we dig deep into the <a href="https://github.com/pine64/bl602-docs/blob/main/mirrored/Pine64%20BL602%20EVB%20Schematic%20ver%201.1.pdf">PineCone Schematics</a> and check the BL602 Pins connected to our LED… (See pic above)</p>
|
||
<div><table><thead><tr><th style="text-align: left">LED Pin</th><th style="text-align: left">BL602 Pin</th></tr></thead><tbody>
|
||
<tr><td style="text-align: left"><strong><code>LED Blue</code></strong></td><td style="text-align: left"><code>IO 11</code></td></tr>
|
||
<tr><td style="text-align: left"><strong><code>LED Green</code></strong></td><td style="text-align: left"><code>IO 14</code></td></tr>
|
||
<tr><td style="text-align: left"><strong><code>LED Red</code></strong></td><td style="text-align: left"><code>IO 17</code></td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<p>Aha! PineCone’s LED is connected to the same pins as the JTAG Port. Which explains the disco lights during JTAG programming!</p>
|
||
<p>This is a problem… If we control the PineCone LED in our firmware, it will interfere with the JTAG Port.</p>
|
||
<p><em>Can we use PineCone’s LED in our firmware… While debugging our firmware with JTAG?</em></p>
|
||
<p>According to the <a href="https://github.com/bouffalolab/bl_docs/blob/main/BL602_RM/en/BL602_BL604_RM_1.2_en.pdf">BL602 Reference Manual</a> (Section 3.2.8 “GPIO Function”, Page 27), we may remap the JTAG Port to other GPIO Pins (and avoid the conflict).</p>
|
||
<h2 id="free-the-led-from-jtag-port"><a class="doc-anchor" href="#free-the-led-from-jtag-port">§</a>7.1 Free the LED from JTAG Port</h2>
|
||
<p>Here’s our plan to free the LED from the JTAG Port…</p>
|
||
<ol>
|
||
<li>
|
||
<p>We remap the three LED pins from JTAG to PWM, so that we may to control the LED…</p>
|
||
<div><table><thead><tr><th style="text-align: left">LED Pin</th><th style="text-align: left">BL602 Pin</th><th style="text-align: left">Remap Pin Function</th></tr></thead><tbody>
|
||
<tr><td style="text-align: left"><strong><code>LED Blue</code></strong></td><td style="text-align: left"><code>IO 11</code></td><td style="text-align: left">JTAG → PWM</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>LED Green</code></strong></td><td style="text-align: left"><code>IO 14</code></td><td style="text-align: left">JTAG → PWM</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>LED Red</code></strong></td><td style="text-align: left"><code>IO 17</code></td><td style="text-align: left">JTAG → PWM</td></tr>
|
||
</tbody></table>
|
||
</div></li>
|
||
<li>
|
||
<p>Then we pick three unused BL602 Pins and remap them to JTAG…</p>
|
||
<div><table><thead><tr><th style="text-align: left">JTAG Pin</th><th style="text-align: left">BL602 Pin</th><th style="text-align: left">Remap Pin Function</th></tr></thead><tbody>
|
||
<tr><td style="text-align: left"><strong><code>JTAG TDI</code></strong></td><td style="text-align: left"><code>IO 1</code></td><td style="text-align: left">SDIO → JTAG</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>JTAG TCK</code></strong></td><td style="text-align: left"><code>IO 2</code></td><td style="text-align: left">SDIO → JTAG</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>JTAG TDO</code></strong></td><td style="text-align: left"><code>IO 3</code></td><td style="text-align: left">SDIO → JTAG</td></tr>
|
||
</tbody></table>
|
||
</div></li>
|
||
<li>
|
||
<p>We keep the JTAG TMS pin as is because it wasn’t invited to the disco party…</p>
|
||
<div><table><thead><tr><th style="text-align: left">JTAG Pin</th><th style="text-align: left">BL602 Pin</th><th style="text-align: left">Remap Pin Function</th></tr></thead><tbody>
|
||
<tr><td style="text-align: left"><strong><code>JTAG TMS</code></strong></td><td style="text-align: left"><code>IO 12</code></td><td style="text-align: left">JTAG → JTAG</td></tr>
|
||
</tbody></table>
|
||
</div></li>
|
||
<li>
|
||
<p>Finally we set the GPIO Control bits for the pins remapped to JTAG…</p>
|
||
<div><table><thead><tr><th style="text-align: left">GPIO Control</th><th style="text-align: left">Value</th></tr></thead><tbody>
|
||
<tr><td style="text-align: left">Pull Down Control</td><td style="text-align: left">0</td></tr>
|
||
<tr><td style="text-align: left">Pull Up Control</td><td style="text-align: left">0</td></tr>
|
||
<tr><td style="text-align: left">Driving Control</td><td style="text-align: left">0</td></tr>
|
||
<tr><td style="text-align: left">SMT Control</td><td style="text-align: left">1</td></tr>
|
||
<tr><td style="text-align: left">Input Enable</td><td style="text-align: left">1</td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<p>(These values were obtained by sniffing the GPIO Control bits for the default JTAG Port)</p>
|
||
</li>
|
||
</ol>
|
||
<p>Let’s study the firmware code that remaps the JTAG Port… And frees our LED!</p>
|
||
<p><img src="https://lupyuen.github.io/images/pinecone-gpio.png" alt="BL602 Configuration Register for Pins IO 0 and IO 1" /></p>
|
||
<p><em>BL602 Configuration Register for Pins IO 0 and IO 1</em></p>
|
||
<h1 id="remap-the-jtag-port"><a class="doc-anchor" href="#remap-the-jtag-port">§</a>8 Remap the JTAG Port</h1>
|
||
<p>Remember that we need to remap JTAG and PWM functions of the following pins…</p>
|
||
<div><table><thead><tr><th style="text-align: left">LED / JTAG Pin</th><th style="text-align: left">BL602 Pin</th><th style="text-align: left">Remap Pin Function</th></tr></thead><tbody>
|
||
<tr><td style="text-align: left"><strong><code>JTAG TDI</code></strong></td><td style="text-align: left"><code>IO 1</code></td><td style="text-align: left">SDIO → JTAG</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>JTAG TCK</code></strong></td><td style="text-align: left"><code>IO 2</code></td><td style="text-align: left">SDIO → JTAG</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>JTAG TDO</code></strong></td><td style="text-align: left"><code>IO 3</code></td><td style="text-align: left">SDIO → JTAG</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>LED Blue</code></strong></td><td style="text-align: left"><code>IO 11</code></td><td style="text-align: left">JTAG → PWM</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>LED Green</code></strong></td><td style="text-align: left"><code>IO 14</code></td><td style="text-align: left">JTAG → PWM</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>LED Red</code></strong></td><td style="text-align: left"><code>IO 17</code></td><td style="text-align: left">JTAG → PWM</td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<p>Here’s how we write the firmware code to remap the pins: <a href="https://github.com/lupyuen/bl_iot_sdk/blob/jtag/customer_app/sdk_app_helloworld/sdk_app_helloworld/main.c#L83-L241"><code>sdk_app_helloworld/main.c</code></a></p>
|
||
<ol>
|
||
<li>
|
||
<p>According to the pic above, we configure BL602 Pin <code>IO 1</code> by writing to the memory address <code>0x40000100</code>. We’ll call this address <code>GP1FUNC_ADDR</code></p>
|
||
<div class="example-wrap"><pre class="language-c"><code>// GPIO_CFGCTL0
|
||
// Address:0x40000100
|
||
uint32_t *GPIO_CFGCTL0 = (uint32_t *) 0x40000100;
|
||
uint32_t *GP1FUNC_ADDR = GPIO_CFGCTL0;</code></pre></div>
|
||
<p>The pic above appears in the <a href="https://github.com/bouffalolab/bl_docs/blob/main/BL602_RM/en/BL602_BL604_RM_1.2_en.pdf">BL602 Reference Manual</a>, Section 3.3.5 “GPIO_CFGCTL0”, Page 33.</p>
|
||
<p>(“地址” is Chinese for “Address”)</p>
|
||
</li>
|
||
<li>
|
||
<p>We’ll set bits 24 to 27 of <code>GP1FUNC_ADDR</code> to select the desired Pin Function (i.e. JTAG).</p>
|
||
<p>We define the Pin Function bit shift (offset) as <code>GP1FUNC_SHIFT</code> and the bit mask as <code>GP1FUNC_MASK</code>…</p>
|
||
<div class="example-wrap"><pre class="language-c"><code>// 27:24 GP1FUNC
|
||
const uint32_t GP1FUNC_SHIFT = 24;
|
||
const uint32_t GP1FUNC_MASK = 0x0f << GP1FUNC_SHIFT;</code></pre></div></li>
|
||
<li>
|
||
<p>Then we’ll set bits 16 to 21 of <code>GP1FUNC_ADDR</code> for the GPIO Pin Control.</p>
|
||
<p>We define the Pin Control bit shift (offset) as <code>GP1CTRL_SHIFT</code> and the bit mask as <code>GP1CTRL_MASK</code>…</p>
|
||
<div class="example-wrap"><pre class="language-c"><code>// 21:16 GP1CTRL
|
||
const uint32_t GP1CTRL_SHIFT = 16;
|
||
const uint32_t GP1CTRL_MASK = 0x3f << GP1CTRL_SHIFT;</code></pre></div></li>
|
||
<li>
|
||
<p>To map Pin <code>IO 1</code> to JTAG, we set the Pin Function of <code>GP1FUNC_ADDR</code> to <code>GPIO_FUN_JTAG</code>, and the Pin Control to <code>GPIO_CTRL</code></p>
|
||
<div class="example-wrap"><pre class="language-c"><code>// IO 1 becomes JTAG TDI. Also set the Pin Control.
|
||
*GP1FUNC_ADDR = (*GP1FUNC_ADDR & ~GP1FUNC_MASK & ~GP1CTRL_MASK)
|
||
| (GPIO_FUN_JTAG << GP1FUNC_SHIFT)
|
||
| (GPIO_CTRL << GP1CTRL_SHIFT);</code></pre></div></li>
|
||
<li>
|
||
<p>The Pin Function values (<code>GPIO_FUN_JTAG</code> and <code>GPIO_FUN_PWM</code>) are defined as…</p>
|
||
<div class="example-wrap"><pre class="language-c"><code>// Pin Functions (4 bits). From components/bl602/bl602_std/bl602_std/StdDriver/Inc/bl602_gpio.h
|
||
const uint32_t GPIO_FUN_PWM = 8; // Pin Function for PWM (0x8)
|
||
const uint32_t GPIO_FUN_JTAG = 14; // Pin Function for JTAG (0xe)</code></pre></div></li>
|
||
<li>
|
||
<p>The Pin Control value <code>GPIO_CTRL</code> is defined as…</p>
|
||
<div class="example-wrap"><pre class="language-c"><code>// Pin Control (6 bits)
|
||
// Pull Down Control: 0 (1 bit)
|
||
// Pull Up Control: 0 (1 bit)
|
||
// Driving Control: 0 (2 bits)
|
||
// SMT Control: 1 (1 bit)
|
||
// Input Enable: 1 (1 bit)
|
||
const uint32_t GPIO_CTRL = 3; // Pin Control</code></pre></div></li>
|
||
<li>
|
||
<p>We apply the above steps to remap each Pin Function and set the Pin Control bits…</p>
|
||
<div><table><thead><tr><th style="text-align: left">LED / JTAG Pin</th><th style="text-align: left">BL602 Pin</th><th style="text-align: left">Remap Pin Function</th></tr></thead><tbody>
|
||
<tr><td style="text-align: left"><strong><code>JTAG TDI</code></strong></td><td style="text-align: left"><code>IO 1</code></td><td style="text-align: left">SDIO → JTAG</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>JTAG TCK</code></strong></td><td style="text-align: left"><code>IO 2</code></td><td style="text-align: left">SDIO → JTAG</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>JTAG TDO</code></strong></td><td style="text-align: left"><code>IO 3</code></td><td style="text-align: left">SDIO → JTAG</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>LED Blue</code></strong></td><td style="text-align: left"><code>IO 11</code></td><td style="text-align: left">JTAG → PWM</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>LED Green</code></strong></td><td style="text-align: left"><code>IO 14</code></td><td style="text-align: left">JTAG → PWM</td></tr>
|
||
<tr><td style="text-align: left"><strong><code>LED Red</code></strong></td><td style="text-align: left"><code>IO 17</code></td><td style="text-align: left">JTAG → PWM</td></tr>
|
||
</tbody></table>
|
||
</div></li>
|
||
</ol>
|
||
<p>The remapping code for all 6 pins may be found here: <a href="https://github.com/lupyuen/bl_iot_sdk/blob/jtag/customer_app/sdk_app_helloworld/sdk_app_helloworld/main.c#L83-L241"><code>sdk_app_helloworld/main.c</code></a></p>
|
||
<h2 id="before-and-after"><a class="doc-anchor" href="#before-and-after">§</a>8.1 Before and After</h2>
|
||
<p>Here are the values of the Pin Function and Pin Control registers before and after remapping…</p>
|
||
<div><table><thead><tr><th style="text-align: left">Register</th><th style="text-align: left">Before</th><th style="text-align: left">After</th><th style="text-align: left">Pin</th></tr></thead><tbody>
|
||
<tr><td style="text-align: left"><code>GPIO_CFGCTL0</code></td><td style="text-align: left"><strong><code>bb</code></strong> <strong><code>17</code></strong> <code>bb</code> <code>17</code></td><td style="text-align: left"><strong><code>ee</code></strong> <strong><code>03</code></strong> <code>bb</code> <code>17</code></td><td style="text-align: left">1</td></tr>
|
||
<tr><td style="text-align: left"><code>GPIO_CFGCTL1</code></td><td style="text-align: left"><strong><code>11</code></strong> <code>03</code> <strong><code>bb</code></strong> <strong><code>17</code></strong></td><td style="text-align: left"><strong><code>ee</code></strong> <code>03</code> <strong><code>ee</code></strong> <strong><code>03</code></strong></td><td style="text-align: left">2, 3</td></tr>
|
||
<tr><td style="text-align: left"><code>GPIO_CFGCTL5</code></td><td style="text-align: left"><strong><code>0e</code></strong> <code>03</code> <code>0b</code> <code>03</code></td><td style="text-align: left"><strong><code>08</code></strong> <code>03</code> <code>0b</code> <code>03</code></td><td style="text-align: left">11</td></tr>
|
||
<tr><td style="text-align: left"><code>GPIO_CFGCTL7</code></td><td style="text-align: left"><code>0b</code> <code>03</code> <strong><code>0e</code></strong> <code>03</code></td><td style="text-align: left"><code>0b</code> <code>03</code> <strong><code>08</code></strong> <code>03</code></td><td style="text-align: left">14</td></tr>
|
||
<tr><td style="text-align: left"><code>GPIO_CFGCTL8</code></td><td style="text-align: left"><strong><code>0e</code></strong> <code>03</code> <code>07</code> <code>17</code></td><td style="text-align: left"><strong><code>08</code></strong> <code>03</code> <code>07</code> <code>17</code></td><td style="text-align: left">17</td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<p>(Changed values have been highlighted)</p>
|
||
<p>Note that the Pin Function fields (4 bits each) have been changed to <code>0xe</code> for JTAG and <code>0x8</code> for PWM.</p>
|
||
<p>The Pin Control fields (6 bits each) have also been changed to <code>0x03</code>.</p>
|
||
<p>Let’s test the remapped JTAG Port on our PineCone!</p>
|
||
<p><img src="https://lupyuen.github.io/images/pinecone-headers2.jpg" alt="Remapped PineCone Connection to JTAG Debugger" /></p>
|
||
<p><em>Remapped JTAG Port connected to JTAG Debugger. The LED lights up in bright white to signify that the JTAG Port has been remapped. Jumper is set to L, for Normal Mode.</em></p>
|
||
<h1 id="test-the-remapped-jtag-port"><a class="doc-anchor" href="#test-the-remapped-jtag-port">§</a>9 Test the Remapped JTAG Port</h1>
|
||
<p><em>How shall we test the JTAG Port remap?</em></p>
|
||
<p>We test by flashing a modified <code>helloworld</code> firmware that contains the remap code from the previous section…</p>
|
||
<h2 id="connect-the-remapped-jtag-port"><a class="doc-anchor" href="#connect-the-remapped-jtag-port">§</a>9.1 Connect the Remapped JTAG Port</h2>
|
||
<ol>
|
||
<li>
|
||
<p>Disconnect PineCone and JTAG Debugger from our computer</p>
|
||
</li>
|
||
<li>
|
||
<p>Connect the remapped JTAG Pins from PineCone to our JTAG Debugger…</p>
|
||
<div><table><thead><tr><th style="text-align: center">JTAG Debugger</th><th style="text-align: left">PineCone Pin</th><th style="text-align: left">Wire Colour</th></tr></thead><tbody>
|
||
<tr><td style="text-align: center"><strong><code>TDI</code></strong></td><td style="text-align: left"><code>IO 1</code></td><td style="text-align: left">Red</td></tr>
|
||
<tr><td style="text-align: center"><strong><code>TCK</code></strong></td><td style="text-align: left"><code>IO 2</code></td><td style="text-align: left">Green</td></tr>
|
||
<tr><td style="text-align: center"><strong><code>TDO</code></strong></td><td style="text-align: left"><code>IO 3</code></td><td style="text-align: left">Blue</td></tr>
|
||
<tr><td style="text-align: center"><strong><code>TMS</code></strong></td><td style="text-align: left"><code>IO 12</code></td><td style="text-align: left">Yellow</td></tr>
|
||
<tr><td style="text-align: center"><strong><code>GND</code></strong></td><td style="text-align: left"><code>GND</code></td><td style="text-align: left">Black</td></tr>
|
||
</tbody></table>
|
||
</div>
|
||
<p>(See the pic above)</p>
|
||
</li>
|
||
<li>
|
||
<p>Set the PineCone Jumper to <code>H</code> (Bootloader Mode), because we shall be flashing the firmware shortly</p>
|
||
</li>
|
||
<li>
|
||
<p>Connect both PineCone and JTAG Debugger to our computer’s USB ports</p>
|
||
</li>
|
||
</ol>
|
||
<h2 id="download-the-remap-firmware"><a class="doc-anchor" href="#download-the-remap-firmware">§</a>9.2 Download the Remap Firmware</h2>
|
||
<p>The firmware code from the previous section has been built and uploaded as a GitHub Release. Here’s how we download the firmware the remaps the JTAG Port…</p>
|
||
<ol>
|
||
<li>
|
||
<p>Browse to this GitHub Release…</p>
|
||
<p><a href="https://github.com/lupyuen/bl_iot_sdk/releases/tag/v0.0.4"><code>github.com/lupyuen/bl_iot_sdk/ releases/tag/v0.0.4</code></a></p>
|
||
</li>
|
||
<li>
|
||
<p>Scroll to the bottom. Under <code>Assets</code>, click <code>build_out.zip</code></p>
|
||
</li>
|
||
<li>
|
||
<p>Unzip the downloaded file <code>build_out.zip</code></p>
|
||
</li>
|
||
<li>
|
||
<p>In the extracted files, look for…</p>
|
||
<div class="example-wrap"><pre class="language-text"><code>build_out/sdk_app_helloworld.bin</code></pre></div>
|
||
<p>We shall be flashing <code>sdk_app_helloworld.bin</code> in the next step.</p>
|
||
<p>This version of the <code>helloworld</code> app has been modified to remap the JTAG Port.</p>
|
||
<p><a href="https://github.com/lupyuen/bl_iot_sdk/blob/jtag/customer_app/sdk_app_helloworld/sdk_app_helloworld/main.c#L83-L241">Browse the source code</a></p>
|
||
</li>
|
||
</ol>
|
||
<h2 id="flash-the-remap-firmware"><a class="doc-anchor" href="#flash-the-remap-firmware">§</a>9.3 Flash the Remap Firmware</h2>
|
||
<ol>
|
||
<li>
|
||
<p>Check that the PineCone Jumper has been set to <code>H</code> (Bootloader Mode), ready for flashing</p>
|
||
</li>
|
||
<li>
|
||
<p>Follow the instructions in this article to flash the <code>sdk_app_helloworld.bin</code> firmware that we have just downloaded. (Not the one from GitHub Actions)</p>
|
||
<p><a href="https://lupyuen.github.io/articles/pinecone">“Quick Peek of PineCone BL602 RISC-V Evaluation Board”</a>, Section 4.2: <a href="https://lupyuen.github.io/articles/pinecone#flashing-firmware">“Flashing Firmware”</a></p>
|
||
</li>
|
||
<li>
|
||
<p>When selecting the firmware file, remember to choose the <code>sdk_app_helloworld.bin</code> firmware that we have just downloaded.</p>
|
||
<p>Make sure there are no spaces in the firmware pathname.</p>
|
||
</li>
|
||
</ol>
|
||
<h2 id="start-the-remap-firmware"><a class="doc-anchor" href="#start-the-remap-firmware">§</a>9.4 Start the Remap Firmware</h2>
|
||
<ol>
|
||
<li>
|
||
<p>After flashing the remap firmware, set the PineCone Jumper to <code>L</code> (Normal Mode) and power on PineCone. (Or press the Reset Button)</p>
|
||
</li>
|
||
<li>
|
||
<p>PineCone’s LED should light up bright white to signify that the JTAG Port has been remapped</p>
|
||
</li>
|
||
</ol>
|
||
<h2 id="run-openocd-1"><a class="doc-anchor" href="#run-openocd-1">§</a>9.5 Run OpenOCD</h2>
|
||
<ol>
|
||
<li>
|
||
<p>Run OpenOCD using the same steps that we have covered in this article</p>
|
||
</li>
|
||
<li>
|
||
<p>We should see the same OpenOCD output, including the CPU ID.</p>
|
||
<p>This means that the remapped JTAG Port is working OK.</p>
|
||
</li>
|
||
<li>
|
||
<p>Remap Tip: When we reboot PineCone with Jumper set to <code>H</code> (Bootloader Mode), PineCone switches back to the Default JTAG Port. The LED turns multicolour.</p>
|
||
<p>Set the Jumper to <code>L</code> (Normal Mode) and reboot PineTime to restore the Remapped JTAG Port. The LED turns bright white.</p>
|
||
</li>
|
||
</ol>
|
||
<h2 id="remove-the-remap-firmware"><a class="doc-anchor" href="#remove-the-remap-firmware">§</a>9.6 Remove the Remap Firmware</h2>
|
||
<ol>
|
||
<li>
|
||
<p>To remove the remap firmware, follow the instructions in this article to flash the original <code>sdk_app_helloworld.bin</code> firmware from GitHub Actions. (Not the modified one we have just downloaded)</p>
|
||
<p><a href="https://lupyuen.github.io/articles/pinecone">“Quick Peek of PineCone BL602 RISC-V Evaluation Board”</a>, Section 4.2: <a href="https://lupyuen.github.io/articles/pinecone#flashing-firmware">“Flashing Firmware”</a></p>
|
||
</li>
|
||
<li>
|
||
<p>Set PineCone’s Jumper to <code>L</code> (Normal Mode) and power on PineCone.</p>
|
||
<p>The LED should no longer light up after booting</p>
|
||
<p>This signifies that the JTAG Port is no longer remapped. And we’re back to the default JTAG Port.</p>
|
||
</li>
|
||
</ol>
|
||
<p><img src="https://lupyuen.github.io/images/pinecone-led2.jpg" alt="PineCone with Remapped JTAG Port" /></p>
|
||
<p><em>PineCone with Remapped JTAG Port. The LED lights up in bright white to signify that the JTAG Port has been remapped.</em></p>
|
||
<h1 id="how-to-fix-the-jtag-port"><a class="doc-anchor" href="#how-to-fix-the-jtag-port">§</a>10 How to fix the JTAG Port</h1>
|
||
<p><em>What are the options for resolving the conflict between the JTAG Pins and the LED Pins on PineCone?</em></p>
|
||
<p>We have a couple of options…</p>
|
||
<h2 id="redesign-the-pinecone-hardware"><a class="doc-anchor" href="#redesign-the-pinecone-hardware">§</a>10.1 Redesign the PineCone Hardware</h2>
|
||
<p><em>Connect the LED to other pins. Keep the default JTAG Port.</em></p>
|
||
<p>We’ll no longer have the multicolour lights during JTAG programming… But this option allows us to control the LED while doing debugging over JTAG, without having to remap the JTAG Port.</p>
|
||
<p>This makes PineCone coding easier. And we’ll never have to worry about connecting our JTAG Debugger to the wrong PineCone Pins.</p>
|
||
<p>This is my preferred option, though it will cost more to redesign and manufacture the board.</p>
|
||
<h2 id="keep-pinecone-as-is"><a class="doc-anchor" href="#keep-pinecone-as-is">§</a>10.2 Keep PineCone as is</h2>
|
||
<p><em>LED is connected on the default JTAG Pins.</em></p>
|
||
<p>But will we need to use the LED and JTAG Debugging at the same time?</p>
|
||
<ol>
|
||
<li>
|
||
<p><strong>Only LED</strong>: We’ll remap the LED Pins to PWM so that we may control them.</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Only JTAG</strong>: We’ll use the default JTAG Port. No remapping needed.</p>
|
||
<p>(And we get free disco lights during JTAG loading and debugging)</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Both LED and JTAG</strong>: This gets tricky.</p>
|
||
<p>As we have learnt earlier, we need to remap the LED Pins to PWM, and remap the JTAG Port to other pins.</p>
|
||
<ul>
|
||
<li>
|
||
<p>This remapping can be done in the PineCone Firmware.</p>
|
||
<p>But whenever PineCone reboots, the JTAG Port reverts to the default pins, until our firmware remaps the port.</p>
|
||
<p>This may be a problem if we need to reboot PineCone during JTAG loading or debugging.</p>
|
||
</li>
|
||
<li>
|
||
<p>Alternatively: We may remap the LED and JTAG pins in the PineCone Bootloader <code>blsp_boot2</code></p>
|
||
<p>This ensures that the pins are remapped quickly whenever PineCone reboots.</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ol>
|
||
<h2 id="integrate-jtag-debugger-with-pinecone"><a class="doc-anchor" href="#integrate-jtag-debugger-with-pinecone">§</a>10.3 Integrate JTAG Debugger with PineCone</h2>
|
||
<p>We hear that Sipeed’s upcoming BL602 Board will have an onboard JTAG Debugger. (Probably FT2232)</p>
|
||
<p>This increases the cost of the BL602 board… But it simplifies the USB connection between our computer and the BL602 board.</p>
|
||
<p>For PineCone we’re using 2 USB ports (PineCone USB + JTAG Debugger). With an integrated JTAG Debugger, we’ll need only 1 USB port.</p>
|
||
<h1 id="whats-next"><a class="doc-anchor" href="#whats-next">§</a>11 What’s Next</h1>
|
||
<p>Today we have connected OpenOCD to PineCone… Next we shall try loading and debugging RISC-V firmware on PineCone! (With VSCode, GDB, …)</p>
|
||
<ul>
|
||
<li><a href="https://lupyuen.github.io/articles/debug"><strong>“Debug Rust on PineCone BL602 with VSCode and GDB”</strong></a></li>
|
||
</ul>
|
||
<p>In the above article we’ll also be testing the <strong>Embedded Rust Firmware</strong>, kindly contributed by the Sipeed BL602 Community.</p>
|
||
<ul>
|
||
<li>
|
||
<p><a href="https://lupyuen.github.io/articles/book">Read “The RISC-V BL602 Book”</a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://lupyuen.github.io/articles/sponsor">Sponsor me a coffee</a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://lupyuen.github.io">Check out my articles</a></p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://lupyuen.github.io/rss.xml">RSS Feed</a></p>
|
||
</li>
|
||
</ul>
|
||
<p><em>Got a question, comment or suggestion? Create an Issue or submit a Pull Request here…</em></p>
|
||
<p><a href="https://github.com/lupyuen/lupyuen.github.io/blob/master/src/openocd.md"><code>lupyuen.github.io/src/openocd.md</code></a></p>
|
||
|
||
|
||
<!-- Begin scripts/rustdoc-after.html: Post-HTML for Custom Markdown files processed by rustdoc, like chip8.md -->
|
||
|
||
<!-- Begin Theme Picker and Prism Theme -->
|
||
<script src="../theme.js"></script>
|
||
<script src="../prism.js"></script>
|
||
<!-- Theme Picker and Prism Theme -->
|
||
|
||
<!-- End scripts/rustdoc-after.html -->
|
||
|
||
|
||
</body>
|
||
</html> |