luat_i2s_air101.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include "luat_base.h"
  2. #include "luat_i2s.h"
  3. #include "wm_include.h"
  4. #include "wm_i2s.h"
  5. #include "wm_gpio_afsel.h"
  6. #include "c_common.h"
  7. #define LUAT_LOG_TAG "i2s"
  8. #include "luat_log.h"
  9. #define AUDIO_BUF_SIZE (1024 * 10)
  10. #define PERIOD_PLAY 64
  11. static uint8_t i2s_tx_buffer[PERIOD_PLAY];
  12. static wm_dma_handler_type dma_tx;
  13. static Buffer_Struct dma_tx_buf;
  14. #define CODEC_RUNING (1 << 0)
  15. volatile uint8_t run_status = 0;
  16. static int I2s_tx_send(){
  17. uint16_t send_bytes;
  18. if (PERIOD_PLAY>dma_tx_buf.Pos){
  19. send_bytes = dma_tx_buf.Pos;
  20. }else{
  21. send_bytes = PERIOD_PLAY;
  22. }
  23. memcpy(i2s_tx_buffer, dma_tx_buf.Data, send_bytes);
  24. OS_BufferRemove(&dma_tx_buf, send_bytes);
  25. if(send_bytes == 0)
  26. return -1;
  27. DMA_SRCADDR_REG(dma_tx.channel) = (uint32_t )i2s_tx_buffer;
  28. DMA_CTRL_REG(dma_tx.channel) &= ~0xFFFF00;
  29. DMA_CTRL_REG(dma_tx.channel) |= (send_bytes<<8);
  30. DMA_CHNLCTRL_REG(dma_tx.channel) = DMA_CHNL_CTRL_CHNL_ON;
  31. wm_i2s_tx_dma_enable(1);
  32. wm_i2s_tx_enable(1);
  33. wm_i2s_enable(1);
  34. return 0;
  35. }
  36. static void I2s_dma_tx_irq(void *p){
  37. int ret_len = dma_tx_buf.Pos;
  38. if(ret_len >= 4 ){
  39. I2s_tx_send();
  40. }else{
  41. run_status &= ~CODEC_RUNING;
  42. }
  43. }
  44. static int I2s_tx_dma_init(void){
  45. if (dma_tx_buf.Data){
  46. return 0;
  47. }
  48. OS_InitBuffer(&dma_tx_buf, AUDIO_BUF_SIZE);
  49. memset(&dma_tx, 0, sizeof(wm_dma_handler_type));
  50. if(dma_tx.channel){
  51. tls_dma_free(dma_tx.channel);
  52. }
  53. dma_tx.channel = tls_dma_request(WM_I2S_TX_DMA_CHANNEL, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_I2S_TX) | TLS_DMA_FLAGS_HARD_MODE);
  54. if(dma_tx.channel == 0){
  55. return -1;
  56. }
  57. if (tls_dma_stop(dma_tx.channel)){
  58. return -1;
  59. }
  60. tls_dma_irq_register(dma_tx.channel, I2s_dma_tx_irq, &dma_tx, TLS_DMA_IRQ_TRANSFER_DONE);
  61. DMA_INTMASK_REG &= ~(0x02<<(dma_tx.channel*2));
  62. DMA_DESTADDR_REG(dma_tx.channel) = HR_I2S_TX;
  63. DMA_CTRL_REG(dma_tx.channel) = DMA_CTRL_SRC_ADDR_INC | DMA_CTRL_DATA_SIZE_WORD | DMA_CTRL_BURST_SIZE1;
  64. DMA_MODE_REG(dma_tx.channel) = DMA_MODE_SEL_I2S_TX | DMA_MODE_HARD_MODE;
  65. DMA_CTRL_REG(dma_tx.channel) &= ~0xFFFF00;
  66. return 0;
  67. }
  68. static int tls_i2s_io_init(void){
  69. wm_i2s_ck_config(WM_IO_PB_08);
  70. wm_i2s_ws_config(WM_IO_PB_09);
  71. wm_i2s_di_config(WM_IO_PB_10);
  72. wm_i2s_do_config(WM_IO_PB_11);
  73. wm_i2s_extclk_config(WM_IO_PA_07);
  74. LLOGD("ck--PB08, ws--PB09, di--PB10, do--PB11, mclk--PA07");
  75. return WM_SUCCESS;
  76. }
  77. int luat_i2s_setup(luat_i2s_conf_t *conf) {
  78. if (I2s_tx_dma_init()){
  79. return -1;
  80. }
  81. tls_i2s_io_init();
  82. // 然后转本地i2s配置
  83. I2S_InitDef opts = { I2S_MODE_MASTER, I2S_CTRL_STEREO, I2S_RIGHT_CHANNEL, I2S_Standard, I2S_DataFormat_16, 8000, 5000000 };
  84. uint8_t stereo = 1;
  85. opts.I2S_Mode_MS = I2S_MODE_MASTER;
  86. opts.I2S_Mode_SS = (stereo<<22);
  87. opts.I2S_Mode_LR = conf->channel_format==0?I2S_LEFT_CHANNEL : I2S_RIGHT_CHANNEL;
  88. opts.I2S_Trans_STD = (conf->communication_format*0x1000000);
  89. opts.I2S_DataFormat = (conf->bits_per_sample/8 - 1)*0x10;
  90. opts.I2S_AudioFreq = conf->sample_rate;
  91. opts.I2S_MclkFreq = conf->mclk;
  92. wm_i2s_port_init(&opts);
  93. // wm_i2s_register_callback(NULL);
  94. run_status = 0;
  95. return 0;
  96. }
  97. int luat_i2s_send(uint8_t id, char* buff, size_t len) {
  98. int ret;
  99. if (buff == NULL) {
  100. return -1;
  101. }
  102. if (len == 0) {
  103. return 0;
  104. }
  105. OS_BufferWrite(&dma_tx_buf, buff, len);
  106. if ((run_status & CODEC_RUNING) == 0) {
  107. run_status |= CODEC_RUNING;
  108. ret = I2s_tx_send();
  109. if(ret == -1){
  110. printf("fifo empty for send\n");
  111. run_status &= ~CODEC_RUNING;
  112. }
  113. }
  114. return len;
  115. }
  116. int luat_i2s_recv(uint8_t id, char* buff, size_t len) {
  117. wm_i2s_rx_int((int16_t *)buff, len / 2);
  118. return len;
  119. }
  120. int luat_i2s_resume(uint8_t id) {
  121. wm_i2s_tx_enable(1);
  122. return 0;
  123. }
  124. int luat_i2s_stop(uint8_t id) {
  125. wm_i2s_tx_enable(0);
  126. run_status = 0;
  127. return 0;
  128. }
  129. int luat_i2s_close(uint8_t id) {
  130. luat_i2s_stop(id);
  131. if(dma_tx.channel){
  132. tls_dma_free(dma_tx.channel);
  133. }
  134. if (dma_tx_buf.Data){
  135. OS_DeInitBuffer(&dma_tx_buf);
  136. }
  137. return 0;
  138. }