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.

CCS/EK-TM4C123GXL: Unable to Turn on LED

Part Number: EK-TM4C123GXL

Tool/software: Code Composer Studio

I am a new user, and I am trying to debug one of my programs. Allow me to quickly summarize my situation.

Originally, I wanted the LED to light up if value >= 1. This worked fine, for a while. Then, I made several changes to the functions above the main function. I made these changes in the Code::Blocks IDE, and when I compiled and ran these changes in Code::Blocks, everything was fine. However, when I tried porting these changes back to CCS, I found I could no longer light the LED, even if the argument of the if statement is 1==1, which should always return true no matter what. To me, this implies that there is something fundamentally wrong with the code or with a CCS setting.

How do I light up the LED again? It should be noted that the CCS code can compile, but when I try debugging it, the LED no longer lights up.

Attached is the code. The most important section is down in the main function.

Thank you for your time. Any help would be appreciated.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include "driverlib/adc.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"

uint8_t ui8PinData = 2;

// Creates data square wave (for testing purposes, for the real implementation actual ADC data will be used). This
// square wave has unity magnitude.
// The number of high values in each period is determined by high values = array size / (2 * number of pulses)
void createDataWave(uint16_t arraySize, uint8_t pulsesNumber, uint8_t wave[]){
    uint8_t highValues = arraySize / (2 * pulsesNumber);
    uint8_t counter = 0;
    uint16_t p;
    for(p = 0; p < arraySize; p++){
        if ((counter % 2) == 0){
            wave[p] = 1;
        } else{
            wave[p] = 0;
        }
        if ((p + 1) % highValues == 0){
            counter++;
        }
    }
}

// Creates analyzing square wave. This square wave has unity (1) magnitude.
// The number of high values in each period is determined by high values = (analyzingT/2) / time increment
void createAnalyzingWave(uint16_t analyzingFreq, uint16_t dataFreq, uint16_t arraySize, uint8_t pulsesNumber, uint8_t wave[]){
    uint8_t highValues = (1 / analyzingFreq) * 0.5 / ((pulsesNumber * (1 / dataFreq)) / arraySize);
    uint8_t counter = 0;
    uint16_t p;

    for(p = 1; p <= arraySize; p++){
        if ((counter % 2) == 0){
            wave[p - 1] = 1;
        } else{
            wave[p - 1] = 0;
        }
        if (p % highValues == 0){
            counter++;
        }
    }
}


// Multiply each array element with the respective element of the other
// array and add each product together. returns the product. This forms
// the basis of the cross-correlation process.
// Technically, this function only multiplies and adds arrays of size arraySize.
// array2 is the big analyzing wave.
uint16_t multiplyAdd(uint8_t array1[], uint8_t array2[], uint16_t arraySize, uint16_t bigArraySize){
    uint8_t productArray[arraySize];
    uint16_t i;
    uint16_t stepper = bigArraySize - 1;
    uint16_t sum = 0;

    for(i = arraySize - 1; i >= 0; i--){
        productArray[i] = array1[i] * array2[stepper];
        sum = sum + productArray[i];
        stepper--;
    }
    return sum;
}

// Circle shift array one element to the left. This forms the basis of the
// time-shifting operation of the cross-correlation.
// ArraySize MUST be calculated separately
void circleShiftL(uint8_t array[], uint16_t arraySize){
    uint16_t lastArrayIndex = arraySize - 1;
    uint8_t lastElement = array[lastArrayIndex];
    uint16_t j;
    for(j = lastArrayIndex; j > 0 ; j--){
        array[j] = array[j - 1];
    }
    array[0] = lastElement;
}

// Averages the array with the maximum correlation values
uint16_t arrayAverage(uint16_t array[], uint16_t arraySize){
    uint16_t i;
    uint16_t sum = 0;
    //double average;
    for(i = 0; i < arraySize; i++){
        sum = array[i] + sum;
    }
    //average = sum / arraySize;
    return sum / arraySize;
}

