Hello
I'm trying to control the neopixeled WS2812. I referred to the following site.
https://electronut.in/nrf52-i2s-ws2812/
I'm going to use this example of neopixel LED to control LED 3chain. I want to remove the Bluetooth function from this code and use only the control part of the LED, but there seems to be a problem with my code. This LEDs is connected to 5V, Gnd, I2S_SDIN_Pin(P0.26) on the nrf52DK board. But the LED doesn't work at all.
I don't know because it's my first time using I2S and neopixel LED. Can I get some help with this problem?
Thank you.
#include <stdio.h>
#include "nrf.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 NLEDS 16
#define RESET_BITS 6
#define I2S_BUFFER_SIZE 3*NLEDS + RESET_BITS
static uint32_t m_buffer_tx[I2S_BUFFER_SIZE];
static volatile int nled = 1;
volatile uint8_t g_demo_mode = 0;
volatile bool g_i2s_start = true;
volatile bool g_i2s_running = false;
// This is the I2S data handler - all data exchange related to the I2S transfers
// is done here.
static void data_handler(uint32_t const * p_data_received,
uint32_t * p_data_to_send,
uint16_t number_of_words)
{
// Non-NULL value in 'p_data_to_send' indicates that the driver needs
// a new portion of data to send.
if (p_data_to_send != NULL)
{
// do nothing - buffer is updated elsewhere
}
}
/*
caclChannelValue()
Sets up a 32 bit value for a channel (R/G/B).
A channel has 8 x 4-bit codes. Code 0xe is HIGH and 0x8 is LOW.
So a level of 128 would be represented as:
0xe8888888
The 16 bit values need to be swapped because of the way I2S sends data - right/left channels.
So for the above example, final value sent would be:
0x8888e888
*/
uint32_t caclChannelValue(uint8_t level)
{
uint32_t val = 0;
// 0
if(level == 0) {
val = 0x88888888;
}
// 255
else if (level == 255) {
val = 0xeeeeeeee;
}
else {
// apply 4-bit 0xe HIGH pattern wherever level bits are 1.
val = 0x88888888;
for (uint8_t i = 0; i < 8; i++) {
if((1 << i) & level) {
uint32_t mask = ~(0x0f << 4*i);
uint32_t patt = (0x0e << 4*i);
val = (val & mask) | patt;
}
}
// swap 16 bits
val = (val >> 16) | (val << 16);
}
return val;
}
// set LED data
void set_led_data()
{
for(int i = 0; i < 3*NLEDS; i += 3) {
if (i == 3*nled) {
switch(g_demo_mode)
{
case 0:
{
m_buffer_tx[i] = 0x88888888;
m_buffer_tx[i+1] = caclChannelValue(128);
m_buffer_tx[i+2] = 0x88888888;
}
break;
case 1:
{
m_buffer_tx[i] = caclChannelValue(128);;
m_buffer_tx[i+1] = 0x88888888;
m_buffer_tx[i+2] = 0x88888888;
}
break;
case 2:
{
m_buffer_tx[i] = 0x88888888;
m_buffer_tx[i+1] = 0x88888888;
m_buffer_tx[i+2] = caclChannelValue(128);
}
break;
default:
break;
}
}
else {
m_buffer_tx[i] = 0x88888888;
m_buffer_tx[i+1] = 0x88888888;
m_buffer_tx[i+2] = 0x88888888;
}
}
// reset
for(int i = 3*NLEDS; i < I2S_BUFFER_SIZE; i++) {
m_buffer_tx[i] = 0;
}
}
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("I2S loopback example started.");
set_led_data(); //first time
//I2S setting
nrf_drv_i2s_config_t config = NRF_DRV_I2S_DEFAULT_CONFIG;
// In Master mode the MCK frequency and the MCK/LRCK ratio should be
// set properly in order to achieve desired audio sample rate (which
// is equivalent to the LRCK frequency).
// For the following settings we'll get the LRCK frequency equal to
// 15873 Hz (the closest one to 16 kHz that is possible to achieve).
config.sdin_pin = I2S_SDIN_PIN; //26
config.sdout_pin = I2S_SDOUT_PIN; //27
config.mck_setup = NRF_I2S_MCK_32MDIV10; //< 32 MHz / 10 = 3.2 MHz.
config.ratio = NRF_I2S_RATIO_32X; //96X, //< LRCK = MCK / 32.
config.channels = NRF_I2S_CHANNELS_STEREO;
err_code = nrf_drv_i2s_init(&config, data_handler);
APP_ERROR_CHECK(err_code);
for (;;)
{
// start I2S
g_i2s_running = true;
g_i2s_start = true;
g_demo_mode = 2; //0~2
// stop I2S
//nrf_drv_i2s_stop();
nrf_delay_ms(250);
// update
if (g_i2s_running)
{
nled = (nled + 1) % NLEDS;
set_led_data();
}
}
}
/** @} */