Sunday, November 10, 2024

Rotary Encoder Expermenter's Board: Improving the Hardware

Quick one this time....I have posted a few projects lately that incorporated a Raspberry Pi Pico, rotary encoder, and .96" OLED: here, here, and here. To make it unnecessary to breadboard the hardware, I posted an "experimenters board"--a development board to enhance a RP Pico.

Just now I updated the KICAD and Gerber files to the PCBWAY community site salient to the posts: go here.


The 9-29-24 experimenter's board uses less components, incorporates the encoder debounce library here, superceding the slightly less responsive CD4011 based hardware debouncing discussed here

All in all--if we can do something in software, do it in software, right?

For now it all works.

Thanks to Wendy and the gang and PCBWAY for patiently providing revised PCB's. You can help this blog by checking 'em out. 

9-29-24 revision

To make sure the grounding issues I saw with earlier revisions was a function the PCB's layout, not the schematic nor code, I breadboarded put the entire "dev board for a dev board":


The breadboard worked every time.

I thought trace layouts for low frequency audio wasn't terribly important--put things almost anywhere, thrown in whatever traces you want--it will work--we are the bottom feeders?

Wrong. Apparently the I2C traces (at the very least) needed to be treated with forethought. 

Previously: more narrow traces....no ground pour


9-29-24 design improves that. 

I found myself putting the 9-29-24 assembly on hold for a couple of weeks, partially because I was pretty tired of revising the board, and also having a feeling (an incorrect one, fortunately) that the 9-29-24 revisions would make things less reliable, not more.


Word of caution: 1306 128x64 .96 OLEDs are everywhere, but there appear to be 2 different pinouts coming from Shenzen: GND far left, and VCC far left.  

My design requires VCC on the far left--make sure you get that style of OLED if you build this project.

Spinning the rotary encoder advances or diminishes the counter on the OLED as expected. Every time. Thank goodness.  

Next: I have augment the code to create a user interface for the frequency counter....yes, I will get to that someday, but it means a lot of code changes.  

For now it's back to my day job--for better or worse the Pandemic is over.



Saturday, October 12, 2024

Building a Moog T904B Inspired High Pass Filter--Using an SMD hotplate--Works!

Readers: If you'd like to build the project featured in today's post, please go to PCBWAY's Community pages--gerber file (main board); gerber for jacks board, front panel gerber, KiCAD project/pcb/schematic/library files, a B.O.M. and more are here.  

You can also help out this site immensely by checking out PCBWAY using the link here. Thanks!

=====

This is a continuation of this previous post...where I laid out and built a Moog T904B HighPass Filter homage, based on a schematic from DIY pioneer Tom Gamble.  

Revision one's design/build attempt was disappointing, since it "worked" but sounded, well, terrible.

After rewatching the Kristian Blasol video (here) I wanted to keep working. The filter in his video sounds--interesting.  

Really interesting. Nasal, but also shimmery and a bit phase-shifty? 

To get my version of this filter off DogDoo Island I redesigned two of Revision 1's PCB's, improving ground planes; REV1's ground and audio traces looked terrible on my oscilloscope.

Good news: after building a REV2 Moog/EFM T904B, with PCB's provided by this blog's humble sponsor, PCBWAY, then spending an entire Sunday fixing stupid mistakes and experimenting with different component values, the Moog ladder highpass VCF sounds (I think)--much better. Maybe even good.

 I recall back in the day Mr. Gamble posting that his designs and kits were for experienced builders--something like that. In this case he was right! This HPF is a complex build, in terms of parts count, design complexity, and need for modification. This is not a good project for a beginner.  

AN ASIDE: WORDS FOR MY SPONSOR

Happiness is a new batch of boards from PCBWAY....

Shout out to Serene and the nice people at PCBWAY for sponsoring this blog. It sometimes takes me 2 or 3 revisions to get something to work; the T904B inspired HPF has been no exception. 

PCBWAY has always been patient, friendly and extremely supportive as I work through design changes. 

