i2s_hal.c
1 // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // The HAL layer for I2S (common part) 16 17 #include "soc/soc.h" 18 #include "hal/i2s_hal.h" 19 20 #define I2S_TX_PDM_FP_DEF 960 // Set to the recommended value(960) in TRM 21 #define I2S_RX_PDM_DSR_DEF 0 22 23 void i2s_hal_set_tx_mode(i2s_hal_context_t *hal, i2s_channel_t ch, i2s_bits_per_sample_t bits) 24 { 25 if (bits <= I2S_BITS_PER_SAMPLE_16BIT) { 26 i2s_ll_set_tx_fifo_mod(hal->dev, (ch == I2S_CHANNEL_STEREO) ? 0 : 1); 27 } else { 28 i2s_ll_set_tx_fifo_mod(hal->dev, (ch == I2S_CHANNEL_STEREO) ? 2 : 3); 29 } 30 i2s_ll_set_tx_chan_mod(hal->dev, (ch == I2S_CHANNEL_STEREO) ? 0 : 1); 31 #if SOC_I2S_SUPPORTS_DMA_EQUAL 32 i2s_ll_set_tx_dma_equal(hal->dev, (ch == I2S_CHANNEL_STEREO) ? 0 : 1); 33 #endif 34 } 35 36 void i2s_hal_set_rx_mode(i2s_hal_context_t *hal, i2s_channel_t ch, i2s_bits_per_sample_t bits) 37 { 38 if (bits <= I2S_BITS_PER_SAMPLE_16BIT) { 39 i2s_ll_set_rx_fifo_mod(hal->dev, (ch == I2S_CHANNEL_STEREO) ? 0 : 1); 40 } else { 41 i2s_ll_set_rx_fifo_mod(hal->dev, (ch == I2S_CHANNEL_STEREO) ? 2 : 3); 42 } 43 i2s_ll_set_rx_chan_mod(hal->dev, (ch == I2S_CHANNEL_STEREO) ? 0 : 1); 44 #if SOC_I2S_SUPPORTS_DMA_EQUAL 45 i2s_ll_set_rx_dma_equal(hal->dev, (ch == I2S_CHANNEL_STEREO) ? 0 : 1); 46 #endif 47 } 48 49 void i2s_hal_set_in_link(i2s_hal_context_t *hal, uint32_t bytes_num, uint32_t addr) 50 { 51 i2s_ll_set_in_link_addr(hal->dev, addr); 52 i2s_ll_set_rx_eof_num(hal->dev, bytes_num); 53 } 54 55 #if SOC_I2S_SUPPORTS_PDM 56 void i2s_hal_tx_pdm_cfg(i2s_hal_context_t *hal, uint32_t fp, uint32_t fs) 57 { 58 i2s_ll_tx_pdm_cfg(hal->dev, fp, fs); 59 } 60 61 void i2s_hal_get_tx_pdm(i2s_hal_context_t *hal, uint32_t *fp, uint32_t *fs) 62 { 63 i2s_ll_get_tx_pdm(hal->dev, fp, fs); 64 } 65 66 void i2s_hal_rx_pdm_cfg(i2s_hal_context_t *hal, uint32_t dsr) 67 { 68 i2s_ll_rx_pdm_cfg(hal->dev, dsr); 69 } 70 71 void i2s_hal_get_rx_pdm(i2s_hal_context_t *hal, uint32_t *dsr) 72 { 73 i2s_ll_get_rx_pdm(hal->dev, dsr); 74 } 75 #endif 76 77 void i2s_hal_set_clk_div(i2s_hal_context_t *hal, int div_num, int div_a, int div_b, int tx_bck_div, int rx_bck_div) 78 { 79 i2s_ll_set_clkm_div_num(hal->dev, div_num); 80 i2s_ll_set_clkm_div_a(hal->dev, div_a); 81 i2s_ll_set_clkm_div_b(hal->dev, div_b); 82 i2s_ll_set_tx_bck_div_num(hal->dev, tx_bck_div); 83 i2s_ll_set_rx_bck_div_num(hal->dev, rx_bck_div); 84 } 85 86 void i2s_hal_set_tx_bits_mod(i2s_hal_context_t *hal, i2s_bits_per_sample_t bits) 87 { 88 i2s_ll_set_tx_bits_mod(hal->dev, bits); 89 } 90 91 void i2s_hal_set_rx_bits_mod(i2s_hal_context_t *hal, i2s_bits_per_sample_t bits) 92 { 93 i2s_ll_set_rx_bits_mod(hal->dev, bits); 94 } 95 96 void i2s_hal_reset(i2s_hal_context_t *hal) 97 { 98 // Reset I2S TX/RX module first, and then, reset DMA and FIFO. 99 i2s_ll_reset_tx(hal->dev); 100 i2s_ll_reset_rx(hal->dev); 101 i2s_ll_reset_dma_in(hal->dev); 102 i2s_ll_reset_dma_out(hal->dev); 103 i2s_ll_reset_rx_fifo(hal->dev); 104 i2s_ll_reset_tx_fifo(hal->dev); 105 } 106 107 void i2s_hal_start_tx(i2s_hal_context_t *hal) 108 { 109 i2s_ll_start_out_link(hal->dev); 110 i2s_ll_start_tx(hal->dev); 111 } 112 113 void i2s_hal_start_rx(i2s_hal_context_t *hal) 114 { 115 i2s_ll_start_in_link(hal->dev); 116 i2s_ll_start_rx(hal->dev); 117 } 118 119 void i2s_hal_stop_tx(i2s_hal_context_t *hal) 120 { 121 i2s_ll_stop_out_link(hal->dev); 122 i2s_ll_stop_tx(hal->dev); 123 } 124 125 void i2s_hal_stop_rx(i2s_hal_context_t *hal) 126 { 127 i2s_ll_stop_in_link(hal->dev); 128 i2s_ll_stop_rx(hal->dev); 129 } 130 131 void i2s_hal_format_config(i2s_hal_context_t *hal, const i2s_config_t *i2s_config) 132 { 133 switch (i2s_config->communication_format) { 134 case I2S_COMM_FORMAT_STAND_MSB: 135 if (i2s_config->mode & I2S_MODE_TX) { 136 i2s_ll_set_tx_format_msb_align(hal->dev); 137 } 138 if (i2s_config->mode & I2S_MODE_RX) { 139 i2s_ll_set_rx_format_msb_align(hal->dev); 140 } 141 break; 142 case I2S_COMM_FORMAT_STAND_PCM_SHORT: 143 if (i2s_config->mode & I2S_MODE_TX) { 144 i2s_ll_set_tx_pcm_long(hal->dev); 145 } 146 if (i2s_config->mode & I2S_MODE_RX) { 147 i2s_ll_set_rx_pcm_long(hal->dev); 148 } 149 break; 150 case I2S_COMM_FORMAT_STAND_PCM_LONG: 151 if (i2s_config->mode & I2S_MODE_TX) { 152 i2s_ll_set_tx_pcm_short(hal->dev); 153 } 154 if (i2s_config->mode & I2S_MODE_RX) { 155 i2s_ll_set_rx_pcm_short(hal->dev); 156 } 157 break; 158 default: //I2S_COMM_FORMAT_STAND_I2S 159 if (i2s_config->mode & I2S_MODE_TX) { 160 i2s_ll_set_tx_format_philip(hal->dev); 161 } 162 if (i2s_config->mode & I2S_MODE_RX) { 163 i2s_ll_set_rx_format_philip(hal->dev); 164 } 165 break; 166 } 167 } 168 169 void i2s_hal_config_param(i2s_hal_context_t *hal, const i2s_config_t *i2s_config) 170 { 171 //reset i2s 172 i2s_ll_reset_tx(hal->dev); 173 i2s_ll_reset_rx(hal->dev); 174 175 //reset dma 176 i2s_ll_reset_dma_in(hal->dev); 177 i2s_ll_reset_dma_out(hal->dev); 178 179 i2s_ll_enable_dma(hal->dev); 180 181 i2s_ll_set_lcd_en(hal->dev, 0); 182 i2s_ll_set_camera_en(hal->dev, 0); 183 184 i2s_ll_set_dscr_en(hal->dev, 0); 185 186 i2s_ll_set_tx_chan_mod(hal->dev, i2s_config->channel_format < I2S_CHANNEL_FMT_ONLY_RIGHT ? i2s_config->channel_format : (i2s_config->channel_format >> 1)); // 0-two channel;1-right;2-left;3-righ;4-left 187 i2s_ll_set_tx_fifo_mod(hal->dev, i2s_config->channel_format < I2S_CHANNEL_FMT_ONLY_RIGHT ? 0 : 1); // 0-right&left channel;1-one channel 188 i2s_ll_set_tx_mono(hal->dev, 0); 189 190 i2s_ll_set_rx_chan_mod(hal->dev, i2s_config->channel_format < I2S_CHANNEL_FMT_ONLY_RIGHT ? i2s_config->channel_format : (i2s_config->channel_format >> 1)); // 0-two channel;1-right;2-left;3-righ;4-left 191 i2s_ll_set_rx_fifo_mod(hal->dev, i2s_config->channel_format < I2S_CHANNEL_FMT_ONLY_RIGHT ? 0 : 1); // 0-right&left channel;1-one channel 192 i2s_ll_set_rx_mono(hal->dev, 0); 193 194 i2s_ll_set_dscr_en(hal->dev, 1); //connect dma to fifo 195 196 i2s_ll_stop_tx(hal->dev); 197 i2s_ll_stop_rx(hal->dev); 198 199 if (i2s_config->mode & I2S_MODE_TX) { 200 i2s_ll_set_tx_msb_right(hal->dev, 0); 201 i2s_ll_set_tx_right_first(hal->dev, 0); 202 203 i2s_ll_set_tx_slave_mod(hal->dev, 0); // Master 204 i2s_ll_set_tx_fifo_mod_force_en(hal->dev, 1); 205 206 if (i2s_config->mode & I2S_MODE_SLAVE) { 207 i2s_ll_set_tx_slave_mod(hal->dev, 1); //TX Slave 208 } 209 } 210 211 if (i2s_config->mode & I2S_MODE_RX) { 212 i2s_ll_set_rx_msb_right(hal->dev, 0); 213 i2s_ll_set_rx_right_first(hal->dev, 0); 214 i2s_ll_set_rx_slave_mod(hal->dev, 0); // Master 215 i2s_ll_set_rx_fifo_mod_force_en(hal->dev, 1); 216 217 if (i2s_config->mode & I2S_MODE_SLAVE) { 218 i2s_ll_set_rx_slave_mod(hal->dev, 1); //RX Slave 219 } 220 } 221 222 #if SOC_I2S_SUPPORTS_PDM 223 if (!(i2s_config->mode & I2S_MODE_PDM)) { 224 i2s_ll_set_rx_pdm_en(hal->dev, 0); 225 i2s_ll_set_tx_pdm_en(hal->dev, 0); 226 } else { 227 if (i2s_config->mode & I2S_MODE_TX) { 228 i2s_ll_tx_pdm_cfg(hal->dev, I2S_TX_PDM_FP_DEF, i2s_config->sample_rate/100); 229 } 230 if(i2s_config->mode & I2S_MODE_RX) { 231 i2s_ll_rx_pdm_cfg(hal->dev, I2S_RX_PDM_DSR_DEF); 232 } 233 // PDM mode have nothing to do with communication format configuration. 234 return; 235 } 236 #endif 237 238 #if SOC_I2S_SUPPORTS_ADC_DAC 239 if (i2s_config->mode & (I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN)) { 240 if (i2s_config->mode & I2S_MODE_DAC_BUILT_IN) { 241 i2s_ll_build_in_dac_ena(hal->dev); 242 } 243 if (i2s_config->mode & I2S_MODE_ADC_BUILT_IN) { 244 i2s_ll_build_in_adc_ena(hal->dev); 245 i2s_ll_set_rx_chan_mod(hal->dev, 1); 246 i2s_ll_set_rx_fifo_mod(hal->dev, 1); 247 i2s_ll_set_rx_mono(hal->dev, 0); 248 } 249 // Buildin ADC and DAC have nothing to do with communication format configuration. 250 return; 251 } 252 #endif 253 254 i2s_hal_format_config(hal, i2s_config); 255 } 256 257 void i2s_hal_enable_master_mode(i2s_hal_context_t *hal) 258 { 259 i2s_ll_set_tx_slave_mod(hal->dev, 0); //MASTER Slave 260 i2s_ll_set_rx_slave_mod(hal->dev, 1); //RX Slave 261 } 262 263 void i2s_hal_enable_slave_mode(i2s_hal_context_t *hal) 264 { 265 i2s_ll_set_tx_slave_mod(hal->dev, 1); //TX Slave 266 i2s_ll_set_rx_slave_mod(hal->dev, 1); //RX Slave 267 } 268 269 void i2s_hal_init(i2s_hal_context_t *hal, int i2s_num) 270 { 271 //Get hardware instance. 272 hal->dev = I2S_LL_GET_HW(i2s_num); 273 }