Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 5045

General • Re: USB poll?

$
0
0
I am kind of surprised that the USB IRQ could interfere with an NMI interrupt since it has the highest priority. I guess the USB code running might throw your time sensitive interrupt handler code out of the XIP cache and that would make it run slower. Flagging your time sensitive code to all run out of RAM should fix that issue. I tend to run my time sensitive code out of RAM on the second core and allow the USB stack to do as it pleases with the first core and the XIP cache.
Unfortunatelly it is already on ram... Also, I've tried the two core option using a queue to comunicate between cores, but it also introduces delays... I expected that the NMI would have no timming variations because other subsystems but it does, I'm not an expert in ARM architecture but I suppose that whenever there is a context change depending on the processor status it has to do more or less work when it enters/leaves the interrupt. That or the interrupt risen by the PIO gets delayed somehow.

In case someone wants to see the code here it is, is a bit complex, is from a logic analyzer that I've been developing for some years now, it has a "burst mode" and what I'm trying to implement is the measurement of the time that happens between bursts. As the analyzer is capable of sampling 100Mhz signals I need that 5ns resolution...

Code:

;PIO program.program POSITIVE_CAPTURE_MEASUREBURSTS    pull    out y 32            ;read loop count    pull    mov x, osr                  ;read capture length (use MOV instead of PULL so we can MOV it again on each loop)    irq wait 1                  ;trigger NMI to sync first timestamp    .wrap_target    in pins 32        ;read sample    jmp pin POST_CAPTURE;exit wrap if pin is set.wrapPOST_CAPTURE:    in pins 32        ;read sample    jmp x-- POST_CAPTURE;loop if more samples needed    jmp y-- LOOP                ;jump to loop control    irq 1                       ;trigger NMI on the CPU to capture burst timestamp    irq 0                       ;notify to the main program that we have finished capturingLOCK:    jmp LOCK                    ;block the programLOOP:        irq 1                       ;trigger NMI on the CPU to capture burst timestamp    mov x, osr                  ;read loop countINNER_LOOP:    jmp pin POST_CAPTURE        ;wait for trigger    jmp INNER_LOOP

Code:

