SFU

group SFU

A pmsis-style driver for SFU module.

Defines

CONFIG_AUDIO_SW_QUEUES

Enable/disable software queue for MEM_IN/MEM_OUT transfers.

CONFIG_SFU_CMD_QUEUE

Enable/disable software queue for SFU commands.

CONFIG_TRACE_SFU

Enable/disable stdout traces (SFU print macros). To be used in conjunction with PI_LOG_LOCAL_LEVEL, which is 0 (NONE) by default.

PI_LOG_LOCAL_LEVEL

Global (system-wide) trace level. If not set, it’s 0 (NONE) by default (see pi_log.h):

  • PI_LOG_NONE 0

  • PI_LOG_ERROR 1

  • PI_LOG_WARNING 2

  • PI_LOG_INFO 3

  • PI_LOG_DEBUG 4

  • PI_LOG_TRACE 5

CONFIG_PORT_DIRECTION_INFO

Enable/disable MEM port direction tracking. Currently it is never used, so disabled.

PI_SFU_SAI_ID_0

SAI block identifiers: PI_SFU_SAI_ID_*

PI_SFU_SAI_ID_1
PI_SFU_SAI_ID_2
PI_SFU_SAI_ID_3
PI_SFU_SAI_ID_LAST
PI_SFU_SAI_CH_0
PI_SFU_SAI_CH_1
PI_SFU_SAI_CH_2
PI_SFU_SAI_CH_3
PI_SFU_SAI_CH_4
PI_SFU_SAI_CH_5
PI_SFU_SAI_CH_LAST
PI_SFU_MEM_MAX

Total number of MEM_IN or MEM_OUT blocks within SFU. In GAP9 there are 8 MEM_IN and 8 MEM_OUT blocks.

PI_SFU_UDMA_FLAGS_DIR_MASK

Direction of MEM port (from SFU perspective) in currently active graph.

Same port may be used by other graphs loaded later with possibly different direction.

0: Rx - MEM_IN 1: Tx - MEM_OUT 2: Unknown

To be used internally when there is need to distinguish between the two, for example to automate resuming of MEM_IN ports (currently this resuming must be done by the user). Use with pi_sfu_mem_port_t.udma.flags bitmask.

PI_SFU_UDMA_FLAGS_DIR_SHIFT
PI_SFU_UDMA_FLAGS_DIR_VAL_RX
PI_SFU_UDMA_FLAGS_DIR_VAL_TX
PI_SFU_UDMA_FLAGS_DIR_VAL_UNK
PI_SFU_UDMA_FLAGS_TMODE_MASK

Transfer mode of the uDMA linear channel: PI_SFU_UDMA_FLAGS_TMODE_*

PI_SFU_UDMA_FLAGS_TMODE_SHIFT
PI_SFU_UDMA_FLAGS_TMODE_VAL_SINGLE
PI_SFU_UDMA_FLAGS_TMODE_VAL_CONT
SFU_TAG
SFU_COLOR
SFU_ERR(fmt, ...)
SFU_WNG(fmt, ...)
SFU_INF(fmt, ...)
SFU_DBG(fmt, ...)
SFU_TRC(fmt, ...)
SFU_NONE(fmt, ...)

Typedefs

typedef struct pi_sfu_conf pi_sfu_conf_t
typedef struct pi_sfu_gfu_filter_refs_t pi_sfu_gfu_filter_refs_t
typedef struct pi_sfu_gfu_filter_refs_short_t pi_sfu_gfu_filter_refs_short_t
typedef struct pi_sfu_pdm_itf_id_s pi_sfu_pdm_itf_id_t

Description of one PDM channel (in GAP SAI block).

typedef struct pi_sfu_i2s_itf_id_s pi_sfu_i2s_itf_id_t

Description of SAI block.

Functions

static inline void pi_sfu_conf_init(struct pi_sfu_conf *conf)

Initialize an sfu configuration with default values.

This function can be called to get default values for all parameters before setting some of them. The structure containing the configuration must be kept alive until the sfu is opened.

Parameters:
  • conf[in] A pointer to the sfu configuration.

void pi_sfu_enable()

Enable SFU device.

Enable SFU domain FLL, power on SFU, ungate SFU clock and deassert SFU reset.

void pi_sfu_disable()

Disable SFU device.

Assert SFU reset, gate its clock and power it down. Keep FLL running.

void pi_sfu_switch(int32_t power_en, int32_t clock_en)

Switch on/off SFU power or clock.

