Skip to content

Commit 91a3f18

Browse files
committed
extmod/machine_i2s: Factor comments, some enums and macros.
Signed-off-by: Damien George <[email protected]>
1 parent 46ae3b5 commit 91a3f18

File tree

5 files changed

+52
-188
lines changed

5 files changed

+52
-188
lines changed

extmod/machine_i2s.c

+46
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,52 @@
3232

3333
#include "extmod/modmachine.h"
3434

35+
// The I2S class has 3 modes of operation:
36+
//
37+
// Mode1: Blocking
38+
// - readinto() and write() methods block until the supplied buffer is filled (read) or emptied (write)
39+
// - this is the default mode of operation
40+
//
41+
// Mode2: Non-Blocking
42+
// - readinto() and write() methods return immediately
43+
// - buffer filling and emptying happens asynchronously to the main MicroPython task
44+
// - a callback function is called when the supplied buffer has been filled (read) or emptied (write)
45+
// - non-blocking mode is enabled when a callback is set with the irq() method
46+
// - implementation of asynchronous background operations is port specific
47+
//
48+
// Mode3: Asyncio
49+
// - implements the stream protocol
50+
// - asyncio mode is enabled when the ioctl() function is called
51+
// - the state of the internal ring buffer is used to detect that I2S samples can be read or written
52+
//
53+
// The samples contained in the app buffer supplied for the readinto() and write() methods have the following convention:
54+
// Mono: little endian format
55+
// Stereo: little endian format, left channel first
56+
//
57+
// I2S terms:
58+
// "frame": consists of two audio samples (Left audio sample + Right audio sample)
59+
//
60+
// Misc:
61+
// - for Mono configuration:
62+
// - readinto method: samples are gathered from the L channel only
63+
// - write method: every sample is output to both the L and R channels
64+
// - for readinto method the I2S hardware is read using 8-byte frames
65+
// (this is standard for almost all I2S hardware, such as MEMS microphones)
66+
67+
#define NUM_I2S_USER_FORMATS (4)
68+
#define I2S_RX_FRAME_SIZE_IN_BYTES (8)
69+
70+
typedef enum {
71+
MONO,
72+
STEREO
73+
} format_t;
74+
75+
typedef enum {
76+
BLOCKING,
77+
NON_BLOCKING,
78+
ASYNCIO
79+
} io_mode_t;
80+
3581
// Arguments for I2S() constructor and I2S.init().
3682
enum {
3783
ARG_sck,

ports/esp32/machine_i2s.c

+1-48
Original file line numberDiff line numberDiff line change
@@ -29,47 +29,16 @@
2929

3030
#include "py/mphal.h"
3131

32-
#if MICROPY_PY_MACHINE_I2S
33-
3432
#include "driver/i2s.h"
3533
#include "soc/i2s_reg.h"
3634
#include "freertos/FreeRTOS.h"
3735
#include "freertos/task.h"
3836
#include "freertos/queue.h"
3937
#include "esp_task.h"
4038

41-
// The I2S module has 3 modes of operation:
42-
//
43-
// Mode1: Blocking
44-
// - readinto() and write() methods block until the supplied buffer is filled (read) or emptied (write)
45-
// - this is the default mode of operation
46-
//
47-
// Mode2: Non-Blocking
48-
// - readinto() and write() methods return immediately.
49-
// - buffer filling and emptying happens asynchronously to the main MicroPython task
50-
// - a callback function is called when the supplied buffer has been filled (read) or emptied (write)
51-
// - non-blocking mode is enabled when a callback is set with the irq() method
39+
// Notes on this port's specific implementation of I2S:
5240
// - a FreeRTOS task is created to implement the asynchronous background operations
5341
// - a FreeRTOS queue is used to transfer the supplied buffer to the background task
54-
//
55-
// Mode3: Asyncio
56-
// - implements the stream protocol
57-
// - asyncio mode is enabled when the ioctl() function is called
58-
// - the I2S event queue is used to detect that I2S samples can be read or written from/to DMA memory
59-
//
60-
// The samples contained in the app buffer supplied for the readinto() and write() methods have the following convention:
61-
// Mono: little endian format
62-
// Stereo: little endian format, left channel first
63-
//
64-
// I2S terms:
65-
// "frame": consists of two audio samples (Left audio sample + Right audio sample)
66-
//
67-
// Misc:
68-
// - for Mono configuration:
69-
// - readinto method: samples are gathered from the L channel only
70-
// - write method: every sample is output to both the L and R channels
71-
// - for readinto method the I2S hardware is read using 8-byte frames
72-
// (this is standard for almost all I2S hardware, such as MEMS microphones)
7342
// - all sample data transfers use DMA
7443

7544
#define I2S_TASK_PRIORITY (ESP_TASK_PRIO_MIN + 1)
@@ -82,20 +51,6 @@
8251
// The size of 240 bytes is an engineering optimum that balances transfer performance with an acceptable use of heap space
8352
#define SIZEOF_TRANSFORM_BUFFER_IN_BYTES (240)
8453

85-
#define NUM_I2S_USER_FORMATS (4)
86-
#define I2S_RX_FRAME_SIZE_IN_BYTES (8)
87-
88-
typedef enum {
89-
MONO,
90-
STEREO
91-
} format_t;
92-
93-
typedef enum {
94-
BLOCKING,
95-
NON_BLOCKING,
96-
ASYNCIO
97-
} io_mode_t;
98-
9954
typedef enum {
10055
I2S_TX_TRANSFER,
10156
I2S_RX_TRANSFER,
@@ -510,5 +465,3 @@ STATIC void mp_machine_i2s_irq_update(machine_i2s_obj_t *self) {
510465
}
511466

512467
MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[I2S_NUM_AUTO]);
513-
514-
#endif // MICROPY_PY_MACHINE_I2S

ports/mimxrt/machine_i2s.c

+2-47
Original file line numberDiff line numberDiff line change
@@ -37,38 +37,8 @@
3737
#include "fsl_edma.h"
3838
#include "fsl_sai.h"
3939

40-
#if MICROPY_PY_MACHINE_I2S
41-
// The I2S module has 3 modes of operation:
42-
//
43-
// Mode1: Blocking
44-
// - readinto() and write() methods block until the supplied buffer is filled (read) or emptied (write)
45-
// - this is the default mode of operation
46-
//
47-
// Mode2: Non-Blocking
48-
// - readinto() and write() methods return immediately
49-
// - buffer filling and emptying happens asynchronously to the main MicroPython task
50-
// - a callback function is called when the supplied buffer has been filled (read) or emptied (write)
51-
// - non-blocking mode is enabled when a callback is set with the irq() method
52-
// - the DMA callback is used to implement the asynchronous background operations
53-
//
54-
// Mode3: Asyncio
55-
// - implements the stream protocol
56-
// - asyncio mode is enabled when the ioctl() function is called
57-
// - the state of the internal ring buffer is used to detect that I2S samples can be read or written
58-
//
59-
// The samples contained in the app buffer supplied for the readinto() and write() methods have the following convention:
60-
// Mono: little endian format
61-
// Stereo: little endian format, left channel first
62-
//
63-
// I2S terms:
64-
// "frame": consists of two audio samples (Left audio sample + Right audio sample)
65-
//
66-
// Misc:
67-
// - for Mono configuration:
68-
// - readinto method: samples are gathered from the L channel only
69-
// - write method: every sample is output to both the L and R channels
70-
// - for readinto method the I2S hardware is read using 8-byte frames
71-
// (this is standard for almost all I2S hardware, such as MEMS microphones)
40+
// Notes on this port's specific implementation of I2S:
41+
// - the DMA callback is used to implement the asynchronous background operations, for non-blocking mode
7242
// - all 3 Modes of operation are implemented using the peripheral drivers in the NXP MCUXpresso SDK
7343
// - all sample data transfers use DMA
7444
// - the DMA ping-pong buffer needs to be aligned to a cache line size of 32 bytes. 32 byte
@@ -88,8 +58,6 @@
8858
#define NON_BLOCKING_RATE_MULTIPLIER (4)
8959
#define SIZEOF_NON_BLOCKING_COPY_IN_BYTES (SIZEOF_HALF_DMA_BUFFER_IN_BYTES * NON_BLOCKING_RATE_MULTIPLIER)
9060

91-
#define NUM_I2S_USER_FORMATS (4)
92-
#define I2S_RX_FRAME_SIZE_IN_BYTES (8)
9361
#define SAI_CHANNEL_0 (0)
9462
#define SAI_NUM_AUDIO_CHANNELS (2U)
9563

@@ -105,17 +73,6 @@ typedef enum {
10573
TX,
10674
} i2s_mode_t;
10775

108-
typedef enum {
109-
MONO,
110-
STEREO
111-
} format_t;
112-
113-
typedef enum {
114-
BLOCKING,
115-
NON_BLOCKING,
116-
ASYNCIO
117-
} io_mode_t;
118-
11976
typedef enum {
12077
TOP_HALF,
12178
BOTTOM_HALF
@@ -766,5 +723,3 @@ STATIC void mp_machine_i2s_irq_update(machine_i2s_obj_t *self) {
766723
}
767724

768725
MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[MICROPY_HW_I2S_NUM]);
769-
770-
#endif // MICROPY_PY_MACHINE_I2S

ports/rp2/machine_i2s.c

+2-45
Original file line numberDiff line numberDiff line change
@@ -37,37 +37,8 @@
3737
#include "hardware/dma.h"
3838
#include "hardware/irq.h"
3939

40-
// The I2S class has 3 modes of operation:
41-
//
42-
// Mode1: Blocking
43-
// - readinto() and write() methods block until the supplied buffer is filled (read) or emptied (write)
44-
// - this is the default mode of operation
45-
//
46-
// Mode2: Non-Blocking
47-
// - readinto() and write() methods return immediately
48-
// - buffer filling and emptying happens asynchronously to the main MicroPython task
49-
// - a callback function is called when the supplied buffer has been filled (read) or emptied (write)
50-
// - non-blocking mode is enabled when a callback is set with the irq() method
51-
// - the DMA IRQ handler is used to implement the asynchronous background operations
52-
//
53-
// Mode3: Asyncio
54-
// - implements the stream protocol
55-
// - asyncio mode is enabled when the ioctl() function is called
56-
// - the state of the internal ring buffer is used to detect that I2S samples can be read or written
57-
//
58-
// The samples contained in the app buffer supplied for the readinto() and write() methods have the following convention:
59-
// Mono: little endian format
60-
// Stereo: little endian format, left channel first
61-
//
62-
// I2S terms:
63-
// "frame": consists of two audio samples (Left audio sample + Right audio sample)
64-
//
65-
// Misc:
66-
// - for Mono configuration:
67-
// - readinto method: samples are gathered from the L channel only
68-
// - write method: every sample is output to both the L and R channels
69-
// - for readinto method the I2S hardware is read using 8-byte frames
70-
// (this is standard for almost all I2S hardware, such as MEMS microphones)
40+
// Notes on this port's specific implementation of I2S:
41+
// - the DMA IRQ handler is used to implement the asynchronous background operations, for non-blocking mode
7142
// - the PIO is used to drive the I2S bus signals
7243
// - all sample data transfers use non-blocking DMA
7344
// - the DMA controller is configured with 2 DMA channels in chained mode
@@ -86,9 +57,6 @@
8657
#define NON_BLOCKING_RATE_MULTIPLIER (4)
8758
#define SIZEOF_NON_BLOCKING_COPY_IN_BYTES (SIZEOF_HALF_DMA_BUFFER_IN_BYTES * NON_BLOCKING_RATE_MULTIPLIER)
8859

89-
#define NUM_I2S_USER_FORMATS (4)
90-
#define I2S_RX_FRAME_SIZE_IN_BYTES (8)
91-
9260
#define SAMPLES_PER_FRAME (2)
9361
#define PIO_INSTRUCTIONS_PER_BIT (2)
9462

@@ -97,17 +65,6 @@ typedef enum {
9765
TX
9866
} i2s_mode_t;
9967

100-
typedef enum {
101-
MONO,
102-
STEREO
103-
} format_t;
104-
105-
typedef enum {
106-
BLOCKING,
107-
NON_BLOCKING,
108-
ASYNCIO
109-
} io_mode_t;
110-
11168
typedef enum {
11269
GP_INPUT = 0,
11370
GP_OUTPUT = 1

ports/stm32/machine_i2s.c

+1-48
Original file line numberDiff line numberDiff line change
@@ -33,39 +33,8 @@
3333
#include "pin.h"
3434
#include "dma.h"
3535

36-
#if MICROPY_PY_MACHINE_I2S
37-
38-
// The I2S module has 3 modes of operation:
39-
//
40-
// Mode1: Blocking
41-
// - readinto() and write() methods block until the supplied buffer is filled (read) or emptied (write)
42-
// - this is the default mode of operation
43-
//
44-
// Mode2: Non-Blocking
45-
// - readinto() and write() methods return immediately
46-
// - buffer filling and emptying happens asynchronously to the main MicroPython task
47-
// - a callback function is called when the supplied buffer has been filled (read) or emptied (write)
48-
// - non-blocking mode is enabled when a callback is set with the irq() method
36+
// Notes on this port's specific implementation of I2S:
4937
// - the DMA callbacks (1/2 complete and complete) are used to implement the asynchronous background operations
50-
//
51-
// Mode3: Asyncio
52-
// - implements the stream protocol
53-
// - asyncio mode is enabled when the ioctl() function is called
54-
// - the state of the internal ring buffer is used to detect that I2S samples can be read or written
55-
//
56-
// The samples contained in the app buffer supplied for the readinto() and write() methods have the following convention:
57-
// Mono: little endian format
58-
// Stereo: little endian format, left channel first
59-
//
60-
// I2S terms:
61-
// "frame": consists of two audio samples (Left audio sample + Right audio sample)
62-
//
63-
// Misc:
64-
// - for Mono configuration:
65-
// - readinto method: samples are gathered from the L channel only
66-
// - write method: every sample is output to both the L and R channels
67-
// - for readinto method the I2S hardware is read using 8-byte frames
68-
// (this is standard for almost all I2S hardware, such as MEMS microphones)
6938
// - all 3 Modes of operation are implemented using the HAL I2S Generic Driver
7039
// - all sample data transfers use DMA
7140
// - the DMA controller is configured in Circular mode to fulfil continuous and gapless sample flows
@@ -86,20 +55,6 @@
8655
#define NON_BLOCKING_RATE_MULTIPLIER (4)
8756
#define SIZEOF_NON_BLOCKING_COPY_IN_BYTES (SIZEOF_HALF_DMA_BUFFER_IN_BYTES * NON_BLOCKING_RATE_MULTIPLIER)
8857

89-
#define NUM_I2S_USER_FORMATS (4)
90-
#define I2S_RX_FRAME_SIZE_IN_BYTES (8)
91-
92-
typedef enum {
93-
MONO,
94-
STEREO
95-
} format_t;
96-
97-
typedef enum {
98-
BLOCKING,
99-
NON_BLOCKING,
100-
ASYNCIO
101-
} io_mode_t;
102-
10358
typedef enum {
10459
TOP_HALF,
10560
BOTTOM_HALF
@@ -618,5 +573,3 @@ STATIC void mp_machine_i2s_irq_update(machine_i2s_obj_t *self) {
618573
}
619574

620575
MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[MICROPY_HW_MAX_I2S]);
621-
622-
#endif // MICROPY_PY_MACHINE_I2S

0 commit comments

Comments
 (0)