3 #include "AudioConfig.h"
5 #if defined(USE_NANO33BLE)
7 #include "AudioI2S/I2SConfig.h"
8 #include "AudioTools/AudioLogger.h"
9 #include "AudioTools/AudioTypes.h"
10 #include "AudioTools/Buffers.h"
14 static int i2s_buffer_size = 0;
15 static BaseBuffer<uint8_t> *p_i2s_buffer =
nullptr;
16 static uint8_t *p_i2s_array =
nullptr;
17 static uint8_t *p_i2s_array_1 =
nullptr;
18 static uint8_t *p_i2s_array_2 =
nullptr;
19 static uint32_t i2s_underflow_count = 0;
21 static Stream *p_nano_ble_stream =
nullptr;
32 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8, 32.0 / 8},
33 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV10, 32 / 10},
34 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11, 32.0 / 11},
35 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV15, 32.0 / 15},
36 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16, 32.0 / 16},
37 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21, 32.0 / 21},
38 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23, 32.0 / 23},
39 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV30, 32.0 / 30},
40 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31, 32.0 / 31},
41 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV32, 32.0 / 32},
42 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV42, 32.0 / 42},
43 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV63, 32.0 / 63},
44 {I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV125, 32.0 / 125}};
55 {I2S_CONFIG_RATIO_RATIO_32X, 32.0}, {I2S_CONFIG_RATIO_RATIO_48X, 48.0},
56 {I2S_CONFIG_RATIO_RATIO_64X, 64.0}, {I2S_CONFIG_RATIO_RATIO_96X, 96.0},
57 {I2S_CONFIG_RATIO_RATIO_128X, 128.0}, {I2S_CONFIG_RATIO_RATIO_192X, 192.0},
58 {I2S_CONFIG_RATIO_RATIO_256X, 256.0}, {I2S_CONFIG_RATIO_RATIO_384X, 384.0},
59 {I2S_CONFIG_RATIO_RATIO_512X, 512.0}};
61 void I2S_IRQWrite(
void) {
63 if (NRF_I2S->EVENTS_TXPTRUPD == 1) {
67 p_i2s_array = p_i2s_array == p_i2s_array_1 ? p_i2s_array_2 : p_i2s_array_1;
69 if (p_nano_ble_stream !=
nullptr) {
71 eff_read = p_nano_ble_stream->readBytes(p_i2s_array, i2s_buffer_size);
74 eff_read = p_i2s_buffer->
readArray(p_i2s_array, i2s_buffer_size);
77 if (eff_read < i2s_buffer_size) {
78 memset(p_i2s_array, 0, i2s_buffer_size);
80 i2s_underflow_count++;
82 NRF_I2S->TXD.PTR = (uint32_t)p_i2s_array;
83 NRF_I2S->EVENTS_TXPTRUPD = 0;
87 void I2S_IRQRead(
void) {
89 if (NRF_I2S->EVENTS_RXPTRUPD == 1) {
93 p_i2s_array = p_i2s_array == p_i2s_array_1 ? p_i2s_array_2 : p_i2s_array_1;
94 NRF_I2S->RXD.PTR = (uint32_t)p_i2s_array;
95 NRF_I2S->EVENTS_RXPTRUPD = 0;
104 if (p_i2s_buffer ==
nullptr || p_i2s_array == 0) {
105 NRF_I2S->EVENTS_TXPTRUPD = 0;
106 NRF_I2S->EVENTS_RXPTRUPD = 0;
147 LOGE(
"32 bits not supported");
152 LOGE(
"out of memory");
158 NVIC_EnableIRQ(I2S_IRQn);
169 if (cfg.
rx_tx_mode == RX_MODE || p_nano_ble_stream !=
nullptr) {
181 int availableForWrite() {
190 NRF_I2S->TASKS_START = 0;
204 size_t result = p_i2s_buffer->
writeArray((uint8_t *)src, size_bytes);
207 if (!is_active && result < size_bytes) {
215 size_t result = p_i2s_buffer->
readArray((uint8_t *)dest, size_bytes);
225 void setBufferSize(
int size) { i2s_buffer_size = size; }
229 bool is_active =
false;
237 NRF_I2S->CONFIG.TXEN =
238 (I2S_CONFIG_TXEN_TXEN_Enabled << I2S_CONFIG_TXEN_TXEN_Pos);
242 NRF_I2S->CONFIG.RXEN =
243 (I2S_CONFIG_RXEN_RXEN_Enabled << I2S_CONFIG_RXEN_RXEN_Pos);
246 LOGE(
"rx_tx_mode not supported");
257 NRF_I2S->CONFIG.MCKEN =
258 (I2S_CONFIG_MCKEN_MCKEN_Enabled << I2S_CONFIG_MCKEN_MCKEN_Pos);
263 float selected_freq = 0;
264 for (
auto freq : freq_table) {
265 for (
auto div : ratio_table) {
266 float freq_value = freq.freq * 1000000 / div.ratio;
267 if (abs(freq_value - freq_requested) <
268 abs(selected_freq - freq_requested)) {
270 NRF_I2S->CONFIG.MCKFREQ = freq.id << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
272 NRF_I2S->CONFIG.RATIO = div.id << I2S_CONFIG_RATIO_RATIO_Pos;
273 selected_freq = freq_value;
274 LOGD(
"frequency requested %f vs %f", freq_requested, selected_freq);
278 LOGI(
"Frequency req. %f vs eff. %f", freq_requested, selected_freq);
284 uint16_t swidth = I2S_CONFIG_SWIDTH_SWIDTH_16Bit;
287 NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_8Bit
288 << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
291 NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_16Bit
292 << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
295 NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_24Bit
296 << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
307 switch (cfg.i2s_format) {
309 case I2S_PHILIPS_FORMAT:
311 case I2S_LEFT_JUSTIFIED_FORMAT:
312 NRF_I2S->CONFIG.FORMAT = I2S_CONFIG_FORMAT_FORMAT_I2S
313 << I2S_CONFIG_FORMAT_FORMAT_Pos;
314 NRF_I2S->CONFIG.ALIGN = I2S_CONFIG_ALIGN_ALIGN_Left
315 << I2S_CONFIG_ALIGN_ALIGN_Pos;
319 case I2S_RIGHT_JUSTIFIED_FORMAT:
320 NRF_I2S->CONFIG.FORMAT = I2S_CONFIG_FORMAT_FORMAT_I2S
321 << I2S_CONFIG_FORMAT_FORMAT_Pos;
322 NRF_I2S->CONFIG.ALIGN = I2S_CONFIG_ALIGN_ALIGN_Right
323 << I2S_CONFIG_ALIGN_ALIGN_Pos;
327 LOGW(
"i2s_format not supported");
333 #if defined(USE_ALT_PIN_SUPPORT)
334 return cfg.is_arduino_pin_numbers ? digitalPinToPinName(pin) : pin;
336 return digitalPinToPinName(pin);
345 if (cfg.is_master && cfg.pin_mck >= 0) {
346 NRF_I2S->PSEL.MCK =
getPinName(cfg.pin_mck) << I2S_PSEL_MCK_PIN_Pos;
349 NRF_I2S->PSEL.SCK =
getPinName(cfg.pin_bck) << I2S_PSEL_SCK_PIN_Pos;
351 NRF_I2S->PSEL.LRCK =
getPinName(cfg.pin_ws) << I2S_PSEL_LRCK_PIN_Pos;
355 NRF_I2S->PSEL.SDOUT =
getPinName(cfg.pin_data)
356 << I2S_PSEL_SDOUT_PIN_Pos;
359 NRF_I2S->PSEL.SDIN =
getPinName(cfg.pin_data) << I2S_PSEL_SDIN_PIN_Pos;
368 unsigned long result = 0;
369 switch (cfg.rx_tx_mode) {
371 result = I2S_INTENSET_TXPTRUPD_Enabled << I2S_INTENSET_TXPTRUPD_Pos;
374 result = I2S_INTENSET_RXPTRUPD_Enabled << I2S_INTENSET_RXPTRUPD_Pos;
386 NRF_I2S->CONFIG.CHANNELS = I2S_CONFIG_CHANNELS_CHANNELS_Stereo
387 << I2S_CONFIG_CHANNELS_CHANNELS_Pos;
389 NRF_I2S->CONFIG.MODE =
390 cfg.is_master ? I2S_CONFIG_MODE_MODE_MASTER << I2S_CONFIG_MODE_MODE_Pos
391 : I2S_CONFIG_MODE_MODE_Slave << I2S_CONFIG_MODE_MODE_Pos;
394 NRF_I2S->TXD.PTR = (uint32_t)p_i2s_array;
395 NRF_I2S->RXD.PTR = (uint32_t)p_i2s_array;
397 NRF_I2S->RXTXD.MAXCNT = i2s_buffer_size / 4;
404 NRF_I2S->TASKS_START = 1;
412 i2s_buffer_size = cfg.buffer_size;
414 if (p_i2s_array ==
nullptr) {
415 p_i2s_array_1 =
new uint8_t[i2s_buffer_size]{0};
416 p_i2s_array_2 =
new uint8_t[i2s_buffer_size]{0};
417 p_i2s_array = p_i2s_array_1;
419 memset(p_i2s_array_1, 0, i2s_buffer_size);
420 memset(p_i2s_array_2, 0, i2s_buffer_size);
424 if (p_i2s_buffer ==
nullptr && p_nano_ble_stream ==
nullptr) {
429 if (p_nano_ble_stream !=
nullptr) {
430 return p_i2s_array_1 !=
nullptr && p_i2s_array_2 !=
nullptr;
432 return p_i2s_array_1 !=
nullptr && p_i2s_array_2 !=
nullptr &&
433 p_i2s_buffer !=
nullptr;
441 p_i2s_array =
nullptr;
442 delete p_i2s_array_1;
443 p_i2s_array_1 =
nullptr;
444 delete p_i2s_array_2;
445 p_i2s_array_2 =
nullptr;
448 p_i2s_buffer =
nullptr;
452 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:26