summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2023-10-10 16:44:02 +1100
committerDamien George <damien@micropython.org>2023-10-20 17:40:17 +1100
commit91a3f183916e1514fbb8dc58ca5b77acc59d4346 (patch)
tree9468a7b456e4c7b325d3c3de034769eb71457dc8
parent46ae3b5a34d33d3c696e1fb66661983315686712 (diff)
extmod/machine_i2s: Factor comments, some enums and macros.
Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r--extmod/machine_i2s.c46
-rw-r--r--ports/esp32/machine_i2s.c49
-rw-r--r--ports/mimxrt/machine_i2s.c49
-rw-r--r--ports/rp2/machine_i2s.c47
-rw-r--r--ports/stm32/machine_i2s.c49
5 files changed, 52 insertions, 188 deletions
diff --git a/extmod/machine_i2s.c b/extmod/machine_i2s.c
index bbff560a0..cc97f011a 100644
--- a/extmod/machine_i2s.c
+++ b/extmod/machine_i2s.c
@@ -32,6 +32,52 @@
#include "extmod/modmachine.h"
+// The I2S class has 3 modes of operation:
+//
+// Mode1: Blocking
+// - readinto() and write() methods block until the supplied buffer is filled (read) or emptied (write)
+// - this is the default mode of operation
+//
+// Mode2: Non-Blocking
+// - readinto() and write() methods return immediately
+// - buffer filling and emptying happens asynchronously to the main MicroPython task
+// - a callback function is called when the supplied buffer has been filled (read) or emptied (write)
+// - non-blocking mode is enabled when a callback is set with the irq() method
+// - implementation of asynchronous background operations is port specific
+//
+// Mode3: Asyncio
+// - implements the stream protocol
+// - asyncio mode is enabled when the ioctl() function is called
+// - the state of the internal ring buffer is used to detect that I2S samples can be read or written
+//
+// The samples contained in the app buffer supplied for the readinto() and write() methods have the following convention:
+// Mono: little endian format
+// Stereo: little endian format, left channel first
+//
+// I2S terms:
+// "frame": consists of two audio samples (Left audio sample + Right audio sample)
+//
+// Misc:
+// - for Mono configuration:
+// - readinto method: samples are gathered from the L channel only
+// - write method: every sample is output to both the L and R channels
+// - for readinto method the I2S hardware is read using 8-byte frames
+// (this is standard for almost all I2S hardware, such as MEMS microphones)
+
+#define NUM_I2S_USER_FORMATS (4)
+#define I2S_RX_FRAME_SIZE_IN_BYTES (8)
+
+typedef enum {
+ MONO,
+ STEREO
+} format_t;
+
+typedef enum {
+ BLOCKING,
+ NON_BLOCKING,
+ ASYNCIO
+} io_mode_t;
+
// Arguments for I2S() constructor and I2S.init().
enum {
ARG_sck,
diff --git a/ports/esp32/machine_i2s.c b/ports/esp32/machine_i2s.c
index 9a5e5c603..89d460e45 100644
--- a/ports/esp32/machine_i2s.c
+++ b/ports/esp32/machine_i2s.c
@@ -29,8 +29,6 @@
#include "py/mphal.h"
-#if MICROPY_PY_MACHINE_I2S
-
#include "driver/i2s.h"
#include "soc/i2s_reg.h"
#include "freertos/FreeRTOS.h"
@@ -38,38 +36,9 @@
#include "freertos/queue.h"
#include "esp_task.h"
-// The I2S module has 3 modes of operation:
-//
-// Mode1: Blocking
-// - readinto() and write() methods block until the supplied buffer is filled (read) or emptied (write)
-// - this is the default mode of operation
-//
-// Mode2: Non-Blocking
-// - readinto() and write() methods return immediately.
-// - buffer filling and emptying happens asynchronously to the main MicroPython task
-// - a callback function is called when the supplied buffer has been filled (read) or emptied (write)
-// - non-blocking mode is enabled when a callback is set with the irq() method
+// Notes on this port's specific implementation of I2S:
// - a FreeRTOS task is created to implement the asynchronous background operations
// - a FreeRTOS queue is used to transfer the supplied buffer to the background task
-//
-// Mode3: Asyncio
-// - implements the stream protocol
-// - asyncio mode is enabled when the ioctl() function is called
-// - the I2S event queue is used to detect that I2S samples can be read or written from/to DMA memory
-//
-// The samples contained in the app buffer supplied for the readinto() and write() methods have the following convention:
-// Mono: little endian format
-// Stereo: little endian format, left channel first
-//
-// I2S terms:
-// "frame": consists of two audio samples (Left audio sample + Right audio sample)
-//
-// Misc:
-// - for Mono configuration:
-// - readinto method: samples are gathered from the L channel only
-// - write method: every sample is output to both the L and R channels
-// - for readinto method the I2S hardware is read using 8-byte frames
-// (this is standard for almost all I2S hardware, such as MEMS microphones)
// - all sample data transfers use DMA
#define I2S_TASK_PRIORITY (ESP_TASK_PRIO_MIN + 1)
@@ -82,20 +51,6 @@
// The size of 240 bytes is an engineering optimum that balances transfer performance with an acceptable use of heap space
#define SIZEOF_TRANSFORM_BUFFER_IN_BYTES (240)
-#define NUM_I2S_USER_FORMATS (4)
-#define I2S_RX_FRAME_SIZE_IN_BYTES (8)
-
-typedef enum {
- MONO,
- STEREO
-} format_t;
-
-typedef enum {
- BLOCKING,
- NON_BLOCKING,
- ASYNCIO
-} io_mode_t;
-
typedef enum {
I2S_TX_TRANSFER,
I2S_RX_TRANSFER,
@@ -510,5 +465,3 @@ STATIC void mp_machine_i2s_irq_update(machine_i2s_obj_t *self) {
}
MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[I2S_NUM_AUTO]);
-
-#endif // MICROPY_PY_MACHINE_I2S
diff --git a/ports/mimxrt/machine_i2s.c b/ports/mimxrt/machine_i2s.c
index dcdebd4c7..077c9e76f 100644
--- a/ports/mimxrt/machine_i2s.c
+++ b/ports/mimxrt/machine_i2s.c
@@ -37,38 +37,8 @@
#include "fsl_edma.h"
#include "fsl_sai.h"
-#if MICROPY_PY_MACHINE_I2S
-// The I2S module has 3 modes of operation:
-//
-// Mode1: Blocking
-// - readinto() and write() methods block until the supplied buffer is filled (read) or emptied (write)
-// - this is the default mode of operation
-//
-// Mode2: Non-Blocking
-// - readinto() and write() methods return immediately
-// - buffer filling and emptying happens asynchronously to the main MicroPython task
-// - a callback function is called when the supplied buffer has been filled (read) or emptied (write)
-// - non-blocking mode is enabled when a callback is set with the irq() method
-// - the DMA callback is used to implement the asynchronous background operations
-//
-// Mode3: Asyncio
-// - implements the stream protocol
-// - asyncio mode is enabled when the ioctl() function is called
-// - the state of the internal ring buffer is used to detect that I2S samples can be read or written
-//
-// The samples contained in the app buffer supplied for the readinto() and write() methods have the following convention:
-// Mono: little endian format
-// Stereo: little endian format, left channel first
-//
-// I2S terms:
-// "frame": consists of two audio samples (Left audio sample + Right audio sample)
-//
-// Misc:
-// - for Mono configuration:
-// - readinto method: samples are gathered from the L channel only
-// - write method: every sample is output to both the L and R channels
-// - for readinto method the I2S hardware is read using 8-byte frames
-// (this is standard for almost all I2S hardware, such as MEMS microphones)
+// Notes on this port's specific implementation of I2S:
+// - the DMA callback is used to implement the asynchronous background operations, for non-blocking mode
// - all 3 Modes of operation are implemented using the peripheral drivers in the NXP MCUXpresso SDK
// - all sample data transfers use DMA
// - the DMA ping-pong buffer needs to be aligned to a cache line size of 32 bytes. 32 byte
@@ -88,8 +58,6 @@
#define NON_BLOCKING_RATE_MULTIPLIER (4)
#define SIZEOF_NON_BLOCKING_COPY_IN_BYTES (SIZEOF_HALF_DMA_BUFFER_IN_BYTES * NON_BLOCKING_RATE_MULTIPLIER)
-#define NUM_I2S_USER_FORMATS (4)
-#define I2S_RX_FRAME_SIZE_IN_BYTES (8)
#define SAI_CHANNEL_0 (0)
#define SAI_NUM_AUDIO_CHANNELS (2U)
@@ -106,17 +74,6 @@ typedef enum {
} i2s_mode_t;
typedef enum {
- MONO,
- STEREO
-} format_t;
-
-typedef enum {
- BLOCKING,
- NON_BLOCKING,
- ASYNCIO
-} io_mode_t;
-
-typedef enum {
TOP_HALF,
BOTTOM_HALF
} ping_pong_t;
@@ -766,5 +723,3 @@ STATIC void mp_machine_i2s_irq_update(machine_i2s_obj_t *self) {
}
MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[MICROPY_HW_I2S_NUM]);
-
-#endif // MICROPY_PY_MACHINE_I2S
diff --git a/ports/rp2/machine_i2s.c b/ports/rp2/machine_i2s.c
index 9df0f09f2..68a0f296a 100644
--- a/ports/rp2/machine_i2s.c
+++ b/ports/rp2/machine_i2s.c
@@ -37,37 +37,8 @@
#include "hardware/dma.h"
#include "hardware/irq.h"
-// The I2S class has 3 modes of operation:
-//
-// Mode1: Blocking
-// - readinto() and write() methods block until the supplied buffer is filled (read) or emptied (write)
-// - this is the default mode of operation
-//
-// Mode2: Non-Blocking
-// - readinto() and write() methods return immediately
-// - buffer filling and emptying happens asynchronously to the main MicroPython task
-// - a callback function is called when the supplied buffer has been filled (read) or emptied (write)
-// - non-blocking mode is enabled when a callback is set with the irq() method
-// - the DMA IRQ handler is used to implement the asynchronous background operations
-//
-// Mode3: Asyncio
-// - implements the stream protocol
-// - asyncio mode is enabled when the ioctl() function is called
-// - the state of the internal ring buffer is used to detect that I2S samples can be read or written
-//
-// The samples contained in the app buffer supplied for the readinto() and write() methods have the following convention:
-// Mono: little endian format
-// Stereo: little endian format, left channel first
-//
-// I2S terms:
-// "frame": consists of two audio samples (Left audio sample + Right audio sample)
-//
-// Misc:
-// - for Mono configuration:
-// - readinto method: samples are gathered from the L channel only
-// - write method: every sample is output to both the L and R channels
-// - for readinto method the I2S hardware is read using 8-byte frames
-// (this is standard for almost all I2S hardware, such as MEMS microphones)
+// Notes on this port's specific implementation of I2S:
+// - the DMA IRQ handler is used to implement the asynchronous background operations, for non-blocking mode
// - the PIO is used to drive the I2S bus signals
// - all sample data transfers use non-blocking DMA
// - the DMA controller is configured with 2 DMA channels in chained mode
@@ -86,9 +57,6 @@
#define NON_BLOCKING_RATE_MULTIPLIER (4)
#define SIZEOF_NON_BLOCKING_COPY_IN_BYTES (SIZEOF_HALF_DMA_BUFFER_IN_BYTES * NON_BLOCKING_RATE_MULTIPLIER)
-#define NUM_I2S_USER_FORMATS (4)
-#define I2S_RX_FRAME_SIZE_IN_BYTES (8)
-
#define SAMPLES_PER_FRAME (2)
#define PIO_INSTRUCTIONS_PER_BIT (2)
@@ -98,17 +66,6 @@ typedef enum {
} i2s_mode_t;
typedef enum {
- MONO,
- STEREO
-} format_t;
-
-typedef enum {
- BLOCKING,
- NON_BLOCKING,
- ASYNCIO
-} io_mode_t;
-
-typedef enum {
GP_INPUT = 0,
GP_OUTPUT = 1
} gpio_dir_t;
diff --git a/ports/stm32/machine_i2s.c b/ports/stm32/machine_i2s.c
index 6d195432f..dbcd9352d 100644
--- a/ports/stm32/machine_i2s.c
+++ b/ports/stm32/machine_i2s.c
@@ -33,39 +33,8 @@
#include "pin.h"
#include "dma.h"
-#if MICROPY_PY_MACHINE_I2S
-
-// The I2S module has 3 modes of operation:
-//
-// Mode1: Blocking
-// - readinto() and write() methods block until the supplied buffer is filled (read) or emptied (write)
-// - this is the default mode of operation
-//
-// Mode2: Non-Blocking
-// - readinto() and write() methods return immediately
-// - buffer filling and emptying happens asynchronously to the main MicroPython task
-// - a callback function is called when the supplied buffer has been filled (read) or emptied (write)
-// - non-blocking mode is enabled when a callback is set with the irq() method
+// Notes on this port's specific implementation of I2S:
// - the DMA callbacks (1/2 complete and complete) are used to implement the asynchronous background operations
-//
-// Mode3: Asyncio
-// - implements the stream protocol
-// - asyncio mode is enabled when the ioctl() function is called
-// - the state of the internal ring buffer is used to detect that I2S samples can be read or written
-//
-// The samples contained in the app buffer supplied for the readinto() and write() methods have the following convention:
-// Mono: little endian format
-// Stereo: little endian format, left channel first
-//
-// I2S terms:
-// "frame": consists of two audio samples (Left audio sample + Right audio sample)
-//
-// Misc:
-// - for Mono configuration:
-// - readinto method: samples are gathered from the L channel only
-// - write method: every sample is output to both the L and R channels
-// - for readinto method the I2S hardware is read using 8-byte frames
-// (this is standard for almost all I2S hardware, such as MEMS microphones)
// - all 3 Modes of operation are implemented using the HAL I2S Generic Driver
// - all sample data transfers use DMA
// - the DMA controller is configured in Circular mode to fulfil continuous and gapless sample flows
@@ -86,20 +55,6 @@
#define NON_BLOCKING_RATE_MULTIPLIER (4)
#define SIZEOF_NON_BLOCKING_COPY_IN_BYTES (SIZEOF_HALF_DMA_BUFFER_IN_BYTES * NON_BLOCKING_RATE_MULTIPLIER)
-#define NUM_I2S_USER_FORMATS (4)
-#define I2S_RX_FRAME_SIZE_IN_BYTES (8)
-
-typedef enum {
- MONO,
- STEREO
-} format_t;
-
-typedef enum {
- BLOCKING,
- NON_BLOCKING,
- ASYNCIO
-} io_mode_t;
-
typedef enum {
TOP_HALF,
BOTTOM_HALF
@@ -618,5 +573,3 @@ STATIC void mp_machine_i2s_irq_update(machine_i2s_obj_t *self) {
}
MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[MICROPY_HW_MAX_I2S]);
-
-#endif // MICROPY_PY_MACHINE_I2S