//Capture start and NMI/SysTick handlersvoid __not_in_flash_func(sysTickRoll)(){    systickLoops++;}void __not_in_flash_func(loopEndHandler)(){    //Save timestamp    loopTimestamp[timestampIndex++] = systick_hw->cvr | systickLoops << 24; //timestamp;        //Clear PIO interrupt    capturePIO->irq = (1u << 1);}bool startCaptureSimple(uint32_t freq, uint32_t preLength, uint32_t postLength, uint8_t loopCount, uint8_t measureBursts, const uint8_t* capturePins, uint8_t capturePinCount, uint8_t triggerPin, bool invertTrigger, CHANNEL_MODE captureMode){    int maxSamples;    switch(captureMode)    {        case MODE_8_CHANNEL:            maxSamples = 131072;            break;        case MODE_16_CHANNEL:            maxSamples = 65536;            break;        case MODE_24_CHANNEL:            maxSamples = 32768;            break;    }    //Too many samples requested?    if(preLength + (postLength * (loopCount + 1)) >= maxSamples)        return false;    //Frequency too high?    if(freq > 100000000)        return false;    //Incorrect pin count?    if(capturePinCount < 0 || capturePinCount > 24)        return false;    //Incorrect trigger pin?    if(triggerPin < 0 || triggerPin > 24)        return false;    //Clear capture buffer (to avoid sending bad data if the trigger happens before the presamples are filled)    memset(captureBuffer, 0, sizeof(captureBuffer));    //Store info about the capture    lastPreSize = preLength;    lastPostSize = postLength;    lastLoopCount = loopCount;    lastCapturePinCount = capturePinCount;    lastTriggerInverted = invertTrigger;    lastCaptureComplexFast = false;    lastCaptureMode = captureMode;    //Map channels to pins    for(uint8_t i = 0; i < capturePinCount; i++)        lastCapturePins[i] = pinMap[capturePins[i]];    //Store trigger info    triggerPin = pinMap[triggerPin];    lastTriggerPin = triggerPin;    //Calculate clock divider based on frequency, it generates a clock 2x faster than the capture freequency    float clockDiv = (float)clock_get_hz(clk_sys) / (float)(freq * 2);        //Store the PIO unit and clear program memory    capturePIO = pio0;    pio_clear_instruction_memory(capturePIO);    //Configure capture SM    sm_Capture = pio_claim_unused_sm(capturePIO, true);    pio_sm_clear_fifos(capturePIO, sm_Capture);    pio_sm_restart(capturePIO, sm_Capture);    //Load correct program, depending on the trigger edge    if(invertTrigger)    {        if(measureBursts)            captureOffset = pio_add_program(capturePIO, &NEGATIVE_CAPTURE_MEASUREBURSTS_program);        else            captureOffset = pio_add_program(capturePIO, &NEGATIVE_CAPTURE_program);    }    else    {        if(measureBursts)            captureOffset = pio_add_program(capturePIO, &POSITIVE_CAPTURE_MEASUREBURSTS_program);        else            captureOffset = pio_add_program(capturePIO, &POSITIVE_CAPTURE_program);            }    //Configure capture pins    for(int i = 0; i < 24; i++)        pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, pinMap[i], 1, false);    for(uint8_t i = 0; i < 24; i++)        pio_gpio_init(capturePIO, pinMap[i]);    //Configure trigger pin    pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, triggerPin, 1, false);    pio_gpio_init(capturePIO, triggerPin);    //Configure state machines    pio_sm_config smConfig = measureBursts?                                (invertTrigger?                                NEGATIVE_CAPTURE_MEASUREBURSTS_program_get_default_config(captureOffset):                                POSITIVE_CAPTURE_MEASUREBURSTS_program_get_default_config(captureOffset)) :                                (invertTrigger?                                NEGATIVE_CAPTURE_program_get_default_config(captureOffset):                                POSITIVE_CAPTURE_program_get_default_config(captureOffset));    //Input starts at pin INPUT_PIN_BASE    sm_config_set_in_pins(&smConfig, INPUT_PIN_BASE);    //Set clock to 2x required frequency    sm_config_set_clkdiv(&smConfig, clockDiv);    //Autopush per dword    sm_config_set_in_shift(&smConfig, true, true, 0);    //Configure trigger pin as JMP pin.    sm_config_set_jmp_pin(&smConfig, triggerPin);    //Configure interupt 0    pio_interrupt_clear (capturePIO, 0);    pio_set_irq0_source_enabled(capturePIO, pis_interrupt0, true);    irq_set_exclusive_handler(PIO0_IRQ_0, simple_capture_completed);    irq_set_enabled(PIO0_IRQ_0, true);    //Set-up burst measure    if(loopCount > 0 && measureBursts)    {        //Configure NMI to get capture timestamp        pio_interrupt_clear (capturePIO, 1);        pio_set_irq1_source_enabled(capturePIO, pis_interrupt1, true);        syscfg_hw->proc0_nmi_mask = 1 << PIO0_IRQ_1;        oldNMIHandler = exception_set_exclusive_handler(NMI_EXCEPTION, loopEndHandler);        //Reset loop counter        systickLoops = 0;        //Enable systick        oldSysTickHandler = exception_set_exclusive_handler(SYSTICK_EXCEPTION, sysTickRoll);        systick_hw->rvr = 0x00FFFFFF;        systick_hw->cvr = 0x00FFFFFF;        systick_hw->csr = 0x5;    }        //Reset timestamp index    timestampIndex = 0;    //Initialize state machine    pio_sm_init(capturePIO, sm_Capture, captureOffset, &smConfig);    //Configure DMA's    configureCaptureDMAs(captureMode);    //Enable state machine    pio_sm_set_enabled(capturePIO, sm_Capture, true);    //Write loop count and capture length to post program to start the capture process    pio_sm_put_blocking(capturePIO, sm_Capture, loopCount);    pio_sm_put_blocking(capturePIO, sm_Capture, postLength - 1);        //Finally clear capture status, process flags and capture type    captureFinished = false;    captureProcessed = false;    lastCaptureType = CAPTURE_TYPE_SIMPLE;    //We're done    return true;}

Statistics: Posted by Dr.Gusman — Sat Jun 08, 2024 11:42 pm



Viewing all articles
Browse latest Browse all 5045

Trending Articles