RZ/A Flexible Software Package Documentation  Release v3.3.0

 
Serial Sound Interface (r_ssi)

Functions

fsp_err_t R_SSI_Open (i2s_ctrl_t *const p_ctrl, i2s_cfg_t const *const p_cfg)
 
fsp_err_t R_SSI_Stop (i2s_ctrl_t *const p_ctrl)
 
fsp_err_t R_SSI_StatusGet (i2s_ctrl_t *const p_ctrl, i2s_status_t *const p_status)
 
fsp_err_t R_SSI_Write (i2s_ctrl_t *const p_ctrl, void const *const p_src, uint32_t const bytes)
 
fsp_err_t R_SSI_Read (i2s_ctrl_t *const p_ctrl, void *const p_dest, uint32_t const bytes)
 
fsp_err_t R_SSI_WriteRead (i2s_ctrl_t *const p_ctrl, void const *const p_src, void *const p_dest, uint32_t const bytes)
 
fsp_err_t R_SSI_Mute (i2s_ctrl_t *const p_ctrl, i2s_mute_t const mute_enable)
 
fsp_err_t R_SSI_Close (i2s_ctrl_t *const p_ctrl)
 
fsp_err_t R_SSI_CallbackSet (i2s_ctrl_t *const p_api_ctrl, void(*p_callback)(i2s_callback_args_t *), void const *const p_context, i2s_callback_args_t *const p_callback_memory)
 

Detailed Description

Driver for the SSIF peripheral on RZ MPUs. This module implements the I2S Interface.

Overview

Features

The SSI module supports the following features:

Configuration

Build Time Configurations for r_ssi

The following build time configurations are defined in fsp_cfg/r_ssi_cfg.h:

ConfigurationOptionsDefaultDescription
Parameter Checking
  • Default (BSP)
  • Enabled
  • Disabled
Default (BSP) If selected code for parameter checking is included in the build.
DMAC Support
  • Enabled
  • Disabled
Disabled If code for DMAC transfer support is included in the build.

Configurations for Connectivity > I2S Driver on r_ssi

This module can be added to the Stacks tab via New Stack > Connectivity > I2S Driver on r_ssi.

ConfigurationOptionsDefaultDescription
NameName must be a valid C symbolg_i2s0 Module name.
ChannelValue must be an integer between 0 and 30 Specify the I2S channel.
Operating Mode (Master/Slave)
  • Master Mode
  • Slave Mode
Master Mode Select if the MCU is I2S master or slave.
Bit Depth
  • 8 Bits
  • 16 Bits
  • 18 Bits
  • 20 Bits
  • 22 Bits
  • 24 Bits
  • 32 Bits
16 Bits Select the bit depth of one sample of audio data.
Word Length
  • 8 Bits
  • 16 Bits
  • 24 Bits
  • 32 Bits
  • 48 Bits
  • 64 Bits
  • 128 Bits
  • 256 Bits
16 Bits Select the word length of audio data. Must be at least as large as Data bits.
WS Continue Mode
  • Enabled
  • Disabled
Disabled Enable WS continue mode to output the word select (WS) pin even when transmission is idle.
Bit Clock Source(available only in Master mode)MCU Specific OptionsSelect one of the two external AUDIO_CLKs as the external signal to the AUDIO_CLK input pin.
Bit Clock DividerRefer to the RZA Configuration tool for available options.Audio Clock / 1 Select divider used to generate bit clock from audio clock.
CallbackName must be a valid C symbolNULL A user callback function can be provided. If this callback function is provided, it will be called from all three interrupt service routines (ISR).
Transmit Interrupt EnableMCU Specific OptionsEnable the transmit interrupt.
Transmit Interrupt PriorityValue must be an integer between 0 and 3124 Select the transmit interrupt priority.
Receive Interrupt EnableMCU Specific OptionsEnable the receive inetrrupt.
Receive Interrupt PriorityValue must be an integer between 0 and 3124 Select the receive interrupt priority.
Idle/Error Interrupt PriorityValue must be an integer between 0 and 3124 Select the Idle/Error interrupt priority.

Clock Configuration

The SSI peripheral runs on P0Φ. The P0Φ frequency can be configured on the Clocks tab of the RZ Configuration editor. The SSI audio clock can optionally be supplied from an external source through the AUDIO_CLK pin in master mode.

Pin Configuration

The SSI uses the following pins:

Usage Notes

SSI Frames

An SSI frame is 2 samples worth of data. The frame boundary (end of previous frame, start of next frame) is on the falling edge of the SSILRCKn signal.

r_ssi_frame_diagram.PNG
SSI Frame Diagram (8-bit word, 8-bit samples)
Note
If the word length is longer than the sample bit depth, padding bits (0) will be added after the sample.

Audio Data

Only uncompressed PCM data is supported.

Data arrays have the following size, alignment, and length based on the "Bit Depth" setting:

Bit Depth Array Data Type Required Alignment Required Length (bytes)
8 Bits 8-bit integer 1 byte alignment Multiple of 2
16 Bits 16-bit integer 2 byte alignment Multiple of 4
18 Bits 32-bit integer, right justified 4 byte alignment Multiple of 8
20 Bits 32-bit integer, right justified 4 byte alignment Multiple of 8
22 Bits 32-bit integer, right justified 4 byte alignment Multiple of 8
24 Bits 32-bit integer, right justified 4 byte alignment Multiple of 8
32 Bits 32-bit integer 4 byte alignment Multiple of 8
Note
The length of the array must be a multiple of 2 when the data type is the recommended data type. The 2 represents the frame size (left and right channel) of I2S communication. The SSIF peripheral does not support odd read/write lengths in I2S mode.

Audio Clock

The audio clock is only required for master mode.

Audio Clock Frequency

The bit clock frequency is the product of the sampling frequency and channels and bits per system word:

bit_clock (Hz) = sampling_frequency (Hz) * channels * system_word_bits

I2S data always has 2 channels.

For example, the bit clock for transmitting 2 channels of 16-bit data (using a 16-bit system word) at 44100 Hz would be:

44100 * 2 * 16 = 1,411,200 Hz

The audio clock frequency is used to generate the bit clock frequency. It must be a multiple of the bit clock frequency. Refer to the Bit Clock Divider configuration for divider options. The input audio clock frequency must be:

audio_clock (Hz) = desired_bit_clock (Hz) * bit_clock_divider

To get a bit clock of 1.4 MHz from an audio clock of 2.8 MHz, select the divider Audio Clock / 2.

Audio Clock Source

The audio clock source can come from:

Limitations

Developers should be aware of the following limitations when using the SSI:

Examples

Basic Example

This is a basic example of minimal use of the SSI in an application.

#define SSI_EXAMPLE_SAMPLES_TO_TRANSFER (1024)
#define SSI_EXAMPLE_TONE_FREQUENCY_HZ (800)
int16_t g_src[SSI_EXAMPLE_SAMPLES_TO_TRANSFER];
int16_t g_dest[SSI_EXAMPLE_SAMPLES_TO_TRANSFER];
void ssi_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Create a stereo sine wave. Using formula sample = sin(2 * pi * tone_frequency * t / sampling_frequency) */
uint32_t freq = SSI_EXAMPLE_TONE_FREQUENCY_HZ;
for (uint32_t t = 0; t < SSI_EXAMPLE_SAMPLES_TO_TRANSFER / 2; t += 1)
{
float input = (((float) (freq * t)) * (M_TWOPI)) / SSI_EXAMPLE_AUDIO_SAMPLING_FREQUENCY_HZ;
g_src[2 * t] = (int16_t) ((INT16_MAX * sinf(input)));
g_src[2 * t + 1] = (int16_t) ((INT16_MAX * sinf(input)));
}
/* Initialize the module. */
err = R_SSI_Open(&g_i2s_ctrl, &g_i2s_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* Transfer data. */
(void) R_SSI_WriteRead(&g_i2s_ctrl,
(uint8_t *) &g_src[0],
(uint8_t *) &g_dest[0],
SSI_EXAMPLE_SAMPLES_TO_TRANSFER * sizeof(int16_t));
}

Streaming Example

This is an example of using SSI to stream audio data. This application uses a double buffer to store PCM sine wave data. It starts transmitting in the main loop, then loads the next buffer if it is ready in the callback. If the next buffer is not ready, a flag is set in the callback so the application knows to restart transmission in the main loop.

This example also checks the return code of R_SSI_Write() because R_SSI_Write() can return an error if a transmit overflow occurs before the FIFO is reloaded. If a transmit overflow occurs before the FIFO is reloaded, the SSI will be stopped in the error interrupt, and it cannot be restarted until the I2S_EVENT_IDLE callback is received.

