Mercurial > hg > beaglert
comparison core/PRU.cpp @ 41:4255ecbb9bec ultra-staging
Timers to measure performances, ultra experimental
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Tue, 19 May 2015 16:41:07 +0100 |
parents | a9af130097e8 |
children | 3068421c0737 |
comparison
equal
deleted
inserted
replaced
40:419ce4ebfc4c | 41:4255ecbb9bec |
---|---|
18 #include "../include/pruss_intc_mapping.h" | 18 #include "../include/pruss_intc_mapping.h" |
19 #include "../include/digital_gpio_mapping.h" | 19 #include "../include/digital_gpio_mapping.h" |
20 #include "../include/GPIOcontrol.h" | 20 #include "../include/GPIOcontrol.h" |
21 #include "../include/render.h" | 21 #include "../include/render.h" |
22 #include "../include/pru_rtaudio_bin.h" | 22 #include "../include/pru_rtaudio_bin.h" |
23 #include "../include/intervals.h" | |
23 | 24 |
24 #include <iostream> | 25 #include <iostream> |
25 #include <stdlib.h> | 26 #include <stdlib.h> |
26 #include <cstdio> | 27 #include <cstdio> |
27 #include <cerrno> | 28 #include <cerrno> |
97 | 98 |
98 const unsigned int PRU::kPruGPIOTestPin = 60; // GPIO1(28); P9-12 | 99 const unsigned int PRU::kPruGPIOTestPin = 60; // GPIO1(28); P9-12 |
99 const unsigned int PRU::kPruGPIOTestPin2 = 31; // GPIO0(31); P9-13 | 100 const unsigned int PRU::kPruGPIOTestPin2 = 31; // GPIO0(31); P9-13 |
100 const unsigned int PRU::kPruGPIOTestPin3 = 26; // GPIO0(26); P8-14 | 101 const unsigned int PRU::kPruGPIOTestPin3 = 26; // GPIO0(26); P8-14 |
101 | 102 |
102 extern int gShouldStop; | 103 //extern int gShouldStop; |
103 extern int gRTAudioVerbose; | 104 extern int gRTAudioVerbose; |
105 extern PRU *gPRU; | |
104 | 106 |
105 // Constructor: specify a PRU number (0 or 1) | 107 // Constructor: specify a PRU number (0 or 1) |
106 PRU::PRU() | 108 PRU::PRU() |
107 : pru_number(0), running(false), spi_enabled(false), gpio_enabled(false), led_enabled(false), | 109 : renderTimer(100,0,44100.0,"renderTimer"), sleepTimer(100,0,44100.0,"sleepTimer"), |
110 pru_number(0), running(false), spi_enabled(false), gpio_enabled(false), led_enabled(false), | |
108 gpio_test_pin_enabled(false), spi_num_channels(0), xenomai_gpio_fd(-1), xenomai_gpio(0) | 111 gpio_test_pin_enabled(false), spi_num_channels(0), xenomai_gpio_fd(-1), xenomai_gpio(0) |
109 { | 112 { |
110 | 113 |
111 } | 114 } |
112 | 115 |
433 // Polling interval is 1/4 of the period | 436 // Polling interval is 1/4 of the period |
434 RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * (spi_num_channels / 2) * spi_buffer_frames / 4; | 437 RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * (spi_num_channels / 2) * spi_buffer_frames / 4; |
435 float *audioInBuffer, *audioOutBuffer; | 438 float *audioInBuffer, *audioOutBuffer; |
436 float *analogInBuffer, *analogOutBuffer, *lastAnalogOutFrame; | 439 float *analogInBuffer, *analogOutBuffer, *lastAnalogOutFrame; |
437 uint32_t *digitalBuffer0, *digitalBuffer1, *lastDigitalBuffer; | 440 uint32_t *digitalBuffer0, *digitalBuffer1, *lastDigitalBuffer; |
438 | |
439 audioInBuffer = (float *)malloc(2 * audio_buffer_frames * sizeof(float)); | 441 audioInBuffer = (float *)malloc(2 * audio_buffer_frames * sizeof(float)); |
440 audioOutBuffer = (float *)malloc(2 * audio_buffer_frames * sizeof(float)); | 442 audioOutBuffer = (float *)malloc(2 * audio_buffer_frames * sizeof(float)); |
441 analogInBuffer = (float *)malloc(spi_num_channels * spi_buffer_frames * sizeof(float)); | 443 analogInBuffer = (float *)malloc(spi_num_channels * spi_buffer_frames * sizeof(float)); |
442 analogOutBuffer = (float *)malloc(spi_num_channels * spi_buffer_frames * sizeof(float)); | 444 analogOutBuffer = (float *)malloc(spi_num_channels * spi_buffer_frames * sizeof(float)); |
443 lastAnalogOutFrame = (float *)malloc(spi_num_channels * sizeof(float)); | 445 lastAnalogOutFrame = (float *)malloc(spi_num_channels * sizeof(float)); |
445 digitalBuffer1 = pru_buffer_digital+MEM_DIGITAL_BUFFER1_OFFSET/sizeof(uint32_t); | 447 digitalBuffer1 = pru_buffer_digital+MEM_DIGITAL_BUFFER1_OFFSET/sizeof(uint32_t); |
446 digital_buffer_frames = digital_enabled ? audio_buffer_frames : 0; //TODO: find a more elegant solution for when the digital is disabled e.g.: | 448 digital_buffer_frames = digital_enabled ? audio_buffer_frames : 0; //TODO: find a more elegant solution for when the digital is disabled e.g.: |
447 // - embed in the digitalWrite/Read macros a check whether digital is enabled | 449 // - embed in the digitalWrite/Read macros a check whether digital is enabled |
448 // - allocate some memory in ARM just to allow render() to run regardless. | 450 // - allocate some memory in ARM just to allow render() to run regardless. |
449 // in this case it can be digitalBuffer0 == digitalBuffer1 | 451 // in this case it can be digitalBuffer0 == digitalBuffer1 |
450 printf("digital_buffer_frames: %d;\n",digital_buffer_frames); | |
451 lastDigitalBuffer = (uint32_t *)malloc(digital_buffer_frames*sizeof(uint32_t)); //temp buffer to hold previous states | 452 lastDigitalBuffer = (uint32_t *)malloc(digital_buffer_frames*sizeof(uint32_t)); //temp buffer to hold previous states |
452 if(audioInBuffer == 0 || audioOutBuffer == 0) { | 453 if(audioInBuffer == 0 || audioOutBuffer == 0) { |
453 rt_printf("Error: couldn't allocate audio buffers\n"); | 454 rt_printf("Error: couldn't allocate audio buffers\n"); |
454 return; | 455 return; |
455 } | 456 } |
460 if(lastDigitalBuffer == 0) { | 461 if(lastDigitalBuffer == 0) { |
461 rt_printf("Error: couldn't allocate digital buffers\n"); | 462 rt_printf("Error: couldn't allocate digital buffers\n"); |
462 return; | 463 return; |
463 } | 464 } |
464 | 465 |
465 for(unsigned int n=0; n<digital_buffer_frames; n++){ //initialize lastDigitalFrames to all inputs | 466 if(digital_enabled){ |
466 lastDigitalBuffer[n]= 0x0000ffff; | 467 for(unsigned int n=0; n<digital_buffer_frames; n++){ //initialize lastDigitalFrames to all inputs |
467 } | 468 lastDigitalBuffer[n]= 0x0000ffff; |
469 } | |
470 } | |
471 int count=0; | |
472 sleepTimer.setNumFrames(audio_buffer_frames); | |
473 renderTimer.setNumFrames(audio_buffer_frames); | |
468 while(!gShouldStop) { | 474 while(!gShouldStop) { |
469 // Wait for PRU to move to buffer 1 | 475 // Wait for PRU to move to buffer 1 |
476 sleepTimer.start(); | |
470 while(pru_buffer_comm[PRU_CURRENT_BUFFER] == 0 && !gShouldStop) { | 477 while(pru_buffer_comm[PRU_CURRENT_BUFFER] == 0 && !gShouldStop) { |
471 rt_task_sleep(sleepTime); | 478 rt_task_sleep(sleepTime); |
472 } | 479 } |
480 sleepTimer.split(); | |
481 | |
473 if(gShouldStop) | 482 if(gShouldStop) |
474 break; | 483 break; |
475 | 484 renderTimer.start(); |
476 if(xenomai_gpio != 0) { | 485 if(xenomai_gpio != 0) { |
477 // Set the test pin high | 486 // Set the test pin high |
478 xenomai_gpio[GPIO_SETDATAOUT] = TEST_PIN_MASK; | 487 xenomai_gpio[GPIO_SETDATAOUT] = TEST_PIN_MASK; |
479 } | 488 } |
480 | 489 |
487 for(unsigned int n = 0; n < spi_num_channels * spi_buffer_frames; n++) | 496 for(unsigned int n = 0; n < spi_num_channels * spi_buffer_frames; n++) |
488 analogInBuffer[n] = (float)pru_buffer_spi_adc[n] / 65536.0; | 497 analogInBuffer[n] = (float)pru_buffer_spi_adc[n] / 65536.0; |
489 //initialize the output buffer with the values that were in the last frame of the previous output | 498 //initialize the output buffer with the values that were in the last frame of the previous output |
490 for(int n = 0; n < spi_num_channels; n++){ | 499 for(int n = 0; n < spi_num_channels; n++){ |
491 for(unsigned int j = 0; j < spi_buffer_frames; j++){ | 500 for(unsigned int j = 0; j < spi_buffer_frames; j++){ |
492 analogOutBuffer[j*spi_buffer_frames + n] = lastAnalogOutFrame[n]; | 501 analogOutBuffer[j*spi_num_channels + n] = lastAnalogOutFrame[n]; |
493 } | 502 } |
494 } | 503 } |
504 | |
495 //use past digital values to initialize the array properly. | 505 //use past digital values to initialize the array properly. |
496 //For each frame: | 506 //For each frame: |
497 //- pins previously set as outputs will keep the output value they had in the last frame of the previous buffer, | 507 //- pins previously set as outputs will keep the output value they had in the last frame of the previous buffer, |
498 //- pins previously set as inputs will carry the newly read input value | 508 //- pins previously set as inputs will carry the newly read input value |
499 if(digital_enabled){ | 509 if(digital_enabled){ |
537 | 547 |
538 if(xenomai_gpio != 0) { | 548 if(xenomai_gpio != 0) { |
539 // Set the test pin high | 549 // Set the test pin high |
540 xenomai_gpio[GPIO_CLEARDATAOUT] = TEST_PIN_MASK; | 550 xenomai_gpio[GPIO_CLEARDATAOUT] = TEST_PIN_MASK; |
541 } | 551 } |
542 | 552 renderTimer.split(); |
543 // Wait for PRU to move to buffer 0 | 553 // Wait for PRU to move to buffer 0 |
554 sleepTimer.start(); | |
544 while(pru_buffer_comm[PRU_CURRENT_BUFFER] != 0 && !gShouldStop) { | 555 while(pru_buffer_comm[PRU_CURRENT_BUFFER] != 0 && !gShouldStop) { |
545 rt_task_sleep(sleepTime); | 556 rt_task_sleep(sleepTime); |
546 } | 557 } |
547 | 558 sleepTimer.split(); |
548 if(gShouldStop) | 559 if(gShouldStop) |
549 break; | 560 break; |
550 | 561 |
562 renderTimer.start(); | |
551 if(xenomai_gpio != 0) { | 563 if(xenomai_gpio != 0) { |
552 // Set the test pin high | 564 // Set the test pin high |
553 xenomai_gpio[GPIO_SETDATAOUT] = TEST_PIN_MASK; | 565 xenomai_gpio[GPIO_SETDATAOUT] = TEST_PIN_MASK; |
554 } | 566 } |
555 | 567 |
565 analogInBuffer[n] = (float)pru_buffer_spi_adc[n + spi_buffer_frames * spi_num_channels] / 65536.0; | 577 analogInBuffer[n] = (float)pru_buffer_spi_adc[n + spi_buffer_frames * spi_num_channels] / 65536.0; |
566 } | 578 } |
567 //initialize the output buffer with the values that were in the last frame of the previous output | 579 //initialize the output buffer with the values that were in the last frame of the previous output |
568 for(int n = 0; n < spi_num_channels; n++){ | 580 for(int n = 0; n < spi_num_channels; n++){ |
569 for(unsigned int j = 0; j < spi_buffer_frames; j++){ | 581 for(unsigned int j = 0; j < spi_buffer_frames; j++){ |
570 analogOutBuffer[j*spi_buffer_frames + n] = lastAnalogOutFrame[n]; | 582 analogOutBuffer[j*spi_num_channels + n] = lastAnalogOutFrame[n]; |
571 } | 583 } |
572 } | 584 } |
573 if(digital_enabled){ | 585 if(digital_enabled){ |
574 for(unsigned int n = 0; n < digital_buffer_frames; n++){ | 586 for(unsigned int n = 0; n < digital_buffer_frames; n++){ |
575 uint16_t inputs=lastDigitalBuffer[n]&0xffff;//half-word, has 1 for inputs and 0 for outputs | 587 uint16_t inputs=lastDigitalBuffer[n]&0xffff;//half-word, has 1 for inputs and 0 for outputs |
612 | 624 |
613 if(xenomai_gpio != 0) { | 625 if(xenomai_gpio != 0) { |
614 // Set the test pin high | 626 // Set the test pin high |
615 xenomai_gpio[GPIO_CLEARDATAOUT] = TEST_PIN_MASK; | 627 xenomai_gpio[GPIO_CLEARDATAOUT] = TEST_PIN_MASK; |
616 } | 628 } |
629 renderTimer.split(); | |
630 count+=audio_buffer_frames; | |
631 if((count&32767)==0){ | |
632 scheduleAuxiliaryTask(gPRU->printIntervalsTask); | |
633 } | |
617 } | 634 } |
618 | 635 |
619 // Tell PRU to stop | 636 // Tell PRU to stop |
620 pru_buffer_comm[PRU_SHOULD_STOP] = 1; | 637 pru_buffer_comm[PRU_SHOULD_STOP] = 1; |
621 | |
622 free(analogOutBuffer); | 638 free(analogOutBuffer); |
639 free(analogInBuffer); | |
640 free(audioOutBuffer); | |
623 free(audioInBuffer); | 641 free(audioInBuffer); |
624 free(audioOutBuffer); | |
625 free(analogInBuffer); | |
626 free(lastAnalogOutFrame); | 642 free(lastAnalogOutFrame); |
627 free(lastDigitalBuffer); | 643 free(lastDigitalBuffer); |
628 } | 644 } |
629 | 645 |
630 // Wait for an interrupt from the PRU indicate it is finished | 646 // Wait for an interrupt from the PRU indicate it is finished |