// Cross-correlate two arrays with each other. Returns the maximum cross-correlation value.
// Array size of each array must be specified.
uint16_t crossCorrelationV2(uint8_t dataWave[], uint8_t analyzingWave[], uint16_t arraySize){
    uint16_t bigArraySize = (2 * arraySize) - 1;
    // Expand analyzing array into array of size 2arraySize-1
    uint8_t bigAnalyzingArray[bigArraySize];

    uint16_t i;

    // Set first few elements of the array equal to analyzingWave
    // Set remainder of big analyzing array to 0
    for(i = 0; i < arraySize; i++){
        bigAnalyzingArray[i] = analyzingWave[i];
        bigAnalyzingArray[i + arraySize] = 0;
    }

    uint16_t maxCorrelationValue = 0;
    uint16_t currentCorrelationValue;

    for (i = 0; i < bigArraySize; i++){
        currentCorrelationValue = multiplyAdd(dataWave, bigAnalyzingArray, arraySize, bigArraySize);
        if (currentCorrelationValue > maxCorrelationValue){
            maxCorrelationValue = currentCorrelationValue;
        }
        circleShiftL(bigAnalyzingArray, bigArraySize);
    }
    return maxCorrelationValue;
}

int main(){
    // Enables the clock
    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    // Enables pin F
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    // Enables the output LEDs
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

    uint16_t dataFreq = 1300;
    uint16_t analyzingFreq = 1300;
    uint16_t arraySize = 64;
    uint8_t pulsesNumber = 16;

    uint8_t analyzingWave[arraySize];
    uint8_t dataWave[arraySize];
    createAnalyzingWave(analyzingFreq, dataFreq, arraySize, pulsesNumber, analyzingWave);
    createDataWave(arraySize, pulsesNumber, dataWave);

    uint16_t value = crossCorrelationV2(dataWave, analyzingWave, arraySize);

    while (1){
        if(1==1){
            GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, ui8PinData);
        } else {
            GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);
        }
        SysCtlDelay(2000000);
    }
}

  • I suggest you put a breakpoint on the GPIOPinWrite that should turn on the LED (line 150 above). Verify that the value in ui8PinData was not corrupted by the functions above writing outside of the arrays.

  • I put a breakpoint where you suggested, and I deleted "ui8PinData" and replaced it with just 4, so that theoretically the LED should be red. However, the LED still doesn't light up.

    I tried a few more things besides the things you recommended. I commented out line 146 (the "crossCorrelationV2" line), and the LED lights up. However, when I uncomment it and include that line in my code, then the LED does not light up. I don't understand why this happens; I assume there is something intrinsically wrong with the crossCorrelationV2 function. As a new user, maybe there's something I'm missing with how Code Composer Studio works.

    I appreciate your help.

  • The issue is that your code never gets to the point to turn on the LED. It is getting stuck in the FaultISR. In the function multiplyAdd you have a for loop:

        for(i = arraySize - 1; i >= 0; i--)
    

    since i is defined as unsigned, it will always be greater than or equal to zero. When i decrements to 0xFFFFFF, you reference memory that is not valid, and create a memory fault.

    Do you really need to do all of the arrays as variable length? Your code would be much more efficient if you used a #define for arraySize and bigArraySize. Using a variable causes the compiler to generate calls to malloc and grab data off of the heap.

  • If you change arraySize and pulsesNumber to be #define, then remove them as parameters to function calls. Values that are constant during the entire execution of the program are best done with #define. 

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <stdint.h>
    #include "driverlib/adc.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    
    #define arraySize 64
    #define pulsesNumber 16
    
    uint8_t ui8PinData = 2;
    // Creates data square wave (for testing purposes, for the real implementation actual ADC data will be used). This
    // square wave has unity magnitude.
    // The number of high values in each period is determined by high values = array size / (2 * number of pulses)
    void createDataWave(uint8_t wave[]){
        uint8_t highValues = arraySize / (2 * pulsesNumber);
        uint8_t counter = 0;
        uint16_t p;
        for(p = 0; p < arraySize; p++){
            if ((counter % 2) == 0){
                wave[p] = 1;
            } else{
                wave[p] = 0;
            }
            if ((p + 1) % highValues == 0){
                counter++;
            }
        }
    }
    
    // Creates analyzing square wave. This square wave has unity (1) magnitude.
    // The number of high values in each period is determined by high values = (analyzingT/2) / time increment
    void createAnalyzingWave(uint16_t analyzingFreq, uint16_t dataFreq, uint8_t wave[]){
        uint8_t highValues = (1 / analyzingFreq) * 0.5 / ((pulsesNumber * (1 / dataFreq)) / arraySize);
        uint8_t counter = 0;
        uint16_t p;
    
        for(p = 1; p <= arraySize; p++){
            if ((counter % 2) == 0){
                wave[p - 1] = 1;
            } else{
                wave[p - 1] = 0;
            }
            if (p % highValues == 0){
                counter++;
            }
        }
    }
    
    
    // Multiply each array element with the respective element of the other
    // array and add each product together. returns the product. This forms
    // the basis of the cross-correlation process.
    // Technically, this function only multiplies and adds arrays of size arraySize.
    // array2 is the big analyzing wave.
    uint16_t multiplyAdd(uint8_t array1[], uint8_t array2[], uint16_t bigArraySize){
        uint8_t productArray[arraySize];
        int i;
        uint16_t stepper = bigArraySize - 1;
        uint16_t sum = 0;
    
        for(i = arraySize - 1; i >= 0; i--){
            productArray[i] = array1[i] * array2[stepper];
            sum = sum + productArray[i];
            stepper--;
        }
        return sum;
    }
    
    // Circle shift array one element to the left. This forms the basis of the
    // time-shifting operation of the cross-correlation.
    // ArraySize MUST be calculated separately
    void circleShiftL(uint8_t array[], uint16_t bigArraySize){
        uint16_t lastArrayIndex = bigArraySize - 1;
        uint8_t lastElement = array[lastArrayIndex];
        uint16_t j;
        for(j = lastArrayIndex; j > 0 ; j--){
            array[j] = array[j - 1];
        }
        array[0] = lastElement;
    }
    
    // Averages the array with the maximum correlation values
    uint16_t arrayAverage(uint16_t array[]){
        uint16_t i;
        uint16_t sum = 0;
        //double average;
        for(i = 0; i < arraySize; i++){
            sum = array[i] + sum;
        }
        //average = sum / arraySize;
        return sum / arraySize;
    }
    
    // Cross-correlate two arrays with each other. Returns the maximum cross-correlation value.
    // Array size of each array must be specified.
    uint16_t crossCorrelationV2(uint8_t dataWave[], uint8_t analyzingWave[]){
        uint16_t bigArraySize = (2 * arraySize) - 1;
        // Expand analyzing array into array of size 2arraySize-1
        uint8_t bigAnalyzingArray[bigArraySize];
    
        uint16_t i;
    
        // Set first few elements of the array equal to analyzingWave
        // Set remainder of big analyzing array to 0
        for(i = 0; i < arraySize; i++){
            bigAnalyzingArray[i] = analyzingWave[i];
            bigAnalyzingArray[i + arraySize] = 0;
        }
    
        uint16_t maxCorrelationValue = 0;
        uint16_t currentCorrelationValue;
    
        for (i = 0; i < bigArraySize; i++){
            currentCorrelationValue = multiplyAdd(dataWave, bigAnalyzingArray, bigArraySize);
            if (currentCorrelationValue > maxCorrelationValue){
                maxCorrelationValue = currentCorrelationValue;
            }
            circleShiftL(bigAnalyzingArray, bigArraySize);
        }
        return maxCorrelationValue;
    }
    
    int main(){
        // Enables the clock
        SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
        // Enables pin F
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        // Enables the output LEDs
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    
        uint16_t dataFreq = 1300;
        uint16_t analyzingFreq = 1300;
    
        uint8_t analyzingWave[arraySize];
        uint8_t dataWave[arraySize];
        createAnalyzingWave(analyzingFreq, dataFreq, analyzingWave);
        createDataWave(dataWave);
    
        uint16_t value = crossCorrelationV2(dataWave, analyzingWave);
    
        while (1){
            if(1==1){
                GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, ui8PinData);
            } else {
                GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);
            }
            SysCtlDelay(2000000);
        }
    }
    

  • Thanks, that makes sense.