My Beep-BRRR notes

New 2Apr2021. Updated 14Sep2021. It concerns use of the round XMOS microphone array board, with code in xC. This is not in group Technology yet, but it is in Just started refs. [[TODO]]

Background

Icon download: PDF

Beep-BRRR is supposed to listen to alarm sounds of any kind and then vibrate into a bed’s structure to wake a sleeping person. A sleep that might not, due to some degree of hearing loss, have been interrupted without this remedy.

Thanks, Kenny in Scotland, for suggesting it to be three R’s in the BRRR, so that the English reader sees that all those R’s are rolling. Or feels them in the body. .

Yes, I know that there exist a lot of boxes that would do this. May plan was to let go with one.

Intro

Apart from the real intro (discovering the need) this started with me asking some xCORE Microphone Array board questions on the XCore Exchange Forum. I then bought two boards DEV KIT FOR MICROPHONE ARRAY of type XK-USB-MIC-UF216 from XMOS. Let’s just call it MIC_ARRAY.

Now I’ve made a box for one of them and mounted it on my desk. The other board will, if I succeed, end up at a bedside table, inside a wooden box. I have the box design also planned. So I’d better succeed!

Getting started log

  1. xTIMEcomposer 14.4.1 Makefile: TARGET = XUF212-512-TQ128-C20. No entry for the generic board type. Don’t follow this one. Go directly to point 3:
  2. Analysing debug_printf.c .././XUF212-512-TQ128-C20.xn:27 Warning: XN11206 Oscillator is not specified for USB node.
    • Update: Simon Gapp pointed put that adding
      <Node Id="1" InPackageId="1" Type="periph:XS1-SU" Reference="usb_tile" Oscillator="24MHz“> will work, see his full XUF216-256-TQ128-C20.xn at GitHub, here. This is part of his Master’s thesis [5]
  3. Instead of trying to find out what’s missing I’d rather see what XMOS has for me. I will now  try the AN00220 application note Microphone array phase-aligned capture example.  Download from https://www.xmos.ai/application-notes/ (more below). It depends on the microphone array library lib_mic_array, see 141:[XMOS libraries] or LIBRARIES
  4. Now ImportExisting project into workspace with Copy projects into workspace ticked, from the download location. I am offline from the xmos server
  5. The AN00220 uses
    TARGET = MIC-ARRAY-1V0 together with a file called MIC-ARRAY-1V0.xn.
    But then, there is a newer called MIC-ARRAY-1V3.xn that I found with the lib_mic_array_board_support v.2.2.0 according to its index.pdf  document XM009805, 2017. I also found it here.  It adds names for the expansion header J5. Plus the name “XS2 MC Audio2 for the AN002020 is now “Microphone Array Reference Hardware (XUF216)” for the lib_mic_array_board_support. Finally, I expanded it myself to TARGET = MIC-ARRAY-1V0-MODand MIC-ARRAY-1V3.xn to MIC-ARRAY-1V3-MOD.xn See point 9 (below)
  6. My question is why XMOS didn’t build this in as an option in xTIMEcomposer? Why do I have to download the AN00220 or lib_mic_array_board_support to discover this?

7. Code space left for me

The AN00220 compiled to the below HW usage. They say that “This demo application shows the minimum code to interface to the microphone array.” Fair enough, I shouldn’t be worried at all, I guess:

Creating app_phase_aligned_example.xe
Constraint check for tile[0]:
  Cores available:            8,   used:          4 .  OKAY
  Timers available:          10,   used:          4 .  OKAY
  Chanends available:        32,   used:          8 .  OKAY
  Memory available:       262144,   used:      20680 .  OKAY
    (Stack: 2252, Code: 7160, Data: 11268)
Constraints checks PASSED.
Constraint check for tile[1]:
  Cores available:            8,   used:          1 .  OKAY
  Timers available:          10,   used:          1 .  OKAY
  Chanends available:        32,   used:          0 .  OKAY
  Memory available:       262144,   used:       1232 .  OKAY
    (Stack: 348, Code: 624, Data: 260)
Constraints checks PASSED.

8. Adafruit 128×64 OLED display

Getting the Adafruit 128×64 OLED display up and running was not easy at all.

In my other boxes (aquarium controller, radio client  and bass/treble unit) I had used the smaller 128×32, product 931 (here) with zero problem getting it up and running for the first time. The flora of displays based on the SSD1306 chip from Univision Technology Inc was perhaps smaller then. I have used I2C address 0x3C for them all.

