Skip to content

Infineon/audio-codec-ak4954a

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 

Audio Codec (AK4954A)

Overview

This library provides functions to support use of the AK4954A audio codec found on the CY8CKIT-028-TFT shield.

Quick Start

  1. Create an empty application
  2. Add this library to the application
  3. Add the following code to your application.\n The wave.h and wave.c files can be pulled from this example:\n https://github.com/cypresssemiconductorco/mtb-example-psoc6-i2s

\note This example is targeted for Arduino-based boards.

#include "cyhal.h"
#include "cybsp.h"
#include "mtb_ak4954a.h"
#include "wave.h"

#define AUDIO_SYS_CLOCK_HZ (98304000)   /* in Hz */
#define MCLK_FREQ_HZ       (4096000)    /* in Hz */
#define MCLK_DUTY_CYCLE    (50.0)       /* in %  */

static cyhal_i2c_t i2c;
cyhal_clock_t pll_clock;
cyhal_clock_t audio_clock;
cyhal_pwm_t mclk_pwm;
cyhal_i2s_t i2s;

const cyhal_i2c_cfg_t i2c_config = {
    .is_slave        = false,
    .address         = 0,
    .frequencyhal_hz = 400000
};

const cyhal_i2s_pins_t i2s_pins = {
    .sck  = CYBSP_D1,
    .ws   = CYBSP_D2,
    .data = CYBSP_D3
};

const cyhal_i2s_config_t i2s_config = {
    .is_tx_slave    = false,    /* TX is Master */
    .is_rx_slave    = false,    /* RX not used */
    .mclk_hz        = 0,        /* External MCLK not used */
    .channel_length = 32,       /* In bits */
    .word_length    = 16,       /* In bits */
    .sample_rate_hz = 48000     /* In Hz */
};

void i2s_isr_handler(void *arg, cyhal_i2s_event_t event)
{
    (void) arg;
    (void) event;

    /* Stop the I2S TX */
    cyhal_i2s_stop_tx(&i2s);
}

int main(void)
{
    cy_rslt_t rslt;

    rslt = cybsp_init();
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);

    __enable_irq();

    /* Initialize the I2C to use with the audio codec */
    i2c_init(&i2c, CYBSP_I2C_SDA, CYBSP_I2C_SCL);
    cyhal_i2c_configure(&i2c, &i2c_config);

    /* Initialize the PLL */
    rslt = cyhal_clock_allocate(&pll_clock, CYHAL_CLOCK_BLOCK_PLL);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);
    rslt = cyhal_clock_set_frequency(&pll_clock, AUDIO_SYS_CLOCK_HZ, NULL);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);
    rslt = cyhal_clock_set_enabled(&pll_clock, true, true);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);

    /* Initialize the audio subsystem clock (HFCLK1) */
    rslt = cyhal_clock_get(&audio_clock, &CYHAL_CLOCK_HF[1]);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);
    rslt = cyhal_clock_init(&audio_clock);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);
    rslt = cyhal_clock_set_source(&audio_clock, &pll_clock);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);
    rslt = cyhal_clock_set_enabled(&audio_clock, true, true);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);

    /* Initialize the Master Clock with a PWM */
    rslt = cyhal_pwm_init(&mclk_pwm, CYBSP_D0, NULL);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);
    rslt = cyhal_pwm_set_duty_cycle(&mclk_pwm, MCLK_DUTY_CYCLE, MCLK_FREQ_HZ);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);
    rslt = cyhal_pwm_start(&mclk_pwm);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);

    /* Wait for the MCLK to clock the audio codec */
    cyhal_system_delay_ms(1);

    /* Initialize the I2S */
    rslt = cyhal_i2s_init(&i2s, &i2s_pins, NULL, NC, &i2s_config, &audio_clock);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);
    cyhal_i2s_register_callback(&i2s, i2s_isr_handler, NULL);
    cyhal_i2s_enable_event(&i2s, CYHAL_I2S_ASYNC_TX_COMPLETE,
                                  CYHAL_ISR_PRIORITY_DEFAULT, true);

    rslt = mtb_ak4954a_init(&i2c);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);

    /* Enable the AK494A audio codec with the default volume */
    mtb_ak4954a_activate();
    mtb_ak4954a_adjust_volume(AK4954A_HP_VOLUME_DEFAULT);

    /* Setup complete */

    /* Start the I2S TX */
    cyhal_i2s_start_tx(&i2s);

    /* Initiate a transfer */
    rslt = cyhal_i2s_write_async(&i2s, wave_data, WAVE_SIZE);
    CY_ASSERT(rslt == CY_RSLT_SUCCESS);

    for(;;) { }
}

The follow blocks of code can be used to illustrate other functionality. In the example above, replace the code following the "Setup complete" comment with one of these code blocks.

Generate an audio beep

mtb_ak4954a_set(AK4954A_REG_PWR_MGMT1, AK4954A_PWR_MGMT1_PMBP);
mtb_ak4954a_write_byte(AK4954A_REG_BEEP_ON_TIME, 0x40);
mtb_ak4954a_write_byte(AK4954A_REG_BEEP_FREQ, AK4954A_BEEP_FREQ_BPFR_800Hz);
mtb_ak4954a_write_byte(AK4954A_REG_BEEP_VOL_CTRL, AK4954A_BEEP_VOL_CTRL_BPLVL_m21db);
mtb_ak4954a_set(AK4954A_REG_BEEP_VOL_CTRL, AK4954A_BEEP_VOL_CTRL_BPOUT);

Microphone loopback mode

mtb_ak4954a_write_byte(AK4954A_REG_DIG_FLTR_MODE, AK4954A_DIG_FLTR_MODE_PFSDO |
                                                  AK4954A_DIG_FLTR_MODE_ADCPF |
                                                  AK4954A_DIG_FLTR_MODE_PFDAC);

mtb_ak4954a_set(AK4954A_REG_SIG_SEL1, AK4954A_SIG_SEL1_PMMP);
mtb_ak4954a_set(AK4954A_REG_PWR_MGMT1, AK4954A_PWR_MGMT1_PMADL |
                                       AK4954A_PWR_MGMT1_PMPFIL);

More information


© Cypress Semiconductor Corporation, 2019-2020.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages