22
22
23
23
#include " ../AutoAnalogAudio.h"
24
24
#include < hal/nrf_pdm.h>
25
-
26
- // #define USE_I2s
27
-
28
- #if defined USE_I2s
29
- #include < hal/nrf_i2s.h>
30
- #endif
25
+ #include < hal/nrf_i2s.h>
31
26
32
27
#if !defined __MBED__
33
28
#define myPDM NRF_PDM0
55
50
/* ****************** USER DEFINES - Configure pins etc here *****************/
56
51
#define DEFAULT_PDM_GAIN 40
57
52
58
- /* I2s config */
59
- #define PIN_MCK 15 // (13)
60
- #define PIN_SCK 13 // (14)
61
- #define PIN_LRCK 14 // (15)
62
- #define PIN_SDOUT (5 ) // GPIO Pin numbers
53
+ /* I2s config */ // MAX98357A Breakout also needs SD pin set HIGH
54
+ #define PIN_MCK 2 // Not used with MAX98357A
55
+ #define PORT_MCK 0
56
+ #define PIN_SCK 3 // BCLK
57
+ #define PORT_SCK 0
58
+ #define PIN_LRCK 29 // LRCK
59
+ #define PORT_LRCK 0
60
+ #define PIN_SDOUT 5 // GPIO Pin numbers
61
+ #define PORT_SDOUT 0
63
62
64
63
/* PWM Config */
65
64
#define DEFAULT_PWM_PIN 5 // GPIO Pin number
@@ -105,7 +104,7 @@ AutoAnalog::AutoAnalog(){
105
104
106
105
}
107
106
108
- void AutoAnalog::begin (bool enADC, bool enDAC){
107
+ void AutoAnalog::begin (bool enADC, bool enDAC, uint8_t _useI2S ){
109
108
110
109
#if defined __MBED__
111
110
if (enADC){
@@ -238,7 +237,7 @@ void AutoAnalog::begin(bool enADC, bool enDAC){
238
237
239
238
240
239
if (enDAC){
241
- # if defined USE_I2s
240
+ if (_useI2S){
242
241
// Enable transmission
243
242
NRF_I2S->CONFIG .TXEN = (I2S_CONFIG_TXEN_TXEN_ENABLE << I2S_CONFIG_TXEN_TXEN_Pos);
244
243
@@ -255,8 +254,8 @@ void AutoAnalog::begin(bool enADC, bool enDAC){
255
254
NRF_I2S->CONFIG .MODE = I2S_CONFIG_MODE_MODE_MASTER << I2S_CONFIG_MODE_MODE_Pos;
256
255
257
256
NRF_I2S->CONFIG .SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_16BIT << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
258
- NRF_I2S->CONFIG .MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
259
- NRF_I2S->CONFIG .RATIO = I2S_CONFIG_RATIO_RATIO_256X << I2S_CONFIG_RATIO_RATIO_Pos;
257
+ NRF_I2S->CONFIG .MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
258
+ NRF_I2S->CONFIG .RATIO = I2S_CONFIG_RATIO_RATIO_128X << I2S_CONFIG_RATIO_RATIO_Pos;
260
259
NRF_I2S->CONFIG .ALIGN = I2S_CONFIG_ALIGN_ALIGN_LEFT << I2S_CONFIG_ALIGN_ALIGN_Pos;
261
260
262
261
// Format = I2S
@@ -266,20 +265,17 @@ void AutoAnalog::begin(bool enADC, bool enDAC){
266
265
NRF_I2S->CONFIG .CHANNELS = I2S_CONFIG_CHANNELS_CHANNELS_LEFT << I2S_CONFIG_CHANNELS_CHANNELS_Pos;
267
266
268
267
// Configure pins
269
- NRF_I2S->PSEL .MCK = (PIN_MCK << I2S_PSEL_MCK_PIN_Pos);
270
- NRF_I2S->PSEL .SCK = (PIN_SCK << I2S_PSEL_SCK_PIN_Pos);
271
- NRF_I2S->PSEL .LRCK = (PIN_LRCK << I2S_PSEL_LRCK_PIN_Pos);
272
- NRF_I2S->PSEL .SDOUT = (PIN_SDOUT << I2S_PSEL_SDOUT_PIN_Pos);
273
- /* NRF_I2S->PSEL.MCK = (PIN_MCK << I2S_PSEL_MCK_PIN_Pos) | (I2S_PSEL_MCK_CONNECT_Connected << I2S_PSEL_MCK_CONNECT_Pos);
274
- NRF_I2S->PSEL.SCK = (PIN_SCK << I2S_PSEL_SCK_PIN_Pos) | (I2S_PSEL_SCK_CONNECT_Connected << I2S_PSEL_SCK_CONNECT_Pos);
275
- NRF_I2S->PSEL.LRCK = (PIN_LRCK << I2S_PSEL_LRCK_PIN_Pos) | (I2S_PSEL_LRCK_CONNECT_Connected << I2S_PSEL_LRCK_CONNECT_Pos);
276
- NRF_I2S->PSEL.SDOUT = (PIN_SDOUT << I2S_PSEL_SDOUT_PIN_Pos) | (I2S_PSEL_SDOUT_CONNECT_Connected << I2S_PSEL_SDOUT_CONNECT_Pos);*/
268
+ NRF_I2S->PSEL .MCK = (PIN_MCK << I2S_PSEL_MCK_PIN_Pos) | (I2S_PSEL_MCK_CONNECT_Connected << I2S_PSEL_MCK_CONNECT_Pos) | (PORT_MCK << I2S_PSEL_MCK_PORT_Pos);
269
+ NRF_I2S->PSEL .SCK = (PIN_SCK << I2S_PSEL_SCK_PIN_Pos) | (I2S_PSEL_SCK_CONNECT_Connected << I2S_PSEL_SCK_CONNECT_Pos) | (PORT_SCK << I2S_PSEL_SCK_PORT_Pos);
270
+ NRF_I2S->PSEL .LRCK = (PIN_LRCK << I2S_PSEL_LRCK_PIN_Pos) | (I2S_PSEL_LRCK_CONNECT_Connected << I2S_PSEL_LRCK_CONNECT_Pos) | (PORT_LRCK << I2S_PSEL_LRCK_PORT_Pos);
271
+ NRF_I2S->PSEL .SDOUT = (PIN_SDOUT << I2S_PSEL_SDOUT_PIN_Pos) | (I2S_PSEL_SDOUT_CONNECT_Connected << I2S_PSEL_LRCK_CONNECT_Pos) | (PORT_SDOUT << I2S_PSEL_SDOUT_PORT_Pos);
272
+
277
273
278
274
// NRF_I2S->INTENSET = I2S_INTEN_TXPTRUPD_Enabled << I2S_INTEN_TXPTRUPD_Pos;
279
275
// NVIC_EnableIRQ(I2S_IRQn);
280
276
281
277
// Configure data pointer
282
- NRF_I2S->TXD .PTR = (uint32_t )dacBuf0;
278
+ NRF_I2S->TXD .PTR = (uint32_t )& dacBuf0[ 0 ] ;
283
279
NRF_I2S->RXD .PTR = (uint32_t )dacBuf1;
284
280
NRF_I2S->RXTXD .MAXCNT = 16 ;// / sizeof(uint32_t);
285
281
@@ -289,9 +285,9 @@ void AutoAnalog::begin(bool enADC, bool enDAC){
289
285
// NRF_I2S->TXD.PTR = (uint32_t)&sine_table[0];
290
286
// NRF_I2S->RXTXD.MAXCNT = sizeof(sine_table) / sizeof(uint32_t);
291
287
NRF_I2S->ENABLE = 1 ;
292
- // Start transmitting I2S data
293
288
NRF_I2S->TASKS_START = 1 ;
294
- #else
289
+ useI2S = _useI2S;
290
+ }else {
295
291
296
292
NRF_PWM0->PSEL .OUT [0 ] = (DEFAULT_PWM_PIN << PWM_PSEL_OUT_PIN_Pos) | (PWM_PSEL_OUT_CONNECT_Connected << PWM_PSEL_OUT_CONNECT_Pos | DEFAULT_PWM_PORT << PWM_PSEL_OUT_PORT_Pos);
297
293
#if defined DEFAULT_PWM_PIN2
@@ -311,7 +307,7 @@ void AutoAnalog::begin(bool enADC, bool enDAC){
311
307
// NRF_PWM0->INTENSET = PWM_INTENSET_SEQEND0_Enabled << PWM_INTENSET_SEQEND0_Pos;
312
308
// NVIC_EnableIRQ(PWM0_IRQn);
313
309
NRF_PWM0->TASKS_SEQSTART [0 ] = 1 ;
314
- # endif // USE_I2s
310
+ }
315
311
}
316
312
317
313
@@ -322,14 +318,48 @@ void AutoAnalog::begin(bool enADC, bool enDAC){
322
318
323
319
void AutoAnalog::setSampleRate (uint32_t sampRate, bool stereo){
324
320
325
- NRF_PWM0->TASKS_STOP = 1 ;
326
- uint32_t timer = millis ();
327
- while (NRF_PWM0->EVENTS_STOPPED == 0 ){ if (millis () - timer > 1000 ){break ;} }
328
-
329
- NRF_PWM0->COUNTERTOP = (((uint16_t )((16000000 /sampRate))) << PWM_COUNTERTOP_COUNTERTOP_Pos);
330
- NRF_PWM0->TASKS_SEQSTART [0 ] = 1 ;
331
-
321
+ if (!useI2S){
322
+ NRF_PWM0->TASKS_STOP = 1 ;
323
+ uint32_t timer = millis ();
324
+ while (NRF_PWM0->EVENTS_STOPPED == 0 ){ if (millis () - timer > 1000 ){break ;} }
332
325
326
+ NRF_PWM0->COUNTERTOP = (((uint16_t )((16000000 /sampRate))) << PWM_COUNTERTOP_COUNTERTOP_Pos);
327
+ NRF_PWM0->TASKS_SEQSTART [0 ] = 1 ;
328
+ }else {
329
+ // Stop transmitting I2S data
330
+ NRF_I2S->TASKS_STOP = 1 ;
331
+ NRF_I2S->ENABLE = 0 ;
332
+
333
+ /* if(dacBitsPerSample == 8){
334
+ NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_8BIT << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
335
+ }else
336
+ if(dacBitsPerSample == 16){
337
+ NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_16BIT << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
338
+ }else
339
+ if(dacBitsPerSample == 24){
340
+ NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_24BIT << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
341
+ } */
342
+
343
+ if (sampRate <= 16000 ){
344
+ NRF_I2S->CONFIG .MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
345
+ NRF_I2S->CONFIG .RATIO = I2S_CONFIG_RATIO_RATIO_128X << I2S_CONFIG_RATIO_RATIO_Pos;
346
+ }else
347
+ if (sampRate <= 20000 ){
348
+ NRF_I2S->CONFIG .MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
349
+ NRF_I2S->CONFIG .RATIO = I2S_CONFIG_RATIO_RATIO_256X << I2S_CONFIG_RATIO_RATIO_Pos;
350
+ }else
351
+ if (sampRate <= 32000 ){
352
+ NRF_I2S->CONFIG .MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
353
+ NRF_I2S->CONFIG .RATIO = I2S_CONFIG_RATIO_RATIO_64X << I2S_CONFIG_RATIO_RATIO_Pos;
354
+ }else
355
+ if (sampRate <= 44000 ){
356
+ NRF_I2S->CONFIG .MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
357
+ NRF_I2S->CONFIG .RATIO = I2S_CONFIG_RATIO_RATIO_32X << I2S_CONFIG_RATIO_RATIO_Pos;
358
+ }
359
+ NRF_I2S->ENABLE = 1 ;
360
+ NRF_I2S->TASKS_START = 1 ;
361
+ }
362
+
333
363
if (sampRate <= 16000 ){
334
364
// Set default 16khz sample rate
335
365
NRF_PDM->RATIO = ((PDM_RATIO_RATIO_Ratio80 << PDM_RATIO_RATIO_Pos) & PDM_RATIO_RATIO_Msk);
@@ -347,15 +377,15 @@ void AutoAnalog::setSampleRate(uint32_t sampRate, bool stereo){
347
377
nrf_pdm_clock_set (myPDM,NRF_PDM_FREQ_1280K);
348
378
#endif
349
379
}else
350
- if (sampRate <= 31250 ){
380
+ if (sampRate <= 32000 ){
351
381
NRF_PDM->RATIO = ((PDM_RATIO_RATIO_Ratio64 << PDM_RATIO_RATIO_Pos) & PDM_RATIO_RATIO_Msk);
352
382
#if defined __MBED__
353
383
nrf_pdm_clock_set (NRF_PDM_FREQ_2000K); // 2667 / 64 = 33.337khz, /80 = 41.667
354
384
#else
355
385
nrf_pdm_clock_set (myPDM, NRF_PDM_FREQ_2000K); // 2667 / 64 = 33.337khz, /80 = 41.667
356
386
#endif
357
387
}else
358
- if (sampRate <= 41672 ){
388
+ if (sampRate <= 44000 ){ // 41.67khz
359
389
NRF_PDM->RATIO = ((PDM_RATIO_RATIO_Ratio64 << PDM_RATIO_RATIO_Pos) & PDM_RATIO_RATIO_Msk);
360
390
#if defined __MBED__
361
391
nrf_pdm_clock_set (NRF_PDM_FREQ_2667K);
@@ -409,53 +439,41 @@ bool whichBuf = 0;
409
439
410
440
void AutoAnalog::feedDAC (uint8_t dacChannel, uint32_t samples, bool startInterrupts){
411
441
412
- # if defined USE_I2s
442
+ if (useI2S){
413
443
uint32_t ctr = millis ();
414
444
// while(!nrf_i2s_event_check(NRF_I2S,NRF_I2S_EVENT_TXPTRUPD));//{ if(millis() - ctr > 5){break;}};
415
445
416
446
417
447
418
-
419
448
while (NRF_I2S->EVENTS_TXPTRUPD == 0 ){}
420
- NRF_I2S->EVENTS_TXPTRUPD = 0 ;
421
449
450
+
422
451
if (dacBitsPerSample == 8 ){
423
- // memcpy(dacBuf0,dacBuffer, samples);
424
- for (uint32_t i=0 ; i<samples; i++){
425
- dacBuf0[i] = dacBuffer[i] << 8 ;
452
+ for (uint32_t i=0 ; i< samples; i++){
453
+ dacBuf0[i] = dacBuffer[i] << 7 ;
426
454
}
427
- NRF_I2S->TXD .PTR = (uint32_t )dacBuf0;
428
- }else {
429
- if (whichBuf == 0 ){
430
- for (uint32_t i=0 ; i<samples; i++){
431
- dacBuf0[i] = dacBuffer16[i];
432
- }
433
- NRF_I2S->TXD .PTR = (uint32_t )dacBuf0;
434
- }else {
435
- for (uint32_t i=0 ; i<samples; i++){
436
- dacBuf1[i] = dacBuffer16[i];
437
- }
438
- NRF_I2S->TXD .PTR = (uint32_t )dacBuf1;
439
- }
440
- whichBuf = !whichBuf;
455
+ NRF_I2S->TXD .PTR = (uint32_t )&dacBuf0[0 ];
456
+ }else
457
+ if (dacBitsPerSample == 16 ){
458
+ memcpy (dacBuf0,dacBuffer16,samples * 2 );
459
+ NRF_I2S->TXD .PTR = (uint32_t )&dacBuf0[0 ];
441
460
}
442
- // memcpy(dacBuf0, dacBuffer16, samples * 2);
443
-
444
- // NRF_I2S->TXD.PTR = (uint32_t)&dacBuf0[0];
445
- // memcpy(&dacBuf[0], &dacBuffer16[0], samples);
446
- uint32_t bytes = samples;
447
-
461
+
462
+ uint8_t divider = 2 ;
448
463
if (dacBitsPerSample == 16 ){
449
- bytes *= 2 ;
464
+ divider = 2 ;
465
+ }else
466
+ if (dacBitsPerSample == 24 ){
467
+ divider = 1 ;
450
468
}
451
469
452
- NRF_I2S->RXTXD .MAXCNT = samples / sizeof ( uint32_t ) ;
453
- // nrf_i2s_event_clear( NRF_I2S,NRF_I2S_EVENT_TXPTRUPD) ;
454
-
455
- # else
456
- uint32_t timer = millis ();
470
+ NRF_I2S->RXTXD .MAXCNT = samples / divider ;
471
+ NRF_I2S-> EVENTS_TXPTRUPD = 0 ;
472
+
473
+ } else {
474
+ uint32_t timer = millis () + 1000 ;
457
475
while (NRF_PWM0->EVENTS_SEQEND [0 ] == 0 ){
458
- if (millis () - timer > 1000 ){ NRF_PWM0->TASKS_SEQSTART [0 ] = 1 ; return ; }
476
+ if (millis () > timer ){ NRF_PWM0->TASKS_SEQSTART [0 ] = 1 ; return ; }
459
477
}
460
478
NRF_PWM0->EVENTS_SEQEND [0 ] = 0 ;
461
479
@@ -469,7 +487,7 @@ void AutoAnalog::feedDAC(uint8_t dacChannel, uint32_t samples, bool startInterru
469
487
NRF_PWM0->SEQ [0 ].PTR = ((uint32_t )(&dacBuf0[0 ]) << PWM_SEQ_PTR_PTR_Pos);
470
488
NRF_PWM0->SEQ [0 ].CNT = (samples << PWM_SEQ_CNT_CNT_Pos);
471
489
NRF_PWM0->TASKS_SEQSTART [0 ] = 1 ;
472
- # endif // USE_I2s
490
+ }
473
491
474
492
}
475
493
0 commit comments