Hardware Hacking with FXCore!

Post Reply
DisasterArea
Posts: 26
Joined: Sat Jul 25, 2020 7:07 pm

Hardware Hacking with FXCore!

Post by DisasterArea »

The thing that always bugged me about the FV-1 DSP was its limited hardware control options. Three analog inputs for pots and three address lines to select 1 of 8 algorithms, and that's it!

FXCore has a lot more hardware options, which allows designers to create effects with up to six knobs, five switches, built-in tap tempo, and software-controlled LEDs.

In this thread, I'll cover some of the cool tricks you can use to get even more power out of your FXCore designs.
DisasterArea
Posts: 26
Joined: Sat Jul 25, 2020 7:07 pm

Re: Hardware Hacking with FXCore!

Post by DisasterArea »

Hardware Hacking pt. 1 - Adding Pots

What is a "pot input," anyway? It's a pin on your FXCore that reads in a DC voltage and then allows you to read that voltage in your code. On FXCore, we generally use a potentiometer (aka "pot") connected as a voltage divider between 3.3V and GND, and the connect the wiper of the pot to the pot pin on the DSP. As you turn the pot, the voltage on the pot pin will vary between 0 and 3.3V, and then we can use that to control stuff in our program.

Image

Note the use of a 100nF (0,1uF) capacitor between the wiper and ground - this helps to keep noise out of the pot analog to digital converters.

You can connect up to six pots to your FXCore, which gets you a lot of control! If you're making a delay effect, you could have pots for delay time, repeats, mix, modulation rate, modulation depth, and delay tone. That would certainly be a nice complement of controls, but what if you also wanted to allow the user to select tap tempo subdivisions or modulation wave shape? You could use the switch inputs, but you'll soon run out of switches. Five switch inputs would let you have two switches for the tempo division (four options) and three for the modulation (eight options.) That works great but now you'll need to have some way for the user to select from those options, whether that's a rotary switch or encoder it'll be more expensive than a pot!

So we want to add a couple more pots to our design, how would we go about it? The Rotary + Reverb example has a very cool method of doubling up on the pots by checking the position of a switch. When the switch is moved one way, the pots control the Rotary effect, and the other way they control the Reverb. We're going to use that same idea but actually adding extra physical pots.

The first thing we need to do is add a little bit of hardware. We're going to get an "analog multiplexer" IC, such as a 74HC4053. These are designed to switch between variable voltage signals when controlled by an external logic signal. They're super cheap, too, well under US$1 in quantities.

Here's a typical application schematic combining two physical pots into a single pot pin on FXCore:

Image

The 74HC4053 has three pairs of inputs, so you can multiplex six physical pots into three inputs on your FXCore. If you wanted to have a full twelve physical pots, you could use two '4053s, total cost about $0.75 plus the cost of your extra pots.

NOTE we have connected USROUT0 to the 74HC4053 "A" port! That's how we will control the multiplexer. If you are using the other ports on the '4053, connect USROUT0 to the "B" and / or "C" ports as well. And if you're using two '4053s to get 12 pots total, just connect all of the ABC pins together to USROUT0. Also not shown but you'll need to connect the VSS pin of the '4053 to 3.3V and the VEE + GND pins to ground.

Now that you've got the hardware set up, we'll need to write a bit of software to make it go.

This code is untested but should work fine. If you build this setup and this code doesn't function as intended please let me know.

Code: Select all

; Multiplexed Pot Hardware Test
; uses 74HC4053 to combine two physical pots to one FXCore pot pin

.rn	potA	mr0
.rn	potB	mr1

.rn	potAFil mr2
.rn	potBFil mr3

.rn	ledflag r0
.rn	temp r14
.rn	temp2 r15

.equ	ledflag 0x0001	; set initial value for LED flag
.equ	kpotA	0.01	; smoothing for pot A, make this value smaller if it's jumpy
.equ	kpotB 0.01	; smoothing for pot B


// get sample counter
cpy_cs	acc32, samplecnt
andi	acc32, 0x0400		; flip the bit every 1024 samples, approx. 46Hz at 48Khz sampling
jnz	acc32, doLED

andi	ledflag, 0x0001	; is flag 0x0001?
jz	acc32, setFlag	; if no, then set it to 0x0001
xor	acc32, acc32	; if the flag is 1 set it to zero
cpy_cc	ledflag, acc32
jmp	doLED

setFlag:
xor	acc32, acc32
ori	acc32, 0x0001	; set teh flag ot 0x0001
cpy_cc	ledFlag, acc32

