comparison core/PRU.cpp @ 528:5c8f46fcd4d0 API-update

Updated BelaContext to use separate values for in/ou channels
author Giulio Moro <giuliomoro@yahoo.it>
date Thu, 23 Jun 2016 18:17:35 +0100
parents 3a28a4eb948d
children
comparison
equal deleted inserted replaced
527:1c68ad13bbe4 528:5c8f46fcd4d0
332 if(analog_enabled) { 332 if(analog_enabled) {
333 prussdrv_map_prumem (pru_number == 0 ? PRUSS0_PRU0_DATARAM : PRUSS0_PRU1_DATARAM, (void **)&pruMem); 333 prussdrv_map_prumem (pru_number == 0 ? PRUSS0_PRU0_DATARAM : PRUSS0_PRU1_DATARAM, (void **)&pruMem);
334 pru_buffer_spi_dac = (uint16_t *)&pruMem[PRU_MEM_DAC_OFFSET/sizeof(uint32_t)]; 334 pru_buffer_spi_dac = (uint16_t *)&pruMem[PRU_MEM_DAC_OFFSET/sizeof(uint32_t)];
335 335
336 /* ADC memory starts after N(ch)*2(buffers)*bufsize samples */ 336 /* ADC memory starts after N(ch)*2(buffers)*bufsize samples */
337 pru_buffer_spi_adc = &pru_buffer_spi_dac[2 * context->analogChannels * context->analogFrames]; 337 pru_buffer_spi_adc = &pru_buffer_spi_dac[2 * context->analogInChannels * context->analogFrames];
338 } 338 }
339 else { 339 else {
340 pru_buffer_spi_dac = pru_buffer_spi_adc = 0; 340 pru_buffer_spi_dac = pru_buffer_spi_adc = 0;
341 } 341 }
342 342
374 pru_buffer_comm[PRU_LED_ADDRESS] = 0; 374 pru_buffer_comm[PRU_LED_ADDRESS] = 0;
375 pru_buffer_comm[PRU_LED_PIN_MASK] = 0; 375 pru_buffer_comm[PRU_LED_PIN_MASK] = 0;
376 } 376 }
377 if(analog_enabled) { 377 if(analog_enabled) {
378 pru_buffer_comm[PRU_USE_SPI] = 1; 378 pru_buffer_comm[PRU_USE_SPI] = 1;
379 pru_buffer_comm[PRU_SPI_NUM_CHANNELS] = context->analogChannels; 379 if(context->analogInChannels != context->analogOutChannels){
380 printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n");
381 return 1;
382 }
383 unsigned int analogChannels = context->analogInChannels;
384 pru_buffer_comm[PRU_SPI_NUM_CHANNELS] = analogChannels;
380 } 385 }
381 else { 386 else {
382 pru_buffer_comm[PRU_USE_SPI] = 0; 387 pru_buffer_comm[PRU_USE_SPI] = 0;
383 pru_buffer_comm[PRU_SPI_NUM_CHANNELS] = 0; 388 pru_buffer_comm[PRU_SPI_NUM_CHANNELS] = 0;
384 } 389 }
458 if(last_analog_out_frame == 0) { 463 if(last_analog_out_frame == 0) {
459 rt_printf("Error: couldn't allocate analog persistence buffer\n"); 464 rt_printf("Error: couldn't allocate analog persistence buffer\n");
460 return 1; 465 return 1;
461 } 466 }
462 #else 467 #else
463 context->analogIn = (float *)malloc(context->analogChannels * context->analogFrames * sizeof(float)); 468 context->analogIn = (float *)malloc(context->analogInChannels * context->analogFrames * sizeof(float));
464 context->analogOut = (float *)malloc(context->analogChannels * context->analogFrames * sizeof(float)); 469 context->analogOut = (float *)malloc(context->analogOutChannels * context->analogFrames * sizeof(float));
465 last_analog_out_frame = (float *)malloc(context->analogChannels * sizeof(float)); 470 last_analog_out_frame = (float *)malloc(context->analogOutChannels * sizeof(float));
466 471
467 if(context->analogIn == 0 || context->analogOut == 0 || last_analog_out_frame == 0) { 472 if(context->analogIn == 0 || context->analogOut == 0 || last_analog_out_frame == 0) {
468 rt_printf("Error: couldn't allocate analog buffers\n"); 473 rt_printf("Error: couldn't allocate analog buffers\n");
469 return 1; 474 return 1;
470 } 475 }
471 #endif 476 #endif
472 477
473 memset(last_analog_out_frame, 0, context->analogChannels * sizeof(float)); 478 memset(last_analog_out_frame, 0, context->analogOutChannels * sizeof(float));
474 } 479 }
475 480
476 // Allocate digital buffers 481 // Allocate digital buffers
477 digital_buffer0 = pru_buffer_digital; 482 digital_buffer0 = pru_buffer_digital;
478 digital_buffer1 = pru_buffer_digital + MEM_DIGITAL_BUFFER1_OFFSET / sizeof(uint32_t); 483 digital_buffer1 = pru_buffer_digital + MEM_DIGITAL_BUFFER1_OFFSET / sizeof(uint32_t);
526 { 531 {
527 #ifdef BELA_USE_XENOMAI_INTERRUPTS 532 #ifdef BELA_USE_XENOMAI_INTERRUPTS
528 RTIME irqTimeout = PRU_SAMPLE_INTERVAL_NS * 1024; // Timeout for PRU interrupt: about 10ms, much longer than any expected period 533 RTIME irqTimeout = PRU_SAMPLE_INTERVAL_NS * 1024; // Timeout for PRU interrupt: about 10ms, much longer than any expected period
529 #else 534 #else
530 // Polling interval is 1/4 of the period 535 // Polling interval is 1/4 of the period
531 RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * (context->analogChannels / 2) * context->analogFrames / 4; 536 if(context->analogInChannels != context->analogOutChannels){
537 printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n");
538 return;
539 }
540 unsigned int analogChannels = context->analogInChannels;
541 RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * (analogChannels / 2) * context->analogFrames / 4;
532 #endif 542 #endif
533 543
534 uint32_t pru_audio_offset, pru_spi_offset; 544 uint32_t pru_audio_offset, pru_spi_offset;
535 545
536 // Before starting, look at the last state of the analog and digital outputs which might 546 // Before starting, look at the last state of the analog and digital outputs which might
538 // directions and output values at something other than defaults. 548 // directions and output values at something other than defaults.
539 549
540 if(analog_enabled) { 550 if(analog_enabled) {
541 if(context->flags & BELA_FLAG_ANALOG_OUTPUTS_PERSIST) { 551 if(context->flags & BELA_FLAG_ANALOG_OUTPUTS_PERSIST) {
542 // Remember the content of the last_analog_out_frame 552 // Remember the content of the last_analog_out_frame
543 for(unsigned int ch = 0; ch < context->analogChannels; ch++){ 553 for(unsigned int ch = 0; ch < context->analogOutChannels; ch++){
544 last_analog_out_frame[ch] = context->analogOut[context->analogChannels * (context->analogFrames - 1) + ch]; 554 last_analog_out_frame[ch] = context->analogOut[context->analogOutChannels * (context->analogFrames - 1) + ch];
545 } 555 }
546 } 556 }
547 } 557 }
548 558
549 if(digital_enabled) { 559 if(digital_enabled) {
603 if(digital_enabled) 613 if(digital_enabled)
604 context->digital = digital_buffer0; 614 context->digital = digital_buffer0;
605 } 615 }
606 else { 616 else {
607 // PRU is on buffer 0. We read and write to buffer 1 617 // PRU is on buffer 0. We read and write to buffer 1
608 pru_audio_offset = context->audioFrames * 2; 618 if(context->audioInChannels != context->audioOutChannels){
609 pru_spi_offset = context->analogFrames * context->analogChannels; 619 printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n");
620 return;
621 }
622 unsigned int audioChannels = context->audioInChannels;
623 pru_audio_offset = context->audioFrames * audioChannels;
624 if(context->analogInChannels != context->analogOutChannels){
625 printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n");
626 return;
627 }
628 unsigned int analogChannels = context->analogInChannels;
629 pru_spi_offset = context->analogFrames * analogChannels;
610 if(digital_enabled) 630 if(digital_enabled)
611 context->digital = digital_buffer1; 631 context->digital = digital_buffer1;
612 } 632 }
613 633
614 // FIXME: some sort of margin is needed here to prevent the audio 634 // FIXME: some sort of margin is needed here to prevent the audio
642 662
643 #ifdef USE_NEON_FORMAT_CONVERSION 663 #ifdef USE_NEON_FORMAT_CONVERSION
644 int16_to_float_analog(context->analogChannels * context->analogFrames, 664 int16_to_float_analog(context->analogChannels * context->analogFrames,
645 &pru_buffer_spi_adc[pru_spi_offset], context->analogIn); 665 &pru_buffer_spi_adc[pru_spi_offset], context->analogIn);
646 #else 666 #else
647 for(unsigned int n = 0; n < context->analogChannels * context->analogFrames; n++) { 667 for(unsigned int n = 0; n < context->analogInChannels * context->analogFrames; n++) {
648 context->analogIn[n] = (float)pru_buffer_spi_adc[n + pru_spi_offset] / 65536.0f; 668 context->analogIn[n] = (float)pru_buffer_spi_adc[n + pru_spi_offset] / 65536.0f;
649 } 669 }
650 #endif 670 #endif
651 671
652 if(context->flags & BELA_FLAG_ANALOG_OUTPUTS_PERSIST) { 672 if(context->flags & BELA_FLAG_ANALOG_OUTPUTS_PERSIST) {
653 // Initialize the output buffer with the values that were in the last frame of the previous output 673 // Initialize the output buffer with the values that were in the last frame of the previous output
654 for(unsigned int ch = 0; ch < context->analogChannels; ch++){ 674 for(unsigned int ch = 0; ch < context->analogOutChannels; ch++){
655 for(unsigned int n = 0; n < context->analogFrames; n++){ 675 for(unsigned int n = 0; n < context->analogFrames; n++){
656 context->analogOut[n * context->analogChannels + ch] = last_analog_out_frame[ch]; 676 context->analogOut[n * context->analogOutChannels + ch] = last_analog_out_frame[ch];
657 } 677 }
658 } 678 }
659 } 679 }
660 else { 680 else {
661 // Outputs are 0 unless set otherwise 681 // Outputs are 0 unless set otherwise
662 memset(context->analogOut, 0, context->analogChannels * context->analogFrames * sizeof(float)); 682 memset(context->analogOut, 0, context->analogOutChannels * context->analogFrames * sizeof(float));
663 } 683 }
664 } 684 }
665 685
666 if(digital_enabled){ 686 if(digital_enabled){
667 // Use past digital values to initialize the array properly. 687 // Use past digital values to initialize the array properly.
686 // *********************** 706 // ***********************
687 707
688 if(analog_enabled) { 708 if(analog_enabled) {
689 if(context->flags & BELA_FLAG_ANALOG_OUTPUTS_PERSIST) { 709 if(context->flags & BELA_FLAG_ANALOG_OUTPUTS_PERSIST) {
690 // Remember the content of the last_analog_out_frame 710 // Remember the content of the last_analog_out_frame
691 for(unsigned int ch = 0; ch < context->analogChannels; ch++){ 711 for(unsigned int ch = 0; ch < context->analogOutChannels; ch++){
692 last_analog_out_frame[ch] = context->analogOut[context->analogChannels * (context->analogFrames - 1) + ch]; 712 last_analog_out_frame[ch] = context->analogOut[context->analogOutChannels * (context->analogFrames - 1) + ch];
693 } 713 }
694 } 714 }
695 715
696 // Convert float back to short for SPI output 716 // Convert float back to short for SPI output
697 #ifdef USE_NEON_FORMAT_CONVERSION 717 #ifdef USE_NEON_FORMAT_CONVERSION
698 float_to_int16_analog(context->analogChannels * context->analogFrames, 718 float_to_int16_analog(context->analogChannels * context->analogFrames,
699 context->analogOut, (uint16_t*)&pru_buffer_spi_dac[pru_spi_offset]); 719 context->analogOut, (uint16_t*)&pru_buffer_spi_dac[pru_spi_offset]);
700 #else 720 #else
701 for(unsigned int n = 0; n < context->analogChannels * context->analogFrames; n++) { 721 for(unsigned int n = 0; n < context->analogOutChannels * context->analogFrames; n++) {
702 int out = context->analogOut[n] * 65536.0f; 722 int out = context->analogOut[n] * 65536.0f;
703 if(out < 0) out = 0; 723 if(out < 0) out = 0;
704 else if(out > 65535) out = 65535; 724 else if(out > 65535) out = 65535;
705 pru_buffer_spi_dac[n + pru_spi_offset] = (uint16_t)out; 725 pru_buffer_spi_dac[n + pru_spi_offset] = (uint16_t)out;
706 } 726 }
715 735
716 // Convert float back to short for audio 736 // Convert float back to short for audio
717 #ifdef USE_NEON_FORMAT_CONVERSION 737 #ifdef USE_NEON_FORMAT_CONVERSION
718 float_to_int16_audio(2 * context->audioFrames, context->audioOut, &pru_buffer_audio_dac[pru_audio_offset]); 738 float_to_int16_audio(2 * context->audioFrames, context->audioOut, &pru_buffer_audio_dac[pru_audio_offset]);
719 #else 739 #else
720 for(unsigned int n = 0; n < 2 * context->audioFrames; n++) { 740 for(unsigned int n = 0; n < context->audioOutChannels * context->audioFrames; n++) {
721 int out = context->audioOut[n] * 32768.0f; 741 int out = context->audioOut[n] * 32768.0f;
722 if(out < -32768) out = -32768; 742 if(out < -32768) out = -32768;
723 else if(out > 32767) out = 32767; 743 else if(out > 32767) out = 32767;
724 pru_buffer_audio_dac[n + pru_audio_offset] = (int16_t)out; 744 pru_buffer_audio_dac[n + pru_audio_offset] = (int16_t)out;
725 } 745 }
733 xenomai_gpio[GPIO_CLEARDATAOUT] = TEST_PIN_MASK; 753 xenomai_gpio[GPIO_CLEARDATAOUT] = TEST_PIN_MASK;
734 } 754 }
735 755
736 Bela_autoScheduleAuxiliaryTasks(); 756 Bela_autoScheduleAuxiliaryTasks();
737 757
738 // FIXME: TESTING!!
739 // if(testCount > 100000)
740 // break;
741 } 758 }
742 759
743 #ifdef BELA_USE_XENOMAI_INTERRUPTS 760 #ifdef BELA_USE_XENOMAI_INTERRUPTS
744 // Turn off the interrupt for the PRU if it isn't already off 761 // Turn off the interrupt for the PRU if it isn't already off
745 rt_intr_disable(pru_interrupt); 762 rt_intr_disable(pru_interrupt);
746 #endif 763 #endif
747
748 // FIXME: TESTING
749 // RTIME endTime = rt_timer_read();
750 // RTIME diffTime = endTime - startTime;
751 // rt_printf("%d blocks elapsed in %f seconds, %f Hz block rate\n", testCount, ((float)diffTime / 1.0e9), (float)testCount / ((float)diffTime / 1.0e9));
752 764
753 // Tell PRU to stop 765 // Tell PRU to stop
754 pru_buffer_comm[PRU_SHOULD_STOP] = 1; 766 pru_buffer_comm[PRU_SHOULD_STOP] = 1;
755 767
756 // Wait two buffer lengths for the PRU to finish 768 // Wait two buffer lengths for the PRU to finish