This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LAUNCHXL-CC2640R2: Timer speed is limited

Part Number: LAUNCHXL-CC2640R2

I'm using 2 timers on the LAUNCHXL-CC2640R2: 0A for ADC and UART interrupt callback function, and 1A for pin timing via an interrupt. Both are in 32-bit format. For some reason, Timer 0A is not able to go faster than 50 Hz. I have set it to higher values and it never goes above 50 Hz (this has been verified by timestamps in a terminal). I have disabled all the other timers (to reduce the amount of required flash) but that shouldn't be the issue.

Also, Timer 1A is never faster than 16 Hz. I'm currently testing it at 1 Hz, if that is of any additional help. Is there something that I am missing? I've tried everything that I can think of with no luck.

void MUXtimerCallback(GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask) {
        muxmod = muxidx % channels; //get remainder of muxidx for switch
    switch(muxmod) {
        case 0:
            PIN_setOutputValue(muxPinHandle, IOID_22, 0);
            PIN_setOutputValue(muxPinHandle, IOID_23, 0);
            PIN_setOutputValue(muxPinHandle, IOID_12, 0);
            PIN_setOutputValue(muxPinHandle, IOID_15, 0);
            break;
        case 1:
            PIN_setOutputValue(muxPinHandle, IOID_22, 0);
            PIN_setOutputValue(muxPinHandle, IOID_23, 0);
            PIN_setOutputValue(muxPinHandle, IOID_12, 0);
            PIN_setOutputValue(muxPinHandle, IOID_15, 1);
            break;
    }
    muxidx += 1; // increment counter
    if(muxidx == channels){
        muxidx = 0; //reset counter back to zero, if it equals the number of channels
    }
}

void DACtimerCallback(GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask) {
    GPIO_toggle(Board_GPIO_LED0);
    if (counterDAC%2==0){
        if (lastAmp[muxmod]==signal.ampAC){
            // Signal goes high
            // Do I2C transfer (in callback mode)
            txBuffer1[0] = signal.ampAC >> 8; //hi byte
	        txBuffer1[1] = signal.ampAC; //lower 2 bytes
        }else{ // Change to a new magnitude
            signal.ampAC = lastAmp[muxmod];
            signal.ampDC = signal.ampAC/2;
            txBuffer1[0] = signal.ampAC >> 8; //hi byte
	        txBuffer1[1] = signal.ampAC; //lower 2 bytes
	        txBuffer2[0] = signal.ampDC >> 8; //hi byte
	        txBuffer2[1] = signal.ampDC; //lower 2 bytes
	        I2C_transfer(I2Chandle, &i2cTrans2);
        }
    }else{
            // Signal goes to zero 
            // Do I2C transfer (in callback mode)
            //signal.ampAC = 0;
            txBuffer1[0] = 0; //hi byte
	        txBuffer1[1] = 0; //lower 2 bytes
    }
    I2C_transfer(I2Chandle, &i2cTrans1);
    if(counterDAC == 2){
        counterDAC = 0; //reset counter back to zero, if it equals the 2
    }else{
        uint16_t     i;
        uint_fast16_t uartTxBufferOffset = 0;
        char uartTxBuffer[UARTBUFFERSIZE] = {0};
        
        int amp = 0;
        uint8_t ampFactor = 3;
        int res1 = 0;
        int adcVal = 0;
        
        if (uartTxBufferOffset < UARTBUFFERSIZE) {
            amp = ADC_convertRawToMicroVolts(adc,lastAmp[muxmod])/ampFactor;
            uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,UARTBUFFERSIZE - uartTxBufferOffset, "%u,",(uint8_t)DEVICENUM); // outputs device number
            uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,UARTBUFFERSIZE - uartTxBufferOffset, "%u,",(uint16_t)counterDATA); // outputs sample number
            uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,UARTBUFFERSIZE - uartTxBufferOffset, "%u,",(uint8_t)muxmod); // outputs channel number
            uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,UARTBUFFERSIZE - uartTxBufferOffset, "%u,",(uint32_t)amp); // outputs input voltage
        }
        for (i = 0; i < ADC_SAMPLE_COUNT; i++) {
            res1 = ADC_convert(adc, &adcValue[i]);
            if (res1 == ADC_STATUS_SUCCESS) {            
                    /* Write channel number to the UART buffer if there is room. */
                if (uartTxBufferOffset < UARTBUFFERSIZE) {
                    adcVal = ADC_convertRawToMicroVolts(adc,adcValue[i]);
                    uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,UARTBUFFERSIZE - uartTxBufferOffset, "%u,",(uint32_t)adcVal); // outputs output voltage
                }
            }
        }
            /*
        * Ensure we don't write outside the buffer.
        * Append a newline after the data.
        */
        if (uartTxBufferOffset < UARTBUFFERSIZE) {
            uartTxBuffer[uartTxBufferOffset++] = '\n';
        }
        else {
            uartTxBuffer[UARTBUFFERSIZE-1] = '\n';
        }

        /* Display the data via UART */
        UART_write(uart, uartTxBuffer, uartTxBufferOffset);
        counterDATA += 1; //increment sample counter once finished
    }
    counterDAC += 1;
    
//Check the magnitude of lastAmp[muxmod] and modulate if necessary  
    if (avg < ADCloLimit) {
        lastAmp[muxmod] += 5;
    } else if (avg > ADChiLimit){
        lastAmp[muxmod] -= 5;
    } 
    if (lastAmp[muxmod] < 100){
        lastAmp[muxmod] = minVOLT;
    }
}

GPTimerCC26XX_Params paramsDAC;
GPTimerCC26XX_Params_init(&paramsDAC);
paramsDAC.width          = GPT_CONFIG_32BIT;
paramsDAC.mode           = GPT_MODE_PERIODIC_UP;
paramsDAC.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
hDACTimer = GPTimerCC26XX_open(CC2640R2_LAUNCHXL_GPTIMER0A, &paramsDAC); //Need timer 0A for ADCbuf
if(hDACTimer == NULL) {
    while(1);
}

Types_FreqHz  freq;
BIOS_getCpuFreq(&freq); //48MHz
GPTimerCC26XX_Value loadValDAC = 480000; //48e4 = 0.01 sec = 100 Hz
loadValDAC = loadValDAC - 1;
GPTimerCC26XX_setLoadValue(hDACTimer, loadValDAC);
GPTimerCC26XX_registerInterrupt(hDACTimer, DACtimerCallback, GPT_INT_TIMEOUT);
   
GPTimerCC26XX_start(hDACTimer);

GPTimerCC26XX_Params paramsMUX;
GPTimerCC26XX_Params_init(&paramsMUX);
paramsMUX.width          = GPT_CONFIG_32BIT;
paramsMUX.mode           = GPT_MODE_PERIODIC_UP;
paramsMUX.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
hMUXTimer = GPTimerCC26XX_open(CC2640R2_LAUNCHXL_GPTIMER1A, &paramsMUX); //Need timer 0A for ADCbuf
if(hMUXTimer == NULL) {
  Task_exit();
}
GPTimerCC26XX_Value loadValMUX = 48000000/MUXFREQ;
loadValMUX = loadValMUX - 1;
GPTimerCC26XX_setLoadValue(hMUXTimer, loadValMUX);
GPTimerCC26XX_registerInterrupt(hMUXTimer, MUXtimerCallback, GPT_INT_TIMEOUT);

GPTimerCC26XX_start(hMUXTimer);