But the 128×64 hardware ref. v2.1, product 326 (here) was harder. Or maybe I didn’t pay enough attention to the right detail from the beginning. I could have stumbled upon the correct solution immediately, but Murphy’s law prohibited it. My road became maximum bumpy.

The boards from Univision UG-2832HSWEG02 for the 128×32 (here) and the 128×64 UG-2864HSWEG01 (here) say little about I2C address. The first says nothing, the second says that pin 15 D/C# “In I2C mode, this pin acts as SA0 for slave address selection.” My problem was that I went to the circuit diagram. Don’t do that! The page for 128×32 says right there that “This board/chip uses I2C 7-bit address 0x3C”. Correct. The page for the larger 128×64 says “This board/chip uses I2C 7-bit address between 0x3C-0x3D, selectable with jumpers”. Also 100% correct! But the diagram says 0x7A/0x78 (here). If you download the fresh code via the Arduino system the I2C addresses should be fine. But I ported the Adafruit code to XC some years ago, and have cut that update branch. .

It says “v2.1” and “5V ready” in the print on my 128×64 board. There is a long single page document for all of these display boards (here, updated 2012!) where I finally picked up the address: “128 x 64 size OLEDs (or changing the I2C address). If you are using a 128×64 display, the I2C address is probably different (0x3d), unless you’ve changed it by soldering some jumpers“. Had my attention span down the initial page for the 128×64 been longer, I’d saved a lot. Like this:

Then there is header pin 7 VIN (3V3 ok or 5V required?). My128x64 board as mentioned says “5V ready” in the print and it contains an AP2112K-3.3 regulator (here) according to another diagram. On my proper diagram it’s just drawn anonymously. Since my XMOS MIC_ARRAY board outputs 3V3 only and the AP211K-3.3 according to the data sheet must (?) have 4.3V to get the 3.3V out (even if the dropout is very low) I simply soldered it out and connected VIN and 3.3V internally. This was close to stupid, but was a shot in the dark since I hadn’t found the correct I2C address – the display was so dark. Because, when I got the I2C address correct I saw that the one board that I had not modified (I have two) and the one I did modify worked almost equally well – even if I think my removal got me the voltage drop more “3.3V” for the display, and I think it looked brighter. The AP2112K-3.3 takes 3.3V in quite well! I think this can be read from the single page document (above) as well, but there are so many ifs and buts there that it’s hard to get the cards shuffled correctly.

Adafruit has (as I do) written a lot of words, which is better than few words – provided they all point in the same direction or are able to point in a certain direction at all. I think that Adafruit would need to iterate and read again and then update non consistent information. Much doesn’t always mean correct.

By the way, I also had to add fresher pull-ups on the I2C SCL and SDA lines of 1k. The built-in 10k isn’t for much speed. I use 100 or 333 kbits/sec. Here is the connection diagram (drawn in iCircuit which has a global view of header pin numbering).

beep_brrr_cabling_adafruit_display_326_and_io_and_xmos_mic_array_oyvind_teig
Fig.1 – Cable connection diagram (30 kB) here)

I have noted in Tile[0] rules, what about tile[1]? that I might have a slight problem.

9. Target and .xn file for xflash

See my xCore Exchange community question (14Apr2021) at xCORE Microphone Array .xn file and xflash.

14Apr2021: my .xn file is here: MIC-ARRAY-1V3-MOD.xn. This goes with TARGET = MIC-ARRAY-1V3-MOD in Makefile.

Observe 141:[XFLASH from Terminal].

10. Serial number, processor and internal QSPI FLASH

See ref above. The 2MByte QSPI FLASH is internal (on chip) is integrated on this processor, opposite to the xCORE-200 Explorer board, which has an external 1MByte QSPI FLASH.

Serial number Processor type Internal (on chip) QSPI FLASH
1827-00193 Type: XUF216-512-TQ128
Printed: U11692C20 GT183302 PKKY15.00
(2018 week 33)
IS25LP016D (if newer than 2020.10.05,  [3])
IS25LQ016B (is older, manual)
1827-00254

11. Serial output to 3.5 mm jack

I probably hijacked this one on Tue Apr 27, 2021 9:12 pm: I2S Ports synchronized by same clock in two parallel tasks. Plus, see AN00219 (below).

