rp2/machine_i2s: Add I2S protocol support.

This commit adds I2S protocol support for the rp2 port:
- I2S API is consistent with STM32 and ESP32 ports
- I2S configurations supported:
  - master transmit and master receive
  - 16-bit and 32-bit sample sizes
  - mono and stereo formats
  - sampling frequency
  - 3 modes of operation:
    - blocking
    - non-blocking with callback
    - uasyncio
  - internal ring buffer size can be tuned
- DMA IRQs are managed on an I2S object basis, allowing other
  RP2 entities to use DMA IRQs when I2S is not being used
- MicroPython documentation
- tested on Raspberry Pi Pico development board
- build metric changes for this commit: text(+4552), data(0), bss(+8)

Signed-off-by: Mike Teachman <mike.teachman@gmail.com>
This commit is contained in:
Mike Teachman 2021-09-03 20:34:53 -07:00 committed by Damien George
parent 6d5296e65e
commit b6dbbbe82f
7 changed files with 1177 additions and 0 deletions

View File

@ -219,6 +219,26 @@ has the same methods as software I2C above::
i2c = I2C(0) # default assignment: scl=Pin(9), sda=Pin(8)
i2c = I2C(1, scl=Pin(3), sda=Pin(2), freq=400_000)
I2S bus
-------
See :ref:`machine.I2S <machine.I2S>`. ::
from machine import I2S, Pin
i2s = I2S(0, sck=Pin(16), ws=Pin(17), sd=Pin(18), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=40000) # create I2S object
i2s.write(buf) # write buffer of audio samples to I2S device
i2s = I2S(1, sck=Pin(0), ws=Pin(1), sd=Pin(2), mode=I2S.RX, bits=16, format=I2S.MONO, rate=22050, ibuf=40000) # create I2S object
i2s.readinto(buf) # fill buffer with audio samples from I2S device
The ``ws`` pin number must be one greater than the ``sck`` pin number.
The I2S class is currently available as a Technical Preview. During the preview period, feedback from
users is encouraged. Based on this feedback, the I2S class API and implementation may be changed.
Two I2S buses are supported with id=0 and id=1.
Real time clock (RTC)
---------------------

View File

@ -85,6 +85,7 @@ set(MICROPY_SOURCE_PORT
fatfs_port.c
machine_adc.c
machine_i2c.c
machine_i2s.c
machine_pin.c
machine_rtc.c
machine_spi.c
@ -112,6 +113,7 @@ set(MICROPY_SOURCE_QSTR
${MICROPY_DIR}/shared/runtime/sys_stdio_mphal.c
${PROJECT_SOURCE_DIR}/machine_adc.c
${PROJECT_SOURCE_DIR}/machine_i2c.c
${PROJECT_SOURCE_DIR}/machine_i2s.c
${PROJECT_SOURCE_DIR}/machine_pin.c
${PROJECT_SOURCE_DIR}/machine_rtc.c
${PROJECT_SOURCE_DIR}/machine_spi.c

1150
ports/rp2/machine_i2s.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -109,6 +109,7 @@ int main(int argc, char **argv) {
readline_init0();
machine_pin_init();
rp2_pio_init();
machine_i2s_init0();
#if MICROPY_PY_BLUETOOTH
mp_bluetooth_hci_init();

View File

@ -163,6 +163,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) },
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hw_i2c_type) },
{ MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) },
{ MP_ROM_QSTR(MP_QSTR_I2S), MP_ROM_PTR(&machine_i2s_type) },
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) },
{ MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) },
{ MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) },

View File

@ -5,6 +5,7 @@
extern const mp_obj_type_t machine_adc_type;
extern const mp_obj_type_t machine_hw_i2c_type;
extern const mp_obj_type_t machine_i2s_type;
extern const mp_obj_type_t machine_pin_type;
extern const mp_obj_type_t machine_rtc_type;
extern const mp_obj_type_t machine_spi_type;
@ -14,5 +15,6 @@ extern const mp_obj_type_t machine_wdt_type;
void machine_pin_init(void);
void machine_pin_deinit(void);
void machine_i2s_init0(void);
#endif // MICROPY_INCLUDED_RP2_MODMACHINE_H

View File

@ -176,6 +176,7 @@ struct _mp_bluetooth_nimble_malloc_t;
void *rp2_state_machine_irq_obj[8]; \
void *rp2_uart_rx_buffer[2]; \
void *rp2_uart_tx_buffer[2]; \
void *machine_i2s_obj[2]; \
NETWORK_ROOT_POINTERS \
MICROPY_BOARD_ROOT_POINTERS \
MICROPY_PORT_ROOT_POINTER_BLUETOOTH \