Parameters:
  • power_en – 0: Switch SFU voltage domain off. 1: Switch SFU voltage domain on.

  • clock_en – 0: Disable (gate) SFU domain clock. Keep FLL running. 1: Enable (ungate) SFU domain clock.

void pi_sfu_reset()

\bref Do hardware reset of the SFU.

Do SFU reset without gating clock or powering down the SFU.

int32_t pi_sfu_open(pi_sfu_conf_t *conf)

Open the sfu.

This will allocate and initialize all the resources needed to use the sfu. Once this function is successfully called, other functions for managing graphs can be called.

Note

This function can not be called from an interrupt handler.

Parameters:
  • conf[in] A pointer to the sfu configuration. Can be NULL to take default values.

Return values:
  • 0 – If the operation is successfull.

  • ERRNO – An error code otherwise.

void pi_sfu_close()

Close the sfu.

This will free and deinitialize all the resources. Once this function is called, other functions for managing graphs can not be called anymore, and the sfu must be opened before it can be used again.

Note

This function can not be called from an interrupt handler.

pi_sfu_graph_t *pi_sfu_graph_open(pi_sfu_graph_desc_t *graph_desc)

Open an SFU graph (in new resource group).

This will open an SFU graph and allocate additional resources needed by the graph (e.g. uDMA channels). The function does not interact with SFU, rather it just prepares runtime structures. To actually start the graph execution, pi_sfu_graph_load() must be called afterwards.

The call will always create new resource group for the given graph. See pi_sfu_graph_open_in_group for description of resource group management. If application needs to control group management, pi_sfu_graph_open_in_group() should be used instead of pi_sfu_graph_open().

Note

This function cannot be called from an interrupt handler.

Parameters:
  • graph_desc[in] : A pointer to the SFU config descriptor generated by the SfuGen tool.*

Returns:

A pointer to the sfu graph instance or NULL if it failed.

pi_sfu_graph_t *pi_sfu_graph_open_in_group(pi_sfu_graph_desc_t *graph_desc, int32_t rgroup_id_req, int32_t *rgroup_id)

Open an SFU graph in group.

This will open an SFU graph and allocate additional resources needed by the graph (e.g. uDMA channels). The function does not interact with SFU, rather it just prepares runtime structures. To actually start the graph execution, pi_sfu_graph_load() must be called afterwards.

A non-SFU resource sharing is supported by rgroup* arguments (uDMA linear channel is an example of a resource). Depending on life-cycle of the graphs in appliction, some groups of graphs may need to run concurrently, while some groups of graphs may never have to run concurrently. As pi_sfu manages non-sfu resources internally, the user must give a hint about which graphs are never supposed to run concurrently. This provided by rgroup_id_req and rgroup_id arguments.

Two graphs that belong to the same resource group will use the same pool of resources, meaning that they cannot run concurrently. Two graphs that belong to different resource groups will not overlap in resource usage, meaning that they can run concurrently.

Groups are internaly managed by the driver. Group IDs can be 1, 2, and so on. Group ID 0 is not used because value 0 is used as special value of rgroup_id_req to ask for new group. If rgroup_id_req is 0, a new group will be created at first available ID. Otherwise, the graph will be added to existing group.

Note

This function cannot be called from an interrupt handler.

Parameters:
  • graph_desc[in] : A pointer to the SFU config descriptor generated by the SfuGen tool.

  • rgroup_id_req[in] Requested group ID 0: Create new group with first available ID >0: Add graph to existing group with given ID. If the group doesn’t exist the call will fail

  • rgroup_id[in] Obtained group ID 0: Failure >0 Obtained group ID

Returns:

A pointer to the sfu graph instance or NULL if it failed.

int32_t pi_sfu_graph_close(pi_sfu_graph_t *graph)

Close an sfu graph.

This will free all resources allocated for a graph. After a call to this function, the graph can not be used anymore.

Note

This function can not be called from an interrupt handler.

Parameters:
  • graph[in] A pointer to the graph instance.

Returns:

Error code

pi_sfu_graph_t *pi_sfu_graph_clone(pi_sfu_graph_t *original_graph, int32_t self, pi_sfu_clone_patch_desc_t *patch_desc)

Clone graph by using static cloning. Static cloning relies on cloning info generated by SfuGen, where cloned graphs are selected in .src file by SFU_CloneGraph() directive.

