Axoloti as a 5U Module


#11

ok, i will try and see what it sounds like :slight_smile: i will of course share if it works out ok...


#12

Out of curiosity, did you do this on perf or get a board printed? I'm always keen to see people's layouts.


#13

I've etched the PCB myself...
But I did some mistakes in the original design, so I had to correct them cutting some traces and adding some flying wires, that's why I'm not sharing the PCB layout.
I've corrected the schematic (the one I shared is corrected), but dind't have the time to correct the PCB layout...


#14

Fair enough. :slight_smile:

I'm working on a Eurorack perfboard layout for a very similar setup, challenging since I want to fit it in sparse skiff space. Might just bite the bullet and have it manufactured, no room here for etching or milling a board.


#15

Yes, Euro is too small, you have to go for SMD to get a small module.
Mine is all tru hole and the PCB is big (something like 200mm x 75mm).
I could share the .sch file if that makes your work easier, but as I said is all tru hole.


#16

Thanks, but I have what I think are pretty robust schematics for mine, it's just board layout that's challenging. For certain I would go SMD for most components if I were to get a board or two printed, prefer that way of working already, or should I say debugging.


#17

hmm, i'm getting also heavy aliased results. i scaled and offset the audio to be only positive, but a sine above 600hz still sounds rubbish :frowning:
@johannes, can we make the pwm out's cheap audio outputs? how would one write at audio rate to the pwm pin?

this would be just so cool for dirty 8-bit stuff, and you would not even use up an audio out.


#18

i found this entry on GitHub, it is a little confusing (i guess the comments were not changed to reflect the actual numbers...

// generate 8MHz clock on MCK pin with PWM...

static const PWMConfig pwmcfg = {168000000, /* 400kHz PWM clock frequency. */
21, /* PWM period is 128 cycles. */
NULL, { {PWM_OUTPUT_ACTIVE_HIGH, NULL}, {
PWM_OUTPUT_ACTIVE_HIGH, NULL},
{PWM_OUTPUT_ACTIVE_HIGH, NULL}, {
PWM_OUTPUT_ACTIVE_HIGH, NULL}},
/* HW dependent part.*/
0,
0};

but there is an additional zero at the end, hmm...


#19

I think that isn't the problem... As I said, the PWM is working well, I can measure the 41KHz a the GPIO output, the problem is how the object handles the audio, and how modulates the PWM signal...
My guess is the object is coded to work at krate, so even I converted one of the inputs to srate the audio is still prcessed at krate... But I don't know how to change that...


#20

here is what i tried. (i changed the bit shifts as well, to accommodate for 8bits instead of 12 and the greater range of s-rate signals)

pwmtry.axp (3.7 KB)


#21

maybe our math is wrong. in the example above @johannes uses 168000000 and 21 which divided by each other gives him the 8mhz. so the second number is maybe not the pwm period? since he writes it is 128 cycles.

on what do you base your math?


#22

i also tried to put the stuff in a loop like this (in k-rate):

int j;
for(j=0;j<BUFSIZE;j++){
pwmEnableChannel(&PWMD3, 0, (pwmcnt_t)(inlet_pa6[j]>=0?inlet_pa6[j]>>23:0));
pwmEnableChannel(&PWMD3, 1, (pwmcnt_t)(inlet_pa7[j]>=0?inlet_pa7[j]>>23:0));
pwmEnableChannel(&PWMD3, 2, (pwmcnt_t)(inlet_pb0[j]>=0?inlet_pb0[j]>>23:0));
pwmEnableChannel(&PWMD3, 3, (pwmcnt_t)(inlet_pb1[j]>=0?inlet_pb1[j]>>23:0));
}

but i get the same aliasing. i think we are doing something wrong with the period setting. because as i said, in johannes code example he uses 21 to get 127 steps...


#23

(about the potential of hacking extra audio outputs without extra hardware...)

Looping over the BUFSIZE will not schedule the pwm duty cycle changes on corresponding sample-interval timing.

In Axoloti firmware, there is no code that is scheduled synchronously with the audio sample clock, only at 16-sample buffers, and it is the responsibility of the DMA engine and I2S (SAI) peripheral to transmit the audio data to the audio converter, synchronously to the sample clock.

In order to make PWM duty cycle changes synchronously to the audio sample clock, one approach is to enable an interrupt (an EXTI interrupt on PE4 or PI11 should work as interrupt source).
In the interrupt service routine, read the next sample value from a (double) buffer and set the pwm duty cycle. This requires firmware hacking! An object could then write audio data in that double buffer.
A better (more acceptable) solution would be to set up a DMA stream to the timer, that avoids interrupts consuming precious time. But I'm afraid there is no suitable DMA channel left, or no suitable source to synchronize DMA.

Rather than using PWM out for lofi audio, I'd suggest to use the on-chip DACs. Same story, gpio/out/analog only schedules at k-rate, looping it does not make it schedule at audio-rate. The bad solution: write the DAC register from within an audio-rate interrupt. The good solution: configure conversions to be triggered by the audio clock (refer to chapter "14.3.6 DAC trigger selection" in stmicro's RM0090 reference manual, and use DMA to copy data to the DAC. The only DMA streams that can be mapped to DAC1 and DAC2 are DMA1stream5 and DMA1stream6 (according to chapter "10.3.3 Channel selection" in RM0090), while those are already assigned to I2C on user-gpio pins. So since DMA is not available, need to use interrupts to copy data to the DAC's.

In summary, quite an effort and the result will still have significant side effects. And I fear the audio quality would still be disappointing.


#24

thanks for the in-depth answer. "disappointing" audio quality as in 8-bit pwm would be the point of the idea :slight_smile: at least for me. i like it very much for aggressive bass sounds.

if there is ever time to make such a hack in the firmware, that would be much appreciated, but this is clearly out of my reach for now.


#25

@johannes Thanks for the answer. I suspected it wasn't easy :slight_smile:

By the way I'm doing another strange thing that almost works OK. I'm using a digital output as a Square/PWM oscillator by sending the output of a PWM oscillator objet to PC0. I get about 3 octaves of an usable Square/PWM signal. It's a bit unstable, but it works (I'm using it as second VCO in companion of my Yusynth VCO).
Is there a (easy) way to improve stability and octave range, or it's a case like the audio to PWM out.
Thanks


