blue_pio_i2s.pio 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. ; pio_i2s for the Raspberry Pi Pico RP2040
  2. ;
  3. ; Based loosely off of the MicroPython I2S code in
  4. ; https://github.com/micropython/micropython/blob/master/ports/rp2/machine_i2s.c
  5. ;
  6. ; Copyright (c) 2022 Earle F. Philhower, III <earlephilhower@yahoo.com>
  7. ;
  8. ; This library is free software; you can redistribute it and/or
  9. ; modify it under the terms of the GNU Lesser General Public
  10. ; License as published by the Free Software Foundation; either
  11. ; version 2.1 of the License, or (at your option) any later version.
  12. ;
  13. ; This library is distributed in the hope that it will be useful,
  14. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. ; Lesser General Public License for more details.
  17. ;
  18. ; You should have received a copy of the GNU Lesser General Public
  19. ; License along with this library; if not, write to the Free Software
  20. ; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  21. .program pio_i2s_out
  22. .side_set 2 ; 0 = bclk, 1=wclk
  23. ; The C code should place (number of bits/sample - 2) in Y and
  24. ; also update the SHIFTCTRL to be 24 or 32 as appropriate
  25. ; +----- WCLK
  26. ; |+---- BCLK
  27. mov x, y side 0b01
  28. left:
  29. out pins, 1 side 0b00
  30. jmp x--, left side 0b01
  31. out pins, 1 side 0b10 ; Last bit of left has WCLK change per I2S spec
  32. mov x, y side 0b11
  33. right:
  34. out pins, 1 side 0b10
  35. jmp x--, right side 0b11
  36. out pins, 1 side 0b00 ; Last bit of right also has WCLK change
  37. ; Loop back to beginning...
  38. % c-sdk {
  39. static inline void pio_i2s_out_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits) {
  40. pio_gpio_init(pio, data_pin);
  41. pio_gpio_init(pio, clock_pin_base);
  42. pio_gpio_init(pio, clock_pin_base + 1);
  43. pio_sm_config sm_config = pio_i2s_out_program_get_default_config(offset);
  44. sm_config_set_out_pins(&sm_config, data_pin, 1);
  45. sm_config_set_sideset_pins(&sm_config, clock_pin_base);
  46. sm_config_set_out_shift(&sm_config, false, true, (bits <= 16) ? 2 * bits : bits);
  47. sm_config_set_fifo_join(&sm_config, PIO_FIFO_JOIN_TX);
  48. pio_sm_init(pio, sm, offset, &sm_config);
  49. uint pin_mask = (1u << data_pin) | (3u << clock_pin_base);
  50. pio_sm_set_pindirs_with_mask(pio, sm, pin_mask, pin_mask);
  51. pio_sm_set_pins(pio, sm, 0); // clear pins
  52. pio_sm_exec(pio, sm, pio_encode_set(pio_y, bits - 2));
  53. }
  54. %}