#define SSI_STREAMING_EXAMPLE_AUDIO_SAMPLING_FREQUENCY_HZ (22050)
#define SSI_STREAMING_EXAMPLE_SAMPLES_PER_CHUNK (1024)
#define SSI_STREAMING_EXAMPLE_TONE_FREQUENCY_HZ (800)
int16_t g_stream_src[2][SSI_EXAMPLE_SAMPLES_TO_TRANSFER];
uint32_t g_buffer_index = 0;
volatile bool g_send_data_in_main_loop = true;
volatile bool g_data_ready = false;
/* Example callback called when SSI is ready for more data. */
void ssi_example_callback (i2s_callback_args_t * p_args)
{
/* Reload the FIFO if we hit the transmit watermark or restart transmission if the SSI is idle because it was
* stopped after a transmit FIFO overflow. */
if ((I2S_EVENT_TX_EMPTY == p_args->event) || (I2S_EVENT_IDLE == p_args->event))
{
if (g_data_ready)
{
/* Reload FIFO and handle errors. */
ssi_example_write();
}
else
{
/* Data was not ready yet, send it in the main loop. */
g_send_data_in_main_loop = true;
}
}
}
/* Load the transmit FIFO and check for error conditions. */
void ssi_example_write (void)
{
/* Transfer data. This call is non-blocking. */
fsp_err_t err = R_SSI_Write(&g_i2s_ctrl,
(uint8_t *) &g_stream_src[g_buffer_index][0],
SSI_STREAMING_EXAMPLE_SAMPLES_PER_CHUNK * sizeof(int16_t));
if (FSP_SUCCESS == err)
{
/* Switch the buffer after data is sent. */
g_buffer_index = !g_buffer_index;
/* Allow loop to calculate next buffer only if transmission was successful. */
g_data_ready = false;
}
else
{
/* Getting here most likely means a transmit overflow occurred before the FIFO could be reloaded. The
* application must wait until the SSI is idle, then restart transmission. In this example, the idle
* callback transmits data or resets the flag g_send_data_in_main_loop. */
}
}
/* Calculate samples. This example is just a sine wave. For this type of data, it would be better to calculate
* one period and loop it. This example should be updated for the audio data used by the application. */
void ssi_example_calculate_samples (uint32_t buffer_index)
{
static uint32_t t = 0U;
/* Create a stereo sine wave. Using formula sample = sin(2 * pi * tone_frequency * t / sampling_frequency) */
uint32_t freq = SSI_STREAMING_EXAMPLE_TONE_FREQUENCY_HZ;
for (uint32_t i = 0; i < SSI_STREAMING_EXAMPLE_SAMPLES_PER_CHUNK / 2; i += 1)
{
float input = (((float) (freq * t)) * M_TWOPI) / SSI_STREAMING_EXAMPLE_AUDIO_SAMPLING_FREQUENCY_HZ;
t++;
/* Store sample twice, once for left channel and once for right channel. */
int16_t sample = (int16_t) ((INT16_MAX * sinf(input)));
g_stream_src[buffer_index][2 * i] = sample;
g_stream_src[buffer_index][2 * i + 1] = sample;
}
/* Data is ready to be sent in the interrupt. */
g_data_ready = true;
}
void ssi_streaming_example (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Initialize the module. */
err = R_SSI_Open(&g_i2s_ctrl, &g_i2s_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
while (true)
{
/* Prepare data in a buffer that is not currently used for transmission. */
ssi_example_calculate_samples(g_buffer_index);
/* Send data in main loop the first time, and if it was not ready in the interrupt. */
if (g_send_data_in_main_loop)
{
/* Clear flag. */
g_send_data_in_main_loop = false;
/* Reload FIFO and handle errors. */
ssi_example_write();
}
/* If the next buffer is ready, wait for the data to be sent in the interrupt. */
while (g_data_ready)
{
/* Do nothing. */
}
}
}

Data Structures

struct  ssi_instance_ctrl_t
 
struct  ssi_extended_cfg_t
 

Enumerations

enum  ssi_audio_clock_t
 
enum  ssi_clock_div_t
 

Data Structure Documentation

◆ ssi_instance_ctrl_t

struct ssi_instance_ctrl_t

Channel instance control block. DO NOT INITIALIZE. Initialization occurs when i2s_api_t::open is called.

◆ ssi_extended_cfg_t

struct ssi_extended_cfg_t

SSI configuration extension. This extension is optional.

Data Fields
ssi_audio_clock_t audio_clock Audio clock source, default is SSI_AUDIO_CLOCK_EXTERNAL.
ssi_clock_div_t bit_clock_div Select bit clock division ratio.

Enumeration Type Documentation

◆ ssi_audio_clock_t

Audio clock source.

Enumerator
SSI_AUDIO_CLOCK_EXTERNAL2 

Audio clock source is the AUDIO_CLK2 input pin.

SSI_AUDIO_CLOCK_EXTERNAL1 

Audio clock source is the AUDIO_CLK1 input pin.

◆ ssi_clock_div_t

Bit clock division ratio. Bit clock frequency = audio clock frequency / bit clock division ratio.

Enumerator
SSI_CLOCK_DIV_1 

Clock divisor 1.

SSI_CLOCK_DIV_2 

Clock divisor 2.

SSI_CLOCK_DIV_4 

Clock divisor 4.

SSI_CLOCK_DIV_6 

Clock divisor 6.

SSI_CLOCK_DIV_8 

Clock divisor 8.

SSI_CLOCK_DIV_12 

Clock divisor 12.

SSI_CLOCK_DIV_16 

Clock divisor 16.

SSI_CLOCK_DIV_24 

Clock divisor 24.

SSI_CLOCK_DIV_32 

Clock divisor 32.

SSI_CLOCK_DIV_48 

Clock divisor 48.

SSI_CLOCK_DIV_64 

Clock divisor 64.

SSI_CLOCK_DIV_96 

Clock divisor 96.

SSI_CLOCK_DIV_128 

Clock divisor 128.

Function Documentation

◆ R_SSI_Open()

fsp_err_t R_SSI_Open ( i2s_ctrl_t *const  p_ctrl,
i2s_cfg_t const *const  p_cfg 
)

Opens the SSI. Implements i2s_api_t::open.

This function sets this clock divisor and the configurations specified in i2s_cfg_t. It also opens the timer and transfer instances if they are provided.

Return values
FSP_SUCCESSReady for I2S communication.
FSP_ERR_ASSERTIONThe pointer to p_ctrl or p_cfg is null.
FSP_ERR_ALREADY_OPENThe control block has already been opened.
FSP_ERR_IP_CHANNEL_NOT_PRESENTChannel number is not available on this device.
Returns
See Common Error Codes or functions called by this function for other possible return codes. This function calls:

◆ R_SSI_Stop()

fsp_err_t R_SSI_Stop ( i2s_ctrl_t *const  p_ctrl)

Stops SSI. Implements i2s_api_t::stop.

This function disables both transmission and reception, and disables any transfer instances used.

The SSI will stop on the next frame boundary. Do not restart SSI until it is idle.

Return values
FSP_SUCCESSI2S communication stop request issued.
FSP_ERR_ASSERTIONThe pointer to p_ctrl was null.
FSP_ERR_NOT_OPENThe channel is not opened.
Returns
See Common Error Codes or lower level drivers for other possible return codes.

◆ R_SSI_StatusGet()

fsp_err_t R_SSI_StatusGet ( i2s_ctrl_t *const  p_ctrl,
i2s_status_t *const  p_status 
)

Gets SSI status and stores it in provided pointer p_status. Implements i2s_api_t::statusGet.

Return values
FSP_SUCCESSInformation stored successfully.
FSP_ERR_ASSERTIONThe p_instance_ctrl or p_status parameter was null.
FSP_ERR_NOT_OPENThe channel is not opened.

◆ R_SSI_Write()

fsp_err_t R_SSI_Write ( i2s_ctrl_t *const  p_ctrl,
void const *const  p_src,
uint32_t const  bytes 
)

Writes data buffer to SSI. Implements i2s_api_t::write.

This function resets the transfer if the transfer interface is used, or writes the length of data that fits in the FIFO then stores the remaining write buffer in the control block to be written in the ISR.

Write() cannot be called if another write(), read() or writeRead() operation is in progress. Write can be called when the SSI is idle, or after the I2S_EVENT_TX_EMPTY event.

Return values
FSP_SUCCESSWrite initiated successfully.
FSP_ERR_ASSERTIONThe pointer to p_ctrl or p_src was null, or bytes requested was 0.
FSP_ERR_IN_USEAnother transfer is in progress, data was not written.
FSP_ERR_NOT_OPENThe channel is not opened.
FSP_ERR_UNDERFLOWA transmit underflow error is pending. Wait for the SSI to go idle before resuming communication.
Returns
See Common Error Codes or functions called by this function for other possible return codes. This function calls:

◆ R_SSI_Read()

fsp_err_t R_SSI_Read ( i2s_ctrl_t *const  p_ctrl,
void *const  p_dest,
uint32_t const  bytes 
)

Reads data into provided buffer. Implements i2s_api_t::read.

This function resets the transfer if the transfer interface is used, or reads the length of data available in the FIFO then stores the remaining read buffer in the control block to be filled in the ISR.

Read() cannot be called if another write(), read() or writeRead() operation is in progress. Read can be called when the SSI is idle, or after the I2S_EVENT_RX_FULL event.

Return values
FSP_SUCCESSRead initiated successfully.
FSP_ERR_IN_USEPeripheral is in the wrong mode or not idle.
FSP_ERR_ASSERTIONThe pointer to p_ctrl or p_dest was null, or bytes requested was 0.
FSP_ERR_NOT_OPENThe channel is not opened.
FSP_ERR_OVERFLOWA receive overflow error is pending. Wait for the SSI to go idle before resuming communication.
Returns
See Common Error Codes or functions called by this function for other possible return codes. This function calls:

◆ R_SSI_WriteRead()

fsp_err_t R_SSI_WriteRead ( i2s_ctrl_t *const  p_ctrl,
void const *const  p_src,
void *const  p_dest,
uint32_t const  bytes 
)

Writes from source buffer and reads data into destination buffer. Implements i2s_api_t::writeRead.

This function calls R_SSI_Write and R_SSI_Read.

writeRead() cannot be called if another write(), read() or writeRead() operation is in progress. writeRead() can be called when the SSI is idle, or after the I2S_EVENT_RX_FULL event.

Return values
FSP_SUCCESSWrite and read initiated successfully.
FSP_ERR_IN_USEPeripheral is in the wrong mode or not idle.
FSP_ERR_ASSERTIONAn input parameter was invalid.
FSP_ERR_NOT_OPENThe channel is not opened.
FSP_ERR_UNDERFLOWA transmit underflow error is pending. Wait for the SSI to go idle before resuming communication.
FSP_ERR_OVERFLOWA receive overflow error is pending. Wait for the SSI to go idle before resuming communication.
Returns
See Common Error Codes or functions called by this function for other possible return codes. This function calls:

◆ R_SSI_Mute()

fsp_err_t R_SSI_Mute ( i2s_ctrl_t *const  p_ctrl,
i2s_mute_t const  mute_enable 
)

Mutes SSI on the next frame boundary. Implements i2s_api_t::mute.

Data is still written while mute is enabled, but the transmit line outputs zeros.

Return values
FSP_SUCCESSTransmission is muted.
FSP_ERR_ASSERTIONThe pointer to p_ctrl was null.
FSP_ERR_NOT_OPENThe channel is not opened.

◆ R_SSI_Close()

fsp_err_t R_SSI_Close ( i2s_ctrl_t *const  p_ctrl)

Closes SSI. Implements i2s_api_t::close.

This function powers down the SSI and closes the lower level timer and transfer drivers if they are used.

Return values
FSP_SUCCESSDevice closed successfully.
FSP_ERR_ASSERTIONThe pointer to p_ctrl was null.
FSP_ERR_NOT_OPENThe channel is not opened.

◆ R_SSI_CallbackSet()

fsp_err_t R_SSI_CallbackSet ( i2s_ctrl_t *const  p_api_ctrl,
void(*)(i2s_callback_args_t *)  p_callback,
void const *const  p_context,
i2s_callback_args_t *const  p_callback_memory 
)

Updates the user callback and has option of providing memory for callback structure. Implements i2s_api_t::callbackSet

Return values
FSP_SUCCESSCallback updated successfully.
FSP_ERR_ASSERTIONA required pointer is NULL.
FSP_ERR_NOT_OPENThe control block has not been opened.
FSP_ERR_NO_CALLBACK_MEMORYp_callback is non-secure and p_callback_memory is either secure or NULL.