My Beep-BRRR lab box

Fig.2 – My box with the XMOS microphones board and the Adafruit display

I bored holes for all microphones. The display is also seen.

Libraries

See 141:[XMOS libraries] and 141:[Importing (a source code) library when xTIMEcomposer is offline].

Some of the below have been mentioned above. I assume this is the  the most relevant list. I have experience with those in red:

  • APPLICATION NOTES – just to remind myself of those that may be of interest
    • AN01008 – Adding DSP to the USB Audio 2.0 L1 Reference Design
    • AN00103 – Enabling DSD256 in the USB Audio 2.0 Device Reference Design Software
    • AN00209 – xCORE-200 DSP Elements Library
    • AN00218 – High Resolution Delay and Sum
    • AN00217 – High Resolution Delay Example
    • AN00219 – Low Resolution Delay and Sum (PDF, SW). Should output to the 3.5 mm sound output jack
    • AN00220 – Microphone array phase-aligned capture example (above and below)
    • AN01009 – Optimizing USB Audio for stereo output, battery powered devices
    • AN01027 – Porting the XMOS USB 2.0 Audio Reference Software onto XU208 custom hardware
    • AN00162 – Using the |I2S| library
    • USB Audio Design Guide also covers the xCORE-200 Microphone Array Board. 110 pages! See [4]
  • Microphone array library lib_mic_arraycode github, [7]
    • AN?? = separate application note not needed
    • AN00220 uses it. Plus I base my version 0106 (below) on it
  • xCORE-200 DSP Library lib_dsp
    • AN00209 describes it
  • S/PDIF library lib_spdif
  • Sample Rate Conversion Library lib_src
  • Microphone array board support library lib_mic_array_board_support (latest PDF)
  • I2C Library lib_i2c
  • SPI Library lib_spi

Coding

Version 0106

Download 0106

These downloads may be considered intermediate. Starting with the app note AN002020 I made a new example_task, in AN00220_app_phase_aligned_example.xc. Read it as a .txt file here:

  1. ../AN00220_app_phase_aligned_example.xc.txt

I then added my own task called Handle_Beep_BRRRR_task in file _Beep_BRRR_01.xc Read it as a .txt file here:

  1. ../_Beep_BRRR_01.xc.txt

My code uses the XMOS source code libraries lib_i2c(4.0.0) lib_logging(2.1.0) lib_xassert(3.0.0) lib_mic_array(3.0.1) lib_dsp(3.1.0). From the version numbers I guess that they are rather ripe, even if anyting that ends in 0.0 scares me somewhat. They are not included here:

  1. ../_Beep_BRRR_01.xc.zip – (4.5 MB) also contains version history in .git

It compiles like this (plus xta static timing analysis outputs as “pass”):

Constraints tile[0]: C:8/8 T:10/8 C:32/21 M:48656 S:5192 C:28708 D:14756
Constraints tile[1]: C:8/1 T:10/1 C:32/00 M:1540  S:0348 C:0864  D:00328

As mentioned, I have noted in Tile[0] rules, what about tile[1]? that I might have a slight problem. It’s easy to see this (above). I use 8 cores on tile[0] and 1 only on tile[1]. Well, tile[1] is not used by me.

Chan or interface when critical timing

Here is the output of version 0104, which is about is the present code 0106 compiled with CONFIG_USE_INTERFACE:

Fig.3 – Disturbed by interface call with display write

The two configurations I have in this code is described rather coarsely in the below figure. There are two alternatives:

fig4_219_beep-brrr_msc

Fig.4.interface vs. channel during critical timing: Message Sequence Chart (MSC) (PDFJPG)

The code basically goes like this. The top code (CONFIG_USE_INTERFACE) in the select accepts the interface call from the example_task, and since Dislay_screen calls I2C serial communication to send a bitmap to the display. This would delay example_task too much. It needs to be back in an 8 kHz rate.

Observe that this is the way an interface call (RPC – Remote procedure call) is supposed to work in xC! This is not a design fault or a compiler error. It makes no difference in the semantics for those calls that do return a value and those that don’t.

I could have decorated with xta timing statements in this code, this would have been more accurate than discovering this by coincidence on the scope. In view of this, I find it rather strange that XMOS is parking xta and even interface calls, in the XTC Tools and lib_xcore.

// In Handle_Beep_BRRRR_task while(1) select case