Parameters:
  • original_graph[in] : Pointer to the original graph to clone from

  • self[in] : Whether to clone original graph onto itself. This can be used if application needs to load SFU with original graph after some cloned graphs have been loaded.

  • patch_desc[in] : Cloning patch descirptor generated by SfuGen

int32_t pi_sfu_graph_clone_patch_apply(pi_sfu_graph_t *graph)

Apply patch information of the cloned graph to the L2 config of the original graph. To be called before loading next cloned graph. Can be used only with graph cloned with pi_sfu_graph_clone().

Parameters:
  • graph[in] : Pointer to the cloned graph descriptor

Returns:

Error code : 0 - Success

pi_sfu_graph_t *pi_sfu_graph_dynamic_clone(pi_sfu_graph_t *original_graph, int32_t self, int32_t full)

Clone graph by using dynamic cloning. Dynamic cloning allocates required memory for a cloned graph configuraiton at runtime. Cloned graph refernces the level 1 L2 config of the original graph, but allocates its own L2 copies of GFU coefficients and states. It doesn’t require additional cloning info from SfuGen, except that it should be ensured that .Visible property is set for the GFU nodes that require cloning.

Parameters:
  • original_graph[in] : Pointer to the original graph to clone from

  • self[in] : Whether to clone original graph onto itself. This can be used if application needs to load (again) the original graph in SFU after some cloned graphs have been loaded.

  • full[in] : Whether to make entire new copy of orignal L2 graph. If 1, dynamic patching between loading graphs is not needed (at the cost of more memory spent). Full mode is not supported.

int32_t pi_sfu_graph_dynamic_clone_patch_apply(pi_sfu_graph_t *graph)

Apply patch information of the cloned graph to the L2 config of the original graph. To be called before loading next cloned graph. Can be used only with graph cloned with pi_sfu_graph_dynamic_clone().

Parameters:
  • graph[in] : Pointer to the cloned graph descriptor

Returns:

Error code : 0 - Success

void pi_sfu_graph_load(pi_sfu_graph_t *graph)

Load an sfu graph.

This will load the graph from L2 to sfu and start it, so that it is ready to process data.

Note

This function can not be called from an interrupt handler.

Parameters:
  • graph[in] A pointer to the graph instance.

void pi_sfu_graph_load_async(pi_sfu_graph_t *graph, pi_evt_t *task)

Load a graph asynchronously.

This will load the graph from L2 to sfu and start it, so that it is ready to process data. This operation is done asynchronously, which can be interesting since this can take quite a long time for big graphs. The end of the load operation is notified through a pmsis task, which can be a callback, a blocking task, or an interrupt handler. See pmsis task documentation for more details.

Parameters:
  • graph[in] A pointer to the graph instance.

  • task – The task used to notify the end of the load.

void pi_sfu_graph_graphonly_load_async(pi_sfu_graph_t *graph, pi_evt_t *task)

Send only graph load command without clock load (sync and async variants).

Provided for expermients, but not recommended for use. Recommended is pi_sfu_graph_load(_async). WARNING: GAP9 SFU requires clock mask to be loaded before graph mask, otherwise the processing won’t start correctly.

void pi_sfu_graph_graphonly_load(pi_sfu_graph_t *graph)
void pi_sfu_graph_clockonly_load_async(pi_sfu_graph_t *graph, pi_evt_t *task)

Send only clock load command without graph load (sync and async variants).

Provided for expermients, but not recommended for use. Recommended is pi_sfu_graph_load(_async). WARNING: GAP9 SFU requires clock mask to be loaded before graph mask, otherwise the processing won’t start correctly.

void pi_sfu_graph_clockonly_load(pi_sfu_graph_t *graph)
void pi_sfu_graph_unload(pi_sfu_graph_t *graph)

Unload an sfu graph.

This will unload the graph from the SFU. The graph can be loaded again later on from L2 to sfu. Until it is loaded again, the graph cannot be used.

Parameters:
  • graph[in] A pointer to the graph instance.

void pi_sfu_graph_unload_async(pi_sfu_graph_t *graph, pi_evt_t *task)

Request unload of the SFU graph and register task to be signaled when then unload is finished.

Parameters:
  • graph[in] A pointer to the graph instance.

  • task – The task used to notify the end of the load.

void pi_sfu_graph_end_wait(pi_sfu_graph_t *graph)

Wait for the end of an sfu graph.

This will wait until the graph has finished executing. This can happen in case of an error, or when the graph has no more input samples to process.

Note

This function can not be called from an interrupt handler.

Parameters:
  • graph[in] A pointer to the graph instance.

uint32_t pi_sfu_graph_busy_status_get(pi_sfu_graph_t *graph)

Get BUSY status of a graph.

Note

This function can not be called from an interrupt handler.

Parameters:
  • graph[in] A pointer to the graph instance.

void pi_sfu_graph_end_wait_async(pi_sfu_graph_t *graph, pi_evt_t *task)

Get notified by the end of an sfu graph.

This will register a pmsis task, which will be triggered when the graph has finished executing. This can happen in case of an error, or when the graph has no more input samples to process. The end of the graph is notified through a pmsis task, which can be a callback, a blocking task, or an interrupt handler. See pmsis task documentation for more details.

Warning

Currently this has limited usefulness as pi_sfu can remember only one async request at a time. Caller should ensure that no async requests are pending prior to calling this, otherwise previoiusly requested event/callback will be lost. On the other hand, if this is called after, for example, pi_sfu_graph_load (sync), BUSY=0 event may be lost if the graph completes too quickly, in this case this ‘task’ will never be scheduled.

Parameters:
  • graph[in] A pointer to the graph instance. If NULL, the function will just wait for busy without verifying which graph is actually the current one for BUSY status calculation. If not NULL, the function will check whether given graph is actually the current one for BUSY status calculation. If not, it will first set it as the current.

  • graph[in] A pointer to the graph instance.

  • task – The task used to notify the end of the graph.

int32_t pi_sfu_graph_pdm_bind(pi_sfu_graph_t *graph, int32_t node_id, pi_sfu_pdm_itf_id_t *itf_id)

Update SFU PDM_IN or PDM_OUT block configuration with SAI interface and channel to which they shall be connected. Doesn’t take effect until next SFU graph load.

Parameters:
  • graph[in] Pointer to the graph instance

  • node_id[in] Node index in SFU descriptor list. This list is previously generated by SFUConfigurationGenerator and indexes of configurable blocks is provided in generated file <graph_name>_L2_Descr.h.

  • itf_id[in] Description of PDM interface channel (SAI, channel, tx/rx)

Return values:
  • 0 – : Success

  • Other – : Failure

Returns:

Error code

int32_t pi_sfu_graph_i2s_bind(pi_sfu_graph_t *graph, int32_t node_id, pi_sfu_i2s_itf_id_t *itf_id, int32_t *stream_ch)

Unlike pi_sfu_graph_pdm_bind(), it doesn’t modify configuration of SFU STREAM_IN or STREAM_OUT blocks, rather it just sets physical clock source given by ‘itf_id’ to the SFU clock domain in which given STREAM_IN or STREAM_OUT node ‘node_id’ belongs. Doesn’t take effect until next SFU graph load.

Warning

On GAP9 there is a limitation in SAI when mixing Tx slots of different types in the same TDM/I2S frame. If Tx frame shall contain some slots coming from L2 (via uDMA address generators) and some slots coming from the SFU (via uDMA streams), then all stream slots must be placed before (i.e. have lower index than) all L2 slots. The limitation is not due to SFU per se, but due to SAI / uDMA. Nevertheless it is restated here as a reminder.

Parameters:
  • graph[in] Pointer to the graph instance

  • node_id[in] Node index in SFU descriptor list. This list is previously generated by SFUConfigurationGenerator and indexes of configurable blocks is provided in generated file <graph_name>_L2_Descr.h.

  • itf_id[in] Description of I2S interface channel (SAI, tx/rx)

  • stream_ch[out] Outputs uDMA stream ID of the channel assigned to ‘node_id’. This assignment is normally already done during graph load.

Return values:
  • 0 – : Success

  • Other – : Failure

Returns:

Error code

void pi_sfu_l2_graph_dump(pi_sfu_graph_t *graph)

Dump raw L2 configuration of the SFU graph given by ‘graph’ to stdout.

Parameters:
  • graph[in] Pointer to a SFU graph.

void pi_sfu_l2_graph_patch_dump(pi_sfu_graph_t *graph)

Dump cloned graph’s dynamic patch information.It shows diff elements with respect to the L2 config of the original graph.

Parameters:
  • graph[in] Pointer to a SFU graph.

void pi_sfu_graph_sfu_resource_dump(pi_sfu_graph_t *graph)

Dump bit masks of used blocks and clocks of an SFU graph.

Parameters:
  • graph[in] Pointer to a SFU graph.

