This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nrfx_i2s library never recognized

I am trying to use the nrfx_i2s library to run neopixels on a nRF52 DK. I am using SES to compile and flash the code. I am having trouble correctly using the library though. For the init, start, stop, and uniniti i2s functions I get errors "undefined reference to `nrfx_i2s_init" for all of them. I have the include header at the top for #include "nrfx_i2s.h" and I make sure that the user include directories settings in SES includes the locations of the .h and .c files. I also "Added Existing Files" for the .c file to make sure I wasn't missing anything. Still get an error though.

I am using SDK 17 on Mac with S132 soft device on nRF52 DK with a nRF52832 chip and PCA10040.

Parents Reply Children
  • Hi Egor,

    I figured it out. It was the I2S_ENABLED property in the sdk_config file like you mentioned. After switching it to 1 it started working.

    The reference code I am working with is here: https://github.com/rmptxf/NeoController, in the ble_app_neocontroller folder. In this code there is a custom ble service and characteristic that controls the colors of the neopixels. If you just want to quickly test if the neopixel-code is working, start messing around with the for(;;) loop in main() and utilize the set_neopixel_data() function.

  • Here is the code without all of the ble stuff:

    #include "nrf_delay.h"
    #include "nrf_drv_i2s.h"
    
    #define neopixels_number                8                                       /**< Neopixels number. */
    #define neopixel_pin                    16                                      /**< Neopixel pin number. */
    
    #define reset_bits                      6                                       /**< Reset bits. */
    #define i2s_buffer_size                 ((3 * neopixels_number) + reset_bits)   /**< i2d buffer size for driving the neopixel. */
    static uint32_t m_buffer_tx[i2s_buffer_size];
    static uint32_t       * volatile mp_block_to_fill  = NULL;
    
    static void set_neopixel_data(uint8_t led_index, uint8_t r, uint8_t g, uint8_t b);
    
    /**@brief Function for handeling the i2s data.
     *
     */
    static void i2s_data_handler(nrf_drv_i2s_buffers_t const * p_released,
                                 uint32_t                      status)
    {
        ret_code_t err_code;
        ASSERT(p_released);
    
        if (!(status & NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED))
        {
            return;
        }
    
        if (!p_released->p_rx_buffer)
        {
            nrf_drv_i2s_buffers_t const next_buffers = {
                .p_tx_buffer = m_buffer_tx,
            };
            err_code = nrf_drv_i2s_next_buffers_set(&next_buffers);
            APP_ERROR_CHECK(err_code);
    
            mp_block_to_fill = m_buffer_tx;
        }
        else
        {      
            err_code = nrf_drv_i2s_next_buffers_set(p_released);
            APP_ERROR_CHECK(err_code);
            mp_block_to_fill = (uint32_t *)p_released->p_tx_buffer;
        }
    }
    
    /**@brief Function for calculating the rgb channels data value.
     *
     */
    static uint32_t rgb_channels_value(uint8_t channel_level)
    {
        uint32_t value = 0;
    
        // 0 
        if(channel_level == 0) {
            value = 0x88888888;
        }
        // 255
        else if (channel_level == 255) {
            value = 0xeeeeeeee;
        }
        else 
        {
            // apply 4-bit 0xe HIGH pattern wherever level bits are 1.
            value = 0x88888888;
            for (uint8_t i = 0; i < 8; i++) 
            {
                if((1 << i) & channel_level) 
                {
                    uint32_t mask = ~(0x0f << 4*i);
                    uint32_t patt = (0x0e << 4*i);
                    value = (value & mask) | patt;
                }
            }
    
            // swap 16 bits
            value = (value >> 16) | (value << 16);
        }
    
        return value;
    }
    
    /**@brief Function for setting the leds (rgb) data in the i2s buffer.
     *
     *@param led_n   neopixel number in the array starting with 0.
     *@param r       red led level.
     *@param g       green led level.
     *@param b       blue led level.
     */
    static void set_neopixel_data(uint8_t led_index, uint8_t r, uint8_t g, uint8_t b)
    {
        for(int i = 0; i < (3 * neopixels_number); i += 3) 
        {
            if (i == (3 * led_index)) 
            {          
               m_buffer_tx[i]   = rgb_channels_value(g);
               m_buffer_tx[i+1] = rgb_channels_value(r);
               m_buffer_tx[i+2] = rgb_channels_value(b);
              
            }
            else 
            {
                m_buffer_tx[i]   = 0x88888888;
                m_buffer_tx[i+1] = 0x88888888;
                m_buffer_tx[i+2] = 0x88888888;
            }
        }
    
        // reset 
        for(int i = (3 * neopixels_number); i < i2s_buffer_size; i++) 
        {
            m_buffer_tx[i] = 0;
        }
    
         nrf_drv_i2s_buffers_t const initial_buffers = {
                .p_tx_buffer = m_buffer_tx,
            };
    }
    
    /**@brief Function for initialising the i2s.
     *
     */
    static void i2s_init()
    {
        uint32_t err_code = NRF_SUCCESS;
    
        nrf_drv_i2s_config_t config = NRF_DRV_I2S_DEFAULT_CONFIG;
        config.sdin_pin  = NRFX_I2S_PIN_NOT_USED;
        config.sdout_pin = neopixel_pin;
    
        config.mck_setup = NRF_I2S_MCK_32MDIV10;
        config.ratio     = NRF_I2S_RATIO_32X;
        config.channels  = NRF_I2S_CHANNELS_STEREO;
        err_code = nrf_drv_i2s_init(&config, i2s_data_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for application main entry.
     */
    int main(void)
    {
        ret_code_t err_code;
        bool erase_bonds;
    
        nrf_drv_i2s_buffers_t const initial_buffers = 
        {
            .p_tx_buffer = m_buffer_tx 
        };
    
        i2s_init();
    
        err_code = nrf_drv_i2s_start(&initial_buffers, i2s_buffer_size, 0);            
        APP_ERROR_CHECK(err_code);
        set_neopixel_data(0,100,100,100); // Turn Off the Pixel
    
        // Enter main loop.
        for (;;)
        {
            set_neopixel_data(0,20,0,0); // Turn Off the Pixel
            nrf_delay_ms(250);
            set_neopixel_data(1,0,20,0); // Turn Off the Pixel
            nrf_delay_ms(1000);
            set_neopixel_data(2,0,0,20); // Turn Off the Pixel
            nrf_delay_ms(1000);
            set_neopixel_data(0,0,0,20); // Turn Off the Pixel
            nrf_delay_ms(1000);
        }
    }
    
    
    /**
     * @}
     */
    /**/
    

  • Hi Zack. Thanks for sharing your code.

    I finally found the issue. It was in SDK location. The full path to SDK was: D:\Projects\BLE\Nordic\nRF5_SDK_17.0.2

    When I moved SDK to the root folder like: D:\nRF5_SDK_17.0.2 the issue has gone.

Related