doLED:
set       user0|0, ledflag  ; set the usr0 output per the acc32 LSB

readPot:
cpy_cs	temp, pot0	; don't use the smoothed pot
jz	ledflag, storePotA	; if the LED flag is zero then we just read pot A, skip out
cpy_mc	potB, temp	; if it is one then we just read pot B, store it
jmp	doFilter	; and skip out to filter

storePotA:
cpy_mc	potA, temp	; store temp in potA mreg

doFilter:
; filter A
cpy_cm	temp2, potA	; get pot value
cpy_cm	temp, potAFil	; get old filter value
subs	temp2, temp	; lp filter so: acc32 = input - lp
multri	acc32, kpotA	; acc32*K2
adds	acc32, temp	; acc32+lp
cpy_mc	potAFil, acc32	; write back to lp

; filter B
cpy_cm	temp2, potB	; get pot value
cpy_cm	temp, potBFil	; get old filter value
subs	temp2, temp	; lp filter so: acc32 = input - lp
multri	acc32, kpotB	; acc32*K2
adds	acc32, temp	; acc32+lp
cpy_mc	potBFil, acc32	; write back to lp

; just here for testing
cpy_cs	temp, in0	; get input
cpy_cm	acc32, potAFil	; get filtered pot A
multrr	acc32, temp	; use potA as volume
cpy_sc	out0, acc32	; output to L channel
cpy_cm	acc32, potBFil	; get filtered pot B
multrr	acc32, temp	; use potB as volume
cpy_sc	out1, acc32	; output to R channel

; done

And tha'ts it. Control the multiplexer, read the values, filter, it's pretty simple if you're willing to do the work.

Next up we'll cover using FXCore to control external bypass hardware, as well as how to handle bypassing in software.
Last edited by DisasterArea on Sun Oct 02, 2022 5:55 am, edited 3 times in total.
DisasterArea
Posts: 26
Joined: Sat Jul 25, 2020 7:07 pm

Re: Hardware Hacking with FXCore!

Post by DisasterArea »

Hardware Hacking pt. 2 - External Bypass Switching

Effects are great, but sometimes you want (or need) to turn the thing off. FXCore has a built-in bypass switch using pin 24, hold it low to bypass or leave it floating to enable. When FXCore is in "bypass" the chip connects SDI0 to SDO0 and SDI1 to SDO1 internally, missing out all the processing happening in the core. The core still runs, so anything you have in the delay memory, reverbs, LFOs, tap LEDs, whatever all works fine. And whilst this works great for disabling the effects processing, your audio is still running in and out through the codec. If you want to bypass the codec and implement a true-bypass or buffered-bypass scheme you'll need to do some hardware hacking.

The simplest method is of course to use a 3PDT switch to disconnect the effect input and output. This is such a common practice that I won't bother to detail it here, there are hundreds of other places to find out about true bypass with a 3PDT. A single 3PDT can do true bypass for one audio channel + control a single or bi-colour LED. If you want to bypass stereo audio you'll need a minimum of a 4PDT and you might have some issues with your LED as there won't be a pole on the switch available to manage it.

The FXCore can help you here: It has a bunch of switch inputs that we can access externally, so we'll use one of those instead of the bypass pin. FXCore doesn't actually know what the bypass pin is doing, it's on more of a hardware level and can't be read by our program.

We'll use a normally-open momentary footswitch for our bypass switch, these are available from most pedal parts vendors. Look for something sold as a tap tempo switch and you should be good.

Connect the switch between pin 12 (SW0) and ground, polarity doesn't matter.

Then use this code:

Code: Select all

; use SW0 for bypass reading

.rn	byp	r0

; read in the button and change LED if it has been pressed

cpy_cs	acc32, SWITCH	; read in the switch register, which is an SFR
andi	acc32, SW0PE	; filter for tap press event
jz	acc32, nochange	; if not pressed, don't change
inv	byp		; invert the flag
cpy_cc	byp, acc32	; and store new value

nochange:
set	user0|0, byp	; set the usr1 output per the acc32 LSB
FXCore does the work of debouncing the switch for you, you can use the SW0PE bit of the SWITCH SFR which will be a 1 for one sample after the switch is pressed. If SW0PE is a one, you flip the "byp" register and then you can flip the user output. If you're running this code on the dev board, the User0 LED will light up each time you flip SW0 from 1 to 0.

Now that we have our control output, we can connect it to our hardware. I've set out three options for doing the bypass.