int32_t pi_sfu_stream_id_get(pi_sfu_graph_t *graph, int32_t node_id)

Get uDMA stream ID assigned to SFU stream block ‘node’id’. The ID has already been allocated by SFU driver during graph opening.

Parameters:
  • graph[in] Pointer to a SFU graph.

  • node_id[in] Index of SFU node in generated node descriptor list.

pi_sfu_mem_port_t *pi_sfu_mem_port_get(pi_sfu_graph_t *graph, int32_t id)

Get reference to mem in/out port context from node descriptor id.

Parameters:
  • graph[in] Pointer to the SFU graph instance

  • id[in] Node index in SFU descriptor list

Returns:

Pointer to mem in/out port context

void pi_sfu_continuous_enqueue(pi_sfu_mem_port_t *port, pi_sfu_buffer_t *buffer0, pi_sfu_buffer_t *buffer1)

Enqueue “continuous” L2 <-> SFU transfer on ‘port’. The hardware will automatically reenqueue buffers in alternating fashion (buffer0, then buffer1, then buffer0, …). Since the hardware will reenqueue forever, to eventually stop these transfers, a program must call pi_sfu_udma_transfer_stop(). Buffers 0 and 1 must have the same size (the function will use size of buffer0 to set the size of single transfer, so buffer1 should have the same size).

Parameters:
  • port[in] Pointer to mem in/out port descriptor

  • buffer0[in] Pointer to audio buffer 0

  • buffer1[in] Pointer to audio buffer 1

static inline void pi_sfu_buffer_init(pi_sfu_buffer_t *buffer, void *data, int32_t nb_samples, int32_t sample_size)

Initialize a data buffer descriptor.

Data buffers are containers for samples. They must be initialized with this function before they can be enqueued to a graph. A data buffer must be kept alive as long as the samples are used by a graph. A pointer to the memory for the samples must be provided by the application and kept alive as long as the samples are used by the graph.

Buffer descriptor pi_sfu_buffer_t also contains ‘task’ field. In CONFIG_AUDIO_SW_QUEUES=0 mode, ‘task’ field the pi_sfu_buffer_t is not used by the driver. In CONFIG_AUDIO_SW_QUEUES=1 mode, ‘task’ field is NULL by default. It can be set by the user to OS event object (callback or simple event). If not NULL, the driver with push on this event every time a transfer of a buffer is completed by related uDMA channel. The event can be set by pi_sfu_buffer_task_set().

Parameters:
  • buffer[in] A pointer to the data buffer.

  • data[in] A pointer to the memory used for the samples.

  • nb_samples[in] Number of samples that the buffer can contain.

  • sample_size[in] Size in bytes of the samples.

static inline void pi_sfu_buffer_task_set(pi_sfu_buffer_t *buffer, pi_evt_t *task)

Assign an event to a buffer.

If not NULL, the event will be triggered whenever a transfer of this buffer to/from SFU is finished.

Relevant only in CONFIG_AUDIO_SW_QUEUES=1 mode.

Parameters:
  • task[in] OS event object reference.

static inline void pi_sfu_enqueue(pi_sfu_graph_t *graph, pi_sfu_mem_port_t *port, pi_sfu_buffer_t *buffer)

Enqueue a data buffer to SFU MEM_IN or MEM_OUT ports.

This function can be used to control transfers between SFU and the L2 memory. For memin (L2 -> SFU), the data buffer is enqueued to the uDMA Tx channel that is connected to a SFU MEM_IN block. For memout (SFU -> L2), the data buffer is enqueued to a the uDMA Rx channel that is connected to a SFU MEM_OUT block.

The exact behavior depends on the CONFIG_AUDIO_SW_QUEUES configuration flag.

CONFIG_AUDIO_SW_QUEUES=0 mode is aimed for maximum performance. There are no software queues, so only 2 buffers can be pushed at the same time to a port (uDMA hardware can queue up to 2 buffers at a time). Next buffer can be pushed as soon as the first of the previous 2 has finished. In this mode the driver does not manage uDMA end-of-transfer events. Starved MEM_IN ports are not automatically resumed. The application must resume them when there is a possibility that they become starved (see pi_sfu_resume_all_mem_in_ports()).

In CONFIG_AUDIO_SW_QUEUES=1 mode the driver provides unlimited software queues, manages end-of-transfer events and resumes potentially starved MEM_IN ports of the SFU.

Parameters:
  • graph[in] A pointer to the data buffer.

  • port[in] Pointer to mem in/out port descriptor

  • buffer[in] The data buffer to be enqueued.