PWM on non-PWM digital outputs experiment
#26

Oh if you want a PWM square wave on an extra output...
you could probably tune PWM outputs to an audio frequency and use them as true PWM DCO's.
The disadvantage is that the audio output will only be available on corresponding gpio pins, not as an outlet in a patch.

This wouldn't be quite as complicated in coding as adding a lofi pwm dac output.

If you can make sense of the chapters about the timers in the RM0090 reference manual.
You can access for instance the TIM8_CR1 register as TIM8->CR1 in init or k-rate-code.

Please do not use any other timer than TIM3, TIM4, TIM5 and TIM8 if possible.

Should be fun for modularists: 4 extra DCO's. Additionally there might also be a way to hard-sync one DCO to another cfr. chapter "18.3.14 Timers and external trigger synchronization" in RM0090.


#27

Thanks @johannes!!!
I think that the necesary coding skills are way over my capabilty (right now), but is good to know it could be done :slight_smile:


#28

Awesome project, great work! Thanks also for sharing implementation details and schematics :smiley:


#29

Look amazing, thanks for sharing.

I'm doing a similar thing with a banana synth I'm building. For my CV inputs, I'm thinking of doing it a little differently, by adding the potentiometers as separate ADC in's on the axoloi. That way I can scale the CV input in software or programs the pot's for different functions.

For the analog audio input, do you attenuate it?
For the analog audio output, I think you have a 4x gain. Does that give you approximately +/- 5v levels on the out?


#30

For the audio output I measured 2.3Vpp at the Axoloti output, so I used a gain of 4.3 so at the module output I have 9.89Vpp (almost +/- 5V).

For the input I measured a max of 4Vpp before saturation, so I attenuated the input by 2/5. I used a pasive resistor divider with a 68K and a 47K resistors, that gives me an attenuation of 0.408 and an input impedance of 115K.
Is not in the schematics because I mounted the resistors in a small perfboard near the jacks...