diff --git a/arch/xtensa/src/esp32s2/Kconfig b/arch/xtensa/src/esp32s2/Kconfig index 437b0fae24..1f2855689e 100644 --- a/arch/xtensa/src/esp32s2/Kconfig +++ b/arch/xtensa/src/esp32s2/Kconfig @@ -205,7 +205,7 @@ choice ESP32S2_FLASH_FREQ default ESP32S2_FLASH_FREQ_40M ---help--- SPI FLASH frequency - + config ESP32S2_FLASH_FREQ_80M bool "80 MHz" @@ -256,6 +256,126 @@ config ESP32S2_RNG ---help--- ESP32-S2 supports a RNG that passed on Dieharder test suite. +config ESP32S2_I2S + bool "I2S" + default n + select I2S + select ARCH_DMA + select ESP32S2_GPIO_IRQ + ---help--- + See the Board Selection menu to configure the pins used by I2S. + +if ESP32S2_I2S + +config ESP32S2_I2S_RX + bool "Enable I2S receiver" + default y + ---help--- + Enable I2S receive logic + +config ESP32S2_I2S_TX + bool "Enable I2S transmitter" + default y + ---help--- + Enable I2S transmit logic + +choice + prompt "I2S role" + default ESP32S2_I2S_ROLE_MASTER + ---help--- + Selects the operation role of the I2S. + +config ESP32S2_I2S_ROLE_MASTER + bool "Master" + +config ESP32S2_I2S_ROLE_SLAVE + bool "Slave" + +endchoice + +choice + prompt "Bit width" + ---help--- + Selects the valid data bits per sample. + Note that this option may be overwritten by the audio + according to the bit width of the file being played + +config ESP32S2_I2S_DATA_BIT_WIDTH_8BIT + bool "8 bits" + +config ESP32S2_I2S_DATA_BIT_WIDTH_16BIT + bool "16 bits" + +config ESP32S2_I2S_DATA_BIT_WIDTH_24BIT + bool "24 bits" + +config ESP32S2_I2S_DATA_BIT_WIDTH_32BIT + bool "32 bits" + +endchoice + +config ESP32S2_I2S_DATA_BIT_WIDTH + int + default 8 if ESP32S2_I2S_DATA_BIT_WIDTH_8BIT + default 16 if ESP32S2_I2S_DATA_BIT_WIDTH_16BIT + default 24 if ESP32S2_I2S_DATA_BIT_WIDTH_24BIT + default 32 if ESP32S2_I2S_DATA_BIT_WIDTH_32BIT + +config ESP32S2_I2S_SAMPLE_RATE + int "I2S sample rate" + default 44100 + range 8000 48000 + ---help--- + Selects the sample rate. + Note that this option may be overwritten by the audio + according to the bit width of the file being played + +config ESP32S2_I2S_BCLKPIN + int "I2S BCLK pin" + default 35 + range 0 45 if ESP32S2_I2S_ROLE_MASTER + range 0 46 if ESP32S2_I2S_ROLE_SLAVE + +config ESP32S2_I2S_WSPIN + int "I2S WS pin" + default 34 + range 0 45 if ESP32S2_I2S_ROLE_MASTER + range 0 46 if ESP32S2_I2S_ROLE_SLAVE + +config ESP32S2_I2S_DINPIN + int "I2S DOUT pin" + depends on ESP32S2_I2S_RX + default 37 + range 0 46 + +config ESP32S2_I2S_DOUTPIN + int "I2S DOUT pin" + depends on ESP32S2_I2S_TX + default 36 + range 0 45 + +config ESP32S2_I2S_MCLK + bool "Enable I2S Master Clock" + depends on ESP32S2_I2S_ROLE_MASTER + default n + ---help--- + Enable I2S master clock + +config ESP32S2_I2S_MCLKPIN + int "I2S MCLK pin" + depends on ESP32S2_I2S_MCLK + default 33 + range 0 45 + +config I2S_DMADESC_NUM + int "I2S DMA maximum number of descriptors" + default 2 + ---help--- + Configure the maximum number of out-link/in-link descriptors to + be chained for a I2S DMA transfer. + +endif #ESP32S2_I2S + config ESP32S2_SPI2 bool "SPI 2" default n diff --git a/arch/xtensa/src/esp32s2/Make.defs b/arch/xtensa/src/esp32s2/Make.defs index 6d79385633..10d44cf8eb 100644 --- a/arch/xtensa/src/esp32s2/Make.defs +++ b/arch/xtensa/src/esp32s2/Make.defs @@ -30,6 +30,7 @@ HEAD_CSRC = esp32s2_start.c esp32s2_wdt.c CHIP_CSRCS = esp32s2_allocateheap.c esp32s2_clockconfig.c esp32s2_irq.c CHIP_CSRCS += esp32s2_gpio.c esp32s2_region.c esp32s2_user.c CHIP_CSRCS += esp32s2_timerisr.c esp32s2_lowputc.c esp32s2_systemreset.c +CHIP_CSRCS += esp32s2_dma.c # Configuration-dependent ESP32-S2 files @@ -49,6 +50,10 @@ ifeq ($(CONFIG_ESP32S2_I2C),y) CHIP_CSRCS += esp32s2_i2c.c endif +ifeq ($(CONFIG_ESP32S2_I2S),y) +CHIP_CSRCS += esp32s2_i2s.c +endif + ifeq ($(CONFIG_ESP32S2_SPI),y) CHIP_CSRCS += esp32s2_spi.c endif diff --git a/arch/xtensa/src/esp32s2/esp32s2_dma.c b/arch/xtensa/src/esp32s2/esp32s2_dma.c new file mode 100644 index 0000000000..127159448f --- /dev/null +++ b/arch/xtensa/src/esp32s2/esp32s2_dma.c @@ -0,0 +1,186 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/esp32s2_dma.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "hardware/esp32s2_dma.h" +#include "esp32s2_dma.h" + +/**************************************************************************** + * Preprocessor Definitions + ****************************************************************************/ + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef ALIGN_UP +# define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s2_dma_init + * + * Description: + * Initialize DMA outlink descriptors and bind the target buffer to + * these DMA descriptors. + * + * Input Parameters: + * dmadesc - Pointer to the DMA descriptors + * num - Number of DMA descriptors + * pbuf - RX/TX buffer pointer + * len - RX/TX buffer length + * + * Returned Value: + * Bound pbuf data bytes + * + ****************************************************************************/ + +uint32_t esp32s2_dma_init(struct esp32s2_dmadesc_s *dmadesc, uint32_t num, + uint8_t *pbuf, uint32_t len) +{ + int i; + uint32_t bytes = len; + uint8_t *pdata = pbuf; + uint32_t data_len; + uint32_t buf_len; + + DEBUGASSERT(dmadesc != NULL); + DEBUGASSERT(pbuf != NULL); + DEBUGASSERT(len > 0); + + for (i = 0; i < num; i++) + { + data_len = MIN(bytes, ESP32S2_DMA_DATALEN_MAX); + + /* Buffer length must be rounded to next 32-bit boundary. */ + + buf_len = ALIGN_UP(data_len, sizeof(uintptr_t)); + + dmadesc[i].ctrl = (data_len << DMA_CTRL_DATALEN_S) | + (buf_len << DMA_CTRL_BUFLEN_S) | + DMA_CTRL_OWN; + dmadesc[i].pbuf = pdata; + dmadesc[i].next = &dmadesc[i + 1]; + + bytes -= data_len; + if (bytes == 0) + { + break; + } + + pdata += data_len; + } + + dmadesc[i].ctrl |= DMA_CTRL_EOF; + dmadesc[i].next = NULL; + + return len - bytes; +} + +/**************************************************************************** + * Name: esp32s2_dma_init_with_padding + * + * Description: + * Initialize DMA outlink descriptors and bind the target buffer to + * these DMA descriptors. If len is not word-aligned, add a new descriptor + * containing a 4-byte variable to make the outlink data world-aligned. + * + * Input Parameters: + * dmadesc - Pointer to the DMA descriptors + * num - Number of DMA descriptors + * pbuf - RX/TX buffer pointer + * len - RX/TX buffer length + * stuff - Value to be padded with the buffer + * + * Returned Value: + * Bound pbuf data bytes + * + ****************************************************************************/ + +uint32_t esp32s2_dma_init_with_padding(struct esp32s2_dmadesc_s *dmadesc, + uint32_t num, + uint8_t *pbuf, + uint32_t len, + uint32_t *stuff) +{ + int i; + uint32_t bytes = len; + uint8_t *pdata = pbuf; + uint32_t data_len = 0; + uint32_t buf_len = 0; + + DEBUGASSERT(dmadesc != NULL); + DEBUGASSERT(pbuf != NULL); + DEBUGASSERT(len > 0); + + for (i = 0; i < num - 1; i++) + { + data_len = MIN(bytes, ESP32S2_DMA_DATALEN_MAX); + + /* Buffer length must be rounded to next 32-bit boundary. */ + + buf_len = ALIGN_UP(data_len, sizeof(uintptr_t)); + + dmadesc[i].ctrl = (data_len << DMA_CTRL_DATALEN_S) | + (buf_len << DMA_CTRL_BUFLEN_S) | + DMA_CTRL_OWN; + dmadesc[i].pbuf = pdata; + dmadesc[i].next = &dmadesc[i + 1]; + + bytes -= data_len; + if (bytes == 0) + { + break; + } + + pdata += data_len; + } + + /* Check if the data_len of the last descriptor is different from buf_len. + * If so, it's necessary to add the padding bytes to a new descriptor on + * outlink. + */ + + if (data_len != buf_len) + { + i++; + dmadesc[i].ctrl = ((buf_len - data_len) << DMA_CTRL_DATALEN_S) | + (4 << DMA_CTRL_BUFLEN_S) | + DMA_CTRL_OWN; + dmadesc[i].pbuf = (uint8_t *)stuff; + } + + dmadesc[i].ctrl |= DMA_CTRL_EOF; + dmadesc[i].next = NULL; + + return len - bytes; +} diff --git a/arch/xtensa/src/esp32s2/esp32s2_dma.h b/arch/xtensa/src/esp32s2/esp32s2_dma.h new file mode 100644 index 0000000000..4ce5a32f77 --- /dev/null +++ b/arch/xtensa/src/esp32s2/esp32s2_dma.h @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/esp32s2_dma.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_DMA_H +#define __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_DMA_H + +#include +#include + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* DMA max data length */ + +#define ESP32S2_DMA_DATALEN_MAX (0x1000 - 4) + +/* DMA max buffer length */ + +#define ESP32S2_DMA_BUFLEN_MAX ESP32S2_DMA_DATALEN_MAX + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* DMA descriptor type */ + +struct esp32s2_dmadesc_s +{ + uint32_t ctrl; /* DMA control block */ + uint8_t *pbuf; /* DMA TX/RX buffer address */ + struct esp32s2_dmadesc_s *next; /* Next DMA descriptor address */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s2_dma_init + * + * Description: + * Initialize DMA outlink descriptors and bind the target buffer to + * these DMA descriptors. + * + * Input Parameters: + * dmadesc - Pointer to the DMA descriptors + * num - Number of DMA descriptors + * pbuf - RX/TX buffer pointer + * len - RX/TX buffer length + * + * Returned Value: + * Bound pbuf data bytes + * + ****************************************************************************/ + +uint32_t esp32s2_dma_init(struct esp32s2_dmadesc_s *dmadesc, uint32_t num, + uint8_t *pbuf, uint32_t len); + +/**************************************************************************** + * Name: esp32s2_dma_init_with_padding + * + * Description: + * Initialize DMA outlink descriptors and bind the target buffer to + * these DMA descriptors. If len is not word-aligned, add a new descriptor + * containing a 4-byte variable to make the outlink data world-aligned. + * + * Input Parameters: + * dmadesc - Pointer to the DMA descriptors + * num - Number of DMA descriptors + * pbuf - RX/TX buffer pointer + * len - RX/TX buffer length + * stuff - Value to be padded with the buffer + * + * Returned Value: + * Bound pbuf data bytes + * + ****************************************************************************/ + +uint32_t esp32s2_dma_init_with_padding(struct esp32s2_dmadesc_s *dmadesc, + uint32_t num, + uint8_t *pbuf, + uint32_t len, + uint32_t *stuff); + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_DMA_H */ diff --git a/arch/xtensa/src/esp32s2/esp32s2_i2s.c b/arch/xtensa/src/esp32s2/esp32s2_i2s.c new file mode 100644 index 0000000000..50ea4c13a0 --- /dev/null +++ b/arch/xtensa/src/esp32s2/esp32s2_i2s.c @@ -0,0 +1,1507 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/esp32s2_i2s.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_ESP32S2_I2S + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "esp32s2_i2s.h" +#include "esp32s2_gpio.h" +#include "esp32s2_irq.h" +#include "esp32s2_dma.h" + +#include "xtensa.h" +#include "hardware/esp32s2_gpio_sigmap.h" +#include "hardware/esp32s2_system.h" +#include "hardware/esp32s2_i2s.h" +#include "hardware/esp32s2_soc.h" +#include "hardware/esp32s2_iomux.h" +#include "hardware/esp32s2_pinmap.h" +#include "hardware/esp32s2_dma.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* I2S DMA RX/TX description number */ + +#define I2S_DMADESC_NUM (CONFIG_I2S_DMADESC_NUM) + +/* I2S Clock */ + +#define I2S_LL_BASE_CLK (2 * APB_CLK_FREQ) +#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (6) +#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1) + +/* I2S DMA channel number */ + +#define I2S_DMA_CHANNEL_MAX (2) + +#ifdef CONFIG_ESP32S2_I2S_TX +# define I2S_TX_ENABLED 1 +# define I2S_HAVE_TX 1 +#else +# define I2S_TX_ENABLED 0 +#endif + +#ifdef CONFIG_ESP32S2_I2S_RX +# define I2S_RX_ENABLED 1 +#else +# define I2S_RX_ENABLED 0 +#endif + +/* Debug ********************************************************************/ + +#ifdef CONFIG_DEBUG_I2S_INFO +# define CONFIG_ESP32S2_I2S_DUMPBUFFERS +#else +# undef CONFIG_ESP32S2_I2S_DUMPBUFFERS +#endif + +#ifndef CONFIG_ESP32S2_I2S_MAXINFLIGHT +# define CONFIG_ESP32S2_I2S_MAXINFLIGHT 4 +#endif + +#define I2S_GPIO_UNUSED -1 /* For signals which are not used */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Role of the I2S0 port */ + +typedef enum +{ + I2S_ROLE_MASTER, /* I2S controller master role, bclk and ws signal will be set to output */ + I2S_ROLE_SLAVE /* I2S controller slave role, bclk and ws signal will be set to input */ +} i2s_role_t; + +/* Data width of the I2S channel */ + +typedef enum +{ + I2S_DATA_BIT_WIDTH_8BIT = 8, /* I2S channel data bit-width: 8 */ + I2S_DATA_BIT_WIDTH_16BIT = 16, /* I2S channel data bit-width: 16 */ + I2S_DATA_BIT_WIDTH_24BIT = 24, /* I2S channel data bit-width: 24 */ + I2S_DATA_BIT_WIDTH_32BIT = 32, /* I2S channel data bit-width: 32 */ +} i2s_data_bit_width_t; + +/* Multiplier of MCLK to sample rate */ + +typedef enum +{ + I2S_MCLK_MULTIPLE_128 = 128, /* mclk = sample_rate * 128 */ + I2S_MCLK_MULTIPLE_256 = 256, /* mclk = sample_rate * 256 */ + I2S_MCLK_MULTIPLE_384 = 384, /* mclk = sample_rate * 384 */ + I2S_MCLK_MULTIPLE_512 = 512, /* mclk = sample_rate * 512 */ +} i2s_mclk_multiple_t; + +/* I2S Device hardware configuration */ + +struct esp32s2_i2s_config_s +{ + uint32_t port; /* I2S port */ + uint32_t role; /* I2S port role (master or slave) */ + uint8_t data_width; /* I2S sample data width */ + uint32_t rate; /* I2S sample-rate */ + uint32_t total_slot; /* Total slot number */ + + bool is_apll; /* Select APLL as the source clock */ + uint32_t mclk_multiple; /* The multiple of mclk to the sample rate */ + + bool tx_en; /* Is TX enabled? */ + bool rx_en; /* Is RX enabled? */ + int8_t mclk_pin; /* MCLK pin, output */ + + /* BCLK pin, input in slave role, output in master role */ + + int8_t bclk_pin; + + /* WS pin, input in slave role, output in master role */ + + int8_t ws_pin; + + int8_t dout_pin; /* DATA pin, output */ + int8_t din_pin; /* DATA pin, input */ + + uint8_t periph; /* peripher ID */ + uint8_t irq; /* Interrupt ID */ + + uint32_t bclk_in_insig; /* RX channel BCK signal (slave mode) index */ + uint32_t bclk_in_outsig; /* RX channel BCK signal (master mode) index */ + uint32_t bclk_out_insig; /* TX channel BCK signal (slave mode) index */ + uint32_t bclk_out_outsig; /* TX channel BCK signal (master mode) index */ + uint32_t ws_in_insig; /* RX channel WS signal (slave mode) index */ + uint32_t ws_in_outsig; /* RX channel WS signal (master mode) index */ + uint32_t ws_out_insig; /* TX channel WS signal (slave mode) index */ + uint32_t ws_out_outsig; /* TX channel WS signal (master mode) index */ + uint32_t din_insig; /* RX channel Data Input signal index */ + uint32_t dout_outsig; /* TX channel Data Output signal index */ + uint32_t mclk_out_sig; /* Master clock output index */ + + bool bit_shift; /* Set to enable bit shift in Philips mode */ + bool mono_en; /* Set to enable mono mode on slot */ + + /* WS signal width (the number of bclk ticks that ws signal is high) */ + + uint32_t ws_width; + + /* WS signal polarity, set true to enable high lever first */ + + bool ws_pol; +}; + +struct esp32s2_buffer_s +{ + struct esp32s2_buffer_s *flink; /* Supports a singly linked list */ + + /* The associated DMA outlink */ + + struct esp32s2_dmadesc_s dma_outlink[I2S_DMADESC_NUM]; + + i2s_callback_t callback; /* DMA completion callback */ + uint32_t timeout; /* Timeout value of the DMA transfers */ + void *arg; /* Callback's argument */ + struct ap_buffer_s *apb; /* The audio buffer */ + int result; /* The result of the transfer */ +}; + +/* This structure describes the state of one receiver or transmitter + * transport. + */ + +struct esp32s2_transport_s +{ + sq_queue_t pend; /* A queue of pending transfers */ + sq_queue_t act; /* A queue of active transfers */ + sq_queue_t done; /* A queue of completed transfers */ + struct work_s work; /* Supports worker thread operations */ +}; + +/* The state of the one I2S peripheral */ + +struct esp32s2_i2s_s +{ + struct i2s_dev_s dev; /* Externally visible I2S interface */ + mutex_t lock; /* Assures mutually exclusive access */ + uint32_t rate; /* I2S actual configured sample-rate */ + uint32_t data_width; /* I2S actual configured data_width */ + int cpuint; /* I2S interrupt ID */ + uint8_t cpu; /* CPU ID */ + + /* Port configuration */ + + const struct esp32s2_i2s_config_s *config; + +#ifdef I2S_HAVE_TX + struct esp32s2_transport_s tx; /* TX transport state */ + + /* Stuff var to fill DMA buffer if not word-aligned */ + + uint32_t stuff; +#endif /* I2S_HAVE_TX */ + + /* Pre-allocated pool of buffer containers */ + + sem_t bufsem; /* Buffer wait semaphore */ + struct esp32s2_buffer_s *bf_freelist; /* A list a free buffer containers */ + struct esp32s2_buffer_s containers[CONFIG_ESP32S2_I2S_MAXINFLIGHT]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register helpers */ + +#ifdef CONFIG_ESP32S2_I2S_DUMPBUFFERS +# define i2s_dump_buffer(m,b,s) lib_dumpbuffer(m,b,s) +#else +# define i2s_dump_buffer(m,b,s) +#endif + +/* Semaphore helpers */ + +static int i2s_bufsem_take(struct esp32s2_i2s_s *priv); +#define i2s_bufsem_give(priv) nxsem_post(&priv->bufsem) + +/* Buffer container helpers */ + +static struct esp32s2_buffer_s * + i2s_buf_allocate(struct esp32s2_i2s_s *priv); +static void i2s_buf_free(struct esp32s2_i2s_s *priv, + struct esp32s2_buffer_s *bfcontainer); +static int i2s_buf_initialize(struct esp32s2_i2s_s *priv); + +/* DMA support */ + +#ifdef I2S_HAVE_TX +static int i2s_txdma_setup(struct esp32s2_i2s_s *priv, + struct esp32s2_buffer_s *bfcontainer); +static void i2s_tx_worker(void *arg); +static void i2s_tx_schedule(struct esp32s2_i2s_s *priv, + struct esp32s2_dmadesc_s *outlink); +#endif /* I2S_HAVE_TX */ + +/* I2S methods (and close friends) */ + +static uint32_t esp32s2_i2s_txsamplerate(struct i2s_dev_s *dev, + uint32_t rate); +static uint32_t esp32s2_i2s_txdatawidth(struct i2s_dev_s *dev, int bits); +static int esp32s2_i2s_send(struct i2s_dev_s *dev, + struct ap_buffer_s *apb, + i2s_callback_t callback, void *arg, + uint32_t timeout); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct i2s_ops_s g_i2sops = +{ + .i2s_txsamplerate = esp32s2_i2s_txsamplerate, + .i2s_txdatawidth = esp32s2_i2s_txdatawidth, + .i2s_send = esp32s2_i2s_send, +}; + +#ifdef CONFIG_ESP32S2_I2S +static const struct esp32s2_i2s_config_s esp32s2_i2s0_config = +{ + .port = 0, +#ifdef CONFIG_ESP32S2_I2S_ROLE_MASTER + .role = I2S_ROLE_MASTER, +#else + .role = I2S_ROLE_SLAVE, +#endif /* CONFIG_ESP32S2_I2S_ROLE_MASTER */ + .data_width = CONFIG_ESP32S2_I2S_DATA_BIT_WIDTH, + .rate = CONFIG_ESP32S2_I2S_SAMPLE_RATE, + .total_slot = 2, + .mclk_multiple = I2S_MCLK_MULTIPLE_384, + .tx_en = I2S_TX_ENABLED, + .rx_en = I2S_RX_ENABLED, +#ifdef CONFIG_ESP32S2_I2S_MCLK + .mclk_pin = CONFIG_ESP32S2_I2S_MCLKPIN, +#else + .mclk_pin = I2S_GPIO_UNUSED, +#endif /* CONFIG_ESP32S2_I2S_MCLK */ + .bclk_pin = CONFIG_ESP32S2_I2S_BCLKPIN, + .ws_pin = CONFIG_ESP32S2_I2S_WSPIN, +#ifdef CONFIG_ESP32S2_I2S_DOUTPIN + .dout_pin = CONFIG_ESP32S2_I2S_DOUTPIN, +#else + .dout_pin = I2S_GPIO_UNUSED, +#endif /* CONFIG_ESP32S2_I2S_DOUTPIN */ +#ifdef CONFIG_ESP32S2_I2S_DINPIN + .din_pin = CONFIG_ESP32S2_I2S_DINPIN, +#else + .din_pin = I2S_GPIO_UNUSED, +#endif /* CONFIG_ESP32S2_I2S_DINPIN */ + .periph = ESP32S2_PERIPH_I2S0, + .irq = ESP32S2_IRQ_I2S0, + .bclk_in_insig = I2S0I_BCK_IN_IDX, + .bclk_in_outsig = I2S0I_BCK_OUT_IDX, + .bclk_out_insig = I2S0O_BCK_IN_IDX, + .bclk_out_outsig = I2S0O_BCK_OUT_IDX, + .ws_in_insig = I2S0I_WS_IN_IDX, + .ws_in_outsig = I2S0I_WS_OUT_IDX, + .ws_out_insig = I2S0O_WS_IN_IDX, + .ws_out_outsig = I2S0O_WS_OUT_IDX, + .din_insig = I2S0I_DATA_IN15_IDX, + .dout_outsig = I2S0O_DATA_OUT23_IDX, + .mclk_out_sig = CLK_I2S_MUX_IDX, + .bit_shift = true, + .mono_en = false, + .ws_width = CONFIG_ESP32S2_I2S_DATA_BIT_WIDTH, +}; + +static struct esp32s2_i2s_s esp32s2_i2s0_priv = +{ + .dev = + { + .ops = &g_i2sops + }, + .config = &esp32s2_i2s0_config +}; +#endif /* CONFIG_ESP32S2_I2S */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: i2s_bufsem_take + * + * Description: + * Take the buffer semaphore handling any exceptional conditions + * + * Input Parameters: + * priv - A reference to the i2s peripheral state + * + * Returned Value: + * Normally OK, but may return -ECANCELED in the rare event that the task + * has been canceled. + * + ****************************************************************************/ + +static int i2s_bufsem_take(struct esp32s2_i2s_s *priv) +{ + return nxsem_wait_uninterruptible(&priv->bufsem); +} + +/**************************************************************************** + * Name: i2s_buf_allocate + * + * Description: + * Allocate a buffer container by removing the one at the head of the + * free list + * + * Input Parameters: + * priv - I2S state instance + * + * Returned Value: + * A non-NULL pointer to the allocate buffer container on success; NULL if + * there are no available buffer containers. + * + * Assumptions: + * The caller does NOT have exclusive access to the I2S state structure. + * That would result in a deadlock! + * + ****************************************************************************/ + +static struct esp32s2_buffer_s *i2s_buf_allocate(struct esp32s2_i2s_s *priv) +{ + struct esp32s2_buffer_s *bfcontainer; + irqstate_t flags; + int ret; + + /* Set aside a buffer container. By doing this, we guarantee that we will + * have at least one free buffer container. + */ + + ret = i2s_bufsem_take(priv); + if (ret < 0) + { + return NULL; + } + + /* Get the buffer from the head of the free list */ + + flags = enter_critical_section(); + bfcontainer = priv->bf_freelist; + DEBUGASSERT(bfcontainer); + + /* Unlink the buffer from the freelist */ + + priv->bf_freelist = bfcontainer->flink; + leave_critical_section(flags); + return bfcontainer; +} + +/**************************************************************************** + * Name: i2s_buf_free + * + * Description: + * Free buffer container by adding it to the head of the free list + * + * Input Parameters: + * priv - I2S state instance + * bfcontainer - The buffer container to be freed + * + * Returned Value: + * None + * + * Assumptions: + * The caller has exclusive access to the I2S state structure + * + ****************************************************************************/ + +static void i2s_buf_free(struct esp32s2_i2s_s *priv, + struct esp32s2_buffer_s *bfcontainer) +{ + irqstate_t flags; + + /* Put the buffer container back on the free list (circbuf) */ + + flags = enter_critical_section(); + + bfcontainer->apb = NULL; + bfcontainer->flink = priv->bf_freelist; + priv->bf_freelist = bfcontainer; + + leave_critical_section(flags); + + /* Wake up any threads waiting for a buffer container */ + + i2s_bufsem_give(priv); +} + +/**************************************************************************** + * Name: i2s_buf_initialize + * + * Description: + * Initialize the buffer container allocator by adding all of the + * pre-allocated buffer containers to the free list + * + * Input Parameters: + * priv - I2S state instance + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + * Assumptions: + * Called early in I2S initialization so that there are no issues with + * concurrency. + * + ****************************************************************************/ + +static int i2s_buf_initialize(struct esp32s2_i2s_s *priv) +{ + int ret; + + priv->bf_freelist = NULL; + ret = nxsem_init(&priv->bufsem, 0, 0); + + if (ret < 0) + { + i2serr("ERROR: nxsem_init failed: %d\n", ret); + return ret; + } + + for (int i = 0; i < CONFIG_ESP32S2_I2S_MAXINFLIGHT; i++) + { + i2s_buf_free(priv, &priv->containers[i]); + } + + return OK; +} + +/**************************************************************************** + * Name: i2s_txdma_start + * + * Description: + * Initiate the next TX DMA transfer. The DMA outlink was previously bound + * so it is safe to start the next DMA transfer at interruption level. + * + * Input Parameters: + * priv - I2S state instance + * + * Returned Value: + * OK on success; a negated errno value on failure + * + * Assumptions: + * Interrupts are disabled + * + ****************************************************************************/ + +#ifdef I2S_HAVE_TX +static int i2s_txdma_start(struct esp32s2_i2s_s *priv) +{ + struct esp32s2_buffer_s *bfcontainer; + + /* If there is already an active transmission in progress, then bail + * returning success. + */ + + if (!sq_empty(&priv->tx.act)) + { + return OK; + } + + /* If there are no pending transfer, then bail returning success */ + + if (sq_empty(&priv->tx.pend)) + { + return OK; + } + + bfcontainer = (struct esp32s2_buffer_s *)sq_remfirst(&priv->tx.pend); + + /* If there isn't already an active transmission in progress, + * then start it. + */ + + modifyreg32(I2S_OUT_LINK_REG, I2S_OUTLINK_ADDR_M, + FIELD_TO_VALUE(I2S_OUTLINK_ADDR, + (uintptr_t) bfcontainer->dma_outlink)); + + modifyreg32(I2S_OUT_LINK_REG, I2S_OUTLINK_STOP, I2S_OUTLINK_START); + + modifyreg32(I2S_CONF_REG, 0, I2S_TX_START); + + sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.act); + + return OK; +} +#endif /* I2S_HAVE_TX */ + +/**************************************************************************** + * Name: i2s_txdma_setup + * + * Description: + * Setup the next TX DMA transfer + * + * Input Parameters: + * priv - I2S state instance + * + * Returned Value: + * OK on success; a negated errno value on failure + * + * Assumptions: + * Interrupts are disabled + * + ****************************************************************************/ + +#ifdef I2S_HAVE_TX +static int i2s_txdma_setup(struct esp32s2_i2s_s *priv, + struct esp32s2_buffer_s *bfcontainer) +{ + struct ap_buffer_s *apb; + struct esp32s2_dmadesc_s *outlink; + uintptr_t samp; + apb_samp_t nbytes; + uint32_t bytes_queued; + + DEBUGASSERT(bfcontainer && bfcontainer->apb); + + apb = bfcontainer->apb; + outlink = bfcontainer->dma_outlink; + + /* Get the transfer information, accounting for any data offset */ + + samp = (uintptr_t)&apb->samp[apb->curbyte]; + nbytes = apb->nbytes - apb->curbyte; + + /* Configure DMA stream */ + + bytes_queued = esp32s2_dma_init_with_padding(outlink, I2S_DMADESC_NUM, + (uint8_t *)samp, nbytes, + &priv->stuff); + + if (bytes_queued != nbytes) + { + i2serr("Failed to enqueue I2S buffer (%d bytes of %d)\n", + bytes_queued, (uint32_t)nbytes); + return bytes_queued; + } + + /* Add the buffer container to the end of the TX pending queue */ + + sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.pend); + + return OK; +} +#endif /* I2S_HAVE_TX */ + +/**************************************************************************** + * Name: i2s_tx_schedule + * + * Description: + * An TX DMA completion has occurred. Schedule processing on + * the working thread. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select struction + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + * Assumptions: + * - Interrupts are disabled + * - The TX timeout has been canceled. + * + ****************************************************************************/ + +#ifdef I2S_HAVE_TX +static void i2s_tx_schedule(struct esp32s2_i2s_s *priv, + struct esp32s2_dmadesc_s *outlink) +{ + struct esp32s2_buffer_s *bfcontainer; + struct esp32s2_dmadesc_s *bfdesc; + int ret; + + /* Upon entry, the transfer(s) that just completed are the ones in the + * priv->tx.act queue. + */ + + /* Move all entries from the tx.act queue to the tx.done queue */ + + if (!sq_empty(&priv->tx.act)) + { + /* Remove the next buffer container from the tx.act list */ + + bfcontainer = (struct esp32s2_buffer_s *)sq_peek(&priv->tx.act); + + /* Check if the DMA descriptor that generated an EOF interrupt is the + * last descriptor of the current buffer container's DMA outlink. + * REVISIT: what to do if we miss syncronization and the descriptor + * that generated the interrupt is different from the expected (the + * oldest of the list containing active transmissions)? + */ + + /* Find the last descriptor of the current buffer container */ + + bfdesc = bfcontainer->dma_outlink; + while (!(bfdesc->ctrl & DMA_CTRL_EOF)) + { + DEBUGASSERT(bfdesc->next); + bfdesc = bfdesc->next; + } + + if (bfdesc == outlink) + { + sq_remfirst(&priv->tx.act); + + /* Report the result of the transfer */ + + bfcontainer->result = OK; + + /* Add the completed buffer container to the tail of the tx.done + * queue + */ + + sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.done); + + /* Check if the DMA is IDLE */ + + if (sq_empty(&priv->tx.act)) + { + /* Then start the next DMA. */ + + i2s_txdma_start(priv); + } + } + + /* If the worker has completed running, then reschedule the working + * thread. + */ + + if (work_available(&priv->tx.work)) + { + /* Schedule the TX DMA done processing to occur on the worker + * thread. + */ + + ret = work_queue(HPWORK, &priv->tx.work, i2s_tx_worker, priv, 0); + if (ret != 0) + { + i2serr("ERROR: Failed to queue TX work: %d\n", ret); + } + } + } +} +#endif /* I2S_HAVE_TX */ + +/**************************************************************************** + * Name: i2s_tx_worker + * + * Description: + * TX transfer done worker + * + * Input Parameters: + * arg - the I2S device instance cast to void* + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef I2S_HAVE_TX +static void i2s_tx_worker(void *arg) +{ + struct esp32s2_i2s_s *priv = (struct esp32s2_i2s_s *)arg; + struct esp32s2_buffer_s *bfcontainer; + irqstate_t flags; + + DEBUGASSERT(priv); + + /* When the transfer was started, the active buffer containers were removed + * from the tx.pend queue and saved in the tx.act queue. We get here when + * the DMA is finished. + * + * In any case, the buffer containers in tx.act will be moved to the end + * of the tx.done queue and tx.act will be emptied before this worker is + * started. + * + */ + + i2sinfo("tx.act.head=%p tx.done.head=%p\n", + priv->tx.act.head, priv->tx.done.head); + + /* Process each buffer in the tx.done queue */ + + while (sq_peek(&priv->tx.done) != NULL) + { + /* Remove the buffer container from the tx.done queue. NOTE that + * interrupts must be disabled to do this because the tx.done queue is + * also modified from the interrupt level. + */ + + flags = enter_critical_section(); + bfcontainer = (struct esp32s2_buffer_s *)sq_remfirst(&priv->tx.done); + leave_critical_section(flags); + + /* Perform the TX transfer done callback */ + + DEBUGASSERT(bfcontainer && bfcontainer->callback); + bfcontainer->callback(&priv->dev, bfcontainer->apb, + bfcontainer->arg, bfcontainer->result); + + /* Release our reference on the audio buffer. This may very likely + * cause the audio buffer to be freed. + */ + + apb_free(bfcontainer->apb); + + /* And release the buffer container */ + + i2s_buf_free(priv, bfcontainer); + } +} +#endif /* I2S_HAVE_TX */ + +/**************************************************************************** + * Name: i2s_configure + * + * Description: + * Configure I2S + * + * Input Parameters: + * priv - Partially initialized I2S device structure. This function + * will complete the I2S specific portions of the initialization + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void i2s_configure(struct esp32s2_i2s_s *priv) +{ + /* Set peripheral clock and clear reset */ + + modifyreg32(SYSTEM_PERIP_CLK_EN0_REG, 0, SYSTEM_I2S0_CLK_EN); + modifyreg32(SYSTEM_PERIP_RST_EN0_REG, 0, SYSTEM_I2S0_RST); + modifyreg32(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_I2S0_RST, 0); + + /* I2S module general init, enable I2S clock */ + + if (!(getreg32(I2S_CLKM_CONF_REG) & I2S_CLK_EN)) + { + i2sinfo("Enabling I2S port clock...\n"); + modifyreg32(I2S_CLKM_CONF_REG, 0, I2S_CLK_EN); + modifyreg32(I2S_CLKM_CONF_REG, I2S_CLK_SEL_M, + FIELD_TO_VALUE(I2S_CLK_SEL, 2)); + putreg32(0, I2S_CONF2_REG); + } + + /* Configure multiplexed pins as connected on the board */ + + /* TODO: check for loopback mode */ + + /* Enable TX channel */ + + if (priv->config->dout_pin != I2S_GPIO_UNUSED) + { + esp32s2_gpiowrite(priv->config->dout_pin, 1); + esp32s2_configgpio(priv->config->dout_pin, OUTPUT_FUNCTION_2); + esp32s2_gpio_matrix_out(priv->config->dout_pin, + priv->config->dout_outsig, 0, 0); + } + + /* TODO: repeat above function for RX channel */ + + if (priv->config->role == I2S_ROLE_SLAVE) + { + if (priv->config->tx_en && !priv->config->rx_en) + { + /* For "tx + slave" mode, select TX signal index for ws and bck */ + + esp32s2_gpiowrite(priv->config->ws_pin, 1); + esp32s2_configgpio(priv->config->ws_pin, INPUT_FUNCTION_2); + esp32s2_gpio_matrix_out(priv->config->ws_pin, + priv->config->ws_out_insig, 0, 0); + + esp32s2_gpiowrite(priv->config->bclk_pin, 1); + esp32s2_configgpio(priv->config->bclk_pin, INPUT_FUNCTION_2); + esp32s2_gpio_matrix_out(priv->config->bclk_pin, + priv->config->bclk_out_insig, 0, 0); + } + else + { + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal + * index for ws and bck. + */ + + esp32s2_gpiowrite(priv->config->ws_pin, 1); + esp32s2_configgpio(priv->config->ws_pin, INPUT_FUNCTION_2); + esp32s2_gpio_matrix_out(priv->config->ws_pin, + priv->config->ws_in_insig, 0, 0); + + esp32s2_gpiowrite(priv->config->bclk_pin, 1); + esp32s2_configgpio(priv->config->bclk_pin, INPUT_FUNCTION_2); + esp32s2_gpio_matrix_out(priv->config->bclk_pin, + priv->config->bclk_in_insig, 0, 0); + } + } + else + { + /* Considering master role for the I2S port */ + + /* Set MCLK pin */ + + if (priv->config->mclk_pin != I2S_GPIO_UNUSED) + { + i2sinfo("Configuring GPIO%" PRIu8 " to output master clock\n", + priv->config->mclk_pin); + + esp32s2_gpiowrite(priv->config->mclk_pin, 1); + esp32s2_configgpio(priv->config->mclk_pin, OUTPUT_FUNCTION_2); + esp32s2_gpio_matrix_out(priv->config->mclk_pin, + priv->config->mclk_out_sig, 0, 0); + } + + if (priv->config->rx_en && !priv->config->tx_en) + { + /* For "rx + master" mode, select RX signal index for ws and bck */ + + esp32s2_gpiowrite(priv->config->ws_pin, 1); + esp32s2_configgpio(priv->config->ws_pin, OUTPUT_FUNCTION_2); + esp32s2_gpio_matrix_out(priv->config->ws_pin, + priv->config->ws_in_outsig, 0, 0); + + esp32s2_gpiowrite(priv->config->bclk_pin, 1); + esp32s2_configgpio(priv->config->bclk_pin, OUTPUT_FUNCTION_2); + esp32s2_gpio_matrix_out(priv->config->bclk_pin, + priv->config->bclk_in_outsig, 0, 0); + } + else + { + /* For "tx + rx + master" or "tx + master" mode, select TX signal + * index for ws and bck. + */ + + esp32s2_gpiowrite(priv->config->ws_pin, 1); + esp32s2_configgpio(priv->config->ws_pin, OUTPUT_FUNCTION_2); + esp32s2_gpio_matrix_out(priv->config->ws_pin, + priv->config->ws_out_outsig, 0, 0); + + esp32s2_gpiowrite(priv->config->bclk_pin, 1); + esp32s2_configgpio(priv->config->bclk_pin, OUTPUT_FUNCTION_2); + esp32s2_gpio_matrix_out(priv->config->bclk_pin, + priv->config->bclk_out_outsig, 0, 0); + } + } + + /* TODO: share BCLK and WS if in full-duplex mode */ + + /* Configure the hardware to apply STD format */ + + if (priv->config->tx_en) + { + /* Reset I2S TX module */ + + modifyreg32(I2S_CONF_REG, 0, I2S_TX_RESET); + modifyreg32(I2S_CONF_REG, I2S_TX_RESET, 0); + modifyreg32(I2S_LC_CONF_REG, 0, I2S_OUT_RST); + modifyreg32(I2S_LC_CONF_REG, I2S_OUT_RST, 0); + + /* Enable/disable I2S TX slave mode */ + + if (priv->config->role == I2S_ROLE_SLAVE) + { + modifyreg32(I2S_CONF_REG, 0, I2S_TX_SLAVE_MOD); + } + else + { + modifyreg32(I2S_CONF_REG, I2S_TX_SLAVE_MOD, 0); + } + + /* Congfigure TX chan bit, audio data bit and mono mode. + * On ESP32S2, sample_bit should equals to data_bit + */ + + /* Set TX data width */ + + esp32s2_i2s_txdatawidth((struct i2s_dev_s *)priv, + priv->config->data_width); + + /* Set I2S tx chan mode */ + + modifyreg32(I2S_CONF_CHAN_REG, I2S_TX_CHAN_MOD_M, + FIELD_TO_VALUE(I2S_TX_CHAN_MOD, + priv->config->mono_en ? 4 : 0)); + + /* Enable/disable TX MSB shift, the data will be launch at the first + * BCK clock. + */ + + if (priv->config->bit_shift) + { + modifyreg32(I2S_CONF_REG, 0, I2S_TX_MSB_SHIFT); + } + else + { + modifyreg32(I2S_CONF_REG, I2S_TX_MSB_SHIFT, 0); + } + + /* Configure TX WS signal width. Set to to enable transmitter in PCM + * standard mode. + */ + + if (priv->config->ws_width == 1) + { + modifyreg32(I2S_CONF_REG, 0, I2S_TX_SHORT_SYNC); + } + else + { + modifyreg32(I2S_CONF_REG, I2S_TX_SHORT_SYNC, 0); + } + + /* Set I2S tx right channel first */ + + if (priv->config->ws_pol == 1) + { + modifyreg32(I2S_CONF_REG, 0, I2S_TX_RIGHT_FIRST); + } + else + { + modifyreg32(I2S_CONF_REG, I2S_TX_RIGHT_FIRST, 0); + } + + /* I2S tx fifo module force enable */ + + modifyreg32(I2S_FIFO_CONF_REG, 0, I2S_TX_FIFO_MOD_FORCE_EN); + + esp32s2_i2s_txsamplerate((struct i2s_dev_s *)priv, priv->config->rate); + } + + /* TODO: check for rx enabled flag */ +} + +/**************************************************************************** + * Name: i2s_tx_channel_start + * + * Description: + * Start TX channel for the I2S port + * + * Input Parameters: + * priv - Initialized I2S device structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef I2S_HAVE_TX +static void i2s_tx_channel_start(struct esp32s2_i2s_s *priv) +{ + /* Reset the TX channel */ + + modifyreg32(I2S_CONF_REG, 0, I2S_TX_RESET); + modifyreg32(I2S_CONF_REG, I2S_TX_RESET, 0); + + /* Reset the DMA operation */ + + modifyreg32(I2S_LC_CONF_REG, 0, I2S_OUT_RST); + modifyreg32(I2S_LC_CONF_REG, I2S_OUT_RST, 0); + + /* Reset TX FIFO */ + + modifyreg32(I2S_CONF_REG, 0, I2S_TX_FIFO_RESET); + modifyreg32(I2S_CONF_REG, I2S_TX_FIFO_RESET, 0); + + /* Enable DMA interruption */ + + up_enable_irq(priv->config->irq); + + modifyreg32(I2S_INT_ENA_REG, UINT32_MAX, I2S_OUT_EOF_INT_ENA); + + /* Enable DMA operation mode */ + + modifyreg32(I2S_FIFO_CONF_REG, 0, I2S_DSCR_EN); + + /* Unset the DMA outlink */ + + putreg32(0, I2S_OUT_LINK_REG); + + i2sinfo("Started TX channel on I2S0\n"); +} +#endif /* I2S_HAVE_TX */ + +/**************************************************************************** + * Name: esp32s2_i2s_interrupt + * + * Description: + * Common I2S DMA interrupt handler + * + * Input Parameters: + * arg - i2s controller private data + * + * Returned Value: + * Standard interrupt return value. + * + ****************************************************************************/ + +static int esp32s2_i2s_interrupt(int irq, void *context, void *arg) +{ + struct esp32s2_i2s_s *priv = (struct esp32s2_i2s_s *)arg; + struct esp32s2_dmadesc_s *cur = NULL; + + uint32_t status = getreg32(I2S_INT_ST_REG); + + putreg32(UINT32_MAX, I2S_INT_CLR_REG); + + if (status & I2S_OUT_EOF_INT_ST) + { + cur = (struct esp32s2_dmadesc_s *)getreg32(I2S_OUT_EOF_DES_ADDR_REG); + + /* Schedule completion of the transfer to occur on the worker thread */ + + i2s_tx_schedule(priv, cur); + } + + return 0; +} + +/**************************************************************************** + * Name: esp32s2_i2s_txsamplerate + * + * Description: + * Set the I2S TX sample rate. NOTE: This will have no effect if (1) the + * driver does not support an I2S transmitter or if (2) the sample rate is + * driven by the I2S frame clock. This may also have unexpected side- + * effects of the TX sample is coupled with the RX sample rate. + * + * Input Parameters: + * dev - Device-specific state data + * rate - The I2S sample rate in samples (not bits) per second + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static uint32_t esp32s2_i2s_txsamplerate(struct i2s_dev_s *dev, + uint32_t rate) +{ + struct esp32s2_i2s_s *priv = (struct esp32s2_i2s_s *)dev; + uint32_t bclk; + uint32_t mclk; + uint16_t bclk_div; + uint32_t sclk; + uint32_t mclk_div; + int denominator; + int numerator; + uint32_t regval; + uint32_t freq_diff; + + /* TODO: provide APLL clock support */ + + /* Disable APLL clock, I2S module will using PLL_D2_CLK(160M) as source + * clock. + */ + + modifyreg32(I2S_CLKM_CONF_REG, I2S_CLK_EN, 0); + sclk = I2S_LL_BASE_CLK; + + /* fmclk = bck_div * fbclk = fsclk / (mclk_div + b / a) + * mclk_div is the I2S clock divider's integral value + * b is the fraction clock divider's numerator value + * a is the fraction clock divider's denominator value + */ + + if (priv->config->role == I2S_ROLE_MASTER) + { + bclk = rate * priv->config->total_slot * priv->data_width; + mclk = rate * priv->config->mclk_multiple; + bclk_div = mclk / bclk; + } + else + { + /* For slave mode, mclk >= bclk * 8, so fix bclk_div to 2 first */ + + bclk_div = 8; + bclk = rate * priv->config->total_slot * priv->data_width; + mclk = bclk * bclk_div; + } + + /* Calculate the nearest integer value of the I2S clock divider */ + + mclk_div = sclk / mclk; + + i2sinfo("Clock division info: [sclk]%" PRIu32 " Hz [mdiv] %d " + "[mclk] %" PRIu32 " Hz [bdiv] %d [bclk] %" PRIu32 " Hz\n", + sclk, mclk_div, mclk, bclk_div, bclk); + + freq_diff = abs((int)sclk - (int)(mclk * mclk_div)); + + denominator = 1; + numerator = 0; + + if (freq_diff) + { + float decimal = freq_diff / (float)mclk; + + /* Carry bit if the decimal is greater than + * 1.0 - 1.0 / (63.0 * 2) = 125.0 / 126.0 + */ + + if (decimal > 125.0f / 126.0f) + { + mclk_div++; + } + else + { + uint32_t min = UINT32_MAX; + + for (int a = 2; a <= I2S_LL_MCLK_DIVIDER_MAX; a++) + { + int b = (int)(a * (freq_diff / (double)mclk) + 0.5); + int ma = freq_diff * a; + int mb = mclk * b; + if (ma == mb) + { + denominator = a; + numerator = b; + break; + } + + if (abs((mb - ma)) < min) + { + denominator = a; + numerator = b; + min = abs(mb - ma); + } + } + } + } + + i2sinfo("Clock register: [mclk] %" PRIu32 " Hz [numerator] %d " + "[denominator] %d\n", mclk, numerator, denominator); + + regval = getreg32(I2S_CLKM_CONF_REG); + regval &= ~I2S_CLKM_DIV_NUM_M; + regval |= FIELD_TO_VALUE(I2S_CLKM_DIV_NUM, mclk_div); + regval &= ~I2S_CLKM_DIV_B_M; + regval |= FIELD_TO_VALUE(I2S_CLKM_DIV_B, numerator); + regval &= ~I2S_CLKM_DIV_A_M; + regval |= FIELD_TO_VALUE(I2S_CLKM_DIV_A, denominator); + putreg32(regval, I2S_CLKM_CONF_REG); + + /* Set I2S tx bck div num */ + + modifyreg32(I2S_SAMPLE_RATE_CONF_REG, I2S_TX_BCK_DIV_NUM_M, + FIELD_TO_VALUE(I2S_TX_BCK_DIV_NUM, bclk_div)); + + /* Returns the actual sample rate */ + + bclk = sclk / (float)((mclk_div + numerator / (float)denominator) * + bclk_div); + rate = bclk / (float)(priv->config->total_slot * priv->data_width); + + priv->rate = rate; + + return rate; +} + +/**************************************************************************** + * Name: esp32s2_i2s_txdatawidth + * + * Description: + * Set the I2S TX data width. The TX bitrate is determined by + * sample_rate * data_width. + * + * Input Parameters: + * dev - Device-specific state data + * width - The I2S data with in bits. + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static uint32_t esp32s2_i2s_txdatawidth(struct i2s_dev_s *dev, int bits) +{ + struct esp32s2_i2s_s *priv = (struct esp32s2_i2s_s *)dev; + + modifyreg32(I2S_SAMPLE_RATE_CONF_REG, I2S_TX_BITS_MOD_M, + FIELD_TO_VALUE(I2S_TX_BITS_MOD, bits)); + + priv->data_width = bits; + + /* Set TX FIFO operation mode */ + + modifyreg32(I2S_FIFO_CONF_REG, I2S_TX_FIFO_MOD_M, + priv->data_width <= I2S_DATA_BIT_WIDTH_16BIT ? + FIELD_TO_VALUE(I2S_TX_FIFO_MOD, 0 + priv->config->mono_en) : + FIELD_TO_VALUE(I2S_TX_FIFO_MOD, 2 + priv->config->mono_en)); + + /* I2S TX MSB right enable */ + + if (priv->data_width <= I2S_DATA_BIT_WIDTH_16BIT) + { + modifyreg32(I2S_CONF_REG, 0, I2S_TX_MSB_RIGHT); + } + else + { + modifyreg32(I2S_CONF_REG, I2S_TX_MSB_RIGHT, 0); + } + + return bits; +} + +/**************************************************************************** + * Name: esp32s2_i2s_send + * + * Description: + * Send a block of data on I2S. + * + * Input Parameters: + * dev - Device-specific state data + * apb - A pointer to the audio buffer from which to send data + * callback - A user provided callback function that will be called at + * the completion of the transfer. + * arg - An opaque argument that will be provided to the callback + * when the transfer complete + * timeout - The timeout value to use. The transfer will be cancelled + * and an ETIMEDOUT error will be reported if this timeout + * elapsed without completion of the DMA transfer. Units + * are system clock ticks. Zero means no timeout. + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int esp32s2_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, + i2s_callback_t callback, void *arg, + uint32_t timeout) +{ + struct esp32s2_i2s_s *priv = (struct esp32s2_i2s_s *)dev; + struct esp32s2_buffer_s *bfcontainer; + irqstate_t flags; + int ret = OK; + + /* Check audio buffer data size */ + + if ((apb->nbytes - apb->curbyte) > + (ESP32S2_DMA_DATALEN_MAX * (I2S_DMADESC_NUM - 1))) + { + return -EFBIG; + } + + /* Allocate a buffer container in advance */ + + bfcontainer = i2s_buf_allocate(priv); + DEBUGASSERT(bfcontainer); + + /* Get exclusive access to the I2S driver data */ + + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + goto errout_with_buf; + } + + /* Add a reference to the audio buffer */ + + apb_reference(apb); + + /* Initialize the buffer container structure */ + + bfcontainer->callback = callback; + bfcontainer->timeout = timeout; + bfcontainer->arg = arg; + bfcontainer->apb = apb; + bfcontainer->result = -EBUSY; + + flags = enter_critical_section(); + + ret = i2s_txdma_setup(priv, bfcontainer); + + if (ret != OK) + { + goto errout_with_buf; + } + + ret = i2s_txdma_start(priv); + + if (ret != OK) + { + goto errout_with_buf; + } + + i2sinfo("Queued %d bytes into DMA buffers\n", apb->nbytes); + i2s_dump_buffer("Audio pipeline buffer:", &apb->samp[apb->curbyte], + apb->nbytes - apb->curbyte); + + /* Trigger DMA transfer */ + + leave_critical_section(flags); + nxmutex_unlock(&priv->lock); + + return OK; + +errout_with_buf: + nxmutex_unlock(&priv->lock); + i2s_buf_free(priv, bfcontainer); + return ret; +} + +/**************************************************************************** + * Name: esp32s2_i2sdma_setup + * + * Description: + * Configure the DMA for the I2S peripheral + * + * Input Parameters: + * priv - Partially initialized I2S device structure. This function + * will complete the I2S specific portions of the initialization + * regarding the DMA operation. + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + ****************************************************************************/ + +static int esp32s2_i2sdma_setup(struct esp32s2_i2s_s *priv) +{ + int ret; + + /* Clear the interrupts */ + + putreg32(UINT32_MAX, I2S_INT_CLR_REG); + + /* Set up to receive peripheral interrupts on the current CPU */ + + priv->cpu = up_cpu_index(); + priv->cpuint = esp32s2_setup_irq(priv->config->periph, 1, + ESP32S2_CPUINT_LEVEL); + if (priv->cpuint < 0) + { + i2serr("Failed to allocate a CPU interrupt.\n"); + return priv->cpuint; + } + + ret = irq_attach(priv->config->irq, esp32s2_i2s_interrupt, priv); + if (ret != OK) + { + i2serr("Couldn't attach IRQ to handler.\n"); + esp32s2_teardown_irq(priv->config->periph, priv->cpuint); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: esp32s2_i2sbus_initialize + * + * Description: + * Initialize the I2S peripheral + * + * Input Parameters: + * None + * + * Returned Value: + * Valid I2S device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct i2s_dev_s *esp32s2_i2sbus_initialize(void) +{ + int ret; + struct esp32s2_i2s_s *priv = NULL; + irqstate_t flags; + + /* Statically allocated I2S' device strucuture */ + + priv = &esp32s2_i2s0_priv; + + flags = enter_critical_section(); + + nxmutex_init(&priv->lock); + + i2s_configure(priv); + + /* Allocate buffer containers */ + + ret = i2s_buf_initialize(priv); + if (ret < 0) + { + goto err; + } + + ret = esp32s2_i2sdma_setup(priv); + if (ret < 0) + { + goto err; + } + +#ifdef I2S_HAVE_TX + /* Start TX channel */ + + i2s_tx_channel_start(priv); +#endif /* I2S_HAVE_TX */ + + leave_critical_section(flags); + + /* Success exit */ + + i2sinfo("I2S0 was successfully initialized\n"); + + return &priv->dev; + + /* Failure exit */ + +err: + leave_critical_section(flags); + nxmutex_destroy(&priv->lock); + return NULL; +} + +#endif /* CONFIG_ESP32S2_I2S */ diff --git a/arch/xtensa/src/esp32s2/esp32s2_i2s.h b/arch/xtensa/src/esp32s2/esp32s2_i2s.h new file mode 100644 index 0000000000..20b55c2062 --- /dev/null +++ b/arch/xtensa/src/esp32s2/esp32s2_i2s.h @@ -0,0 +1,74 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/esp32s2_i2s.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_I2S_H +#define __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_I2S_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#ifdef CONFIG_ESP32S2_I2S + +#define ESP32S2_I2S0 0 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s2_i2sbus_initialize + * + * Description: + * Initialize the selected I2S port + * + * Input Parameters: + * None + * + * Returned Value: + * Valid I2S device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct i2s_dev_s *esp32s2_i2sbus_initialize(void); + +#endif /* CONFIG_ESP32S2_I2S */ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_I2S_H */ diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_dma.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_dma.h new file mode 100644 index 0000000000..cd29ee0572 --- /dev/null +++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_dma.h @@ -0,0 +1,36 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s2/hardware/esp32s2_dma.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_DMA_H +#define __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_DMA_H + +/* DMA descriptor */ + +#define DMA_CTRL_OWN (1 << 31) /* Owned by DMA */ +#define DMA_CTRL_EOF (1 << 30) /* End of frame */ +#define DMA_CTRL_SOSF (1 << 29) /* Start of sub-frame */ +#define DMA_CTRL_OFFSET_S (24) /* buffer offset shift */ +#define DMA_CTRL_OFFSET_V (0x1f) /* buffer offset value */ +#define DMA_CTRL_DATALEN_S (12) /* received/sent data length shift */ +#define DMA_CTRL_DATALEN_V (0xfff) /* received/sent data length value */ +#define DMA_CTRL_BUFLEN_S (0) /* received/sent buffer length shift */ +#define DMA_CTRL_BUFLEN_V (0xfff) /* received/sent buffer length value */ + +#endif /* __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_DMA_H */ diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_i2s.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_i2s.h index 74c3732c2c..745006dfd4 100644 --- a/arch/xtensa/src/esp32s2/hardware/esp32s2_i2s.h +++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_i2s.h @@ -32,14 +32,14 @@ ****************************************************************************/ /* I2S_CONF_REG register - * I2S Configure register + * I2S configuration register */ #define I2S_CONF_REG (DR_REG_I2S_BASE + 0x8) /* I2S_RX_RESET_ST : RO; bitpos: [29]; default: 0; - * I2S RX reset status. 1: I2S_RX_RESET is not finished. 0: I2S_RX_RESET is - * finished. + * I2S RX reset status. 1: I2S_RX_RESET is not completed. 0: I2S_RX_RESET is + * completed. */ #define I2S_RX_RESET_ST (BIT(29)) @@ -48,7 +48,7 @@ #define I2S_RX_RESET_ST_S 29 /* I2S_RX_BIG_ENDIAN : R/W; bitpos: [28]; default: 0; - * I2S RX byte endian. + * I2S RX byte endianness. */ #define I2S_RX_BIG_ENDIAN (BIT(28)) @@ -57,7 +57,7 @@ #define I2S_RX_BIG_ENDIAN_S 28 /* I2S_TX_BIG_ENDIAN : R/W; bitpos: [27]; default: 0; - * I2S TX byte endian. + * I2S TX byte endianness. */ #define I2S_TX_BIG_ENDIAN (BIT(27)) @@ -66,7 +66,7 @@ #define I2S_TX_BIG_ENDIAN_S 27 /* I2S_PRE_REQ_EN : R/W; bitpos: [26]; default: 0; - * set this bit to enable i2s to prepare data earlier + * Set this bit to enable I2S to prepare data earlier. */ #define I2S_PRE_REQ_EN (BIT(26)) @@ -75,7 +75,8 @@ #define I2S_PRE_REQ_EN_S 26 /* I2S_RX_DMA_EQUAL : R/W; bitpos: [25]; default: 0; - * 1:data in left channel is equal to data in right channel + * 1: Data in left channel is equal to data in right channel. 0: Data in + * left channel is not equal to data in right channel. */ #define I2S_RX_DMA_EQUAL (BIT(25)) @@ -84,7 +85,8 @@ #define I2S_RX_DMA_EQUAL_S 25 /* I2S_TX_DMA_EQUAL : R/W; bitpos: [24]; default: 0; - * 1:data in left channel is equal to data in right channel + * 1: Data in left channel is equal to data in right channel. 0: Data in + * left channel is not equal to data in right channel. */ #define I2S_TX_DMA_EQUAL (BIT(24)) @@ -93,7 +95,8 @@ #define I2S_TX_DMA_EQUAL_S 24 /* I2S_TX_RESET_ST : RO; bitpos: [23]; default: 0; - * 1: i2s_tx_reset is not ok 0: i2s_tx_reset is ok + * I2S TX reset status. 1: I2S_TX_RESET is not completed. 0: I2S_TX_RESET is + * completed. */ #define I2S_TX_RESET_ST (BIT(23)) @@ -102,7 +105,8 @@ #define I2S_TX_RESET_ST_S 23 /* I2S_RX_FIFO_RESET_ST : RO; bitpos: [22]; default: 0; - * 1:i2s_rx_fifo_reset is not ok 0:i2s_rx_fifo reset is ok + * I2S RX FIFO reset status. 1: I2S_RX_FIFO_RESET is not completed. 0: + * I2S_RX_FIFO_RESET is completed. */ #define I2S_RX_FIFO_RESET_ST (BIT(22)) @@ -111,7 +115,8 @@ #define I2S_RX_FIFO_RESET_ST_S 22 /* I2S_TX_FIFO_RESET_ST : RO; bitpos: [21]; default: 0; - * 1:i2s_tx_fifo reset is not ok 0:i2s_tx_fifo_reset is ok + * I2S TX FIFO reset status. 1: I2S_TX_FIFO_RESET is not completed. 0: + * I2S_TX_FIFO_RESET is completed. */ #define I2S_TX_FIFO_RESET_ST (BIT(21)) @@ -150,7 +155,7 @@ #define I2S_TX_LSB_FIRST_DMA_S 18 /* I2S_RX_MSB_RIGHT : R/W; bitpos: [17]; default: 0; - * Set this bit to place right channel data at the MSB in the receive FIFO. + * Set this bit to place right channel data at the MSB in RX FIFO. */ #define I2S_RX_MSB_RIGHT (BIT(17)) @@ -159,7 +164,7 @@ #define I2S_RX_MSB_RIGHT_S 17 /* I2S_TX_MSB_RIGHT : R/W; bitpos: [16]; default: 0; - * Set this bit to place right channel data at the MSB in the transmit FIFO. + * Set this bit to place right channel data at the MSB in TX FIFO. */ #define I2S_TX_MSB_RIGHT (BIT(16)) @@ -168,7 +173,7 @@ #define I2S_TX_MSB_RIGHT_S 16 /* I2S_RX_MONO : R/W; bitpos: [15]; default: 0; - * Set this bit to enable receiver in mono mode + * Set this bit to enable receiver in mono mode. */ #define I2S_RX_MONO (BIT(15)) @@ -177,7 +182,7 @@ #define I2S_RX_MONO_S 15 /* I2S_TX_MONO : R/W; bitpos: [14]; default: 0; - * Set this bit to enable transmitter in mono mode + * Set this bit to enable transmitter in mono mode. */ #define I2S_TX_MONO (BIT(14)) @@ -186,7 +191,7 @@ #define I2S_TX_MONO_S 14 /* I2S_RX_SHORT_SYNC : R/W; bitpos: [13]; default: 0; - * Set this bit to enable receiver in PCM standard mode + * Set this bit to enable receiver in PCM standard mode. */ #define I2S_RX_SHORT_SYNC (BIT(13)) @@ -195,7 +200,7 @@ #define I2S_RX_SHORT_SYNC_S 13 /* I2S_TX_SHORT_SYNC : R/W; bitpos: [12]; default: 0; - * Set this bit to enable transmitter in PCM standard mode + * Set this bit to enable transmitter in PCM standard mode. */ #define I2S_TX_SHORT_SYNC (BIT(12)) @@ -204,7 +209,7 @@ #define I2S_TX_SHORT_SYNC_S 12 /* I2S_RX_MSB_SHIFT : R/W; bitpos: [11]; default: 0; - * Set this bit to enable receiver in Phillips standard mode + * Set this bit to enable receiver in Phillips standard mode. */ #define I2S_RX_MSB_SHIFT (BIT(11)) @@ -213,7 +218,7 @@ #define I2S_RX_MSB_SHIFT_S 11 /* I2S_TX_MSB_SHIFT : R/W; bitpos: [10]; default: 0; - * Set this bit to enable transmitter in Phillips standard mode + * Set this bit to enable transmitter in Phillips standard mode. */ #define I2S_TX_MSB_SHIFT (BIT(10)) @@ -222,7 +227,7 @@ #define I2S_TX_MSB_SHIFT_S 10 /* I2S_RX_RIGHT_FIRST : R/W; bitpos: [9]; default: 1; - * Set this bit to receive right channel data first + * Set this bit to receive right channel data first. */ #define I2S_RX_RIGHT_FIRST (BIT(9)) @@ -231,7 +236,7 @@ #define I2S_RX_RIGHT_FIRST_S 9 /* I2S_TX_RIGHT_FIRST : R/W; bitpos: [8]; default: 1; - * Set this bit to transmit right channel data first + * Set this bit to transmit right channel data first. */ #define I2S_TX_RIGHT_FIRST (BIT(8)) @@ -240,7 +245,7 @@ #define I2S_TX_RIGHT_FIRST_S 8 /* I2S_RX_SLAVE_MOD : R/W; bitpos: [7]; default: 0; - * Set this bit to enable slave receiver mode + * Set this bit to enable slave receiver mode. */ #define I2S_RX_SLAVE_MOD (BIT(7)) @@ -249,7 +254,7 @@ #define I2S_RX_SLAVE_MOD_S 7 /* I2S_TX_SLAVE_MOD : R/W; bitpos: [6]; default: 0; - * Set this bit to enable slave transmitter mode + * Set this bit to enable slave transmitter mode. */ #define I2S_TX_SLAVE_MOD (BIT(6)) @@ -258,7 +263,7 @@ #define I2S_TX_SLAVE_MOD_S 6 /* I2S_RX_START : R/W; bitpos: [5]; default: 0; - * Set this bit to start receiving data + * Set this bit to start receiving data. */ #define I2S_RX_START (BIT(5)) @@ -267,7 +272,7 @@ #define I2S_RX_START_S 5 /* I2S_TX_START : R/W; bitpos: [4]; default: 0; - * Set this bit to start transmitting data + * Set this bit to start transmitting data. */ #define I2S_TX_START (BIT(4)) @@ -276,7 +281,7 @@ #define I2S_TX_START_S 4 /* I2S_RX_FIFO_RESET : WO; bitpos: [3]; default: 0; - * Set this bit to reset rxFIFO + * Set this bit to reset RX FIFO. */ #define I2S_RX_FIFO_RESET (BIT(3)) @@ -285,7 +290,7 @@ #define I2S_RX_FIFO_RESET_S 3 /* I2S_TX_FIFO_RESET : WO; bitpos: [2]; default: 0; - * Set this bit to reset txFIFO + * Set this bit to reset TX FIFO. */ #define I2S_TX_FIFO_RESET (BIT(2)) @@ -294,7 +299,7 @@ #define I2S_TX_FIFO_RESET_S 2 /* I2S_RX_RESET : WO; bitpos: [1]; default: 0; - * Set this bit to reset receiver + * Set this bit to reset receiver. */ #define I2S_RX_RESET (BIT(1)) @@ -303,7 +308,7 @@ #define I2S_RX_RESET_S 1 /* I2S_TX_RESET : WO; bitpos: [0]; default: 0; - * Set this bit to reset transmitter + * Set this bit to reset transmitter. */ #define I2S_TX_RESET (BIT(0)) @@ -318,7 +323,7 @@ #define I2S_INT_RAW_REG (DR_REG_I2S_BASE + 0xc) /* I2S_V_SYNC_INT_RAW : RO; bitpos: [17]; default: 0; - * The raw interrupt status bit for the i2s_v_sync_int interrupt + * The raw interrupt status bit for I2S_V_SYNC_INT interrupt. */ #define I2S_V_SYNC_INT_RAW (BIT(17)) @@ -327,7 +332,7 @@ #define I2S_V_SYNC_INT_RAW_S 17 /* I2S_OUT_TOTAL_EOF_INT_RAW : RO; bitpos: [16]; default: 0; - * The raw interrupt status bit for the i2s_out_total_eof_int interrupt + * The raw interrupt status bit for I2S_OUT_TOTAL_EOF_INT interrupt. */ #define I2S_OUT_TOTAL_EOF_INT_RAW (BIT(16)) @@ -336,7 +341,7 @@ #define I2S_OUT_TOTAL_EOF_INT_RAW_S 16 /* I2S_IN_DSCR_EMPTY_INT_RAW : RO; bitpos: [15]; default: 0; - * The raw interrupt status bit for the i2s_in_dscr_empty_int interrupt + * The raw interrupt status bit for I2S_IN_DSCR_EMPTY_INT interrupt. */ #define I2S_IN_DSCR_EMPTY_INT_RAW (BIT(15)) @@ -345,7 +350,7 @@ #define I2S_IN_DSCR_EMPTY_INT_RAW_S 15 /* I2S_OUT_DSCR_ERR_INT_RAW : RO; bitpos: [14]; default: 0; - * The raw interrupt status bit for the i2s_out_dscr_err_int interrupt + * The raw interrupt status bit for I2S_OUT_DSCR_ERR_INT interrupt. */ #define I2S_OUT_DSCR_ERR_INT_RAW (BIT(14)) @@ -354,7 +359,7 @@ #define I2S_OUT_DSCR_ERR_INT_RAW_S 14 /* I2S_IN_DSCR_ERR_INT_RAW : RO; bitpos: [13]; default: 0; - * The raw interrupt status bit for the i2s_in_dscr_err_int interrupt + * The raw interrupt status bit for I2S_IN_DSCR_ERR_INT interrupt. */ #define I2S_IN_DSCR_ERR_INT_RAW (BIT(13)) @@ -363,7 +368,7 @@ #define I2S_IN_DSCR_ERR_INT_RAW_S 13 /* I2S_OUT_EOF_INT_RAW : RO; bitpos: [12]; default: 0; - * The raw interrupt status bit for the i2s_out_eof_int interrupt + * The raw interrupt status bit for I2S_OUT_EOF_INT interrupt. */ #define I2S_OUT_EOF_INT_RAW (BIT(12)) @@ -372,7 +377,7 @@ #define I2S_OUT_EOF_INT_RAW_S 12 /* I2S_OUT_DONE_INT_RAW : RO; bitpos: [11]; default: 0; - * The raw interrupt status bit for the i2s_out_done_int interrupt + * The raw interrupt status bit for I2S_OUT_DONE_INT interrupt. */ #define I2S_OUT_DONE_INT_RAW (BIT(11)) @@ -381,7 +386,7 @@ #define I2S_OUT_DONE_INT_RAW_S 11 /* I2S_IN_ERR_EOF_INT_RAW : RO; bitpos: [10]; default: 0; - * don't use + * Reserved. */ #define I2S_IN_ERR_EOF_INT_RAW (BIT(10)) @@ -390,7 +395,7 @@ #define I2S_IN_ERR_EOF_INT_RAW_S 10 /* I2S_IN_SUC_EOF_INT_RAW : RO; bitpos: [9]; default: 0; - * The raw interrupt status bit for the i2s_in_suc_eof_int interrupt + * The raw interrupt status bit for I2S_IN_SUC_EOF_INT interrupt. */ #define I2S_IN_SUC_EOF_INT_RAW (BIT(9)) @@ -399,7 +404,7 @@ #define I2S_IN_SUC_EOF_INT_RAW_S 9 /* I2S_IN_DONE_INT_RAW : RO; bitpos: [8]; default: 0; - * The raw interrupt status bit for the i2s_in_done_int interrupt + * The raw interrupt status bit for I2S_IN_DONE_INT interrupt. */ #define I2S_IN_DONE_INT_RAW (BIT(8)) @@ -408,7 +413,7 @@ #define I2S_IN_DONE_INT_RAW_S 8 /* I2S_TX_HUNG_INT_RAW : RO; bitpos: [7]; default: 0; - * The raw interrupt status bit for the i2s_tx_hung_int interrupt + * The raw interrupt status bit for I2S_TX_HUNG_INT interrupt. */ #define I2S_TX_HUNG_INT_RAW (BIT(7)) @@ -417,7 +422,7 @@ #define I2S_TX_HUNG_INT_RAW_S 7 /* I2S_RX_HUNG_INT_RAW : RO; bitpos: [6]; default: 0; - * The raw interrupt status bit for the i2s_rx_hung_int interrupt + * The raw interrupt status bit for I2S_RX_HUNG_INT interrupt. */ #define I2S_RX_HUNG_INT_RAW (BIT(6)) @@ -426,7 +431,7 @@ #define I2S_RX_HUNG_INT_RAW_S 6 /* I2S_TX_REMPTY_INT_RAW : RO; bitpos: [5]; default: 0; - * The raw interrupt status bit for the i2s_tx_rempty_int interrupt + * The raw interrupt status bit for I2S_TX_REMPTY_INT interrupt. */ #define I2S_TX_REMPTY_INT_RAW (BIT(5)) @@ -435,7 +440,7 @@ #define I2S_TX_REMPTY_INT_RAW_S 5 /* I2S_TX_WFULL_INT_RAW : RO; bitpos: [4]; default: 0; - * The raw interrupt status bit for the i2s_tx_wfull_int interrupt + * The raw interrupt status bit for I2S_TX_WFULL_INT interrupt. */ #define I2S_TX_WFULL_INT_RAW (BIT(4)) @@ -444,7 +449,7 @@ #define I2S_TX_WFULL_INT_RAW_S 4 /* I2S_RX_REMPTY_INT_RAW : RO; bitpos: [3]; default: 0; - * The raw interrupt status bit for the i2s_rx_rempty_int interrupt + * The raw interrupt status bit for I2S_RX_REMPTY_INT interrupt. */ #define I2S_RX_REMPTY_INT_RAW (BIT(3)) @@ -453,7 +458,7 @@ #define I2S_RX_REMPTY_INT_RAW_S 3 /* I2S_RX_WFULL_INT_RAW : RO; bitpos: [2]; default: 0; - * The raw interrupt status bit for the i2s_rx_wfull_int interrupt + * The raw interrupt status bit for I2S_RX_WFULL_INT interrupt. */ #define I2S_RX_WFULL_INT_RAW (BIT(2)) @@ -462,7 +467,7 @@ #define I2S_RX_WFULL_INT_RAW_S 2 /* I2S_TX_PUT_DATA_INT_RAW : RO; bitpos: [1]; default: 0; - * The raw interrupt status bit for the i2s_tx_put_data_int interrupt + * The raw interrupt status bit for I2S_TX_PUT_DATA_INT interrupt. */ #define I2S_TX_PUT_DATA_INT_RAW (BIT(1)) @@ -471,7 +476,7 @@ #define I2S_TX_PUT_DATA_INT_RAW_S 1 /* I2S_RX_TAKE_DATA_INT_RAW : RO; bitpos: [0]; default: 0; - * The raw interrupt status bit for the i2s_rx_take_data_int interrupt + * The raw interrupt status bit for I2S_RX_TAKE_DATA_INT interrupt. */ #define I2S_RX_TAKE_DATA_INT_RAW (BIT(0)) @@ -486,7 +491,7 @@ #define I2S_INT_ST_REG (DR_REG_I2S_BASE + 0x10) /* I2S_V_SYNC_INT_ST : RO; bitpos: [17]; default: 0; - * The masked interrupt status bit for the i2s_v_sync_int interrupt + * The masked interrupt status bit for I2S_V_SYNC_INT interrupt. */ #define I2S_V_SYNC_INT_ST (BIT(17)) @@ -495,7 +500,7 @@ #define I2S_V_SYNC_INT_ST_S 17 /* I2S_OUT_TOTAL_EOF_INT_ST : RO; bitpos: [16]; default: 0; - * The masked interrupt status bit for the i2s_out_total_eof_int interrupt + * The masked interrupt status bit for I2S_OUT_TOTAL_EOF_INT interrupt. */ #define I2S_OUT_TOTAL_EOF_INT_ST (BIT(16)) @@ -504,7 +509,7 @@ #define I2S_OUT_TOTAL_EOF_INT_ST_S 16 /* I2S_IN_DSCR_EMPTY_INT_ST : RO; bitpos: [15]; default: 0; - * The masked interrupt status bit for the i2s_in_dscr_empty_int interrupt + * The masked interrupt status bit for I2S_IN_DSCR_EMPTY_INT interrupt. */ #define I2S_IN_DSCR_EMPTY_INT_ST (BIT(15)) @@ -513,7 +518,7 @@ #define I2S_IN_DSCR_EMPTY_INT_ST_S 15 /* I2S_OUT_DSCR_ERR_INT_ST : RO; bitpos: [14]; default: 0; - * The masked interrupt status bit for the i2s_out_dscr_err_int interrupt + * The masked interrupt status bit for I2S_OUT_DSCR_ERR_INT interrupt. */ #define I2S_OUT_DSCR_ERR_INT_ST (BIT(14)) @@ -522,7 +527,7 @@ #define I2S_OUT_DSCR_ERR_INT_ST_S 14 /* I2S_IN_DSCR_ERR_INT_ST : RO; bitpos: [13]; default: 0; - * The masked interrupt status bit for the i2s_in_dscr_err_int interrupt + * The masked interrupt status bit for I2S_IN_DSCR_ERR_INT interrupt. */ #define I2S_IN_DSCR_ERR_INT_ST (BIT(13)) @@ -531,7 +536,7 @@ #define I2S_IN_DSCR_ERR_INT_ST_S 13 /* I2S_OUT_EOF_INT_ST : RO; bitpos: [12]; default: 0; - * The masked interrupt status bit for the i2s_out_eof_int interrupt + * The masked interrupt status bit for I2S_OUT_EOF_INT interrupt. */ #define I2S_OUT_EOF_INT_ST (BIT(12)) @@ -540,7 +545,7 @@ #define I2S_OUT_EOF_INT_ST_S 12 /* I2S_OUT_DONE_INT_ST : RO; bitpos: [11]; default: 0; - * The masked interrupt status bit for the i2s_out_done_int interrupt + * The masked interrupt status bit for I2S_OUT_DONE_INT interrupt. */ #define I2S_OUT_DONE_INT_ST (BIT(11)) @@ -549,7 +554,7 @@ #define I2S_OUT_DONE_INT_ST_S 11 /* I2S_IN_ERR_EOF_INT_ST : RO; bitpos: [10]; default: 0; - * don't use + * Reserved. */ #define I2S_IN_ERR_EOF_INT_ST (BIT(10)) @@ -558,7 +563,7 @@ #define I2S_IN_ERR_EOF_INT_ST_S 10 /* I2S_IN_SUC_EOF_INT_ST : RO; bitpos: [9]; default: 0; - * The masked interrupt status bit for the i2s_in_suc_eof_int interrupt + * The masked interrupt status bit for I2S_IN_SUC_EOF_INT interrupt. */ #define I2S_IN_SUC_EOF_INT_ST (BIT(9)) @@ -567,7 +572,7 @@ #define I2S_IN_SUC_EOF_INT_ST_S 9 /* I2S_IN_DONE_INT_ST : RO; bitpos: [8]; default: 0; - * The masked interrupt status bit for the i2s_in_done_int interrupt + * The masked interrupt status bit for I2S_IN_DONE_INT interrupt. */ #define I2S_IN_DONE_INT_ST (BIT(8)) @@ -576,7 +581,7 @@ #define I2S_IN_DONE_INT_ST_S 8 /* I2S_TX_HUNG_INT_ST : RO; bitpos: [7]; default: 0; - * The masked interrupt status bit for the i2s_tx_hung_int interrupt + * The masked interrupt status bit for I2S_TX_HUNG_INT interrupt. */ #define I2S_TX_HUNG_INT_ST (BIT(7)) @@ -585,7 +590,7 @@ #define I2S_TX_HUNG_INT_ST_S 7 /* I2S_RX_HUNG_INT_ST : RO; bitpos: [6]; default: 0; - * The masked interrupt status bit for the i2s_rx_hung_int interrupt + * The masked interrupt status bit for I2S_RX_HUNG_INT interrupt. */ #define I2S_RX_HUNG_INT_ST (BIT(6)) @@ -594,7 +599,7 @@ #define I2S_RX_HUNG_INT_ST_S 6 /* I2S_TX_REMPTY_INT_ST : RO; bitpos: [5]; default: 0; - * The masked interrupt status bit for the i2s_tx_rempty_int interrupt + * The masked interrupt status bit for I2S_TX_REMPTY_INT interrupt. */ #define I2S_TX_REMPTY_INT_ST (BIT(5)) @@ -603,7 +608,7 @@ #define I2S_TX_REMPTY_INT_ST_S 5 /* I2S_TX_WFULL_INT_ST : RO; bitpos: [4]; default: 0; - * The masked interrupt status bit for the i2s_tx_wfull_int interrupt + * The masked interrupt status bit for I2S_TX_WFULL_INT interrupt. */ #define I2S_TX_WFULL_INT_ST (BIT(4)) @@ -612,7 +617,7 @@ #define I2S_TX_WFULL_INT_ST_S 4 /* I2S_RX_REMPTY_INT_ST : RO; bitpos: [3]; default: 0; - * The masked interrupt status bit for the i2s_rx_rempty_int interrupt + * The masked interrupt status bit for I2S_RX_REMPTY_INT interrupt. */ #define I2S_RX_REMPTY_INT_ST (BIT(3)) @@ -621,7 +626,7 @@ #define I2S_RX_REMPTY_INT_ST_S 3 /* I2S_RX_WFULL_INT_ST : RO; bitpos: [2]; default: 0; - * The masked interrupt status bit for the i2s_rx_wfull_int interrupt + * The masked interrupt status bit for I2S_RX_WFULL_INT interrupt. */ #define I2S_RX_WFULL_INT_ST (BIT(2)) @@ -630,7 +635,7 @@ #define I2S_RX_WFULL_INT_ST_S 2 /* I2S_TX_PUT_DATA_INT_ST : RO; bitpos: [1]; default: 0; - * The masked interrupt status bit for the i2s_tx_put_data_int interrupt + * The masked interrupt status bit for I2S_TX_PUT_DATA_INT interrupt. */ #define I2S_TX_PUT_DATA_INT_ST (BIT(1)) @@ -639,7 +644,7 @@ #define I2S_TX_PUT_DATA_INT_ST_S 1 /* I2S_RX_TAKE_DATA_INT_ST : RO; bitpos: [0]; default: 0; - * The masked interrupt status bit for the i2s_rx_take_data_int interrupt + * The masked interrupt status bit for I2S_RX_TAKE_DATA_INT interrupt. */ #define I2S_RX_TAKE_DATA_INT_ST (BIT(0)) @@ -654,7 +659,7 @@ #define I2S_INT_ENA_REG (DR_REG_I2S_BASE + 0x14) /* I2S_V_SYNC_INT_ENA : R/W; bitpos: [17]; default: 0; - * The interrupt enable bit for the i2s_v_sync_int interrupt + * The interrupt enable bit for I2S_V_SYNC_INT interrupt. */ #define I2S_V_SYNC_INT_ENA (BIT(17)) @@ -663,7 +668,7 @@ #define I2S_V_SYNC_INT_ENA_S 17 /* I2S_OUT_TOTAL_EOF_INT_ENA : R/W; bitpos: [16]; default: 0; - * The interrupt enable bit for the i2s_out_total_eof_int interrupt + * The interrupt enable bit for I2S_OUT_TOTAL_EOF_INT interrupt. */ #define I2S_OUT_TOTAL_EOF_INT_ENA (BIT(16)) @@ -672,7 +677,7 @@ #define I2S_OUT_TOTAL_EOF_INT_ENA_S 16 /* I2S_IN_DSCR_EMPTY_INT_ENA : R/W; bitpos: [15]; default: 0; - * The interrupt enable bit for the i2s_in_dscr_empty_int interrupt + * The interrupt enable bit for I2S_IN_DSCR_EMPTY_INT interrupt. */ #define I2S_IN_DSCR_EMPTY_INT_ENA (BIT(15)) @@ -681,7 +686,7 @@ #define I2S_IN_DSCR_EMPTY_INT_ENA_S 15 /* I2S_OUT_DSCR_ERR_INT_ENA : R/W; bitpos: [14]; default: 0; - * The interrupt enable bit for the i2s_out_dscr_err_int interrupt + * The interrupt enable bit for I2S_OUT_DSCR_ERR_INT interrupt. */ #define I2S_OUT_DSCR_ERR_INT_ENA (BIT(14)) @@ -690,7 +695,7 @@ #define I2S_OUT_DSCR_ERR_INT_ENA_S 14 /* I2S_IN_DSCR_ERR_INT_ENA : R/W; bitpos: [13]; default: 0; - * The interrupt enable bit for the i2s_in_dscr_err_int interrupt + * The interrupt enable bit for I2S_IN_DSCR_ERR_INT interrupt. */ #define I2S_IN_DSCR_ERR_INT_ENA (BIT(13)) @@ -699,7 +704,7 @@ #define I2S_IN_DSCR_ERR_INT_ENA_S 13 /* I2S_OUT_EOF_INT_ENA : R/W; bitpos: [12]; default: 0; - * The interrupt enable bit for the i2s_out_eof_int interrupt + * The interrupt enable bit for I2S_OUT_EOF_INT interrupt. */ #define I2S_OUT_EOF_INT_ENA (BIT(12)) @@ -708,7 +713,7 @@ #define I2S_OUT_EOF_INT_ENA_S 12 /* I2S_OUT_DONE_INT_ENA : R/W; bitpos: [11]; default: 0; - * The interrupt enable bit for the i2s_out_done_int interrupt + * The interrupt enable bit for I2S_OUT_DONE_INT interrupt. */ #define I2S_OUT_DONE_INT_ENA (BIT(11)) @@ -717,7 +722,7 @@ #define I2S_OUT_DONE_INT_ENA_S 11 /* I2S_IN_ERR_EOF_INT_ENA : R/W; bitpos: [10]; default: 0; - * don't use + * Reserved. */ #define I2S_IN_ERR_EOF_INT_ENA (BIT(10)) @@ -726,7 +731,7 @@ #define I2S_IN_ERR_EOF_INT_ENA_S 10 /* I2S_IN_SUC_EOF_INT_ENA : R/W; bitpos: [9]; default: 0; - * The interrupt enable bit for the i2s_in_suc_eof_int interrupt + * The interrupt enable bit for I2S_IN_SUC_EOF_INT interrupt. */ #define I2S_IN_SUC_EOF_INT_ENA (BIT(9)) @@ -735,7 +740,7 @@ #define I2S_IN_SUC_EOF_INT_ENA_S 9 /* I2S_IN_DONE_INT_ENA : R/W; bitpos: [8]; default: 0; - * The interrupt enable bit for the i2s_in_done_int interrupt + * The interrupt enable bit for I2S_IN_DONE_INT interrupt. */ #define I2S_IN_DONE_INT_ENA (BIT(8)) @@ -744,7 +749,7 @@ #define I2S_IN_DONE_INT_ENA_S 8 /* I2S_TX_HUNG_INT_ENA : R/W; bitpos: [7]; default: 0; - * The interrupt enable bit for the i2s_tx_hung_int interrupt + * The interrupt enable bit for I2S_TX_HUNG_INT interrupt. */ #define I2S_TX_HUNG_INT_ENA (BIT(7)) @@ -753,7 +758,7 @@ #define I2S_TX_HUNG_INT_ENA_S 7 /* I2S_RX_HUNG_INT_ENA : R/W; bitpos: [6]; default: 0; - * The interrupt enable bit for the i2s_rx_hung_int interrupt + * The interrupt enable bit for I2S_RX_HUNG_INT interrupt. */ #define I2S_RX_HUNG_INT_ENA (BIT(6)) @@ -762,7 +767,7 @@ #define I2S_RX_HUNG_INT_ENA_S 6 /* I2S_TX_REMPTY_INT_ENA : R/W; bitpos: [5]; default: 0; - * The interrupt enable bit for the i2s_tx_rempty_int interrupt + * The interrupt enable bit for I2S_TX_REMPTY_INT interrupt. */ #define I2S_TX_REMPTY_INT_ENA (BIT(5)) @@ -771,7 +776,7 @@ #define I2S_TX_REMPTY_INT_ENA_S 5 /* I2S_TX_WFULL_INT_ENA : R/W; bitpos: [4]; default: 0; - * The interrupt enable bit for the i2s_tx_wfull_int interrupt + * The interrupt enable bit for I2S_TX_WFULL_INT interrupt. */ #define I2S_TX_WFULL_INT_ENA (BIT(4)) @@ -780,7 +785,7 @@ #define I2S_TX_WFULL_INT_ENA_S 4 /* I2S_RX_REMPTY_INT_ENA : R/W; bitpos: [3]; default: 0; - * The interrupt enable bit for the i2s_rx_rempty_int interrupt + * The interrupt enable bit for I2S_RX_REMPTY_INT interrupt. */ #define I2S_RX_REMPTY_INT_ENA (BIT(3)) @@ -789,7 +794,7 @@ #define I2S_RX_REMPTY_INT_ENA_S 3 /* I2S_RX_WFULL_INT_ENA : R/W; bitpos: [2]; default: 0; - * The interrupt enable bit for the i2s_rx_wfull_int interrupt + * The interrupt enable bit for I2S_RX_WFULL_INT interrupt. */ #define I2S_RX_WFULL_INT_ENA (BIT(2)) @@ -798,7 +803,7 @@ #define I2S_RX_WFULL_INT_ENA_S 2 /* I2S_TX_PUT_DATA_INT_ENA : R/W; bitpos: [1]; default: 0; - * The interrupt enable bit for the i2s_tx_put_data_int interrupt + * The interrupt enable bit for I2S_TX_PUT_DATA_INT interrupt. */ #define I2S_TX_PUT_DATA_INT_ENA (BIT(1)) @@ -807,7 +812,7 @@ #define I2S_TX_PUT_DATA_INT_ENA_S 1 /* I2S_RX_TAKE_DATA_INT_ENA : R/W; bitpos: [0]; default: 0; - * The interrupt enable bit for the i2s_rx_take_data_int interrupt + * The interrupt enable bit for I2S_RX_TAKE_DATA_INT interrupt. */ #define I2S_RX_TAKE_DATA_INT_ENA (BIT(0)) @@ -822,7 +827,7 @@ #define I2S_INT_CLR_REG (DR_REG_I2S_BASE + 0x18) /* I2S_V_SYNC_INT_CLR : WO; bitpos: [17]; default: 0; - * Set this bit to clear the i2s_v_sync_int interrupt + * Set this bit to clear I2S_V_SYNC_INT interrupt. */ #define I2S_V_SYNC_INT_CLR (BIT(17)) @@ -831,7 +836,7 @@ #define I2S_V_SYNC_INT_CLR_S 17 /* I2S_OUT_TOTAL_EOF_INT_CLR : WO; bitpos: [16]; default: 0; - * Set this bit to clear the i2s_out_total_eof_int interrupt + * Set this bit to clear I2S_OUT_TOTAL_EOF_INT interrupt. */ #define I2S_OUT_TOTAL_EOF_INT_CLR (BIT(16)) @@ -840,7 +845,7 @@ #define I2S_OUT_TOTAL_EOF_INT_CLR_S 16 /* I2S_IN_DSCR_EMPTY_INT_CLR : WO; bitpos: [15]; default: 0; - * Set this bit to clear the i2s_in_dscr_empty_int interrupt + * Set this bit to clear I2S_IN_DSCR_EMPTY_INT interrupt. */ #define I2S_IN_DSCR_EMPTY_INT_CLR (BIT(15)) @@ -849,7 +854,7 @@ #define I2S_IN_DSCR_EMPTY_INT_CLR_S 15 /* I2S_OUT_DSCR_ERR_INT_CLR : WO; bitpos: [14]; default: 0; - * Set this bit to clear the i2s_out_dscr_err_int interrupt + * Set this bit to clear I2S_OUT_DSCR_ERR_INT interrupt. */ #define I2S_OUT_DSCR_ERR_INT_CLR (BIT(14)) @@ -858,7 +863,7 @@ #define I2S_OUT_DSCR_ERR_INT_CLR_S 14 /* I2S_IN_DSCR_ERR_INT_CLR : WO; bitpos: [13]; default: 0; - * Set this bit to clear the i2s_in_dscr_err_int interrupt + * Set this bit to clear I2S_IN_DSCR_ERR_INT interrupt. */ #define I2S_IN_DSCR_ERR_INT_CLR (BIT(13)) @@ -867,7 +872,7 @@ #define I2S_IN_DSCR_ERR_INT_CLR_S 13 /* I2S_OUT_EOF_INT_CLR : WO; bitpos: [12]; default: 0; - * Set this bit to clear the i2s_out_eof_int interrupt + * Set this bit to clear I2S_OUT_EOF_INT interrupt. */ #define I2S_OUT_EOF_INT_CLR (BIT(12)) @@ -876,7 +881,7 @@ #define I2S_OUT_EOF_INT_CLR_S 12 /* I2S_OUT_DONE_INT_CLR : WO; bitpos: [11]; default: 0; - * Set this bit to clear the i2s_out_done_int interrupt + * Set this bit to clear I2S_OUT_DONE_INT interrupt. */ #define I2S_OUT_DONE_INT_CLR (BIT(11)) @@ -885,7 +890,7 @@ #define I2S_OUT_DONE_INT_CLR_S 11 /* I2S_IN_ERR_EOF_INT_CLR : WO; bitpos: [10]; default: 0; - * don't use + * Reserved. */ #define I2S_IN_ERR_EOF_INT_CLR (BIT(10)) @@ -894,7 +899,7 @@ #define I2S_IN_ERR_EOF_INT_CLR_S 10 /* I2S_IN_SUC_EOF_INT_CLR : WO; bitpos: [9]; default: 0; - * Set this bit to clear the i2s_in_suc_eof_int interrupt + * Set this bit to clear I2S_IN_SUC_EOF_INT interrupt. */ #define I2S_IN_SUC_EOF_INT_CLR (BIT(9)) @@ -903,7 +908,7 @@ #define I2S_IN_SUC_EOF_INT_CLR_S 9 /* I2S_IN_DONE_INT_CLR : WO; bitpos: [8]; default: 0; - * Set this bit to clear the i2s_in_done_int interrupt + * Set this bit to clear I2S_IN_DONE_INT interrupt. */ #define I2S_IN_DONE_INT_CLR (BIT(8)) @@ -912,7 +917,7 @@ #define I2S_IN_DONE_INT_CLR_S 8 /* I2S_TX_HUNG_INT_CLR : WO; bitpos: [7]; default: 0; - * Set this bit to clear the i2s_tx_hung_int interrupt + * Set this bit to clear I2S_TX_HUNG_INT interrupt. */ #define I2S_TX_HUNG_INT_CLR (BIT(7)) @@ -921,7 +926,7 @@ #define I2S_TX_HUNG_INT_CLR_S 7 /* I2S_RX_HUNG_INT_CLR : WO; bitpos: [6]; default: 0; - * Set this bit to clear the i2s_rx_hung_int interrupt + * Set this bit to clear I2S_RX_HUNG_INT interrupt. */ #define I2S_RX_HUNG_INT_CLR (BIT(6)) @@ -930,7 +935,7 @@ #define I2S_RX_HUNG_INT_CLR_S 6 /* I2S_TX_REMPTY_INT_CLR : WO; bitpos: [5]; default: 0; - * Set this bit to clear the i2s_tx_rempty_int interrupt + * Set this bit to clear I2S_TX_REMPTY_INT interrupt. */ #define I2S_TX_REMPTY_INT_CLR (BIT(5)) @@ -939,7 +944,7 @@ #define I2S_TX_REMPTY_INT_CLR_S 5 /* I2S_TX_WFULL_INT_CLR : WO; bitpos: [4]; default: 0; - * Set this bit to clear the i2s_tx_wfull_int interrupt + * Set this bit to clear I2S_TX_WFULL_INT interrupt. */ #define I2S_TX_WFULL_INT_CLR (BIT(4)) @@ -948,7 +953,7 @@ #define I2S_TX_WFULL_INT_CLR_S 4 /* I2S_RX_REMPTY_INT_CLR : WO; bitpos: [3]; default: 0; - * Set this bit to clear the i2s_rx_rempty_int interrupt + * Set this bit to clear I2S_RX_REMPTY_INT interrupt. */ #define I2S_RX_REMPTY_INT_CLR (BIT(3)) @@ -957,7 +962,7 @@ #define I2S_RX_REMPTY_INT_CLR_S 3 /* I2S_RX_WFULL_INT_CLR : WO; bitpos: [2]; default: 0; - * Set this bit to clear the i2s_rx_wfull_int interrupt + * Set this bit to clear I2S_RX_WFULL_INT interrupt. */ #define I2S_RX_WFULL_INT_CLR (BIT(2)) @@ -966,7 +971,7 @@ #define I2S_RX_WFULL_INT_CLR_S 2 /* I2S_PUT_DATA_INT_CLR : WO; bitpos: [1]; default: 0; - * Set this bit to clear the i2s_tx_put_data_int interrupt + * Set this bit to clear I2S_TX_PUT_DATA_INT interrupt. */ #define I2S_PUT_DATA_INT_CLR (BIT(1)) @@ -975,7 +980,7 @@ #define I2S_PUT_DATA_INT_CLR_S 1 /* I2S_TAKE_DATA_INT_CLR : WO; bitpos: [0]; default: 0; - * Set this bit to clear the i2s_rx_take_data_int interrupt + * Set this bit to clear I2S_RX_TAKE_DATA_INT interrupt. */ #define I2S_TAKE_DATA_INT_CLR (BIT(0)) @@ -990,7 +995,7 @@ #define I2S_TIMING_REG (DR_REG_I2S_BASE + 0x1c) /* I2S_TX_BCK_IN_INV : R/W; bitpos: [24]; default: 0; - * Set this bit to invert BCK signal input to the slave transmitter + * Set this bit to invert BCK signal input to the slave transmitter. */ #define I2S_TX_BCK_IN_INV (BIT(24)) @@ -999,7 +1004,9 @@ #define I2S_TX_BCK_IN_INV_S 24 /* I2S_DATA_ENABLE_DELAY : R/W; bitpos: [23:22]; default: 0; - * Number of delay cycles for data valid flag. + * Number of delay cycles for data valid flag based on I2S0_CLK. 0: delayed + * by 1.5 cycles. 1: delayed by 2.5 cycles. 2: delayed by 3.5 cycles. 3: + * delayed by 4.5 cycles. */ #define I2S_DATA_ENABLE_DELAY 0x00000003 @@ -1008,8 +1015,10 @@ #define I2S_DATA_ENABLE_DELAY_S 22 /* I2S_RX_DSYNC_SW : R/W; bitpos: [21]; default: 0; - * Set this bit to synchronize signals with the double sync method into the - * receiver + * Set this bit to synchronize signals into the receiver by two flip-flop + * synchronizer. 0: the signals will be clocked by rising clock edge + * firstly, then clocked by falling clock edge. 1: the signals will be + * clocked by falling clock edge firstly, then clocked by rising clock edge. */ #define I2S_RX_DSYNC_SW (BIT(21)) @@ -1018,8 +1027,10 @@ #define I2S_RX_DSYNC_SW_S 21 /* I2S_TX_DSYNC_SW : R/W; bitpos: [20]; default: 0; - * Set this bit to synchronize signals with the double sync method into the - * transmitter + * Set this bit to synchronize signals into the transmitter by two flip-flop + * synchronizer. 0: the signals will be firstly clocked by rising clock edge + * , then clocked by falling clock edge. 1: the signals will be firstly + * clocked by falling clock edge, then clocked by rising clock edge. */ #define I2S_TX_DSYNC_SW (BIT(20)) @@ -1028,7 +1039,9 @@ #define I2S_TX_DSYNC_SW_S 20 /* I2S_RX_BCK_OUT_DELAY : R/W; bitpos: [19:18]; default: 0; - * Number of delay cycles for BCK out of the receiver + * Number of delay cycles for BCK signal out of the receiver based on + * I2S0_CLK. 0: delayed by 0 cycle. 1: delayed by 1 cycle. 2: delayed by 2 + * cycles. 3: delayed by 3 cycles. */ #define I2S_RX_BCK_OUT_DELAY 0x00000003 @@ -1037,7 +1050,9 @@ #define I2S_RX_BCK_OUT_DELAY_S 18 /* I2S_RX_WS_OUT_DELAY : R/W; bitpos: [17:16]; default: 0; - * Number of delay cycles for WS out of the receiver + * Number of delay cycles for WS signal out of the receiver based on + * I2S0_CLK. 0: delayed by 0 cycle. 1: delayed by 1 cycle. 2: delayed by 2 + * cycles. 3: delayed by 3 cycles. */ #define I2S_RX_WS_OUT_DELAY 0x00000003 @@ -1046,7 +1061,9 @@ #define I2S_RX_WS_OUT_DELAY_S 16 /* I2S_TX_SD_OUT_DELAY : R/W; bitpos: [15:14]; default: 0; - * Number of delay cycles for SD out of the transmitter + * Number of delay cycles for SD signal out of the transmitter based on + * I2S0_CLK. 0: delayed by 0 cycle. 1: delayed by 1 cycle. 2: delayed by 2 + * cycles. 3: delayed by 3 cycles. */ #define I2S_TX_SD_OUT_DELAY 0x00000003 @@ -1055,7 +1072,9 @@ #define I2S_TX_SD_OUT_DELAY_S 14 /* I2S_TX_WS_OUT_DELAY : R/W; bitpos: [13:12]; default: 0; - * Number of delay cycles for WS out of the transmitter + * Number of delay cycles for WS signal out of the transmitter based on + * I2S0_CLK. 0: delayed by 0 cycle. 1: delayed by 1 cycle. 2: delayed by 2 + * cycles. 3: delayed by 3 cycles. */ #define I2S_TX_WS_OUT_DELAY 0x00000003 @@ -1064,7 +1083,9 @@ #define I2S_TX_WS_OUT_DELAY_S 12 /* I2S_TX_BCK_OUT_DELAY : R/W; bitpos: [11:10]; default: 0; - * Number of delay cycles for BCK out of the transmitter + * Number of delay cycles for BCK signal out of the transmitter based on + * I2S0_CLK. 0: delayed by 0 cycle. 1: delayed by 1 cycle. 2: delayed by 2 + * cycles. 3: delayed by 3 cycles. */ #define I2S_TX_BCK_OUT_DELAY 0x00000003 @@ -1073,7 +1094,9 @@ #define I2S_TX_BCK_OUT_DELAY_S 10 /* I2S_RX_SD_IN_DELAY : R/W; bitpos: [9:8]; default: 0; - * Number of delay cycles for SD into the receiver + * Number of delay cycles for SD signal into the receiver based on I2S0_CLK. + * 0: delayed by 1.5 cycles. 1: delayed by 2.5 cycles. 2: delayed by 3.5 + * cycles. 3: delayed by 4.5 cycles. */ #define I2S_RX_SD_IN_DELAY 0x00000003 @@ -1082,7 +1105,9 @@ #define I2S_RX_SD_IN_DELAY_S 8 /* I2S_RX_WS_IN_DELAY : R/W; bitpos: [7:6]; default: 0; - * Number of delay cycles for WS into the receiver + * Number of delay cycles for WS signal into the receiver based on I2S0_CLK. + * 0: delayed by 1.5 cycles. 1: delayed by 2.5 cycles. 2: delayed by 3.5 + * cycles. 3: delayed by 4.5 cycles. */ #define I2S_RX_WS_IN_DELAY 0x00000003 @@ -1091,7 +1116,9 @@ #define I2S_RX_WS_IN_DELAY_S 6 /* I2S_RX_BCK_IN_DELAY : R/W; bitpos: [5:4]; default: 0; - * Number of delay cycles for BCK into the receiver + * Number of delay cycles for BCK signal into the receiver based on + * I2S0_CLK. 0: delayed by 1.5 cycles. 1: delayed by 2.5 cycles. 2: delayed + * by 3.5 cycles. 3: delayed by 4.5 cycles. */ #define I2S_RX_BCK_IN_DELAY 0x00000003 @@ -1100,7 +1127,9 @@ #define I2S_RX_BCK_IN_DELAY_S 4 /* I2S_TX_WS_IN_DELAY : R/W; bitpos: [3:2]; default: 0; - * Number of delay cycles for WS into the transmitter + * Number of delay cycles for WS signal into the transmitter based on + * I2S0_CLK. 0: delayed by 1.5 cycles. 1: delayed by 2.5 cycles. 2: delayed + * by 3.5 cycles. 3: delayed by 4.5 cycles. */ #define I2S_TX_WS_IN_DELAY 0x00000003 @@ -1109,7 +1138,9 @@ #define I2S_TX_WS_IN_DELAY_S 2 /* I2S_TX_BCK_IN_DELAY : R/W; bitpos: [1:0]; default: 0; - * Number of delay cycles for BCK into the transmitter + * Number of delay cycles for BCK signal into the transmitter based on + * I2S0_CLK. 0: delayed by 1.5 cycles. 1: delayed by 2.5 cycles. 2: delayed + * by 3.5 cycles. 3: delayed by 4.5 cycles. */ #define I2S_TX_BCK_IN_DELAY 0x00000003 @@ -1118,7 +1149,7 @@ #define I2S_TX_BCK_IN_DELAY_S 0 /* I2S_FIFO_CONF_REG register - * I2S FIFO configure register + * I2S FIFO configuration register */ #define I2S_FIFO_CONF_REG (DR_REG_I2S_BASE + 0x20) @@ -1189,7 +1220,7 @@ #define I2S_TX_FIFO_MOD_S 13 /* I2S_DSCR_EN : R/W; bitpos: [12]; default: 1; - * Set this bit to enable I2S DMA mode + * Set this bit to enable I2S DMA mode. */ #define I2S_DSCR_EN (BIT(12)) @@ -1198,7 +1229,9 @@ #define I2S_DSCR_EN_S 12 /* I2S_TX_DATA_NUM : R/W; bitpos: [11:6]; default: 32; - * Threshold of data length in transmitter FIFO + * I2S_TX_PUT_DATA_INT is triggered when the left and right channel data + * number in TX FIFO is smaller than the value of I2S_TX_DATA_NUM[5:0]. (TX + * FIFO is almost empty threshold.) */ #define I2S_TX_DATA_NUM 0x0000003F @@ -1207,7 +1240,9 @@ #define I2S_TX_DATA_NUM_S 6 /* I2S_RX_DATA_NUM : R/W; bitpos: [5:0]; default: 32; - * Threshold of data length in receiver FIFO + * I2S_RX_TAKE_DATA_INT is triggered when the left and right channel data + * number in RX FIFO is larger than the value of I2S_RX_DATA_NUM[5:0]. (RX + * FIFO is almost full threshold.) */ #define I2S_RX_DATA_NUM 0x0000003F @@ -1222,7 +1257,7 @@ #define I2S_RXEOF_NUM_REG (DR_REG_I2S_BASE + 0x24) /* I2S_RX_EOF_NUM : R/W; bitpos: [31:0]; default: 64; - * the length of data to be received. It will trigger i2s_in_suc_eof_int. + * The length of data to be received. It will trigger I2S_IN_SUC_EOF_INT. */ #define I2S_RX_EOF_NUM 0xFFFFFFFF @@ -1237,8 +1272,8 @@ #define I2S_CONF_SIGLE_DATA_REG (DR_REG_I2S_BASE + 0x28) /* I2S_SIGLE_DATA : R/W; bitpos: [31:0]; default: 0; - * the right channel or left channel put out constant value stored in this - * register according to tx_chan_mod and reg_tx_msb_right + * The right channel or left channel transmits constant value stored in this + * register according to I2S_TX_CHAN_MOD and I2S_TX_MSB_RIGHT. */ #define I2S_SIGLE_DATA 0xFFFFFFFF @@ -1247,7 +1282,7 @@ #define I2S_SIGLE_DATA_S 0 /* I2S_CONF_CHAN_REG register - * I2S channel configure register + * I2S channel configuration register */ #define I2S_CONF_CHAN_REG (DR_REG_I2S_BASE + 0x2c) @@ -1271,7 +1306,7 @@ #define I2S_TX_CHAN_MOD_S 0 /* I2S_OUT_LINK_REG register - * I2S DMA TX configure register + * I2S DMA TX configuration register */ #define I2S_OUT_LINK_REG (DR_REG_I2S_BASE + 0x30) @@ -1284,7 +1319,7 @@ #define I2S_OUTLINK_PARK_S 31 /* I2S_OUTLINK_RESTART : R/W; bitpos: [30]; default: 0; - * Set this bit to restart outlink descriptor + * Set this bit to restart outlink descriptor. */ #define I2S_OUTLINK_RESTART (BIT(30)) @@ -1293,7 +1328,7 @@ #define I2S_OUTLINK_RESTART_S 30 /* I2S_OUTLINK_START : R/W; bitpos: [29]; default: 0; - * Set this bit to start outlink descriptor + * Set this bit to start outlink descriptor. */ #define I2S_OUTLINK_START (BIT(29)) @@ -1302,7 +1337,7 @@ #define I2S_OUTLINK_START_S 29 /* I2S_OUTLINK_STOP : R/W; bitpos: [28]; default: 0; - * Set this bit to stop outlink descriptor + * Set this bit to stop outlink descriptor. */ #define I2S_OUTLINK_STOP (BIT(28)) @@ -1311,7 +1346,7 @@ #define I2S_OUTLINK_STOP_S 28 /* I2S_OUTLINK_ADDR : R/W; bitpos: [19:0]; default: 0; - * The address of first outlink descriptor + * The address of first outlink descriptor. */ #define I2S_OUTLINK_ADDR 0x000FFFFF @@ -1320,7 +1355,7 @@ #define I2S_OUTLINK_ADDR_S 0 /* I2S_IN_LINK_REG register - * I2S DMA RX configure register + * I2S DMA RX configuration register */ #define I2S_IN_LINK_REG (DR_REG_I2S_BASE + 0x34) @@ -1333,7 +1368,7 @@ #define I2S_INLINK_PARK_S 31 /* I2S_INLINK_RESTART : R/W; bitpos: [30]; default: 0; - * Set this bit to restart inlink descriptor + * Set this bit to restart inlink descriptor. */ #define I2S_INLINK_RESTART (BIT(30)) @@ -1342,7 +1377,7 @@ #define I2S_INLINK_RESTART_S 30 /* I2S_INLINK_START : R/W; bitpos: [29]; default: 0; - * Set this bit to start inlink descriptor + * Set this bit to start inlink descriptor. */ #define I2S_INLINK_START (BIT(29)) @@ -1351,7 +1386,7 @@ #define I2S_INLINK_START_S 29 /* I2S_INLINK_STOP : R/W; bitpos: [28]; default: 0; - * Set this bit to stop inlink descriptor + * Set this bit to stop inlink descriptor. */ #define I2S_INLINK_STOP (BIT(28)) @@ -1360,7 +1395,7 @@ #define I2S_INLINK_STOP_S 28 /* I2S_INLINK_ADDR : R/W; bitpos: [19:0]; default: 0; - * The address of first inlink descriptor + * The address of first inlink descriptor. */ #define I2S_INLINK_ADDR 0x000FFFFF @@ -1369,13 +1404,13 @@ #define I2S_INLINK_ADDR_S 0 /* I2S_OUT_EOF_DES_ADDR_REG register - * The address of outlink descriptor that produces EOF + * Address of outlink descriptor that produces EOF */ #define I2S_OUT_EOF_DES_ADDR_REG (DR_REG_I2S_BASE + 0x38) /* I2S_OUT_EOF_DES_ADDR : RO; bitpos: [31:0]; default: 0; - * The address of outlink descriptor that produces EOF + * The address of outlink descriptor that produces EOF. */ #define I2S_OUT_EOF_DES_ADDR 0xFFFFFFFF @@ -1384,13 +1419,13 @@ #define I2S_OUT_EOF_DES_ADDR_S 0 /* I2S_IN_EOF_DES_ADDR_REG register - * The address of inlink descriptor that produces EOF + * Address of inlink descriptor that produces EOF */ #define I2S_IN_EOF_DES_ADDR_REG (DR_REG_I2S_BASE + 0x3c) /* I2S_IN_SUC_EOF_DES_ADDR : RO; bitpos: [31:0]; default: 0; - * The address of inlink descriptor that produces EOF + * The address of inlink descriptor that produces EOF. */ #define I2S_IN_SUC_EOF_DES_ADDR 0xFFFFFFFF @@ -1399,13 +1434,14 @@ #define I2S_IN_SUC_EOF_DES_ADDR_S 0 /* I2S_OUT_EOF_BFR_DES_ADDR_REG register - * The address of buffer relative to the outlink descriptor that produces EOF + * Address of buffer relative to the outlink descriptor that produces EOF */ #define I2S_OUT_EOF_BFR_DES_ADDR_REG (DR_REG_I2S_BASE + 0x40) /* I2S_OUT_EOF_BFR_DES_ADDR : RO; bitpos: [31:0]; default: 0; - * The address of buffer relative to the outlink descriptor that produces EOF + * The address of buffer relative to the outlink descriptor that produces + * EOF. */ #define I2S_OUT_EOF_BFR_DES_ADDR 0xFFFFFFFF @@ -1414,13 +1450,13 @@ #define I2S_OUT_EOF_BFR_DES_ADDR_S 0 /* I2S_INLINK_DSCR_REG register - * The address of current inlink descriptor + * Address of current inlink descriptor */ #define I2S_INLINK_DSCR_REG (DR_REG_I2S_BASE + 0x48) /* I2S_INLINK_DSCR : RO; bitpos: [31:0]; default: 0; - * The address of current inlink descriptor + * The address of current inlink descriptor. */ #define I2S_INLINK_DSCR 0xFFFFFFFF @@ -1429,13 +1465,13 @@ #define I2S_INLINK_DSCR_S 0 /* I2S_INLINK_DSCR_BF0_REG register - * The address of next inlink descriptor + * Address of next inlink descriptor */ #define I2S_INLINK_DSCR_BF0_REG (DR_REG_I2S_BASE + 0x4c) /* I2S_INLINK_DSCR_BF0 : RO; bitpos: [31:0]; default: 0; - * The address of next inlink descriptor + * The address of next inlink descriptor. */ #define I2S_INLINK_DSCR_BF0 0xFFFFFFFF @@ -1444,13 +1480,13 @@ #define I2S_INLINK_DSCR_BF0_S 0 /* I2S_INLINK_DSCR_BF1_REG register - * The address of next inlink data buffer + * Address of next inlink data buffer */ #define I2S_INLINK_DSCR_BF1_REG (DR_REG_I2S_BASE + 0x50) /* I2S_INLINK_DSCR_BF1 : RO; bitpos: [31:0]; default: 0; - * The address of next inlink data buffer + * The address of next inlink data buffer. */ #define I2S_INLINK_DSCR_BF1 0xFFFFFFFF @@ -1459,13 +1495,13 @@ #define I2S_INLINK_DSCR_BF1_S 0 /* I2S_OUTLINK_DSCR_REG register - * The address of current outlink descriptor + * Address of current outlink descriptor */ #define I2S_OUTLINK_DSCR_REG (DR_REG_I2S_BASE + 0x54) /* I2S_OUTLINK_DSCR : RO; bitpos: [31:0]; default: 0; - * The address of current outlink descriptor + * The address of current outlink descriptor. */ #define I2S_OUTLINK_DSCR 0xFFFFFFFF @@ -1474,13 +1510,13 @@ #define I2S_OUTLINK_DSCR_S 0 /* I2S_OUTLINK_DSCR_BF0_REG register - * The address of next outlink descriptor + * Address of next outlink descriptor */ #define I2S_OUTLINK_DSCR_BF0_REG (DR_REG_I2S_BASE + 0x58) /* I2S_OUTLINK_DSCR_BF0 : RO; bitpos: [31:0]; default: 0; - * The address of next outlink descriptor + * The address of next outlink descriptor. */ #define I2S_OUTLINK_DSCR_BF0 0xFFFFFFFF @@ -1489,13 +1525,13 @@ #define I2S_OUTLINK_DSCR_BF0_S 0 /* I2S_OUTLINK_DSCR_BF1_REG register - * The address of next outlink data buffer + * Address of next outlink data buffer */ #define I2S_OUTLINK_DSCR_BF1_REG (DR_REG_I2S_BASE + 0x5c) /* I2S_OUTLINK_DSCR_BF1 : RO; bitpos: [31:0]; default: 0; - * The address of next outlink data buffer + * The address of next outlink data buffer. */ #define I2S_OUTLINK_DSCR_BF1 0xFFFFFFFF @@ -1510,8 +1546,8 @@ #define I2S_LC_CONF_REG (DR_REG_I2S_BASE + 0x60) /* I2S_EXT_MEM_BK_SIZE : R/W; bitpos: [15:14]; default: 0; - * DMA access external memory block size. 0: 16 bytes 1: 32 bytes - * 2:64 bytes 3:reserved + * DMA access external memory block size. 0: 16 bytes. 1: 32 bytes. 2: 64 + * bytes. 3: reserved. */ #define I2S_EXT_MEM_BK_SIZE 0x00000003 @@ -1520,7 +1556,7 @@ #define I2S_EXT_MEM_BK_SIZE_S 14 /* I2S_MEM_TRANS_EN : R/W; bitpos: [13]; default: 0; - * don't use + * Reserved. */ #define I2S_MEM_TRANS_EN (BIT(13)) @@ -1529,7 +1565,7 @@ #define I2S_MEM_TRANS_EN_S 13 /* I2S_CHECK_OWNER : R/W; bitpos: [12]; default: 0; - * Set this bit to enable check owner bit by hardware + * Set this bit to enable check owner bit by hardware. */ #define I2S_CHECK_OWNER (BIT(12)) @@ -1538,8 +1574,8 @@ #define I2S_CHECK_OWNER_S 12 /* I2S_OUT_DATA_BURST_EN : R/W; bitpos: [11]; default: 0; - * Transmitter data transfer mode configuration bit. 1: to prepare out data - * with burst mode 0: to prepare out data with byte mode + * Transmitter data transfer mode configuration bit. 1: Prepare out data + * with burst mode. 0: Prepare out data with byte mode. */ #define I2S_OUT_DATA_BURST_EN (BIT(11)) @@ -1548,9 +1584,8 @@ #define I2S_OUT_DATA_BURST_EN_S 11 /* I2S_INDSCR_BURST_EN : R/W; bitpos: [10]; default: 0; - * DMA inlink descriptor transfer mode configuration bit. 1: to prepare - * inlink descriptor with burst mode 0: to prepare inlink descriptor with - * byte mode + * DMA inlink descriptor transfer mode configuration bit. 1: Prepare inlink + * descriptor with burst mode. 0: Prepare inlink descriptor with byte mode. */ #define I2S_INDSCR_BURST_EN (BIT(10)) @@ -1559,9 +1594,9 @@ #define I2S_INDSCR_BURST_EN_S 10 /* I2S_OUTDSCR_BURST_EN : R/W; bitpos: [9]; default: 0; - * DMA outlink descriptor transfer mode configuration bit. 1: to prepare - * outlink descriptor with burst mode 0: to prepare outlink descriptor - * with byte mode + * DMA outlink descriptor transfer mode configuration bit. 1: Prepare + * outlink descriptor with burst mode. 0: Prepare outlink descriptor with + * byte mode. */ #define I2S_OUTDSCR_BURST_EN (BIT(9)) @@ -1570,8 +1605,8 @@ #define I2S_OUTDSCR_BURST_EN_S 9 /* I2S_OUT_EOF_MODE : R/W; bitpos: [8]; default: 1; - * DMA out EOF flag generation mode . 1: when dma has popped all data from - * the FIFO 0:when ahb has pushed all data to the FIFO + * DMA out EOF flag generation mode. 1: When DMA has popped all data from + * the FIFO. 0: When AHB has pushed all data to the FIFO. */ #define I2S_OUT_EOF_MODE (BIT(8)) @@ -1580,7 +1615,7 @@ #define I2S_OUT_EOF_MODE_S 8 /* I2S_OUT_NO_RESTART_CLR : R/W; bitpos: [7]; default: 0; - * don't use + * Reserved. */ #define I2S_OUT_NO_RESTART_CLR (BIT(7)) @@ -1599,7 +1634,7 @@ #define I2S_OUT_AUTO_WRBACK_S 6 /* I2S_IN_LOOP_TEST : R/W; bitpos: [5]; default: 0; - * Set this bit to loop test outlink + * Set this bit to loop test outlink. */ #define I2S_IN_LOOP_TEST (BIT(5)) @@ -1608,7 +1643,7 @@ #define I2S_IN_LOOP_TEST_S 5 /* I2S_OUT_LOOP_TEST : R/W; bitpos: [4]; default: 0; - * Set this bit to loop test inlink + * Set this bit to loop test inlink. */ #define I2S_OUT_LOOP_TEST (BIT(4)) @@ -1617,7 +1652,8 @@ #define I2S_OUT_LOOP_TEST_S 4 /* I2S_AHBM_RST : R/W; bitpos: [3]; default: 0; - * Set this bit to reset ahb interface of DMA + * Set this bit to reset AHB interface of DMA. Set this bit before the DMA + * configuration. */ #define I2S_AHBM_RST (BIT(3)) @@ -1626,7 +1662,8 @@ #define I2S_AHBM_RST_S 3 /* I2S_AHBM_FIFO_RST : R/W; bitpos: [2]; default: 0; - * Set this bit to reset ahb interface cmdFIFO of DMA + * Set this bit to reset AHB interface cmdFIFO of DMA. Set this bit before + * the DMA configuration. */ #define I2S_AHBM_FIFO_RST (BIT(2)) @@ -1635,7 +1672,8 @@ #define I2S_AHBM_FIFO_RST_S 2 /* I2S_OUT_RST : R/W; bitpos: [1]; default: 0; - * Set this bit to reset out dma FSM + * Set this bit to reset out-DMA FSM. Set this bit before the DMA + * configuration. */ #define I2S_OUT_RST (BIT(1)) @@ -1644,7 +1682,8 @@ #define I2S_OUT_RST_S 1 /* I2S_IN_RST : R/W; bitpos: [0]; default: 0; - * Set this bit to reset in dma FSM + * Set this bit to reset in-DMA FSM. Set this bit before the DMA + * configuration. */ #define I2S_IN_RST (BIT(0)) @@ -1821,13 +1860,13 @@ #define I2S_INLINK_DSCR_ADDR_S 0 /* I2S_LC_HUNG_CONF_REG register - * I2S Hung configure register + * I2S Hung configuration register */ #define I2S_LC_HUNG_CONF_REG (DR_REG_I2S_BASE + 0x74) /* I2S_LC_FIFO_TIMEOUT_ENA : R/W; bitpos: [11]; default: 1; - * The enable bit for FIFO timeout + * The enable bit for FIFO timeout. */ #define I2S_LC_FIFO_TIMEOUT_ENA (BIT(11)) @@ -1836,8 +1875,10 @@ #define I2S_LC_FIFO_TIMEOUT_ENA_S 11 /* I2S_LC_FIFO_TIMEOUT_SHIFT : R/W; bitpos: [10:8]; default: 0; - * The bits are used to scale tick counter threshold. The tick counter is - * reset when counter value >= 88000/2^i2s_lc_fifo_timeout_shift + * The bits are used to set the tick counter threshold. The tick counter is + * clocked by APB_CLK. The tick counter threshold is + * 88000/2^I2S_LC_FIFO_TIMEOUT_SHIFT. The tick counter is reset when it + * reaches the threshold. */ #define I2S_LC_FIFO_TIMEOUT_SHIFT 0x00000007 @@ -1846,8 +1887,8 @@ #define I2S_LC_FIFO_TIMEOUT_SHIFT_S 8 /* I2S_LC_FIFO_TIMEOUT : R/W; bitpos: [7:0]; default: 16; - * the i2s_tx_hung_int interrupt or the i2s_rx_hung_int interrupt will be - * triggered when fifo hung counter is equal to this value + * I2S_TX_HUNG_INT interrupt or I2S_RX_HUNG_INT interrupt will be triggered + * when FIFO hung counter is equal to this value. */ #define I2S_LC_FIFO_TIMEOUT 0x000000FF @@ -1855,14 +1896,14 @@ #define I2S_LC_FIFO_TIMEOUT_V 0x000000FF #define I2S_LC_FIFO_TIMEOUT_S 0 -/* I2S_CONF1 _REG register - * I2S configure1 register +/* I2S_CONF1_REG register + * I2S configuration register 1 */ -#define I2S_CONF1 _REG (DR_REG_I2S_BASE + 0xa0) +#define I2S_CONF1_REG (DR_REG_I2S_BASE + 0xa0) /* I2S_TX_ZEROS_RM_EN : R/W; bitpos: [9]; default: 0; - * don't use + * Reserved. */ #define I2S_TX_ZEROS_RM_EN (BIT(9)) @@ -1871,8 +1912,8 @@ #define I2S_TX_ZEROS_RM_EN_S 9 /* I2S_TX_STOP_EN : R/W; bitpos: [8]; default: 0; - * Set this bit to stop disable output BCK signal and WS signal when tx FIFO - * is emtpy + * Set this bit to stop the output of BCK signal and WS signal when TX FIFO + * is empty. */ #define I2S_TX_STOP_EN (BIT(8)) @@ -1919,13 +1960,13 @@ #define I2S_TX_PCM_CONF_S 0 /* I2S_PD_CONF_REG register - * I2S power down configure register + * I2S power-down configuration register */ #define I2S_PD_CONF_REG (DR_REG_I2S_BASE + 0xa4) /* I2S_DMA_RAM_CLK_FO : R/W; bitpos: [6]; default: 0; - * Set this bit to force on the DMA ram clock. + * Set this bit to force on DMA RAM clock. */ #define I2S_DMA_RAM_CLK_FO (BIT(6)) @@ -1934,7 +1975,7 @@ #define I2S_DMA_RAM_CLK_FO_S 6 /* I2S_DMA_RAM_FORCE_PU : R/W; bitpos: [5]; default: 1; - * Force DMA FIFO power-up + * Force DMA FIFO power-up. */ #define I2S_DMA_RAM_FORCE_PU (BIT(5)) @@ -1943,7 +1984,7 @@ #define I2S_DMA_RAM_FORCE_PU_S 5 /* I2S_DMA_RAM_FORCE_PD : R/W; bitpos: [4]; default: 0; - * Force DMA FIFO power-down + * Force DMA FIFO power-down. */ #define I2S_DMA_RAM_FORCE_PD (BIT(4)) @@ -1952,7 +1993,7 @@ #define I2S_DMA_RAM_FORCE_PD_S 4 /* I2S_PLC_MEM_FORCE_PU : R/W; bitpos: [3]; default: 1; - * Force I2S memory power-up + * Force I2S memory power-up. */ #define I2S_PLC_MEM_FORCE_PU (BIT(3)) @@ -1961,7 +2002,7 @@ #define I2S_PLC_MEM_FORCE_PU_S 3 /* I2S_PLC_MEM_FORCE_PD : R/W; bitpos: [2]; default: 0; - * Force I2S memory power-down + * Force I2S memory power-down. */ #define I2S_PLC_MEM_FORCE_PD (BIT(2)) @@ -1970,7 +2011,7 @@ #define I2S_PLC_MEM_FORCE_PD_S 2 /* I2S_FIFO_FORCE_PU : R/W; bitpos: [1]; default: 1; - * Force FIFO power-up + * Force FIFO power-up. */ #define I2S_FIFO_FORCE_PU (BIT(1)) @@ -1979,7 +2020,7 @@ #define I2S_FIFO_FORCE_PU_S 1 /* I2S_FIFO_FORCE_PD : R/W; bitpos: [0]; default: 0; - * Force FIFO power-down + * Force FIFO power-down. */ #define I2S_FIFO_FORCE_PD (BIT(0)) @@ -1988,13 +2029,13 @@ #define I2S_FIFO_FORCE_PD_S 0 /* I2S_CONF2_REG register - * I2S configure2 register + * I2S configuration register 2 */ #define I2S_CONF2_REG (DR_REG_I2S_BASE + 0xa8) /* I2S_VSYNC_FILTER_THRES : R/W; bitpos: [13:11]; default: 0; - * Configure the I2S VSYNC filter threshold value + * Configure the I2S VSYNC filter threshold value. */ #define I2S_VSYNC_FILTER_THRES 0x00000007 @@ -2012,7 +2053,7 @@ #define I2S_VSYNC_FILTER_EN_S 10 /* I2S_CAM_CLK_LOOPBACK : R/W; bitpos: [9]; default: 0; - * Set this bit to loopback cam_clk from i2s_rx + * Set this bit to loopback PCLK from I2S0I_WS_out. */ #define I2S_CAM_CLK_LOOPBACK (BIT(9)) @@ -2021,7 +2062,7 @@ #define I2S_CAM_CLK_LOOPBACK_S 9 /* I2S_CAM_SYNC_FIFO_RESET : R/W; bitpos: [8]; default: 0; - * Set this bit to reset cam_sync_fifo + * Set this bit to reset FIFO in camera mode. */ #define I2S_CAM_SYNC_FIFO_RESET (BIT(8)) @@ -2030,7 +2071,8 @@ #define I2S_CAM_SYNC_FIFO_RESET_S 8 /* I2S_INTER_VALID_EN : R/W; bitpos: [7]; default: 0; - * Set this bit to enable camera internal valid + * Set this bit to enable camera VGA reducing-resolution mode: only receive + * two consecutive cycle data in four consecutive clocks. */ #define I2S_INTER_VALID_EN (BIT(7)) @@ -2049,7 +2091,7 @@ #define I2S_EXT_ADC_START_EN_S 6 /* I2S_LCD_EN : R/W; bitpos: [5]; default: 0; - * Set this bit to enable LCD mode + * Set this bit to enable LCD mode. */ #define I2S_LCD_EN (BIT(5)) @@ -2094,7 +2136,7 @@ #define I2S_LCD_TX_WRX2_EN_S 1 /* I2S_CAMERA_EN : R/W; bitpos: [0]; default: 0; - * Set this bit to enable camera mode + * Set this bit to enable camera mode. */ #define I2S_CAMERA_EN (BIT(0)) @@ -2103,7 +2145,7 @@ #define I2S_CAMERA_EN_S 0 /* I2S_CLKM_CONF_REG register - * I2S module clock configure register + * I2S module clock configuration register */ #define I2S_CLKM_CONF_REG (DR_REG_I2S_BASE + 0xac) @@ -2119,7 +2161,7 @@ #define I2S_CLK_SEL_S 21 /* I2S_CLK_EN : R/W; bitpos: [20]; default: 0; - * Set this bit to enable clk gate + * Set this bit to enable clock gate. */ #define I2S_CLK_EN (BIT(20)) @@ -2128,7 +2170,7 @@ #define I2S_CLK_EN_S 20 /* I2S_CLKM_DIV_A : R/W; bitpos: [19:14]; default: 0; - * Fractional clock divider denominator value + * Fractional clock divider denominator value. */ #define I2S_CLKM_DIV_A 0x0000003F @@ -2137,7 +2179,7 @@ #define I2S_CLKM_DIV_A_S 14 /* I2S_CLKM_DIV_B : R/W; bitpos: [13:8]; default: 0; - * Fractional clock divider numerator value + * Fractional clock divider numerator value. */ #define I2S_CLKM_DIV_B 0x0000003F @@ -2146,7 +2188,7 @@ #define I2S_CLKM_DIV_B_S 8 /* I2S_CLKM_DIV_NUM : R/W; bitpos: [7:0]; default: 4; - * Integral I2S clock divider value + * Integral I2S clock divider value. */ #define I2S_CLKM_DIV_NUM 0x000000FF @@ -2161,7 +2203,8 @@ #define I2S_SAMPLE_RATE_CONF_REG (DR_REG_I2S_BASE + 0xb0) /* I2S_RX_BITS_MOD : R/W; bitpos: [23:18]; default: 16; - * Set the bits to configure bit length of I2S receiver channel. + * Set the bits to configure bit length of I2S receiver channel, the value + * of which can only be 8, 16, 24 and 32. */ #define I2S_RX_BITS_MOD 0x0000003F @@ -2170,7 +2213,8 @@ #define I2S_RX_BITS_MOD_S 18 /* I2S_TX_BITS_MOD : R/W; bitpos: [17:12]; default: 16; - * Set the bits to configure bit length of I2S transmitter channel. + * Set the bits to configure bit length of I2S transmitter channel, the + * value of which can only be 8, 16, 24 and 32. */ #define I2S_TX_BITS_MOD 0x0000003F diff --git a/boards/xtensa/esp32s2/common/src/Make.defs b/boards/xtensa/esp32s2/common/src/Make.defs index 3508237018..1a8957b55e 100644 --- a/boards/xtensa/esp32s2/common/src/Make.defs +++ b/boards/xtensa/esp32s2/common/src/Make.defs @@ -28,6 +28,10 @@ ifeq ($(CONFIG_SENSORS_MAX6675),y) CSRCS += esp32s2_max6675.c endif +ifeq ($(CONFIG_ESP32S2_I2S),y) + CSRCS += esp32s2_board_i2sdev.c +endif + DEPPATH += --dep-path src VPATH += :src CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src) diff --git a/boards/xtensa/esp32s2/common/src/esp32s2_board_i2sdev.c b/boards/xtensa/esp32s2/common/src/esp32s2_board_i2sdev.c new file mode 100644 index 0000000000..600ae14c1d --- /dev/null +++ b/boards/xtensa/esp32s2/common/src/esp32s2_board_i2sdev.c @@ -0,0 +1,113 @@ +/**************************************************************************** + * boards/xtensa/esp32s2/common/src/esp32s2_board_i2sdev.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "esp32s2_i2s.h" + +#if defined(CONFIG_ESP32S2_I2S) && !defined(CONFIG_AUDIO_CS4344) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_i2sdev_initialize + * + * Description: + * This function is called by platform-specific, setup logic to configure + * and register the generic I2S audio driver. This function will register + * the driver as /dev/audio/pcm[x] where x is determined by the I2S port + * number. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int board_i2sdev_initialize(void) +{ + struct audio_lowerhalf_s *audio_i2s; + struct audio_lowerhalf_s *pcm; + struct i2s_dev_s *i2s; + char devname[5]; + int ret; + + ainfo("Initializing I2S\n"); + + i2s = esp32s2_i2sbus_initialize(); + +#ifdef CONFIG_AUDIO_I2SCHAR + ret = i2schar_register(i2s, 0); + if (ret < 0) + { + aerr("ERROR: i2schar_register failed: %d\n", ret); + return ret; + } +#endif + + audio_i2s = audio_i2s_initialize(i2s, true); + + if (!audio_i2s) + { + auderr("ERROR: Failed to initialize the Generic I2S audio driver\n"); + return -ENODEV; + } + + pcm = pcm_decode_initialize(audio_i2s); + + if (!pcm) + { + auderr("ERROR: Failed create the PCM decoder\n"); + return -ENODEV; + } + + snprintf(devname, 5, "pcm0"); + + ret = audio_register(devname, pcm); + + if (ret < 0) + { + auderr("ERROR: Failed to register /dev/%s device: %d\n", devname, ret); + } + + return ret; +} + +#endif /* (CONFIG_ESP32S2_I2S) && !defined (CONFIG_AUDIO_CS4344) */ diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/configs/i2schar/defconfig b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/i2schar/defconfig new file mode 100644 index 0000000000..a9cead0ae9 --- /dev/null +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/i2schar/defconfig @@ -0,0 +1,60 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_LEDS is not set +# CONFIG_ESP32S2_I2S_RX is not set +# CONFIG_NDEBUG is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_CMDPARMS is not set +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD="esp32s2-saola-1" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32S2_SAOLA_1=y +CONFIG_ARCH_CHIP="esp32s2" +CONFIG_ARCH_CHIP_ESP32S2=y +CONFIG_ARCH_CHIP_ESP32S2WROVER=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_AUDIO=y +CONFIG_AUDIO_I2S=y +CONFIG_AUDIO_I2SCHAR=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DRIVERS_AUDIO=y +CONFIG_ESP32S2_I2S=y +CONFIG_ESP32S2_I2S_MCLK=y +CONFIG_ESP32S2_UART0=y +CONFIG_EXAMPLES_I2SCHAR=y +CONFIG_EXAMPLES_I2SCHAR_TX=y +CONFIG_EXAMPLES_I2SCHAR_TXSTACKSIZE=4096 +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=4096 +CONFIG_INTELHEX_BINARY=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSTEM_NSH=y +CONFIG_UART0_SERIAL_CONSOLE=y diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h index b2a1a455b9..bd46eca2a7 100644 --- a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h @@ -152,5 +152,27 @@ int board_i2c_init(void); int board_bmp180_initialize(int devno, int busno); #endif +/**************************************************************************** + * Name: board_i2sdev_initialize + * + * Description: + * This function is called by platform-specific, setup logic to configure + * and register the generic I2S audio driver. This function will register + * the driver as /dev/audio/pcm[x] where x is determined by the I2S port + * number. + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32S2_I2S +int board_i2sdev_initialize(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __BOARDS_XTENSA_ESP32S2_ESP32S2_SAOLA_1_SRC_ESP32S2_SAOLA_1_H */ diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c index 861dca693e..49fb1f8f28 100644 --- a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c @@ -229,6 +229,18 @@ int esp32s2_bringup(void) } #endif +#ifdef CONFIG_ESP32S2_I2S + + /* Configure I2S generic audio on I2S0 */ + + ret = board_i2sdev_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to initialize I2S0 driver: %d\n", ret); + } + +#endif /* CONFIG_ESP32S2_I2S */ + /* If we got here then perhaps not all initialization was successful, but * at least enough succeeded to bring-up NSH with perhaps reduced * capabilities.