#if (MY_CONFIG == CONFIG_USE_INTERFACE)

case if_mic_result.send_mic_data (const mic_result_t mic_result) : {
    buttons_context.mic_result = mic_result;

    // BREAKS TIMING, probably because interface returns at the end of the case, and this
    // needs to wait unitil Display_screen and by it writeToDisplay_i2c_all_buffer

#elif (MY_CONFIG == CONFIG_USE_CHAN)

case c_mic_result :> buttons_context.mic_result : {

// TIMING of example_task not disturbed because the channel input "returns" immediately

#endif
    display_context.state = is_on;
    display_context.screen_timeouts_since_last_button_countdown = NUM_TIMEOUTS_BEFORE_SCREEN_DARK;
    display_context.display_screen_name = SCREEN_MIC;
    Display_screen (display_context, buttons_context, if_i2c_internal_commands);
} break;

The lower config (CONFIG_USE_CHAN) shows the use of a channel instead. Everything is synchronous here, interface calls as well as chan comms. But with the semantics of a chan, only its “rendezvous” time is atomic. When the communication has passed the data across, the sender and the receiver are independent. Therefore this is the method I need to use to move data from the mic tasks to user tasks.

Min value from mic is constant

I have decided to count positive signed int values as positive dB as and negative values as negative dB and 0 as zero dB. I use 20 * log10 (value) as the basis. Meaning that 1000 or -1000 gives 60 dB and 10000 or -10000 gives 80 dB. Of course, this is not as clean math, see Decibel on Wikipedia. But my usage would look like having two digital VU meters.

20 * log10 (5174375) = 134 dB and -20 * log10 (2147351294) = -186 dB. In maths.xc I have this code:

int32_t int32_dB (const int32_t arg) {

    int32_t ret_dB;

    if (arg == 0) {
        ret_dB = 0; // (by math NaN or Inf)
    } else {
        float dB;
        if (arg > 0) {
            dB =    20 * (log10 ((float)   arg ));
        } else { // if (arg < 0) {
            dB = - (20 * (log10 ((float) -(arg) )));
        }
        ret_dB = (int32_t) dB;
    }

    return ret_dB;
}

I can see that if I make some sounds then the positive dB might become, like 161 dB. But the problem is that the negative value constantly shows the same value 2147351294 (0x7FFDFAFE)! I have not solved this. Update: with 4 mics it’s the positive max that is stuck! See Version 0109

I have set the S_DC_OFFSET_REMOVAL_ENABLED to 1. It runs a single pole high pass IIR filter: Y[n] = Y[n-1] * alpha + x[n] - x[n-1] which mutes DC. See [7] chapter 15. I don’t know if this is even relevant.

Tile[0] rules, what about tile[1]?

My startup code in main.c goes like this:

main.c config code (0106)
#define INCLUDES
#ifdef INCLUDES
    #include <xs1.h>
    #include <platform.h> // slice
    #include <timer.h>    // delay_milliseconds(200), XS1_TIMER_HZ etc
    #include <stdint.h>   // uint8_t
    #include <stdio.h>    // printf
    #include <string.h>   // memcpy
    #include <xccompat.h> // REFERENCE_PARAM(my_app_ports_t, my_app_ports) -> my_app_ports_t &my_app_ports
    #include <iso646.h>   // not etc.
    #include <i2c.h>

    #include "_version.h" // First this..
    #include "_globals.h" // ..then this

    #include "param.h"
    #include "i2c_client_task.h"
    #include "display_ssd1306.h"
    #include "core_graphics_adafruit_gfx.h"
    #include "_texts_and_constants.h"
    #include "button_press.h"
    #include "pwm_softblinker.h"
#endif

#include "mic_array.h"
#include "AN00220_app_phase_aligned_example.h"

#include "_Beep_BRRR_01.h"

#if (IS_MYTARGET == IS_MYTARGET_MIC_ARRAY)
    //                                                            MIC-ARRAY-1V3-MOD.xc
    on tile[0]: in port p_pdm_clk              = XS1_PORT_1E;  // PORT_PDM_CLK
    on tile[0]: in buffered port:32 p_pdm_mics = XS1_PORT_8B;  // The 8 bit wide port connected to the PDM microphones
                                                               // 7 used: MIC_0_DATA 8B0 to MIC_6_DATA 8B6 (8B7 not connected)
                                                               // Also: "Count of microphones(channels) must be set to a multiple of 4"
                                                               // PORT_PDM_DATA Inputs four chunks of 8 bits into a 32 bits value
    on tile[0]: in port p_mclk                 = XS1_PORT_1F;  // PORT_MCLK_TILE0
    on tile[0]: clock pdmclk                   = XS1_CLKBLK_1; // In "xs1b_user.h" system

    //                                                       MIC-ARRAY-1V3-MOD.xc
    on tile[1]:     port p_i2c             = XS1_PORT_4E; // PORT_I2C             SCL=BIT0, SDA=BIT1
    on tile[1]: out port p_shared_notReset = XS1_PORT_4F; // PORT_SHARED_RESET    BIT0 reset when low
    on tile[1]:     port p_i2s_bclk        = XS1_PORT_1M; // PORT_I2S_BCLK
    on tile[1]:     port p_i2s_lrclk       = XS1_PORT_1N; // PORT_I2S_LRCLK
    on tile[1]:     port p_i2s_dac_data    = XS1_PORT_1P; // PORT_I2S_DAC0

    on tile[0]: out port p_scope_gray       = XS1_PORT_1J; // Mic array expansion header J5, pin 10

    on tile[0]: in buffered port:4 inP_4_buttons = XS1_PORT_4A; // BUTTONS_NUM_CLIENTS
    //
    on tile[0]:     port p_display_scl      = XS1_PORT_1H; // Mic array expansion header J5, pin  3
    on tile[0]:     port p_display_sda      = XS1_PORT_1G; // Mic array expansion header J5, pin  1
    on tile[0]: out port p_display_notReset = XS1_PORT_1A; // Mic array expansion header J5, pin  5 Adafruit 326 v2.1 does not NOT have on-board reset logic
    on tile[0]: out port p_scope_orange     = XS1_PORT_1D; // Mic array expansion header J5, pin  7
    on tile[0]: out port p_scope_violet     = XS1_PORT_1I; // Mic array expansion header J5, pin  9


    on tile[0]: out port leds_00_07 = XS1_PORT_8C;  // BIT0 is LED_0

    on tile[0]: out buffered port:1 led_08 = XS1_PORT_1K;
    on tile[0]: out port led_09            = XS1_PORT_1L;
    on tile[0]: out port led_10            = XS1_PORT_1M;
    on tile[0]: out port led_11            = XS1_PORT_1N;
    on tile[0]: out port led_12            = XS1_PORT_1O;

    // If we need to collect them:
    //out port leds_08_12[NUM_LEDS_08_12] = {XS1_PORT_1K, XS1_PORT_1L, XS1_PORT_1M, XS1_PORT_1N, XS1_PORT_1O};

#endif

#define I2C_DISPLAY_MASTER_SPEED_KBPS  100 // 333 is same speed as used in the aquarium in i2c_client_task.xc,
                                           // i2c_internal_config.clockTicks 300 for older XMOS code struct r_i2c in i2c.h and module_i2c_master
#define I2C_INTERNAL_NUM_CLIENTS 1


#if ((MY_CONFIG == CONFIG_USE_INTERFACE) or (MY_CONFIG == CONFIG_USE_CHAN))
    #if (WARNINGS == 1)
        #warning MY_CONFIG == CONFIG_USE_INTERFACE
    #endif

    int data [NUM_DATA_X] [NUM_DATA_Y];

    int main() {

        interface pin_if_1       if_pin    [BUTTONS_NUM_CLIENTS];
        interface button_if_1    if_button [BUTTONS_NUM_CLIENTS];
        interface pwm_if         if_pwm;
        interface softblinker_if if_softblinker;
        i2c_general_commands_if  if_i2c_general_commands;
        i2c_internal_commands_if if_i2c_internal_commands;
        i2c_master_if            if_i2c[I2C_HARDWARE_NUM_BUSES][I2C_HARDWARE_NUM_CLIENTS];

        #if (MY_CONFIG == CONFIG_USE_INTERFACE)
            mic_result_if      if_mic_result;
            #define MIC_RESULT if_mic_result
            #if (WARNINGS == 1)
                #warning MY_CONFIG == CONFIG_USE_INTERFACE
            #endif
        #elif (MY_CONFIG == CONFIG_USE_CHAN)
            chan               c_mic_result;
            #define MIC_RESULT c_mic_result
            #if (WARNINGS == 1)
                #warning MY_CONFIG == CONFIG_USE_CHAN
            #endif
        #endif

        par {
            on tile[0]:{
                configure_clock_src_divide  (pdmclk, p_mclk, 4);
                configure_port_clock_output (p_pdm_clk, pdmclk);
                configure_in_port           (p_pdm_mics, pdmclk);
                start_clock                 (pdmclk);

                streaming chan c_pdm_to_dec[DECIMATOR_COUNT];
                streaming chan c_ds_ptr_output[DECIMATOR_COUNT]; // chan contains pointers to data and control information
                                                                 // Relies oo shared memory, so both's ends taks must on the same tile as this task
                // mic_array_pdm_rx()
                //     samples up to 8 microphones and filters the data to provide up to eight 384 kHz data streams, split in two streams of four channels.
                //     The gain is corrected so that a maximum signal on the PDM microphone corresponds to a maximum signal on the PCM signal.
                // PDM microphones typically have an initialization delay in the order of about 28ms. They also typically have a DC offset.
                // Both of these will be specified in the datasheet.

                par {
                    mic_array_pdm_rx              (p_pdm_mics, c_pdm_to_dec[0], c_pdm_to_dec[1]);                     // in pdm.xc, calls pdm_rx_asm in pdm_rx.xc which never returns
                    mic_array_decimate_to_pcm_4ch (c_pdm_to_dec[0], c_ds_ptr_output[0], MIC_ARRAY_NO_INTERNAL_CHANS); // asm in decimate_to_pcm_4ch.S
                    mic_array_decimate_to_pcm_4ch (c_pdm_to_dec[1], c_ds_ptr_output[1], MIC_ARRAY_NO_INTERNAL_CHANS); // asm in decimate_to_pcm_4ch.S
                    example_task                  (c_ds_ptr_output, data, p_scope_gray, MIC_RESULT);                  // chan contains ptr to shared data, must be on the same tile
                                                                                                                      // as mic_array_decimate_to_pcm_4ch
                }
            }

            par {
                on tile[0]: Handle_Beep_BRRRR_task (
                        if_button, leds_00_07, if_softblinker,
                        if_i2c_internal_commands,
                        if_i2c_general_commands,
                        p_display_notReset,
                        MIC_RESULT);

                // Having this here, and not in combined part below, avoids "line 2303" compiler crash:
                on tile[0].core[0]: I2C_Client_Task_simpler (if_i2c_internal_commands, if_i2c_general_commands, if_i2c);
            }

            on tile[0]: { // Having these share a core avoids "line 183" compiler crash and runs:
                [[combine]]
                par {
                    softblinker_task (if_pwm, if_softblinker);
                    pwm_for_LED_task (if_pwm, led_08);
                    i2c_master (if_i2c[I2C_HARDWARE_IOF_DISPLAY_AND_IO], I2C_HARDWARE_NUM_CLIENTS, p_display_scl, p_display_sda, I2C_DISPLAY_MASTER_SPEED_KBPS); // Synchronous==distributable
                }
            }

            on tile[0]: {
                [[combine]]
                par {
                    Buttons_demux_task (inP_4_buttons, if_pin);
                    Button_task        (IOF_BUTTON_LEFT,      if_pin[IOF_BUTTON_LEFT],      if_button[IOF_BUTTON_LEFT]);      // BUTTON_A
                    Button_task        (IOF_BUTTON_CENTER,    if_pin[IOF_BUTTON_CENTER],    if_button[IOF_BUTTON_CENTER]);    // BUTTON_B
                    Button_task        (IOF_BUTTON_RIGHT,     if_pin[IOF_BUTTON_RIGHT],     if_button[IOF_BUTTON_RIGHT]);     // BUTTON_C
                    Button_task        (IOF_BUTTON_FAR_RIGHT, if_pin[IOF_BUTTON_FAR_RIGHT], if_button[IOF_BUTTON_FAR_RIGHT]); // BUTTON_D
                }
            }
        }
        return 0;
    }
#else
    #error no config
#endif

Read less…

The mic array board only has one only expansion header, with all pins connected to tile[0]! Plus, the mics are connected to the same tile. So I have no code on tile[1] – which gives the system a major slant towards tile[0]. I guess I need to make some multplexer task to make it possible to have my data processing code code on tile[1]. Stay tuned. I will.

Version 0109

This version decimates 4 mics instead of 8. The very strange thing is that this time it’s the negative max value (= min value) that changes, while it’s the most positive value that is constant. But at a different value than the for the negative, which for 0106 was 2147351294 (0x7FFDFAFE). The stuck positive max this time is 670763580 (0x27FB0A3C). What is happening here?

Download 0109

This download may be considered intermediate.

  1. ../_Beep_BRRR_01.xc.zip – (500 kB) no .build or /bin, but .git

Log B

  1. I am trying to get aquantained with the code and documentation (and my requirements, looking at sound files and their FFT spectrum/spectra), and found this piece of code: 141:[Ordered select combined with default case]

Download code

When this project is finished the code will be downloadable from My xC code downloads page. However, on this page I have the following local intermediate downloads. So download any while it’s still here if you are curious:

  1. Download 0106 (9Sep2021)
  2. Download 0109 (12Sep2021)

References

Wiki-refs: DecibelQ (number format) (also see [8])

  1. MICROPHONE AGGREGATION SOLUTIONS by XMOS, with ref to software tools, software libraries, application notes, hardware manual (below), design files and advisories & notices, see https://www.xmos.ai/microphone-aggregation/
  2. xCORE Microphone Array Hardware Manual (XMOS XM009730A 2018/6/14), download from [1] or https://www.xmos.ai/download/xCORE-Microphone-Array-hardware-manual(2V0).pdf –
    There is a small fault in it , with the errata here: On page 14 the pin X0D39 is called LED_OEN when it in fact goes to the expansion header J5 pin 10 (this is ok documented). The LEDs are always output enabled (OE) by all the hardware buffer chips 74LVC125A and 74LVC1G125 all have their OE control pins tied to GND, ie. always enabling all LEDs.
    Update: in lib_mic_array_board_support there is an #if defined PORT_LED_OEN which indicates that this output has at some stage been connected to the LED OE control pins
  3. XUF216-512-TQ128 Datasheet, 2020/10/05 XMOS Document Number: X007542, see https://www.xmos.ai/download/XUF216-512-TQ128-Datasheet 1.17.pdf. This document is not for my processors, but it’s only the QSPI flash that has changed. But it has a much nicer layout then the older documents, by which [1] on 15Apr2021 is referring to the older document 1.16. There is a “latest” url here: https://www.xmos.ai/file/xuf216-512-tq128-datasheet?version=latest
  4. USB Audio Design Guide by XMOS, 2016/5/12 (XM0088546.1). Also covers the xCORE-200 Microphone Array Board and not only USB. 110 pages. See https://www.xmos.ai/download/sw_usb_audio:-sw_usb_audio-[design-guide](6.16.1alpha1).pdf. XMOS helped me find it, even if it didn’t show up on any search: “This design guide can be found on our website on usb multichannel audio page here https://www.xmos.ai/usb-multichannel-audio/. If you scroll down to the quick links section at the bottom of the page you will find the document linked under the ‘software design guide’ link.
  5. XMOS USB – MEMS microphone array audio interface by Simon Gapp (2021). Part of master thesis at TU Berlin, Department of Engineering Acoustics. See https://github.com/simongapp/xmos_usb_mems_interface
  6. USB Audio 2.0 Device Software – source code by XMOS. See https://www.xmos.ai/file/usbaudiodevice-software/ which downloads sw_usb_audio-[sw]_6 with directories lib_logging, sc_i2c, sc_usb_device, lib_mic_array, sc_spdif, sc_util, lib_xassert, sc_usb, sc_xud, sc_adat, sc_usb_audio, sw_usb_audio
  7. Microphone array library (3.0.1) by XMOS (2017). See https://www.xmos.ai/download/lib_mic_array-[userguide](3.0.1rc1).pdf (from https://www.xmos.ai/libraries/). Also dwonload from https://www.xmos.ai/file/lib_mic_array-userguide/
  8. Fixed-Point Representation & Fractional Math, Revison 1.2 by Erick L. Oberstar (2007). See https://www.researchgate.net/publication/235791711_Fixed-Point_Representation_Fractional_Math_Revison_12?channel=doi&linkId=0912f5138a6546059b000000&showFulltext=true. Provides an overall understanding of the nature of Q[QI].[QF] format integer fixed-point numbers. Also see Wiki-refs (above)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.