static inline void pi_sfu_resume_all_mem_in_ports()

Write to SFU MEM_IN_STATUS register to resume all starved MEM_IN ports.

During graph execution, if SFU MEM_IN port asks for next data from uDMA and there is no available data enqueued by the application at that moment, MEM_IN block will stop trying and enter “starved” error condition. SFU nodes downstream from this MEM_IN will soon hang as they will no longer receive new samples. Later when the program enqueues more data, after enqueueing it must also request MEM_IN resume by writing to SFU MEM_IN_STATUS register, otherwise the MEM_IN block will stay idle forever.

In CONFIG_AUDIO_SW_QUEUES=1 mode, this is done automatically by the driver. In CONFIG_AUDIO_SW_QUEUES=0 mode, the application shall call this API (after the enqueue) when there is possibility that the MEM_IN has previously starved.

static inline void pi_sfu_flush_udma_transfer(pi_sfu_mem_port_t *port)

Write to uDMA core register of a linear channel related to the port to cancel transfer of remaining size that has not yet been transferred at the moment of a call. This is useful when an unknown number of samples is expected on MEM_OUT port, for example in case of ASRC manual ratio resampling or POLYPHASE resampling. In this case user can set a maximum expected size, then after the graph halts retrieve whatever size has been transferred so far (use pi_sfu_nb_transferred_bytes_get() to get actual transferred size). However the remaining size is still pending in uDMA core so pi_sfu_flush_udma_transfer() must be called before enqueueing the next transfer in order to cancel pending transfer and start anew.

Parameters:
  • port – SFU MEM I/O port descriptor

static inline void pi_sfu_udma_transfer_stop(pi_sfu_mem_port_t *port)

Stop ongoing/pending uDMA transfer. Another alias to pi_sfu_flush_udma_transfer().

static inline uint32_t pi_sfu_nb_transferred_bytes_get(pi_sfu_mem_port_t *port)

Get number of transferred bytes on port. To be used in cases where number of samples that would be transferred is not known in advance (e.g. ASRC or POLYPHASE resampling).

Parameters:
  • port – SFU MEM I/O port descriptor

static inline void *pi_sfu_buffer_data(pi_sfu_buffer_t *buffer)

Get buffer data memory.

Return the pointer to the memory of samples given when the buffer was initialized.

Parameters:
  • buffer[in] The data buffer.

Returns:

The pointer to the sample memory.

static inline int32_t pi_sfu_buffer_size_get(pi_sfu_buffer_t *buffer)

Get size (in bytes) of the pi_sfu buffer data.

void pi_sfu_inout_udma_enqueue(pi_sfu_node_inout_header_t *channel, pi_sfu_buffer_t *buffer, pi_evt_t *task)

Enqueue uDMA transfer with option to provide a blocking or callback ‘task’.

Parameters:
  • channel[in] pi_sfu uDMA channel descriptor

  • buffer[in] Audio buffer

  • task[in] Task that will be used to wake up the caller.

void pi_sfu_graph_save(pi_sfu_graph_t *graph)

Save an SFU graph.

Save the state of an sfu graph. The state is saved to L2. This can be used to switch to a different graph and come back to this one later on. The state will be automatically restored when the graph is loaded.

Note

This function can not be called from an interrupt handler.

Parameters:
  • graph[in] The graph to be saved.

void pi_sfu_graph_save_async(pi_sfu_graph_t *graph, pi_evt_t *task)

Save an SFU graph asynchronously.

Save the state of an sfu graph. The state is saved to L2. This can be used to switch to a different graph and come back to this one later on. The state will be automatically restored when the graph is loaded.

  • This operation is done asynchronously, which can be interesting since this can take quite a long time for big graphs. The end of the save operation is notified through a pmsis task, which can be a callback, a blocking task, or an interrupt handler. See pmsis task documentation for more details.

Parameters:
  • graph[in] The graph to be saved.

  • task[in] The task used to notify the end of the save.

void pi_sfu_graph_reconfigure(pi_sfu_graph_t *graph)

Reconfigure GFU filters in an SFU graph.

Send RECONF command for ‘graph’ to the SFU and wait for it to finish.

On RECONF command, SFU will reload coefficients from L2 for all GFU filters that belong to the ‘graph’ and that are flagged as reconfigurable.

Note

This function cannot be called from an interrupt handler.

Parameters:
  • graph[in] The graph to be reconfigured.

