Hello
I am using nrf52832 and sdk v17.0
I recently succeeded in controlling several ws2812 LEDs through I2S. And now I'm going to combine these codes with the others.
However, when I debug the combined code, 'i2s_init()' outputs the following error:
<error> app: ERROR 3735928559 [Unknown error code] at ../../../../../../modules/nrfx/hal/nrf_gpio.h:492 PC at: 0x00033413 //nrf_gpio.h 492line __STATIC_INLINE NRF_GPIO_Type * nrf_gpio_pin_port_decode(uint32_t * p_pin) { NRFX_ASSERT(nrf_gpio_pin_present_check(*p_pin)); //<< error #if (GPIO_COUNT == 1) return NRF_P0; #else if (*p_pin < P0_PIN_NUM) { return NRF_P0; } else { *p_pin = *p_pin & 0x1F; return NRF_P1; } #endif }
This is the code I used to control led with i2s.
/** @file * @defgroup i2s_example_main main.c * @{ * @ingroup i2s_example * * @brief SK6812 I2S Example Application main file. * * This file contains the source code for a sample application using I2S with SK6812 LEDs. */ #include <stdio.h> #include "nrf_drv_i2s.h" #include "nrf_delay.h" #include "app_util_platform.h" #include "app_error.h" #include "boards.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #define LED_DIN_PIN 15//27 //2 #define LED_LRCK_PIN 11 #define LED_SCK_PIN 18 #define NUM_LEDS 3 //9 #define DATA_BYTES_PER_LED 3 // 24-bit GRB data structure #define LEDS_DATA_BYTE_SIZE NUM_LEDS * DATA_BYTES_PER_LED //LEDs * (8bit * 3 = 24bit) #define I2S_BITS_PER_DATA_BIT 4 //SK68xx LED #define I2S_SK6812_ZERO 0x8 //0b'1000 (0.3us; 0.9us) #define I2S_SK6812_ONE 0xC //0b'1100 (0.6us; 0.6us) //WS28xx LED #define I2S_WS2812B_ZERO 0x8 //0b'1000 (0.4us; 0.85us) #define I2S_WS2812B_ONE 0xE //0b'1110 (0.8us; 0.45us) #define I2S_BYTES_PER_RESET 256/8 //reset_pulse / period = 80us / 0.3125us = 256 #define I2S_LEDS_WORD_SIZE BYTES_TO_WORDS(LEDS_DATA_BYTE_SIZE * I2S_BITS_PER_DATA_BIT) #define I2S_RESET_WORD_SIZE BYTES_TO_WORDS(I2S_BYTES_PER_RESET) //8 words #define I2S_LEDS_FRAME_WORD_SIZE I2S_LEDS_WORD_SIZE + I2S_RESET_WORD_SIZE typedef struct { //LED colors uint8_t g; uint8_t r; uint8_t b; } sk6812_led_t; sk6812_led_t m_led_buffer_tx[NUM_LEDS]; uint32_t m_i2s_led_buffer_tx[I2S_LEDS_FRAME_WORD_SIZE]; //sk6812_led_t *p_led_buffer_tx; //uint32_t *p_i2s_led_buffer_tx; /** * @brief Clears the LED and I2S data buffers */ ret_code_t sk6812_i2s_init_mem() { // TODO: dynamically allocate memory when needed instead of using global arrays // // Init memory for LED data // if (p_led_buffer_tx) free(p_led_buffer_tx); // p_led_buffer_tx = (sk6812_led_t *)malloc(LEDS_DATA_BYTE_SIZE); // if (p_led_buffer_tx) memset(p_led_buffer_tx, 0, LEDS_DATA_BYTE_SIZE); // else return NRF_ERROR_NO_MEM; // // // Init memory for I2S data // if (p_i2s_led_buffer_tx) free(p_i2s_led_buffer_tx); // p_i2s_led_buffer_tx = (uint32_t *)malloc(I2S_LEDS_WORD_SIZE * 4); // if (p_i2s_led_buffer_tx) memset(p_i2s_led_buffer_tx, 0, I2S_LEDS_WORD_SIZE * 4); // else return NRF_ERROR_NO_MEM; // Reset data buffers, memory value and size memset(m_led_buffer_tx, 0, sizeof(m_led_buffer_tx)); memset(m_i2s_led_buffer_tx, 0, sizeof(m_i2s_led_buffer_tx)); return NRF_SUCCESS; } /** * @brief Stops data transfer after the first full transmission (only using single buffer) * @brief Handles transmitted data when receiving the TXPTRUPD and RXPTRUPD events, every RXTXD.MAXCNT number of transmitted data words * @brief Addresses written to the pointer registers TXD.PTR and RXD.PTR are double-buffered in hardware, and these double buffers are updated for every RXTXD.MAXCNT words */ void data_handler(nrf_drv_i2s_buffers_t const * p_released, uint32_t status) { // NRF_LOG_DEBUG("status: %d; p_tx_buffer: 0x%08X; p_rx_buffer: 0x%08X", status, p_released->p_tx_buffer, p_released->p_rx_buffer); // 'nrf_drv_i2s_next_buffers_set' is called directly from the handler // each time next buffers are requested, so data corruption is not expected. // ASSERT(p_released); // When the handler is called after the transfer has been stopped // (no next buffers are needed, only the used buffers are to be // released), there is nothing to do. if (!(status & NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED)) { //No buffer data, nothing to do return; } // Stop data transfer after the first full transmission (only using single buffer) if (p_released->p_tx_buffer != NULL) { // nrf_drv_i2s_stop(); nrf_drv_i2s_uninit(); } } /** * @brief Initializes the I2S interface for ~3.2MHz clock for SK6812 */ ret_code_t sk6812_i2s_init() { nrf_drv_i2s_config_t config; //= NRF_DRV_I2S_DEFAULT_CONFIG; config.sck_pin = LED_SCK_PIN; // Don't set NRF_DRV_I2S_PIN_NOT_USED for I2S_CONFIG_SCK_PIN. (The program will stack.) config.lrck_pin = NRF_DRV_I2S_PIN_NOT_USED; //LED_LRCK_PIN; // I2S_CONFIG_LRCK_PIN config.mck_pin = NRF_DRV_I2S_PIN_NOT_USED; config.sdout_pin = LED_DIN_PIN; // I2S_CONFIG_SDOUT_PIN config.sdin_pin = NRF_DRV_I2S_PIN_NOT_USED; config.irq_priority = I2S_CONFIG_IRQ_PRIORITY; config.mode = NRF_I2S_MODE_MASTER; config.format = NRF_I2S_FORMAT_I2S; config.alignment = NRF_I2S_ALIGN_LEFT; config.sample_width = NRF_I2S_SWIDTH_8BIT; config.channels = NRF_I2S_CHANNELS_STEREO; config.mck_setup = NRF_I2S_MCK_32MDIV5; config.ratio = NRF_I2S_RATIO_32X; uint32_t err_code = nrf_drv_i2s_init(&config, data_handler); // APP_ERROR_CHECK(err_code); return err_code; } /** * @brief Convert a byte of LED data to a word of I2S data * @brief 1 data bit <--> 4 I2S bits * @brief 1 data byte <--> 1 I2S word */ uint32_t convert_byte_to_i2s_bits(uint8_t data_byte) { uint32_t data_bits = 0; // Set data_bits based on MSB, then left-shift data_byte for (int ii=0; ii < 8; ii++) { data_bits |= ((data_byte & 0x80) ? I2S_SK6812_ONE : I2S_SK6812_ZERO) << ((8-1-ii) * 4); //SK68xx //data_bits |= ((data_byte & 0x80) ? I2S_WS2812B_ONE : I2S_WS2812B_ZERO) << ((8-1-ii) * 4); //WS28xx data_byte = data_byte << 1; } return data_bits; } /** * @brief Sets I2S data from converted LED data */ void set_i2s_led_data() { //each color data uint16_t jj = 0; for (uint16_t ii=0; ii < NUM_LEDS; ii++) { m_i2s_led_buffer_tx[jj] = convert_byte_to_i2s_bits(m_led_buffer_tx[ii].g); m_i2s_led_buffer_tx[jj+1] = convert_byte_to_i2s_bits(m_led_buffer_tx[ii].r); m_i2s_led_buffer_tx[jj+2] = convert_byte_to_i2s_bits(m_led_buffer_tx[ii].b); jj += 3; } } /** * @brief Initializes I2S and starts the data transfer * @brief Assumes data buffers have already been set */ void send_i2s_led_data() { // Configure the I2S module and map IO pins uint32_t err_code = sk6812_i2s_init(); // Prevent starting a new data transfer if I2S already initialized if (err_code == NRF_SUCCESS) { // Configure TX data buffer nrf_drv_i2s_buffers_t const initial_buffers = { .p_tx_buffer = m_i2s_led_buffer_tx, .p_rx_buffer = NULL }; // Enable the I2S module and start data streaming err_code = nrf_drv_i2s_start(&initial_buffers, I2S_LEDS_FRAME_WORD_SIZE+1, 0); APP_ERROR_CHECK(err_code); } else { // Reset to all I2S_SK6812_ZERO's memset(m_i2s_led_buffer_tx, 0x88, I2S_LEDS_WORD_SIZE * 4); } } void clear_leds() { // Set to all I2S_SK6812_ZERO's memset(m_i2s_led_buffer_tx, 0x88, I2S_LEDS_WORD_SIZE * 4); send_i2s_led_data(); } /** * @brief Set an RGB LED color data in the global sk6812_led_t array */ void set_led_pixel_RGB(uint16_t pos, uint8_t r, uint8_t g, uint8_t b) { m_led_buffer_tx[pos].r = r; m_led_buffer_tx[pos].g = g; m_led_buffer_tx[pos].b = b; } /** * @brief Ported Adafruit NeoPixel paint animation functions */ // Fill the dots one after the other with a color void color_wipe(uint8_t r, uint8_t g, uint8_t b, uint8_t ms_delay) { sk6812_i2s_init_mem(); for(uint16_t ii=0; ii < NUM_LEDS; ii++) { set_led_pixel_RGB(ii, r, g, b); set_i2s_led_data(); send_i2s_led_data(); nrf_delay_ms(ms_delay); } } // Input a value 0 to 255 to get a color value sk6812_led_t wheel(uint8_t wheel_pos) { sk6812_led_t color; wheel_pos = 255 - wheel_pos; if(wheel_pos < 85) { color.r = 255 - wheel_pos * 3; color.g = 0; color.b = wheel_pos * 3; return color; } if(wheel_pos < 170) { wheel_pos -= 85; color.r = 0; color.g = wheel_pos * 3; color.b = 255 - wheel_pos * 3; return color; } wheel_pos -= 170; color.r = wheel_pos * 3; color.g = 255 - wheel_pos * 3; color.b = 0; return color; } void rainbow(uint16_t ms_delay) { uint16_t ii, jj; sk6812_led_t color; sk6812_i2s_init_mem(); for (jj=0; jj < NUM_LEDS; jj++) { for (ii=0; ii < NUM_LEDS; ii++) { color = wheel(((ii * 256 / NUM_LEDS) + jj) & 255); set_led_pixel_RGB(ii, color.r, color.g, color.b); } set_i2s_led_data(); send_i2s_led_data(); nrf_delay_ms(ms_delay); } } // Slightly different, this makes the rainbow equally distributed throughout void rainbow_cycle(uint16_t ms_delay) { uint16_t ii, jj; sk6812_led_t color; sk6812_i2s_init_mem(); for(jj=0; jj < 256*3; jj++) { // 3 cycles of all colors on wheel for(ii=0; ii < NUM_LEDS; ii++) { color = wheel(((ii * 256 / NUM_LEDS) + jj) & 255); set_led_pixel_RGB(ii, color.r, color.g, color.b); } set_i2s_led_data(); send_i2s_led_data(); nrf_delay_ms(ms_delay); } } // Theater-style crawling lights. void theater_chase(uint8_t r, uint8_t g, uint8_t b, uint16_t ms_delay) { sk6812_i2s_init_mem(); for (int jj=0; jj < 10; jj++) { //do 10 cycles of chasing for (int qq=0; qq < 3; qq++) { for (uint16_t ii=0; ii < NUM_LEDS; ii=ii+3) { set_led_pixel_RGB(ii+qq, r, g, b); //turn every third pixel on } set_i2s_led_data(); send_i2s_led_data(); nrf_delay_ms(ms_delay); for (uint16_t ii=0; ii < NUM_LEDS; ii=ii+3) { set_led_pixel_RGB(ii+qq, 0, 0, 0); //turn every third pixel off } } } } // Theater-style crawling lights with rainbow effect void theater_chase_rainbow(uint16_t ms_delay) { sk6812_led_t color; sk6812_i2s_init_mem(); for (int jj=0; jj < 256; jj++) { // cycle all 256 colors in the wheel for (int qq=0; qq < 3; qq++) { for (uint16_t ii=0; ii < NUM_LEDS; ii=ii+3) { color = wheel((ii+jj) % 255); set_led_pixel_RGB(ii+qq, color.r, color.g, color.b); //turn every third pixel on } set_i2s_led_data(); send_i2s_led_data(); nrf_delay_ms(ms_delay); for (uint16_t ii=0; ii < NUM_LEDS; ii=ii+3) { set_led_pixel_RGB(ii+qq, 0, 0, 0); //turn every third pixel off } } } } //======================================================================== void color_test1(uint8_t r, uint8_t g, uint8_t b) { //sk6812_i2s_init_mem(); set_led_pixel_RGB(0, r, g, b); set_i2s_led_data(); send_i2s_led_data(); } void color_test2(uint8_t r, uint8_t g, uint8_t b) { //sk6812_i2s_init_mem(); set_led_pixel_RGB(1, r, g, b); set_i2s_led_data(); send_i2s_led_data(); } void color_test3(uint8_t r, uint8_t g, uint8_t b) { //sk6812_i2s_init_mem(); set_led_pixel_RGB(2, r, g, b); set_i2s_led_data(); send_i2s_led_data(); } //======================================================================== int main(void) { uint32_t err_code = NRF_SUCCESS; err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); NRF_LOG_DEFAULT_BACKENDS_INIT(); NRF_LOG_INFO("nRF52 I2S and SK6812 LED example started."); NRF_LOG_FLUSH(); // Ported LED paint animations from Adafruit's Neopixel library // https://github.com/adafruit/Adafruit_NeoPixel/blob/master/examples/strandtest/strandtest.ino // Some example procedures showing how to display to the pixels: /*color_wipe(255, 0, 0, 50); // Red color_wipe(0, 255, 0, 50); // Green color_wipe(0, 0, 255, 50); // Blue // Send a theater pixel chase in... theater_chase(127, 127, 127, 50); // White theater_chase(127, 0, 0, 50); // Red theater_chase(0, 0, 127, 50); // Blue rainbow(20); rainbow_cycle(20); theater_chase_rainbow(50); */ //each position led multi control /* color_test1(0, 255, 0); nrf_delay_ms(1000); color_test2(0, 0, 255); nrf_delay_ms(1000); color_test3(255, 50, 0); nrf_delay_ms(3000); clear_leds(); //led off */ // Stop and uninitialize the I2S interface to reduce current consumption // nrf_drv_i2s_stop(); // nrf_drv_i2s_uninit(); for(;;) { color_test1(0, 255, 0); nrf_delay_ms(1000); color_test2(0, 0, 255); nrf_delay_ms(1000); color_test3(255, 50, 0); nrf_delay_ms(1000); sk6812_i2s_init_mem(); clear_leds(); //led off nrf_delay_ms(1000); } } /** @} */
And I attach the combined code below. (It controls devices including LEDs with buttons and apps.)
pca10040,h
#ifndef PCA10040_H #define PCA10040_H #ifdef __cplusplus extern "C" { #endif #include "nrf_gpio.h" // LEDs definitions for PCA10040 #define LEDS_NUMBER 4 #define LED_START 17 #define LED_1 17 #define LED_2 18 #define LED_3 19 #define LED_4 20 #define LED_STOP 20 #define LEDS_ACTIVE_STATE 0 #define LEDS_INV_MASK LEDS_MASK #define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 } #define BSP_LED_0 LED_1 #define BSP_LED_1 LED_2 #define BSP_LED_2 LED_3 #define BSP_LED_3 LED_4 #define BUTTONS_NUMBER 1 //4 #define BUTTON_START 13 #define BUTTON_1 13 //#define BUTTON_2 14 //#define BUTTON_3 15 //#define BUTTON_4 16 #define BUTTON_STOP 13 //16 #define BUTTON_PULL NRF_GPIO_PIN_PULLUP #define BUTTONS_ACTIVE_STATE 0 //#define BUTTONS_LIST { BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4 } #define BUTTONS_LIST { BUTTON_1 } #define BSP_BUTTON_0 BUTTON_1 /*#define BSP_BUTTON_1 BUTTON_2 #define BSP_BUTTON_2 BUTTON_3 #define BSP_BUTTON_3 BUTTON_4 */ #define RX_PIN_NUMBER 8 #define TX_PIN_NUMBER 6 #define CTS_PIN_NUMBER 7 #define RTS_PIN_NUMBER 5 #define HWFC true #define SPIS_MISO_PIN 28 // SPI MISO signal. #define SPIS_CSN_PIN 12 // SPI CSN signal. #define SPIS_MOSI_PIN 25 // SPI MOSI signal. #define SPIS_SCK_PIN 29 // SPI SCK signal. #define SPIM0_SCK_PIN 29 // SPI clock GPIO pin number. #define SPIM0_MOSI_PIN 25 // SPI Master Out Slave In GPIO pin number. #define SPIM0_MISO_PIN 28 // SPI Master In Slave Out GPIO pin number. #define SPIM0_SS_PIN 12 // SPI Slave Select GPIO pin number. #define SPIM1_SCK_PIN 2 // SPI clock GPIO pin number. #define SPIM1_MOSI_PIN 3 // SPI Master Out Slave In GPIO pin number. #define SPIM1_MISO_PIN 4 // SPI Master In Slave Out GPIO pin number. #define SPIM1_SS_PIN 5 // SPI Slave Select GPIO pin number. #define SPIM2_SCK_PIN 12 // SPI clock GPIO pin number. #define SPIM2_MOSI_PIN 13 // SPI Master Out Slave In GPIO pin number. #define SPIM2_MISO_PIN 14 // SPI Master In Slave Out GPIO pin number. #define SPIM2_SS_PIN 15 // SPI Slave Select GPIO pin number. // serialization APPLICATION board - temp. setup for running serialized MEMU tests #define SER_APP_RX_PIN 23 // UART RX pin number. #define SER_APP_TX_PIN 24 // UART TX pin number. #define SER_APP_CTS_PIN 2 // UART Clear To Send pin number. #define SER_APP_RTS_PIN 25 // UART Request To Send pin number. #define SER_APP_SPIM0_SCK_PIN 27 // SPI clock GPIO pin number. #define SER_APP_SPIM0_MOSI_PIN 2 // SPI Master Out Slave In GPIO pin number #define SER_APP_SPIM0_MISO_PIN 26 // SPI Master In Slave Out GPIO pin number #define SER_APP_SPIM0_SS_PIN 23 // SPI Slave Select GPIO pin number #define SER_APP_SPIM0_RDY_PIN 25 // SPI READY GPIO pin number #define SER_APP_SPIM0_REQ_PIN 24 // SPI REQUEST GPIO pin number // serialization CONNECTIVITY board #define SER_CON_RX_PIN 24 // UART RX pin number. #define SER_CON_TX_PIN 23 // UART TX pin number. #define SER_CON_CTS_PIN 25 // UART Clear To Send pin number. Not used if HWFC is set to false. #define SER_CON_RTS_PIN 2 // UART Request To Send pin number. Not used if HWFC is set to false. #define SER_CON_SPIS_SCK_PIN 27 // SPI SCK signal. #define SER_CON_SPIS_MOSI_PIN 2 // SPI MOSI signal. #define SER_CON_SPIS_MISO_PIN 26 // SPI MISO signal. #define SER_CON_SPIS_CSN_PIN 23 // SPI CSN signal. #define SER_CON_SPIS_RDY_PIN 25 // SPI READY GPIO pin number. #define SER_CON_SPIS_REQ_PIN 24 // SPI REQUEST GPIO pin number. #define SER_CONN_CHIP_RESET_PIN 11 // Pin used to reset connectivity chip // Arduino board mappings #define ARDUINO_SCL_PIN 27 // SCL signal pin #define ARDUINO_SDA_PIN 26 // SDA signal pin #define ARDUINO_AREF_PIN 2 // Aref pin #define ARDUINO_13_PIN 25 // Digital pin 13 #define ARDUINO_12_PIN 24 // Digital pin 12 #define ARDUINO_11_PIN 23 // Digital pin 11 #define ARDUINO_10_PIN 22 // Digital pin 10 #define ARDUINO_9_PIN 20 // Digital pin 9 #define ARDUINO_8_PIN 19 // Digital pin 8 #define ARDUINO_7_PIN 18 // Digital pin 7 #define ARDUINO_6_PIN 17 // Digital pin 6 #define ARDUINO_5_PIN 16 // Digital pin 5 #define ARDUINO_4_PIN 15 // Digital pin 4 #define ARDUINO_3_PIN 14 // Digital pin 3 #define ARDUINO_2_PIN 13 // Digital pin 2 #define ARDUINO_1_PIN 12 // Digital pin 1 #define ARDUINO_0_PIN 11 // Digital pin 0 #define ARDUINO_A0_PIN 3 // Analog channel 0 #define ARDUINO_A1_PIN 4 // Analog channel 1 #define ARDUINO_A2_PIN 28 // Analog channel 2 #define ARDUINO_A3_PIN 29 // Analog channel 3 #define ARDUINO_A4_PIN 30 // Analog channel 4 #define ARDUINO_A5_PIN 31 // Analog channel 5 //digital pin #define BUZZER 25 #define Magnetic 24 #define Piezo 23 //ultrasonic pin #define UVC_LED 22 #define Charge_CHG 20 //charge IC CHG pin(charging check) #ifdef __cplusplus } #endif #endif // PCA10040_H
6747.nRF5_SDK_17.0.0_9d13099.zip
Can I know about this problem because the same problem occurs even if I erase the code of main() and run i2s and led code?
Thank you in advance.