RAFW Flexible Software Package Documentation  Release v2.0.1

 
I2S (r_i2s_w)

Functions

fsp_err_t R_I2S_W_Open (i2s_ctrl_t *const p_ctrl, i2s_cfg_t const *const p_cfg)
 
fsp_err_t R_I2S_W_Stop (i2s_ctrl_t *const p_ctrl)
 
fsp_err_t R_I2S_W_StatusGet (i2s_ctrl_t *const p_ctrl, i2s_status_t *const p_status)
 
fsp_err_t R_I2S_W_Write (i2s_ctrl_t *const p_ctrl, void const *const p_src, uint32_t const bytes)
 
fsp_err_t R_I2S_W_Read (i2s_ctrl_t *const p_ctrl, void *const p_dest, uint32_t const bytes)
 
fsp_err_t R_I2S_W_WriteRead (i2s_ctrl_t *const p_ctrl, void const *const p_src, void *const p_dest, uint32_t const bytes)
 
fsp_err_t R_I2S_W_Mute (i2s_ctrl_t *const p_ctrl, i2s_mute_t const mute_enable)
 
fsp_err_t R_I2S_W_Close (i2s_ctrl_t *const p_ctrl)
 
fsp_err_t R_I2S_W_CallbackSet (i2s_ctrl_t *const p_api_ctrl, void(*p_callback)(i2s_callback_args_t *), void *const p_context, i2s_callback_args_t *const p_callback_memory)
 

Detailed Description

Driver for the I2S_W peripheral on RAFW MCUs. This module implements the I2S Interface.

Overview

Features

The I2S_W module supports the following features:

Configuration

Build Time Configurations for r_i2s_w

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

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

Configurations for Connectivity > I2S (r_i2s_w)

This module can be added to the Stacks tab via New Stack > Connectivity > I2S (r_i2s_w). Non-secure callable guard functions can be generated for this module by right clicking the module in the RA Configuration tool and checking the "Non-secure Callable" box.

ConfigurationOptionsDefaultDescription
NameName must be a valid C symbolg_i2s0 Module name.
Operating Mode (Master/Slave)
  • Master Mode
  • Slave Mode
Master Mode Select if the MCU is I2S master or slave.
Bit Depth
  • 16 Bits
  • 20 Bits
  • 24 Bits
  • 32 Bits
16 Bits Select the bit depth of one sample of audio data.
Word Length
  • 32 Bits
  • 64 Bits
  • 128 Bits
  • 256 Bits
32 Bits Select the word length of audio data. Must be at least as large as Data bits.
Sample Rate(available only in Master mode)
  • 8000Hz
  • 11025Hz
  • 12000Hz
  • 16000Hz
  • 22050Hz
  • 24000Hz
  • 32000Hz
  • 44100Hz
  • 48000Hz
8000Hz Select sample rate 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 PriorityMCU Specific OptionsSelect the transmit interrupt priority.
Receive Interrupt PriorityMCU Specific OptionsSelect the receive interrupt priority.

Clock Configuration

The I2S_W peripheral runs on FPLLCLK. The FPLLCLK frequency can be configured on the Clocks tab of the RA6W1/RA6W2 Configuration editor. The I2S_W audio clock can optionally be supplied from an external source through the PCM_CLK pin in slave mode.

Pin Configuration

The I2S_W uses the following pins:

Usage Notes

I2S_W Frames

An I2S_W 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 PCM_FSC signal.

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)
16 Bits 16-bit integer 2 byte alignment Multiple of 4
20 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_W communication. The SSIE peripheral does not support odd read/write lengths in I2S_W 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) * Word Length

I2S_W data always has 2 channels.

For example, the bit clock for transmitting 32-bit word length (using a 16-bit bit depth per channel) at 44100 Hz would be:

44100 * 32 = 1,411,200 Hz

Audio Clock Source

The audio clock source can come from:

Examples

Basic Example

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

