3 #include "AudioConfig.h"
5 #if defined(USE_NANO33BLE)
7 #include "AudioTools/CoreAudio/AudioI2S/I2SConfig.h"
8 #include "AudioTools/CoreAudio/AudioLogger.h"
9 #include "AudioTools/CoreAudio/AudioTypes.h"
10 #include "AudioTools/CoreAudio/Buffers.h"
12 #define IS_I2S_IMPLEMENTED
16 static int i2s_buffer_size = 0;
17 static BaseBuffer<uint8_t> *p_i2s_buffer =
nullptr;
18 static uint8_t *p_i2s_array =
nullptr;
19 static uint8_t *p_i2s_array_1 =
nullptr;
20 static uint8_t *p_i2s_array_2 =
nullptr;
21 static uint32_t i2s_underflow_count = 0;
23 static Stream *p_nano_ble_stream =
nullptr;
34 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8, 32.0 / 8},
35 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV10, 32 / 10},
36 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11, 32.0 / 11},
37 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV15, 32.0 / 15},
38 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16, 32.0 / 16},
39 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21, 32.0 / 21},
40 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23, 32.0 / 23},
41 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV30, 32.0 / 30},
42 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31, 32.0 / 31},
43 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV32, 32.0 / 32},
44 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV42, 32.0 / 42},
45 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV63, 32.0 / 63},
46 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV125, 32.0 / 125}};
57 {I2S_CONFIG_RATIO_RATIO_32X, 32.0}, {I2S_CONFIG_RATIO_RATIO_48X, 48.0},
58 {I2S_CONFIG_RATIO_RATIO_64X, 64.0}, {I2S_CONFIG_RATIO_RATIO_96X, 96.0},
59 {I2S_CONFIG_RATIO_RATIO_128X, 128.0}, {I2S_CONFIG_RATIO_RATIO_192X, 192.0},
60 {I2S_CONFIG_RATIO_RATIO_256X, 256.0}, {I2S_CONFIG_RATIO_RATIO_384X, 384.0},
61 {I2S_CONFIG_RATIO_RATIO_512X, 512.0}};
63 void I2S_IRQWrite(
void) {
65 if (NRF_I2S->EVENTS_TXPTRUPD == 1) {
69 p_i2s_array = p_i2s_array == p_i2s_array_1 ? p_i2s_array_2 : p_i2s_array_1;
71 if (p_nano_ble_stream !=
nullptr) {
73 eff_read = p_nano_ble_stream->readBytes(p_i2s_array, i2s_buffer_size);
76 eff_read = p_i2s_buffer->
readArray(p_i2s_array, i2s_buffer_size);
79 if (eff_read < i2s_buffer_size) {
80 memset(p_i2s_array, 0, i2s_buffer_size);
82 i2s_underflow_count++;
84 NRF_I2S->TXD.PTR = (uint32_t)p_i2s_array;
85 NRF_I2S->EVENTS_TXPTRUPD = 0;
89 void I2S_IRQRead(
void) {
91 if (NRF_I2S->EVENTS_RXPTRUPD == 1) {
95 p_i2s_array = p_i2s_array == p_i2s_array_1 ? p_i2s_array_2 : p_i2s_array_1;
96 NRF_I2S->RXD.PTR = (uint32_t)p_i2s_array;
97 NRF_I2S->EVENTS_RXPTRUPD = 0;
106 if (p_i2s_buffer ==
nullptr || p_i2s_array == 0) {
107 NRF_I2S->EVENTS_TXPTRUPD = 0;
108 NRF_I2S->EVENTS_RXPTRUPD = 0;
149 LOGE(
"32 bits not supported");
154 LOGE(
"out of memory");
160 NVIC_EnableIRQ(I2S_IRQn);
171 if (cfg.
rx_tx_mode == RX_MODE || p_nano_ble_stream !=
nullptr) {
183 int availableForWrite() {
192 NRF_I2S->TASKS_START = 0;
206 size_t result = p_i2s_buffer->
writeArray((uint8_t *)src, size_bytes);
209 if (!is_active && result < size_bytes) {
217 size_t result = p_i2s_buffer->
readArray((uint8_t *)dest, size_bytes);
227 void setBufferSize(
int size) { i2s_buffer_size = size; }
231 bool is_active =
false;
239 NRF_I2S->CONFIG.TXEN =
240 (I2S_CONFIG_TXEN_TXEN_Enabled << I2S_CONFIG_TXEN_TXEN_Pos);
244 NRF_I2S->CONFIG.RXEN =
245 (I2S_CONFIG_RXEN_RXEN_Enabled << I2S_CONFIG_RXEN_RXEN_Pos);
248 LOGE(
"rx_tx_mode not supported");
259 NRF_I2S->CONFIG.MCKEN =
260 (I2S_CONFIG_MCKEN_MCKEN_Enabled << I2S_CONFIG_MCKEN_MCKEN_Pos);
265 float selected_freq = 0;
266 for (
auto freq : freq_table) {
267 for (
auto div : ratio_table) {
268 float freq_value = freq.freq * 1000000 / div.ratio;
269 if (abs(freq_value - freq_requested) <
270 abs(selected_freq - freq_requested)) {
272 NRF_I2S->CONFIG.MCKFREQ = freq.id << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
274 NRF_I2S->CONFIG.RATIO = div.id << I2S_CONFIG_RATIO_RATIO_Pos;
275 selected_freq = freq_value;
276 LOGD(
"frequency requested %f vs %f", freq_requested, selected_freq);
280 LOGI(
"Frequency req. %f vs eff. %f", freq_requested, selected_freq);
286 uint16_t swidth = I2S_CONFIG_SWIDTH_SWIDTH_16Bit;
289 NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_8Bit
290 << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
293 NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_16Bit
294 << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
297 NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_24Bit
298 << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
309 switch (cfg.i2s_format) {
311 case I2S_PHILIPS_FORMAT:
313 case I2S_LEFT_JUSTIFIED_FORMAT:
314 NRF_I2S->CONFIG.FORMAT = I2S_CONFIG_FORMAT_FORMAT_I2S
315 << I2S_CONFIG_FORMAT_FORMAT_Pos;
316 NRF_I2S->CONFIG.ALIGN = I2S_CONFIG_ALIGN_ALIGN_Left
317 << I2S_CONFIG_ALIGN_ALIGN_Pos;
321 case I2S_RIGHT_JUSTIFIED_FORMAT:
322 NRF_I2S->CONFIG.FORMAT = I2S_CONFIG_FORMAT_FORMAT_I2S
323 << I2S_CONFIG_FORMAT_FORMAT_Pos;
324 NRF_I2S->CONFIG.ALIGN = I2S_CONFIG_ALIGN_ALIGN_Right
325 << I2S_CONFIG_ALIGN_ALIGN_Pos;
329 LOGW(
"i2s_format not supported");
333 int digitalPinToPinName(
int pin) {
return pin;}
337 #if defined(USE_ALT_PIN_SUPPORT)
338 return cfg.is_arduino_pin_numbers ? digitalPinToPinName(pin) : pin;
340 return digitalPinToPinName(pin);
349 if (cfg.is_master && cfg.pin_mck >= 0) {
350 NRF_I2S->PSEL.MCK =
getPinName(cfg.pin_mck) << I2S_PSEL_MCK_PIN_Pos;
353 NRF_I2S->PSEL.SCK =
getPinName(cfg.pin_bck) << I2S_PSEL_SCK_PIN_Pos;
355 NRF_I2S->PSEL.LRCK =
getPinName(cfg.pin_ws) << I2S_PSEL_LRCK_PIN_Pos;
359 NRF_I2S->PSEL.SDOUT =
getPinName(cfg.pin_data)
360 << I2S_PSEL_SDOUT_PIN_Pos;
363 NRF_I2S->PSEL.SDIN =
getPinName(cfg.pin_data) << I2S_PSEL_SDIN_PIN_Pos;
372 unsigned long result = 0;
373 switch (cfg.rx_tx_mode) {
375 result = I2S_INTENSET_TXPTRUPD_Enabled << I2S_INTENSET_TXPTRUPD_Pos;
378 result = I2S_INTENSET_RXPTRUPD_Enabled << I2S_INTENSET_RXPTRUPD_Pos;
390 NRF_I2S->CONFIG.CHANNELS = I2S_CONFIG_CHANNELS_CHANNELS_Stereo
391 << I2S_CONFIG_CHANNELS_CHANNELS_Pos;
393 NRF_I2S->CONFIG.MODE =
394 cfg.is_master ? I2S_CONFIG_MODE_MODE_MASTER << I2S_CONFIG_MODE_MODE_Pos
395 : I2S_CONFIG_MODE_MODE_Slave << I2S_CONFIG_MODE_MODE_Pos;
398 NRF_I2S->TXD.PTR = (uint32_t)p_i2s_array;
399 NRF_I2S->RXD.PTR = (uint32_t)p_i2s_array;
401 NRF_I2S->RXTXD.MAXCNT = i2s_buffer_size / 4;
408 NRF_I2S->TASKS_START = 1;
416 i2s_buffer_size = cfg.buffer_size;
418 if (p_i2s_array ==
nullptr) {
419 p_i2s_array_1 =
new uint8_t[i2s_buffer_size]{0};
420 p_i2s_array_2 =
new uint8_t[i2s_buffer_size]{0};
421 p_i2s_array = p_i2s_array_1;
423 memset(p_i2s_array_1, 0, i2s_buffer_size);
424 memset(p_i2s_array_2, 0, i2s_buffer_size);
428 if (p_i2s_buffer ==
nullptr && p_nano_ble_stream ==
nullptr) {
433 if (p_nano_ble_stream !=
nullptr) {
434 return p_i2s_array_1 !=
nullptr && p_i2s_array_2 !=
nullptr;
436 return p_i2s_array_1 !=
nullptr && p_i2s_array_2 !=
nullptr &&
437 p_i2s_buffer !=
nullptr;
445 p_i2s_array =
nullptr;
446 delete p_i2s_array_1;
447 p_i2s_array_1 =
nullptr;
448 delete p_i2s_array_2;
449 p_i2s_array_2 =
nullptr;
452 p_i2s_buffer =
nullptr;
456 using I2SDriver = I2SDriverNanoBLE;
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition: AudioTypes.h:28