PCBWAY also has done great 3D printing for me and offers other useful services. They charge low prices and fabricate quickly. They are an asset to the DIY world; please help out this blog and check 'em out.

Back to the post....

SMOKING HOT


What fun would DiWHY be without trying new (for me) fabrication techniques?  

For the Moog/EFM T904B VCF build I purchased a $39 "Amazon's choice" 100mm x 100mm hotplate and $10 worth of solder paste.  

Links for the plate and paste (hope these links still work):

 TLZBK 350W soldering Station Hot Plate

Wonderway SN42 lead free no clean solder paste

I got building--gooped the paste, not being too neat about it;

 



 I used tweezers to put the 1206 SMD parts on top of the goop, then dropped it on the hotplate.

Note: if you want to try out this fabrication technique, work in a well-ventilated area. This hotplate/paste/SMD process produced a lot of toxic smoke; you shouldn't breathe its fumes.

Baked the jacks board....


Marvey--what temperature to use? 

This chart shows the heat curve one should follow--"IPC/JEDEC J-STD-020C--impressive?--but the plate only had set/enter switches for temperature; inputting complex functions for heating/cooling wasn't possible.


Instead, I decided to heat the damn thing up, and after the parts were put in place and the solder had melted, cool things back down. 

To my surprise this approach worked. At about 195C the parts magically centered themselves to solder pads and the solder flowed where it needed to go. 

After the parts set I let the plate continue to heat up to about 210C, then told the plate to climb back down to 100C, which it did, slowly.  

At about 150C I removed the PCB.

Visually inspecting: in spite of my heat curve being far from ideal, it worked! 


 

I was chicken at first to bake on an SOIC TL071, but successfully soldered 2x TL074's using the hotplate when I soldered the main PCB's SMD parts.

Overall, the process was far more forgiving than anticipated. There was a solder bridge on an SOIC TL074 that I fixed with solder wick, and one 1206 resistor baked on 90 degrees opposed to where it should have, which I corrected with a soldering iron and some tweezers. 

Otherwise--all good.

One byproduct--after the 1206 bake there was a lot of leftover flux on the PCB. I used "no clean"paste, meaning this leftover flux isn't conductive and can stay where it is, but I dislike spoojim all over my PCBs. I am still trying to figure out how to best clean the no clean: flux remover, isopropyl alcohol, and other attempts haven't worked...maybe I have to leave it.

Overall using the hot plate and paste was far easier and less time consuming than soldering 1206 SMD parts by hand, and I imagine with a solder mask difficult SMD parts (QFN's?) are doable for DiWHYers using this inexpensive setup.

I will keep working with this hot plate for upcoming posts.

HIGH PASS DRIFTER

OK, let's talk HP filter.

The original Moog patent design looks like this:




From this MW forum post  the EFM design resembles the Moog ladder filter patent...indeed:

Long Live Moog! Long live EFM! Interesting: this is a 24db/octave high pass filter, a lot of other popular audio HPF's are 12db/octave (the Oberheim SEM's for instance--a favorite); meaning the T403B can be driven to oscillate.


From here it was a VCF build like so many other VCF builds: design and revise PCB's with Kicad; send gerbers off to PCBWAY; solder SMD's first then add through-hole components...

As per a comment in the youtube video: I didn't have to match transistor Vbe's, so I didn't.

Before too long I had new PCB's, populated and ready to test.

Testing. I used an single 3mm nylon phillips screw, standoffs, and nut to secure the jacks and mainboard to each other.

Did it work first time (WFT)?  

Nope.

I spent a masochiastally joyful Sunday (all pain, all day long) troubleshooting the REV2 build. 

There were a few stupid build errors, the biggest: I put .22uF caps in the resonance feedback subcircuit, where .22pF should be used.  

I had a cold solder joint in the 100mil V-- trace between main and jacks board--that didn't help.

EFM mistake? The EFM schematic showed the main frequency cutoff pot with V++ (I used +12) Vdc on one side and ground on the other. Nope. It needed V+ on one side and V- on the other--this is corrected on the PCB's uploaded to the PCBWAY community site:


Otherwise the VCF cutoff required CV values below ground....doable, but not "normal" as I see things.

I found the EFM resistor values for CV mod didn't work for me; for my rack's 0-5V CV setup I used 20K's and B50K pots as in the snippet below.... 

 

Fortunately incorporating 1206 SMD resistors made trying different values for R1/R2 easy: using a 700F soldering iron with a sharply pointed tip I heated up both ends of the tiny resistors, removed them, and soldered in something different. This was faster and easier than working with through hole resistors and posed less danger of damaging traces when changing out components.

MODS AND SODS

Besides messing with resistor values I made two semi-major modifications to the EFM schematic:

First to the jacks board I added an output buffer:

R6 adjusts output--try between 10K and 100K to get the output level you want; I started with 10K (shown) for R6 but later changed it to 47K.
 
Second: I added an audio input attenuator to the jacks board: 

 
I added the latter ("ladder"?) because in this cool Youtube video the filter sounded slightly distorted at times.

Looking at the EFM schematic I thought that high peak to peak input signals saturated the first stage of the PNP/NPN/op amp trifecta--just a guess.

To my surprise the additional input attenuator didn't only let me dial in appropriate audio levels to remediate distortion, in some cases, the attenuator changed the character of the filter's resonance.  Unexpected, but I'll take it!
 
One more tidbit: I didn't have 220K 1206 resistors in my junk box, so on the main board I used 200K for R11 and 30K for R21. I am not sure how common 220K 1206 SMD resistors are at retailers like Tayda--whatever--some resistor values aren't critical--just get them close.

IMPROVED OUTRO

Anything Moog and EFM are cool right?  

Sure, but: this EFM Moog HPF isn't a module where every setting sounds great. In general I found I had to experiment--it's an odd beast--messing around is a big part of what we do, so this is a feature, not a bug? 

If I were to continue working on this filter--I probably don't have time--I'd add a resistor in series with the V++ feed to the cutoff1 pot (current "jacks board" has a resistor for V--, but not V++).  

Why: a lot of potentiometer real estate for the frequency cutoff above 2PM was useless--turn the frequency pot above 60-70% and the audio at output was gone.   

The modification to the cutoff pot should look something like this:



Update: modified! I cut the "3" leg to Cutoff1 on the jacks board and kludged in a 12K THT resistor between it and the V++ rail. Big help! If I do a REV3 of the jacks board I will include this modification.

Also: since this is a highpass filter, it might be useful to change one of the modulation inputs to invert the incoming CV signal and set its bias to somewhere above ground--2.5V perhaps. Even better: add a modulation attenuverter to get cool inverted highpass effects. 

Finally: would matching Vbe in the transistor pairs make this sound better?  A traditional LP Ladder filter doesn't have a buffer between each transitor pair, but this design does, so I am going to guess it doesn't need transistors to be matched. Just a guess. 

OK enough for now--this has been a maddingly fun project--to remain high, consider giving this filter a pass. Something like that. See ya next time.

Sunday, September 15, 2024

4 x 1 Mono Mixer--A Confidence Builder

Readers: If you'd like to build the project featured in today's post, please go to PCBWAY's Community pages--gerber file (main board); gerber for jacks board, front panel gerber, a 3D model of the dual pot (WRL and Freecad formats), KiCAD project/pcb/schematic/library files and a B.O.M. are here.  

You can also help out this site immensely by checking out PCBWAY using the link here. Thanks!

------

I've DIWHY'd many projects lately that don't work due to dumb mistakes and I thought, enough! I'm going to lay out and build something easy, useful and practical. 








Everyone needs more mixers right?

The "EZ MIX" was really easy; it took me an evening to lay out and about a half hour to build: a simple 4 input AC/DC unity gain active mixer in 6HP Eurorack format.





The star of the show: dual concentric pots; you get Eurorack's "fit every damn thing on the head of a pin" paradigm without needing extremely tiny hands to turn the knobs.

           

                              

I laid out a footprint for the concentric potentiometer in Kicad and 3D model in Freecad:  



                                                 