void pi_sfu_graph_reconfigure_async(pi_sfu_graph_t *graph, pi_evt_t *task)

Reconfigure GFU filters in an SFU graph asynchronously.

Send RECONF command for ‘graph’ to the SFU and optionally register a ‘task’ to be notified when the reconfiguration is done. On RECONF command, SFU will reload coefficients from L2 for all GFU filters that belong to the ‘graph’ and that are flagged as reconfigurable. The end of the reconfiguration operation is notified through a pmsis task, which can be a callback, a blocking task, or an interrupt handler. See pmsis task documentation for more details.

Parameters:
  • graph[in] The graph to be reconfigured.

  • task[in] The task used to notify the end of the reconfiguration.

int32_t pi_sfu_graph_filter_coeffs_set(pi_sfu_graph_t *graph, int32_t node_id, uint32_t *coeffs)

Set pointer to filter coefficients of a GFU filter.

The function finds L2 configuration of the GFU filter node ‘node_id’ in ‘graph’ and updates COEFF_PTR field with given pointer ‘coeffs’. It does not interact with SFU.

Parameters:
  • graph[in] Pointer to the graph context

  • node_id[in] Node descriptor index in generated graph descriptor.

  • coeffs[in] Pointer to filter coefficient data. Coefficients must be prepared in SFU format. Each type of filter has its own layout of coefficients, normalization shifts and other parameters that may be part of this configuration (see SFU documentation for details). New coefficent set must preserve previous filter size as SFU does not support changing filter size on the fly.

int32_t pi_sfu_graph_gfu_filter_refs_get(pi_sfu_graph_t *graph, int32_t sfugen_id, pi_sfu_gfu_filter_refs_t *filter_refs)

Get pointers to coefficients and delay line in L2 configuration of node ‘sfugen_id’ of graph ‘graph’.

Note

Available only for dynamic clones of a graph created by pi_sfu_graph_dynamic_clone()

Parameters:
  • graph[in] Pointer to the graph context

  • sfugen_id[in] Node descriptor index in generated graph descriptor.

  • filter_refs[out] Relevant pointers and sizes (see pi_sfu_gfu_filter_refs_t for more details)

int32_t pi_sfu_graph_gfu_filter_refs_any_get(pi_sfu_graph_t *graph, int32_t sfugen_id, pi_sfu_gfu_filter_refs_t *filter_refs)

Get pointers and sizes of coefficients and delay line in L2 configuration of node ‘sfugen_id’ of graph ‘graph’.

Note

Available for any graph (cloned or not).

Parameters:
  • graph[in] Pointer to the graph context

  • sfugen_id[in] Node descriptor index in generated graph descriptor.

  • filter_refs[out] Relevant pointers and sizes (see pi_sfu_gfu_filter_refs_t for more details)

int32_t pi_sfu_volume_set(const uint32_t index, const uint32_t mantissa, const int32_t exponent)

Write volume in form of (mantissa, exponent) to a volume register ‘index’. SFU provides 32 volume registers indexed from 0 to 31. Written value takes immediate effect on all GFU or LIMITER nodes that have volume enabled and have this ‘index’ selected as their volume. The effect on the sample is according to the formula: y = x * mantissa * 2^(exponent).

uint32_t pi_sfu_asrc_ratio_get(pi_sfu_graph_t *graph, uint32_t node_id)

Get current value of ASRC frequency ratio (Fout / Fin).

If ASRC is in automatic mode, function returns current ratio estimation (RO register). If ASRC is in manual mode, function returns value configured value (RW register).

Parameters:
  • graph[in] Pointer to the graph context

  • node_id[in] ASRC node descriptor index

Returns:

ASRC ratio in Q4.22 fixed-point format.

int32_t pi_sfu_asrc_ratio_set(pi_sfu_graph_t *graph, int32_t node_id, uint32_t ratio)

Set ASRC Conversion Ratio.

Set the ASRC Conversion Ratio in manual mode

Parameters:
  • graph[in] Pointer to the graph context

  • node_id[in] ASRC node descriptor index

  • ratio[in] ASRC conversion ratio (Fout/Fin) in Q4.22 fixed-point format

int32_t pi_sfu_status_asrc_lock_get(pi_sfu_graph_t *graph, int32_t node_id)

Get ASRC frequency tracking lock status for ‘node_id’ of the graph ‘graph’.

Parameters:
  • graph[in] Pointer to the graph context

  • node_id[in] ASRC node descriptor index

