Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

nRF52 with WM8960 CODEC

Hi,

I am trying to interface WM8960 CODEC with nRF52832 using (I2S and I2C) .

Problem I am having is with TWI scanner  and also sending data to the know i2c address . have error code of 1

but as same board . testing with Arduino uno and STM32 boards . the twi scanning gives me result 0x1a (7 bit address)

i am not know why nRF doesn't read the CODEC module address

Parents
  • Hi,

    Have you checked the connections to the I2C device is correct, and that it is powered correctly? Which GPIOs are you using for SCL/SDA?

    What is the supply voltage of the I2C device? Arduino uno and STM32 may support 5V level when interfacing I2C devices, but nRF52832 may not support this when running at 3V supply or lower.

    Can you provide a logic trace of the TWI bus?

    Best regards,
    Jørgen

  • Sounds like it should work then.

    Did you change the configuration in the TWI Scanner when adding the "sending data to the know i2c address" part? Did you try the unmodified example?

    Can you provide a logic trace of the TWI bus? 

  • This is the code which i used

    /**
     * Copyright (c) 2016 - 2021, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     * @defgroup tw_scanner main.c
     * @{
     * @ingroup nrf_twi_example
     * @brief TWI Sensor Example main file.
     *
     * This file contains the source code for a sample application using TWI.
     *
     */
    
    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    /* TWI instance ID. */
    #if TWI0_ENABLED
    #define TWI_INSTANCE_ID     0
    #elif TWI1_ENABLED
    #define TWI_INSTANCE_ID     1
    #endif
    
     /* Number of possible TWI addresses. */
     #define TWI_ADDRESSES      127
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    
    /**
     * @brief TWI initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_config = {
           .scl                = ARDUINO_SCL_PIN,
           .sda                = ARDUINO_SDA_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }
    
    #define WM8960_ADDRESS  0x1a
    
    
    #define DMA_MAX_SZE     0xFFFF
    #define DMA_MAX(x)      (((x) <= 0xFFFF)? (x):0xFFFF)
    #define AUDIODATA_SIZE  2   /* 16-bits audio data size */
    
    #define AUIDO_START_ADDRESS       58 /* Offset relative to audio file header size */
    
    
    
    uint32_t AudioTotalSize;  /* This variable holds the total size of the audio file */
    uint32_t AudioRemSize;    /* This variable holds the remaining data in audio file */
    uint16_t *CurrentPos;     /* This variable holds the current position of audio pointer */
    uint32_t WaveDataLength=0;
    uint8_t XferCplt;
    //resgister value
    static uint16_t WM8960_REG_VAL[56] =
    {
      0x0097, 0x0097, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x000A,
      0x01C0, 0x0000, 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x007B, 0x0100, 0x0032, 0x0000, 0x00C3, 0x00C3, 0x01C0,
      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      0x0100, 0x0100, 0x0050, 0x0050, 0x0050, 0x0050, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0040, 0x0000, 0x0000, 0x0050, 0x0050, 0x0000,
      0x0000, 0x0037, 0x004D, 0x0080, 0x0008, 0x0031, 0x0026, 0x00ED
    };
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    /**
      * @brief  Write register of WM8960.
      * @param  reg: The number of resigter which to be read.
      * @param  dat: The data which will be writeen to the register.
      * @retval The value of regsiter.
      */
    uint8_t WM8960_Write_Reg(uint8_t reg, uint16_t dat)  {
    
      uint8_t res,I2C_Data[2];
    
      I2C_Data[0] = (reg<<1)|((uint8_t)((dat>>8)&0x0001));  //RegAddr
      I2C_Data[1] = (uint8_t)(dat&0x00FF);                  //RegValue
    
        res = nrf_drv_twi_tx(&m_twi,(WM8960_ADDRESS<<1),I2C_Data,2,false);
      //res = HAL_I2C_Master_Transmit(&hi2c1,(WM8960_ADDRESS<<1),I2C_Data,2,10);
      if(res == NRF_SUCCESS)
        WM8960_REG_VAL[reg] = dat;
    
      return res;
    }
    
    /**
      * @brief  Read register of WM8960.
      * @param  reg: The number of resigter which to be read.
      * @retval The value of regsiter.
      */
    uint16_t WM8960_Read_Reg(uint8_t reg) {
    
      return WM8960_REG_VAL[reg];
    }
    
    
    /**
      * @brief  Initialize WM8960 device.
      * @param  None
      * @retval None
      */
    uint8_t WM89060_Init(void)  {
    
      uint8_t res;
    
      //Reset Device
      res = WM8960_Write_Reg(0x0f, 0x0000);
      if(res != 0)
        return res;
      else
        printf("WM8960 reset completed !!\r\n");
    
      //Set Power Source
      res =  WM8960_Write_Reg(0x19, 1<<8 | 1<<7 | 1<<6);
      res += WM8960_Write_Reg(0x1A, 1<<8 | 1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3);
      res += WM8960_Write_Reg(0x2F, 1<<3 | 1<<2);
      if(res != 0)  {
        printf("Source set fail !!\r\n");
        printf("Error code: %d\r\n",res);
        return res;
      }
    
      //Configure clock
      //MCLK->div1->SYSCLK->DAC/ADC sample Freq = 25MHz(MCLK)/2*256 = 48.8kHz
      WM8960_Write_Reg(0x04, 0x0000);
    
      //Configure ADC/DAC
      WM8960_Write_Reg(0x05, 0x0000);
    
      //Configure audio interface
      //I2S format 16 bits word length
      WM8960_Write_Reg(0x07, 0x0002);
    
      //Configure HP_L and HP_R OUTPUTS
      WM8960_Write_Reg(0x02, 0x006F | 0x0100);  //LOUT1 Volume Set
      WM8960_Write_Reg(0x03, 0x006F | 0x0100);  //ROUT1 Volume Set
    
      //Configure SPK_RP and SPK_RN
      WM8960_Write_Reg(0x28, 0x007F | 0x0100); //Left Speaker Volume
      WM8960_Write_Reg(0x29, 0x007F | 0x0100); //Right Speaker Volume
    
      //Enable the OUTPUTS
      WM8960_Write_Reg(0x31, 0x00F7); //Enable Class D Speaker Outputs
    
      //Configure DAC volume
      WM8960_Write_Reg(0x0a, 0x00FF | 0x0100);
      WM8960_Write_Reg(0x0b, 0x00FF | 0x0100);
    
      //3D
    //  WM8960_Write_Reg(0x10, 0x001F);
    
      //Configure MIXER
      WM8960_Write_Reg(0x22, 1<<8 | 1<<7);
      WM8960_Write_Reg(0x25, 1<<8 | 1<<7);
    
      //Jack Detect
      WM8960_Write_Reg(0x18, 1<<6 | 0<<5);
      WM8960_Write_Reg(0x17, 0x01C3);
      WM8960_Write_Reg(0x30, 0x0009);//0x000D,0x0005
    
      return 0;
    }
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        ret_code_t err_code;
        uint8_t address;
        uint8_t sample_data;
        bool detected_device = false;
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("TWI scanner started.");
        NRF_LOG_FLUSH();
        twi_init();
    
        for (address = 1; address <= TWI_ADDRESSES; address++)
        {
            err_code = nrf_drv_twi_rx(&m_twi, (address<<1), &sample_data, sizeof(sample_data));
            if (err_code == NRF_SUCCESS)
            {
                detected_device = true;
                NRF_LOG_INFO("TWI device detected at address 0x%x.", address);
            }
            NRF_LOG_FLUSH();
        }
    
        if (!detected_device)
        {
            NRF_LOG_INFO("No device was found.");
            NRF_LOG_FLUSH();
        }
    int res = WM89060_Init();
        if(res == 0)  {
          NRF_LOG_INFO("WM89060_Init complete !!\r\n");
        }
        else  {
          NRF_LOG_INFO("WM89060_Init fail ! Error code: %d\r\n", res);      
        }
    
    NRF_LOG_FLUSH();
       
    }
    
    /** @} */
    

    i want to setup the scope . i will setup and send you the traces

  • I'm not sure why you added a shift in the address, but if I revert your code back to "err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data))", I'm able to correctly detect another I2C sensor.

    If you are not able to detect your sensor with this code, there is either something wrong with the sensor/connections/logic levels/etc, or in your project configuration.

Reply Children
Related