Piece of cake.

The project used 3 boards: front panel, jacks panel, and main PCB, centered around a single dual op amp IC.

Everything on the main board was through-hole; other than triple checking sizes, legends, and drills there wasn't a lot to go wrong. 

To remain old school: JST connectors were used between the main board and jacks board.

Main board

jacks board

Front panel....

Off it all went to this blog's honorable sponsor, PCBWAY....

Happiness: new boards from PCBWAY

Zoom, printed circuit boards were back, I gathered up parts from the junk box and got building.






I was fearful things wouldn't line up, thankfully they did....






Everything worked first time ("WFT")--pots went from no volume to full volume when turning them clockwise, audio signals got mixed, legends on the front panel were correct, and most all silkscreens on the boards were accurate.

One (big) mistake--the "Redstripe" (negative voltage) silkscreen callout was on the wrong end of the Euro power header. This silkscreen error was fixed on the 9-12-24 revision I uploaded to the PCBWAY community.

The only SMD part for the project: I added a 0 ohm 1206 resistor between Out1 and Out2. That way if I reused the 3.5mm jacks board in another project the 2 outputs could be independent of one another.  

But in the spirit of this build I soldered the 2 output wirepads together--who needs SMD?



 Finished!






So much fun I made two of them...

Overall, it was great to kick back and design then build something really easy. 

Getting stoopid from time to time is fun....but now it's back to debugging, dealing with cryptic IDE error messages, C++ that won't compile--all the usual things. I can't wait. 


Saturday, September 7, 2024

Understanding ARM Exceptions/Interrupts

Readers: For upcoming posts--low frequency counter, clock multiplication module, etc., I will dig deeply into ARM processor exceptions, a.k.a. "interrupts."

Exceptions can be complex in the ARM world, requiring mastery of hardware, peripherals, programming concepts, and baffling acronyms (e.g.: "ICSR","AIRCR" "NVIC" etc).

This post captures my lab notes surrounding ARM exceptions.

I will be updating/correcting/augmenting this post going forward as I work at the bench. 

Which means: this post is mostly for me--if you want to skip it, skip it. 

but! if you correct things via the comment section I would be grateful--help from experienced ARM developers is always apprecated. 

Thanks.



LINKS

Good web page for this: https://interrupt.memfault.com/blog/arm-cortex-m-exceptions-and-nvic

Video: https://www.youtube.com/watch?v=Uut2uIODlbQ&t=305s; sadly there is no source code linked--so, useful to RP2040 dev until about 8:00.

SysTick: https://www.youtube.com/watch?v=fMqCBMWZ0pk ARM Programming courses frequently use SysTick exception 15 to demostrate interrupts. SysTick is a relatively simple counter that can throw an exception over and over. The video explains how SysTick is implemented in an ARM core but does not provide code examples one can download.

C code example for Systick: https://users.ece.utexas.edu/~valvano/arm/SysTick.c.  SysTick code for PICO is here. Other forum posts indicate that the PICO SDK does not abstract SysTick functionality, hence, you have to set the registers directly:

#include <stdio.h> #include "pico/stdlib.h" #include "hardware/structs/systick.h" int main() { stdio_init_all(); systick_hw->csr = 0x5; systick_hw->rvr = 0x00FFFFFF;


PDF of the "generic Cortex Users' guide" is here--how an ARM Cortex M core works at a deep level. Section 2.3 covers a lot of what is in this post; section 4.1 covers peripherals such as NVIC (below). I find this PDF more useful than the web based version here.

---------

I hear ARM exceptions referred to as “interrupts” but in the ARM world interrupts are a type of exception.  

Exceptions have a unique number associated with them starting at 1 (not 0!)  

This number is then used as an offset in a vector table; at each offset is a memory address of a routine to be run.

A made-up example:

If the ARM core sees exception 1 run a routine beginning at 0x0002534

If the ARM core sees exception 2 run a routine beginning at 0x0002538

And so on.