Return values:
  • 0 – Not locked

  • 1 – Locked

  • -1 – Error

Returns:

Lock status of ASRC node ‘node_id’.

int32_t pi_sfu_audio_clock_set(uint32_t phy_clock_id, uint32_t enable, uint32_t frequency)

Enable/disable SFU audio clock and set its frequency. This function ignores allocation status of the clock that may be (or not) done by SFU_AllocateAudioClock() and writes directly to one of AUDIO_CLK_CFG_[i] registers. Clock : Must be in range from CLK_AUD0 to CLK_AUD3.

Returns:

0 on success and -1 on failure.

int32_t pi_sfu_mem_out_mute_set(uint32_t mask)

Mute/unmute MEM_OUT outputs.

Parameters:
  • mask[in] Mute bit mask. Each bit corresponds to one MEM_OUT block (bit[i] - MEM_OUT.i). Bit value 0: Unmute corresponding MEM_OUT block Bit value 1: Mute corresponding MEM_OUT block

Returns:

Error code

uint32_t pi_sfu_mem_out_mute_get()

Get mute configuration of MEM_OUT blocks.

Returns:

Mute bit mask. Each bit corresponds to one MEM_OUT block (bit[i] - MEM_OUT.i).

int32_t pi_sfu_stream_out_mute_set(uint32_t mask)

Mute/unmute STREAM_OUT outputs.

Parameters:
  • mask[in] Mute bit mask. Each bit corresponds to one STREAM_OUT block (bit[i] - STREAM_OUT.i). Bit value 0: Unmute corresponding STREAM_OUT block Bit value 1: Mute corresponding STREAM_OUT block

Returns:

Error code

uint32_t pi_sfu_stream_out_mute_get()

Get mute configuration of STREAM_OUT blocks.

Returns:

Mute bit mask. Each bit corresponds to one STREAM_OUT block (bit[i] - STREAM_OUT.i).

int32_t pi_sfu_pdm_out_mute_set(uint32_t mask)

Mute/unmute PDM_OUT outputs.

Warning

Mute doesn’t work properly on GAP9 PDM_OUT with linear interpolator. It works only on PDM_OUT with IIR interpolator.

Parameters:
  • mask[in] Mute bit mask. Each bit corresponds to one PDM_OUT block (bit[i] - PDM_OUT.i). Bit value 0: Unmute corresponding PDM_OUT block Bit value 1: Mute corresponding PDM_OUT block

Returns:

Error code

uint32_t pi_sfu_pdm_out_mute_get()

Get mute configuration of STREAM_OUT blocks.

Returns:

Mute bit mask. Each bit corresponds to one STREAM_OUT block (bit[i] - STREAM_OUT.i).

struct pi_sfu_conf
#include <sfu_pmsis_runtime.h>

SFU configuration structure.

This structure is used to pass the desired sfu configuration to the runtime when opening it.

Public Members

uint32_t sfu_frequency

Initial operating frequency (in Hz)

struct pi_sfu_gfu_filter_refs_t

Public Members

int32_t id

Node entry index in SfuGen descriptor list SFU_RunTimeDescr_T

uint32_t **p_coeff_addr

Pointer to the pointer to L2 coefficients

uint32_t *p_coeff

Pointer to L2 coefficients

uint32_t coeff_len

Coefficients length (in 32-bit words)

uint32_t **p_dlyline_addr

Pointer to the pointer to L2 state

uint32_t *p_dlyline

Pointer to L2 delay line (state)

uint32_t dlyline_len

State length (in 32-bit words)

struct pi_sfu_gfu_filter_refs_short_t

Public Members

uint32_t *p_coeff

Pointer to L2 coefficients

uint32_t *p_dlyline

Pointer to L2 dlyline

struct pi_sfu_pdm_itf_id_s
#include <sfu_pmsis_runtime.h>

Description of one PDM channel (in GAP SAI block).

Public Members

uint32_t sai

SAI interface id (see PI_SFU_SAI_ID_…)

uint32_t ch

Id of the channel within a SAI (see PI_SFU_SAI_CH_ID_…)

uint32_t is_output

0: input, 1: output (from SFU perspective)

struct pi_sfu_i2s_itf_id_s
#include <sfu_pmsis_runtime.h>

Description of SAI block.

Public Members

uint32_t sai

SAI interface id (see PI_SFU_SAI_ID_…)

uint32_t is_output

0: input, 1: output (from SFU perspective)