First, we can use an analog multiplexor, in this case a TMUX4053 (inexpensive but not yet available in Q4 2022) or a DG4053 (more expensive but widely available.) We can't use a garden variety 74HC4053 because it needs a higher voltage level to switch than the FXCore can provide.

Connect the mux to 9V and 0V as shown in the schematic, then use 1M resistors to bias up all the inputs to half the supply voltage (labeled Vb on the schematic.) This will ensure that the inputs can swing both positive and negative, and the 2.2uF caps block that DC from getting into the rest of your circuit. You can use this on its own as a bypass for a single channel, or it also works great following a buffer if you want to do buffered bypass.

Connect USROUT_0 (FXCore pin 18) to the A B C control inputs, and you've got yourself a software-controlled DPDT switch plus an extra pole to control an LED. Expand to stereo by adding a second mux chip, you can connect its control inputs to the same user output pin.

Image

That's not quite true-bypass, though, since your signal is always going through some circuitry, and the mux has a slightly lower input impedance than you might want - when you're bypassed it's about 300k ohms (1M || 1M || 1M.) So we can use a relay, which is essentially a remote-controlled switch. A non-latching relay is simplest to interface, we can use a MOSFET to energize its magnetic coil. The max current for the user outputs is 10mA, so they should be able to drive both an LED and the MOSFET gate as shown in the next schematic. The diode shown is 100% necessary, it acts to suppress the spike the relay coil generates when switching.

Image

You can easily expand this to a stereo setup by adding another MOSFET and relay. You can connect it to the same output pin, the gate consumes basically zero current.
This will work really well, but the relay will consume some current when it's switched on. FXCore plus a codec will already be pretty thirsty, so it's up to you whether 20-40mA more current is a good idea on your product.

Thankfully, the relay industry solved that problem about a hundred years ago with the "latching relay." These relays use a magnetic catch inside to keep the contacts in one position even without any coil current flowing. We're going to use a single-coil latching relay, and we'll use a slick trick to make it go.

Image

The relay stuff is all the same as before for the audio portion of our signal, but the drive circuit is quite a bit different. We'll use a hex inverter (about 30 cents) to charge up the 47uF cap in series with the relay coil. The inverter will pull its output high, and then the cap will charge up to 5V (you can also connect this to 3.3v, just match whatever your relay coil is rated for.) When the cap gets to 5V the relay coil will flip the latch and the relay will change states. The capacitor will then block any more current from flowing, so the coil current goes down to basically zero. Both sides of the capacitor will be sitting at 5V.

When we need to turn off the effect, we turn off the user 0 output, which gets inverted (2x, two negatives make a positive) and the inverter output will pull down to ground. At this point, the right side of the cap is still at 5V but now the left side is at 0V, so the relay coil sees its polarity reverse and will switch. No more current will flow into the capacitor since the output is at 0V, so the whole thing only uses power to charge up the cap and switch the relay into the "on" state. The diodes allow for current spikes to be sent to the supply rail and not break our delicate circuits.

Expand to stereo by adding another relay, the inverter package has six gates so you can use the two unused parts to drive it. We're using two gates to drive the LED here since they're basically free. I've shown the cap here as an electrolytic, but you might want to use a bipolar cap. It won't hurt anything.

More information about using a latching relay with a non-latching control signal here: https://www.te.com/commerce/DocumentDel ... DocLang=EN

There are other ways to handle bypass, which we'll cover in a later post. As always, questions and comments are welcome.
Last edited by DisasterArea on Fri Oct 07, 2022 12:44 pm, edited 1 time in total.
DisasterArea
Posts: 26
Joined: Sat Jul 25, 2020 7:07 pm

Re: Hardware Hacking with FXCore!

Post by DisasterArea »

[reserved]
DisasterArea
Posts: 26
Joined: Sat Jul 25, 2020 7:07 pm

Re: Hardware Hacking with FXCore!

Post by DisasterArea »

[reserved]
stanleyfx
Posts: 42
Joined: Fri Jan 27, 2017 2:19 pm

Re: Hardware Hacking with FXCore!

Post by stanleyfx »

Nice idea to use the 4053 multipexer to allow more physical pots within the FXC pot multiplexing.
Mick (Blue Nebula Design team)
PhilHaw
Posts: 65
Joined: Thu Mar 07, 2019 5:37 pm

Re: Hardware Hacking with FXCore!

Post by PhilHaw »

Excellent idea Matthew - food for thought!
Philip Hawthorne

Blue Nebula Development Team
Post Reply