Along with this unique number is “priority”.  The idea here: if 2 exceptions are recognized by the processor at the same time, which one gets handled first?  The lower the priority #, the higher the "precedence"—the processor handles the lower priority #’d exception first.

 

ISR

INTERRUPT SERVICE ROUTINE (ISR): the routine that is pointed to by the vector.   


STATES

Exceptions in the ARM world have "STATES":

Pending: the processor has seen the exception but hasn’t done anything yet. Important idea: for an exception to be recognized and eventually run, a 1 is put into a register to make the exception “pending”, then based on other factors the ARM core will process it. See REGISTER section below for details.

Active: the exception handler is running but isn’t finished yet.

Pending and active: the processor sees the same exception that it’s currently processing.

Inactive: an exception is neither pending nor active.

 

ARM EXCEPTIONS--"CORE INTERRUPTS"

These are exceptions hard coded into an ARM Cortex M core.  

Built in exceptions are used for housekeeping--you can’t change them.

The NVIC (below) peripheral is not used when processing these particular exceptions (note, is that right? I read different things about this, so I am not sure--are both core and non-core exceptions handled by the NVIC, or not? Does anyone know for sure?).

0 vector table points to reset value of stack pointer.

Reset: 1. The routine that is executed when the chip comes out of reset.

Non Maskable Interrupt or "NMI"--2: this exception cannot be disabled. It is fired when there is an error in another exception handler.  The vector points to a routine to run in this oh-shit scenario.

Hardfault: 3  Routine is run when there is a major fault: memory error, divide by 0, etc.

MemManage: 4

Busfault: 5

7-10 reserved

SVCALL: 11:  routine to handle calls to handle a service routine—for instance, a call to the OS to do something.

Debug monitor: 12

13 reserved

PendSV: 14

SysTick: 15. See below.


EXTERNAL or "NON-CORE EXCEPTIONS" 16+0 to 16+N 

These interrupts are defined by the SOC developer; they vary from chip to chip....

The Cortex M0+ (RP2040) has 32 non-core exceptions; other ARM chips can have more.

IRQ's are the external exception numbers minus 16, so exception 0x0F is IRQ 0x0, 0x10 is IRQ 0x1, etc. 

REGISTERS

Exception state is captured in registers located in the ARM System Control Space ("SCS")

Interrupt Control and State Register, ICSR

If you want to check up on what the processor is doing or is going to do exception-wise look at this register.  The active/inactive/pending/and "what exception is running now" is stored here.

Application Interrupt and reset Control Register (AIRCR)

used to further prioritize your exceptions.

Also--Writing a 1 to bit 2 fires a system reset.

System handler Priority Register:  SHPR1-3   

Used to set priorities of system faults.   You probably will never change this register.

Interrupt Controller Type Register (ICTR) - 

In cortex M0+ (RP2040) it's always set to all 1’s.  Don’t worry about this one.

 

NVIC REGISTERS

NVIC is a peripheral that handles manufacturer-specific exceptions; NVIC supports up to 496 exceptions; the Cortex M0/M0+ is limited to 32 external exceptions. 

Example: if your UART is throwing an exception when its buffer is full, it's utilizing the NVIC registers to inform the processor of this exception.

Interrupt Set-Enable (NVIC_ISER) and Clear-Enable (NVIC_ICER) Registers

  • NVIC_ISPR0-NVIC_ISPR15: << set pending
  • NVIC_ICPR0-NVIC_ICPR15:   << clear pending

Writing 1 to the correct register memory location will set or clear the pending state of the interrupt.  So—you can make an external interrupt pending, telling the processor to deal with it; or set an already pending to 0—telling the processor: nevermind. On Cortex M0+, this is the main way one sets external exceptions—drop bits into the above registers.

 These “Hello! CPU here: thanks for telling me about this exception, I will deal with this exception soon enough” situations are referred to as asynchronous exceptions.  

There are also synchronous exceptions (SVC is one, I read), but I am going to not worry about those right now.

 

Interrupt Active Bit Registers (NVIC_IABR)

Not implemented in M0 (RP2040).  Don’t worry about it.

 

