| 
  • If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • You already know Dokkio is an AI-powered assistant to organize & manage your digital files & messages. Very soon, Dokkio will support Outlook as well as One Drive. Check it out today!

View
 

Software Unit Tests

Page history last edited by james.susinno@... 5 years, 2 months ago

Software Unit Tests

 

Small tests of individual features of the Saucer Platform mentioned in Software Integration. Each demonstrates a single feature.

 


 

Basic Tests(Primitives)

 

DacWrite

This is an important test for any output chip: we need a baseline audio output signal, on any pin you can get it.

There are 3 different examples, each at a different level of the API. analogRead(), from 1, calls dac_write_value() at level 2, which calls HAL_DAC_* at 3.

For the extra setup code using HAL_DAC directly, you get a 10x speedup on the Nucleo 476 and 432! (More accurately, you get a 10x slowdown if you do it the other way).

A uint8_t wraps around to create a sawtooth waveform.

Observed period ~= 200us / 256 = .78ns           Freq=1.2 MHz

              

            L476RG Channel 1                                             L476RG Channel 2                                    ~2-4 us settling time(full range)

 

TimerInterrupt

This test will determine if we can stay in tune. Get a regular callback function firing, toggling the state of a pin each time. measure output frequency against expected for a range of frequency values.

 

AnalogRead

Read as many values from the ADC at once as possible. Output values over serial connection.

TODO: see if we get any benefit from channel setup and pin positioning.

 

DigitalRead

Read as many digital values as possible. Output values over serial connection.

TODO: multiplexing scan matrix logic, n-key rollover, etc.


 

Integration Tests

 

 

Level 1

 

Tone440

DacWrite + TimerInterrupt

Output an audible 440Hz tone to any available pin. Simple square wave output will suffice to demonstrate if the instrument can stay in tune. Sine wave is nicer.

PWM is a decent standin for platforms without a DAC.

TODO: What will it sound like if the chip can't keep up as programmed with the sample rate? High harmonics?

 

 

Combined Input

DigitalRead + AnalogRead

Read as many digital and analog inputs as possible, simultaneously. See which pins conflict. Rearrange pins for maximum input channels on the board.


 

Level 2

 

Simple Synth

DigitalRead + Tone440

Instrument01  https://bitbucket.org/DIY_Instruments/electric_eel_markii/src/master/arduino/stm32duino/Instrument01/

Read as many digital pins as possible, each one triggering a note of a different frequency. Makes a great wiring test!

Instrument02  https://bitbucket.org/DIY_Instruments/electric_eel_markii/src/master/arduino/stm32duino/Instrument02/

A basic monophonic instrument implementation, choose between voices, pick note and fret keys.

Instrument_BlueDog  https://bitbucket.org/DIY_Instruments/electric_eel_markii/src/master/arduino/stm32duino/Instrument_BlueDog2/

The Blue Dog, still under development. Pulls off 4-voice Karplus-Strong polyphony on a 432KC.

 

PitchKnob

AnalogRead + Tone440

Source: https://bitbucket.org/DIY_Instruments/electric_eel_markii/src/master/arduino/stm32duino/PitchKnob/PitchKnob.ino

Read one analog pin, altering the 440Hz frequency of the output.

Discovery: the arduino function analogRead initializes and tears down the ADC channel every read! This is so inefficient that the naive implementation of this test has visible plateau artifacts in the output waveform.

Using a more efficient analog read function that initializes only once, preliminary results are captured on pin PB_0(Channel 15):

 

L476RG Result: Each analog read adds ~100us read/polling time.

      0 reads                                                  1 read                                        2 reads                                        3 reads

TODO Read analogs non-blocking, or overlapped

 

Optimizations

 

Short-term, high-value things :

  • let's background the process.  basically, we poll in software, but don't block.  when conversion is complete, we configure for the next channel.
  • Let's shorten the SAMPLETIME for the ADCs.  we can check the ref to see the smallest possible value.  (we should make sure short sample times don't create too much noise).

 

Longer term, heavier lifting, perfectionist stuff

  • Optional: configure multiple ADCs to do conversions for us.  This is a good way to go for combining fast reads with slow ones.  e.g. knobs can be done at 100-3000Hz. 
  • We can set up the hardware to do that backgrounding for us.  SQR_ register

 

 

Jan 11, 2018:

Some googling on the topic discovered these threads:

https://stackoverflow.com/questions/42790936/stm32-adc-continuous-conv-mode-does-not-automatically-start-conversion

https://visualgdb.com/tutorials/arm/stm32/adc/

https://electronics.stackexchange.com/questions/202938/stm32-adc-conversion-using-hal/202952#202952

https://community.st.com/s/question/0D50X00009XkYVXSA3/stm32-adc-and-continuous-conversion-mode

 

Changing the flag to EOC_SEQ_CONV did not have the desired effect, however.

We should be able to call HAL_ADC_Start just once, and poll and read repeatedly after that. When attempting to do so, no data is read(wave does not change frequency).

The hardware must be fine - as repeatedly initing, reading and destroying works.

 


 

Level 3

 

SensorSynth

SimpleSynth + PitchKnob

With a few responsive analog sensors, an instrument can be made. Any leftover resources the chip/platform has at this point can be devoted to software synthesis.

 


Power-on to audio time delay test.

9/25/2018

HW: STM32L476 Nucleo

SW: Tone440, based on analogWrite()

Result: 100ms from power-on to sinusoid.

Discussion: Far too slow for Electric Eels.  Possibly limited by "analogWrite()"?  But more likely in setup

 

SW: Instrument01, based on writeDacData() / HAL_DAC_SetValue()

Result: 100ms from power-on to sinusoid

Discussion: Possibly setupDac() which calls:

HAL_DAC_DeInit()

HAL_DAC_Init()

HAL_DAC_ConfigChannel()

HAL_DAC_SetValue()

HAL_DAC_Start()

 

Experiment: instrumented Instrument01/setupDac() with digitalWrite(debugTimingPin, *) calls.

All six calls within setupDac took place within 75us!  That's fast enough...

First call took place approximately 5ms after turn on.  That's not quite fast enough.

Questions:

1. What is happening in first 5ms?

     Only call is to FireCbAtFrequency(), which does make calls to TimerPulseInit() and TimerHandleInit

2. What happens in 95 ms following setupDac()?!

    Main calls are to digital_io_init().  Where is that function?  What does it do?

 

Also Observed:  startup time is much faster when USB cable is plugged into board, even though external battery power is used!  ???

 


Control Timing Test

The latest Instrument01 has debug timing outputs on pins 2 and 3 to show timing. With audio rate at 60kHz, the board is freezing on certain instruments.

 

       

Some instruments take more control time than others.

 

Questions:

  • Why is the board becoming unresponsive?
  • Is there a way we can lay out computation for better response time?
  • What's is the optimal audio rate? How high can we push that?
  • Will we get better performance from fixed point math?

Comments (0)

You don't have permission to comment on this page.