f860922d67
I have added a pre-configured version of the ws2812b i2s library to the Arduino code. This removes the need to download and install the ws2812b i2s library manually. The ws2812b code has been preconfigured to reduce the temporal compared to the default value. The default value was found to cause excessive flickering. The readme has been updated to reflect this change. Also added a note about the maximum number of LEDs (255)
103 lines
3.3 KiB
C
103 lines
3.3 KiB
C
// ws2812_init.c
|
|
|
|
// C-based helper function for initilalizing
|
|
// the I2S system
|
|
|
|
#include <string.h>
|
|
#include "slc_register.h"
|
|
#include "user_interface.h"
|
|
#include "ws2812_defs.h"
|
|
#include "ws2812_dma.h"
|
|
|
|
|
|
#if WS2812_USE_INTERRUPT == 1
|
|
// for debugging purposes
|
|
static volatile uint32_t interrupt_count = 0;
|
|
|
|
static void ws2812_isr(void)
|
|
{
|
|
//clear all intr flags
|
|
WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff);//slc_intr_status);
|
|
|
|
interrupt_count++;
|
|
}
|
|
#endif
|
|
|
|
|
|
void ws2812_dma(sdio_queue_t *i2s_pixels_queue)
|
|
{
|
|
// Reset DMA
|
|
SET_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST); //|SLC_TXLINK_RST);
|
|
CLEAR_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST); //|SLC_TXLINK_RST);
|
|
|
|
// Clear DMA int flags
|
|
SET_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff);
|
|
CLEAR_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff);
|
|
|
|
// Enable and configure DMA
|
|
CLEAR_PERI_REG_MASK(SLC_CONF0,(SLC_MODE<<SLC_MODE_S));
|
|
SET_PERI_REG_MASK(SLC_CONF0,(1<<SLC_MODE_S));
|
|
SET_PERI_REG_MASK(SLC_RX_DSCR_CONF,SLC_INFOR_NO_REPLACE|SLC_TOKEN_NO_REPLACE);
|
|
CLEAR_PERI_REG_MASK(SLC_RX_DSCR_CONF, SLC_RX_FILL_EN|SLC_RX_EOF_MODE | SLC_RX_FILL_MODE);
|
|
|
|
// configure DMA descriptor
|
|
CLEAR_PERI_REG_MASK(SLC_RX_LINK,SLC_RXLINK_DESCADDR_MASK);
|
|
SET_PERI_REG_MASK(SLC_RX_LINK, ((uint32)i2s_pixels_queue) & SLC_RXLINK_DESCADDR_MASK);
|
|
|
|
#if WS2812_USE_INTERRUPT == 1
|
|
// Attach the DMA interrupt
|
|
ets_isr_attach(ETS_SLC_INUM, (int_handler_t)ws2812_isr , (void *)0);
|
|
|
|
//Enable DMA operation intr
|
|
// WRITE_PERI_REG(SLC_INT_ENA, SLC_RX_EOF_INT_ENA);
|
|
//clear any interrupt flags that are set
|
|
WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff);
|
|
///enable DMA intr in cpu
|
|
ets_isr_unmask(1<<ETS_SLC_INUM);
|
|
#endif
|
|
|
|
//Start transmission
|
|
SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_START);
|
|
|
|
//Init pins to i2s functions
|
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_I2SO_DATA);
|
|
|
|
//Enable clock to i2s subsystem
|
|
i2c_writeReg_Mask_def(i2c_bbpll, i2c_bbpll_en_audio_clock_out, 1);
|
|
|
|
//Reset I2S subsystem
|
|
CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
|
|
SET_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
|
|
CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
|
|
|
|
//Select 16bits per channel (FIFO_MOD=0), no DMA access (FIFO only)
|
|
CLEAR_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN|(I2S_I2S_RX_FIFO_MOD<<I2S_I2S_RX_FIFO_MOD_S)|(I2S_I2S_TX_FIFO_MOD<<I2S_I2S_TX_FIFO_MOD_S));
|
|
//Enable DMA in i2s subsystem
|
|
SET_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN);
|
|
|
|
//trans master&rece slave,MSB shift,right_first,msb right
|
|
CLEAR_PERI_REG_MASK(I2SCONF, I2S_TRANS_SLAVE_MOD|
|
|
(I2S_BITS_MOD<<I2S_BITS_MOD_S)|
|
|
(I2S_BCK_DIV_NUM <<I2S_BCK_DIV_NUM_S)|
|
|
(I2S_CLKM_DIV_NUM<<I2S_CLKM_DIV_NUM_S));
|
|
SET_PERI_REG_MASK(I2SCONF, I2S_RIGHT_FIRST|I2S_MSB_RIGHT|I2S_RECE_SLAVE_MOD|
|
|
I2S_RECE_MSB_SHIFT|I2S_TRANS_MSB_SHIFT|
|
|
(((WS_I2S_BCK-1)&I2S_BCK_DIV_NUM )<<I2S_BCK_DIV_NUM_S)|
|
|
(((WS_I2S_DIV-1)&I2S_CLKM_DIV_NUM)<<I2S_CLKM_DIV_NUM_S));
|
|
|
|
#if WS2812_USE_INTERRUPT == 1
|
|
//clear int
|
|
SET_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
|
|
CLEAR_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
|
|
//enable int
|
|
SET_PERI_REG_MASK(I2SINT_ENA, I2S_I2S_RX_REMPTY_INT_ENA|I2S_I2S_RX_TAKE_DATA_INT_ENA);
|
|
#endif
|
|
|
|
//Start transmission
|
|
SET_PERI_REG_MASK(I2SCONF,I2S_I2S_TX_START);
|
|
|
|
}
|
|
|
|
// end of file
|
|
|