#define I2S_EXAMPLE_SAMPLES_TO_TRANSFER (1024)
#define I2S_EXAMPLE_TONE_FREQUENCY_HZ (800)
int16_t g_src[I2S_EXAMPLE_SAMPLES_TO_TRANSFER];
int16_t g_dest[I2S_EXAMPLE_SAMPLES_TO_TRANSFER];
void i2s_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 = I2S_EXAMPLE_TONE_FREQUENCY_HZ;
for (uint32_t t = 0; t < I2S_EXAMPLE_SAMPLES_TO_TRANSFER / 2; t += 1)
{
float input = (((float) (freq * t)) * (float) (M_TWOPI)) / I2S_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_I2S_W_Open(&g_i2s_w_ctrl, &g_i2s_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* Transfer data. */
(void) R_I2S_W_WriteRead(&g_i2s_w_ctrl,
(uint8_t *) &g_src[0],
(uint8_t *) &g_dest[0],
I2S_EXAMPLE_SAMPLES_TO_TRANSFER * sizeof(int16_t));
}

Streaming Example

This is an example of using I2S_W 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_I2S_W_Write() because R_I2S_W_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 I2S_W will be stopped in the error interrupt, and it cannot be restarted until the I2S_EVENT_IDLE callback is received.

#define I2S_STREAMING_EXAMPLE_AUDIO_SAMPLING_FREQUENCY_HZ (22050)
#define I2S_STREAMING_EXAMPLE_SAMPLES_PER_CHUNK (1024)
#define I2S_STREAMING_EXAMPLE_TONE_FREQUENCY_HZ (800)
int16_t g_stream_src[2][I2S_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 I2S_w is ready for more data. */
void i2s_example_callback (i2s_callback_args_t * p_args)
{
/* Reload the FIFO if we hit the transmit watermark or restart transmission if the I2S_W 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. */
i2s_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 i2s_example_write (void)
{
/* Transfer data. This call is non-blocking. */
fsp_err_t err = R_I2S_W_Write(&g_i2s_w_ctrl,
(uint8_t *) &g_stream_src[g_buffer_index][0],
I2S_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 I2S_w 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 i2s_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 = I2S_STREAMING_EXAMPLE_TONE_FREQUENCY_HZ;
for (uint32_t i = 0; i < I2S_STREAMING_EXAMPLE_SAMPLES_PER_CHUNK / 2; i += 1)
{
float input = (((float) (freq * t)) * (float) M_TWOPI) / I2S_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 i2s_streaming_example (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Initialize the module. */
err = R_I2S_W_Open(&g_i2s_w_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. */
i2s_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. */
i2s_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  i2s_w_instance_ctrl_t
 
struct  i2s_w_extended_cfg_t
 

Enumerations

enum  i2s_w_audio_clock_t
 
enum  i2s_w_clock_div_t
 
enum  i2s_w_sr_t
 

Data Structure Documentation

◆ i2s_w_instance_ctrl_t

struct i2s_w_instance_ctrl_t

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

◆ i2s_w_extended_cfg_t

struct i2s_w_extended_cfg_t

I2S configuration extension. This extension is optional.

Data Fields
i2s_w_audio_clock_t audio_clock Audio clock source, default is I2S_W_AUDIO_CLOCK_CRYSTAL.
i2s_w_clock_div_t bit_clock_div Select bit clock division ratio.
i2s_w_sr_t sr sampling rate

Enumeration Type Documentation

◆ i2s_w_audio_clock_t

Audio clock source.

Enumerator
I2S_W_AUDIO_CLOCK_CRYSTAL 

Audio clock source is the AUDIO_CLK input pin.

I2S_W_AUDIO_CLOCK_FPLL 

Audio clock source is internal connection to a MCU specific GPT channel output.

◆ i2s_w_clock_div_t

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

Enumerator
I2S_W_CLOCK_DIV_1 

Clock divisor 1.

I2S_W_CLOCK_DIV_2 

Clock divisor 2.

I2S_W_CLOCK_DIV_4 

Clock divisor 4.

I2S_W_CLOCK_DIV_6 

Clock divisor 6.

I2S_W_CLOCK_DIV_8 

Clock divisor 8.

I2S_W_CLOCK_DIV_12 

Clock divisor 12.

I2S_W_CLOCK_DIV_16 

Clock divisor 16.

I2S_W_CLOCK_DIV_24 

Clock divisor 24.

I2S_W_CLOCK_DIV_32 

Clock divisor 32.

I2S_W_CLOCK_DIV_48 

Clock divisor 48.

I2S_W_CLOCK_DIV_64 

Clock divisor 64.

I2S_W_CLOCK_DIV_96 

Clock divisor 96.

I2S_W_CLOCK_DIV_128 

Clock divisor 128.

◆ i2s_w_sr_t

enum i2s_w_sr_t

Sampling rate.

Enumerator
I2S_W_SR_RESERVED 

0, N/A

I2S_W_SR_8000Hz 

1, 8000Hz

I2S_W_SR_11025Hz 

2, 11025Hz

I2S_W_SR_12000Hz 

3, 12000Hz

I2S_W_SR_RESERVED2 

4, N/A

I2S_W_SR_16000Hz 

5, 16000Hz

I2S_W_SR_22050Hz 

6, 22050Hz

I2S_W_SR_24000Hz 

7, 24000Hz

I2S_W_SR_RESERVED3 

8, N/A

I2S_W_SR_32000Hz 

9, 32000Hz

I2S_W_SR_44100Hz 

10, 44100Hz

I2S_W_SR_48000Hz 

11, 48000Hz

I2S_W_SR_RESERVED4 

12, N/A

I2S_W_SR_RESERVED5 

13, N/A

I2S_W_SR_88200Hz 

14, 88200Hz , descoped

I2S_W_SR_96000Hz 

15, 96000Hz , descoped

I2S_W_SR_RESERVED6 

16, N/A

I2S_W_SR_RESERVED7 

17, N/A

I2S_W_SR_176400Hz 

18, 176400Hz , descoped

I2S_W_SR_192000Hz 

19, 192000Hz , descoped

Function Documentation

◆ R_I2S_W_Open()

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

Opens the I2S. 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 MCU.
Returns
See Common Error Codes or functions called by this function for other possible return codes. This function calls:

◆ R_I2S_W_Stop()

fsp_err_t R_I2S_W_Stop ( i2s_ctrl_t *const  p_ctrl)

Stops I2S. Implements i2s_api_t::stop.

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

The I2S will stop on the next frame boundary. Do not restart I2S 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_I2S_W_StatusGet()

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

Gets I2S 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_I2S_W_Write()

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

Writes data buffer to I2S. 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 I2S 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 I2S 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_I2S_W_Read()

fsp_err_t R_I2S_W_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 I2S 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 I2S 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_I2S_W_WriteRead()

fsp_err_t R_I2S_W_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.

writeRead() cannot be called if another write(), read() or writeRead() operation is in progress. writeRead() can be called when the I2S 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 I2S to go idle before resuming communication.
FSP_ERR_OVERFLOWA receive overflow error is pending. Wait for the I2S 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_I2S_W_Mute()

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

Mutes I2S 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_I2S_W_Close()

fsp_err_t R_I2S_W_Close ( i2s_ctrl_t *const  p_ctrl)

Closes I2S. Implements i2s_api_t::close.

This function powers down the I2S 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_I2S_W_CallbackSet()

fsp_err_t R_I2S_W_CallbackSet ( i2s_ctrl_t *const  p_api_ctrl,
void(*)(i2s_callback_args_t *)  p_callback,
void *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.