Software Triggered Interrupt Register (STIR)  

Also not implemented on M0. Don’t worry about it.

 

Interrupt Priority Registers (NVIC_IPR): NVIC_IPR0-NVIC_IPR1-2-3:

Sets interrupt priority.

 

Software Triggered Interrupt Register (STIR)  

Also not implemented on M0. Don’t worry about it.

 

HOW ARM CHIPS DEAL WITH EXCEPTIONS FROM A C COMPILER STANDPOINT

The compiler is set up to conform to Arm Architecture Procedural Calling Standard (AAPCS).

It works like this (oversimplified?):

a)      An exception is called

b)      Caller register values are put on the stack

c)       $lr (link register) gets the EXC_RETURN value—where in the program to go after the exception is handled.

d)      After exception is handled the values are popped back off the stack, the program returns to $lr value and keeps executing. 

      This means the push and pop complexities associated with implementing an exception without clobbering the rest of your code is abstracted by the compiler. That's probably a good thing?

"TAIL CHAINING":

Say we are executing an ISR and another one comes in.  The processor will not redo the caller stack pushes and pulls, it will leave whatever is in the stack, in the stack. This can save CPU cycles.

Sunday, August 25, 2024

Debugging Raspberry Pi PICO with a Segger J-Link EDU Mini

In the previous post here I set up a $4 "Picoprobe" to debug RP2040 C/C++ code running on a PICO development board. 

This worked OK but I found it a bit unwieldy at times; the debugger was often physically larger than whatever I was debugging. 

Could I get a smaller debugger into play?

A tech friend told me about the "EDU" version of popular Segger J-LINK debuggers; I read online that Segger had made a "mini" version of it. 

Segger's J-LINK EDU MINI debugger. Yes, it's mini.



I emailed them; their sales team got back to me quickly. 

This is a USD $60 purchase for non-commercial use; even though it's for education ("EDU") you don't have to present a student ID. 

But you also can't make money off your code.....all audioDiWHY code is MIT open source so I figured: I qualified.

The Segger page here made me think the adapter would work for debugging RP2040's. For what this debugger can do and all the free Segger software it came with it seemed like a hell of a bargain. 

I bought one.

WIRING IT UP

It's tiny! Its JTAG/SWD interface uses 2x5 pin 50 mil pin headers--1.27mm --extremely small--conforming to the "Coresight 10" JTAG pin specification.

The unit comes with a 10 pin to 10 pin IDC ribbon which won't work with the PICO; the PICO has SWD pins that are 100mils apart. 

I had a JTAG 50 mil to dupont breakout I got with my Atmel Ice programmer; this breakout was unused, so I employed that; you will need something similar, try the link here.

OK, time to wire it up. I had to dig around on the Internet re: how to connect the EDU mini to a Pico Dev board and eventually figured it out:

 An SWD breakout is coming soon from this blog's helpful sponsor: PCBWAY.

I wired it up on a breadboard:


Unexpected:  "pro" Segger J-Links have a 5V output for powering your development board, but the EDU mini requires a 5V reference and cannot source 5V.

So: I used a bench 5V power supply for this.

It was time to check my wiring. On my windows system I installed the Segger tools (here) and ran their Commander utility  to verify all the wiring was sound--it was.

DEBUG SOFTWARE

From the previous RP2040 debugger post I knew I needed a version of GDB for the Segger J-link, since GDP for embedded seems to be hardware dependent; fortunately Segger's GDB was available as a free download; here.

OK, the next problem: how to set up this modified debug toolchain without going crazy. 

After some research: I would continue to use Ubuntu VSCODE (as opposed to a different IDE) as the path of least resistance.

Note:The previous post on the initial Ubuntu/VSCODE toolchain setup is here. If you are setting up Segger/GDB/VSCODE for RP2040 "from scratch" you may want to read it or find advice elsewhere on the Internet.....you will need the same extensions for VSCODE installed for the Segger debugger to work as PicoProbe: C/C++ and Marus25's Cortex Debug, along with the arm-non-eabi compiler and so on.

I installed Segger's GDB code on Linux (I use an Ubuntu virtual machine) which ended up in /opt/SEGGER.

Now came the tricky part: getting VSCODE's dreaded launch.json file configured use Seggar's version of GDB.

Here is the launch.json I ended up using; this got copied into my project folder's .vscode folder after renaming the existing picoprobe launch.json file to launch.json.old.

{

"version": "0.2.0",

    "showDevDebugOutput": "raw",

    "configurations": [

     {

        "name": "J-Link",

        "cwd": "${workspaceRoot}",

        //"gdbPath": "gdb-multiarch",

        "gdbPath" : "/usr/bin/arm-none-eabi-gdb",

        "executable": "${command:cmake.launchTargetPath}",

        "servertype": "jlink",

        "serverpath": "/opt/SEGGER/JLink/JLinkGDBServer",

        "armToolchainPath": "/usr/bin/",

        "request": "launch",

        "type": "cortex-debug",

        "interface": "swd",

        "serialNumber": "801056408", //yours won't be

        "device": "RP2040_M0_0",

        "svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",

        "postRestartCommands": [

          "break main",

          "continue"

        ]

      }

    ]    

}

In VSCODE, on the bottom right, I had to set the file type for launch.json from "commented JSON" to
"plain text"....then throw away the previous build file and finally, recompile my stupid blink main.c and push the UF2 file to the Pico.

It worked! 

With this new debugger in play: I can see registry contents, set breakpoints, watch variables, all the usual debug stuff, without having to leave VSCODE. 

And--I got it to work in about 4 hours, start to finish, on single Sunday--surprising even myself. 

SIDENOTE: RTT ADD-IN--FAST PRINTF()

GDB is cool, but arguably nothing in the debug world is easier and cheatee-er than a C printf() statement to reveal a variable value or whatever.

Come on, we all do it right?

Problem with printf(), the version in the RP2040 stdlib anyway: it's pretty MPU hungry and can jam up other I/O while sending strings to the terminal.

SEGGER provides a freely available, more efficient printf() algorithm that's easy to throw into your project. 

Here's how I set that up:

  • Downloaded the tools for debian from the "J-Link Software and Documentation Pack", here
  • Right clicked on the .deb file, said "use other software" and ran the .deb installer.
  • The files I needed got installed in /opt/SEGGER.
  • Gunzipped/unpacked the files in /opt/SEGGER/JLink_[version]/Samples/RTT;
  • I needed SEGGER_RTT.c, SEGGER_RTT.h, SEGGER_RTT_Conf.h, and SEGGER_RTT_printf.c....
  • I copied those files into my RP2040 project.

Next I modified CMakeLists.txt and .c files to get the RTT printf() statement to work. 

Please go to Github (here) and look at the example/proof of concept files, including an example CMakeLists.txt; I think you will find it pretty easy to get an RTT printf() statements into your projects once you see the examples....in the repo--main() is in the file blinkcl.c....

OK with the sample code loaded into a Raspberry Pi Pico:

  •  I hooked up the J-Link Debugger using the wiring diagram above.
  • Went back back to opt/SEGGER and opened JLinkRTTViewerExe:


With the RTT viewer open I needed to connect the RP2040, so I went to to file > connect and clicked the three dots (...)


 and choose the RP2040 Core 0 from the drop down, finally, clicked OK.


When I powered up the PICO the RTT print statements showed up in the RTT viewer:


RTT has a bunch of other cool features--printf() is only a small part of what it can do--more information here.

OUTTRO

Overall this was a good addition to my bench. Getting it going was much smoother sailing than other debug setups to date. 

For $60 the Segger J-Link EU MINI will become an oft-used tool on my bench. 

In future posts I will build/post a simple JTAG to SWD breakout board, which will hopefully make quick set up of this or other SWD debuggers.  Until then: don't breathe the fumes.







Rotary Encoder Expermenter's Board: Improving the Hardware

Quick one this time....I have posted a few projects lately that incorporated a Raspberry Pi Pico, rotary encoder, and .96" OLED:  here ...