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.