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.

MSP432P401R: Need help to use multiple ADC14 comparator windows with interrupts

Part Number: MSP432P401R

Hi I was trying to use the joystick on the educational-boosterpack-mkII so far I've managed to use one window comparator with a memory space, and interrupts to detect the movement of the joystick. To use the other axis as well, I was hoping to use the second available window comparator but the interrupts seem to have no clear way of differentiating which window-comparator set the interrupt.

So, could you please let me know how I can use interrupts to detect the movement of the joystick, I will attach the relevant code below.

Thank You.

void Initialize_ADC()
{
    ADC14_enableModule();

    ADC14_initModule(ADC_CLOCKSOURCE_SYSOSC, ADC_PREDIVIDER_1, ADC_DIVIDER_1, 0);

    ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM1, true);

    ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);

    ADC14_configureConversionMemory(JOYSTICK_HORX_RES_MEM, ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A15, ADC_NONDIFFERENTIAL_INPUTS);

    ADC14_configureConversionMemory(JOYSTICK_VERY_RES_MEM, ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A9, ADC_NONDIFFERENTIAL_INPUTS);

    ADC14_enableComparatorWindow(JOYSTICK_HORX_RES_MEM, ADC_COMP_WINDOW0);

    ADC14_setComparatorWindowValue(ADC_COMP_WINDOW0, 1500, 13500);

//    ADC14_enableComparatorWindow(JOYSTICK_VERY_RES_MEM, ADC_COMP_WINDOW1);
//
//    ADC14_setComparatorWindowValue(ADC_COMP_WINDOW1, 1500, 13500);

    ADC14_clearInterruptFlag(ADC_LO_INT | ADC_HI_INT | ADC_IN_INT);

    ADC14_enableInterrupt(ADC_LO_INT | ADC_HI_INT);

    if (!Interrupt_isEnabled(INT_ADC14))
    {
        Interrupt_enableInterrupt(INT_ADC14);
    }
}

void Initialize_Joystick()
{
    GPIO_setAsPeripheralModuleFunctionInputPin(BOOSTERPACK_JS_VERY_PORT, BOOSTERPACK_JS_VERY_PIN, GPIO_TERTIARY_MODULE_FUNCTION);

    GPIO_setAsPeripheralModuleFunctionInputPin(BOOSTERPACK_JS_HORX_PORT, BOOSTERPACK_JS_HORX_PIN, GPIO_TERTIARY_MODULE_FUNCTION);
}

void Start_ADC()
{
    ADC14_enableConversion();

    ADC14_toggleConversionTrigger();
}

void ADC14_IRQHandler()
{
    if ((ADC14_getEnabledInterruptStatus() & ADC_LO_INT))
    {
        joystickTappedLeft = true;
        joystickTappedRight = false;
        joystickCenter = false;
        ADC14_clearInterruptFlag(ADC_LO_INT | ADC_HI_INT);
        ADC14_disableInterrupt(ADC_LO_INT | ADC_HI_INT);
        ADC14_clearInterruptFlag(ADC_IN_INT);
        ADC14_enableInterrupt(ADC_IN_INT);
    }

    if ((ADC14_getEnabledInterruptStatus() & ADC_HI_INT))
    {
        joystickTappedRight = true;
        joystickTappedLeft = false;
        joystickCenter = false;
        ADC14_clearInterruptFlag(ADC_LO_INT | ADC_HI_INT);
        ADC14_disableInterrupt(ADC_LO_INT | ADC_HI_INT);
        ADC14_clearInterruptFlag(ADC_IN_INT);
        ADC14_enableInterrupt(ADC_IN_INT);
    }

    if ((ADC14_getEnabledInterruptStatus() & ADC_IN_INT))
    {
        joystickTappedLeft = false;
        joystickTappedRight = false;
        if ((ADC14_getResult(JOYSTICK_HORX_RES_MEM) > 6500) && (ADC14_getResult(JOYSTICK_HORX_RES_MEM) < 8500))
        {
            joystickCenter = true;
            ADC14_disableInterrupt(ADC_IN_INT);
            ADC14_clearInterruptFlag(ADC_LO_INT | ADC_HI_INT);
            ADC14_enableInterrupt(ADC_LO_INT | ADC_HI_INT);
        }
        ADC14_clearInterruptFlag(ADC_IN_INT);
    }

//    ADC14_clearInterruptFlag(ADC_LO_INT | ADC_HI_INT | ADC_IN_INT);
}

The code seems to work well for a single axis, but I intend to use it for another axis as well

  • As far as I know your software needs to figure it out. Since there are two comparators but only one set of IFG bits, an (e.g.) ADC_HI_INT could mean either (or both) triggered it. This would look like re-doing the comparison that the WINC did (but only when needed). You would have to do much the same thing if you were to use a (single) WINC on two different channels.

  • Hi Mr. McKenny, thank you for that. I guess I was looking for clarification that I will have to figure out a way to differentiate between them only in software and that there aren't two sets of interrupt flags. I've modified my interrupt handler function to the one below, let me know if I can improve anything

    Thanks again for the clarification

    void Initialize_ADC()
    {
        ADC14_enableModule();
    
        ADC14_initModule(ADC_CLOCKSOURCE_SYSOSC, ADC_PREDIVIDER_1, ADC_DIVIDER_1, 0);
    
        ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM1, true);
    
        ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);
    
        ADC14_configureConversionMemory(JOYSTICK_HORX_RES_MEM, ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A15, ADC_NONDIFFERENTIAL_INPUTS);
    
        ADC14_configureConversionMemory(JOYSTICK_VERY_RES_MEM, ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A9, ADC_NONDIFFERENTIAL_INPUTS);
    
        ADC14_enableComparatorWindow(JOYSTICK_HORX_RES_MEM, ADC_COMP_WINDOW0);
    
        ADC14_setComparatorWindowValue(ADC_COMP_WINDOW0, 1500, 13500);
    
        ADC14_enableComparatorWindow(JOYSTICK_VERY_RES_MEM, ADC_COMP_WINDOW1);
    
        ADC14_setComparatorWindowValue(ADC_COMP_WINDOW1, 1500, 13500);
    
        ADC14_clearInterruptFlag(ADC_LO_INT | ADC_HI_INT | ADC_IN_INT);
    
        ADC14_enableInterrupt(ADC_LO_INT | ADC_HI_INT);
    
        if (!Interrupt_isEnabled(INT_ADC14))
        {
            Interrupt_enableInterrupt(INT_ADC14);
        }
    }
    
    void Initialize_Joystick()
    {
        GPIO_setAsPeripheralModuleFunctionInputPin(BOOSTERPACK_JS_VERY_PORT, BOOSTERPACK_JS_VERY_PIN, GPIO_TERTIARY_MODULE_FUNCTION);
    
        GPIO_setAsPeripheralModuleFunctionInputPin(BOOSTERPACK_JS_HORX_PORT, BOOSTERPACK_JS_HORX_PIN, GPIO_TERTIARY_MODULE_FUNCTION);
    }
    
    void Start_ADC()
    {
        ADC14_enableConversion();
    
        ADC14_toggleConversionTrigger();
    }

    void ADC14_IRQHandler()
    {
        ADC14_disableConversion();
        if ((ADC14_getEnabledInterruptStatus() & ADC_LO_INT))
        {
            if (ADC14_getResult(JOYSTICK_VERY_RES_MEM) < 1500)
            {
                joystickTappedDown = true; joystickTappedLeft = false;
                ADC14_disableComparatorWindow(JOYSTICK_HORX_RES_MEM);
            }
            else if (ADC14_getResult(JOYSTICK_HORX_RES_MEM) < 1500)
            {
                joystickTappedLeft = true; joystickTappedDown = false;
                ADC14_disableComparatorWindow(JOYSTICK_VERY_RES_MEM);
            }
            joystickTappedRight = false;
            joystickTappedUp = false; joystickCenter = false;
            ADC14_clearInterruptFlag(ADC_LO_INT | ADC_HI_INT);
            ADC14_disableInterrupt(ADC_LO_INT | ADC_HI_INT);
            ADC14_clearInterruptFlag(ADC_IN_INT);
            ADC14_enableInterrupt(ADC_IN_INT);
        }
    
        if ((ADC14_getEnabledInterruptStatus() & ADC_HI_INT))
        {
            if (ADC14_getResult(JOYSTICK_VERY_RES_MEM) > 13500)
            {
                joystickTappedUp = true; joystickTappedRight = false;
                ADC14_disableComparatorWindow(JOYSTICK_HORX_RES_MEM);
            }
            else if (ADC14_getResult(JOYSTICK_HORX_RES_MEM) > 13500)
            {
                joystickTappedRight = true; joystickTappedUp = false;
                ADC14_disableComparatorWindow(JOYSTICK_VERY_RES_MEM);
            }
            joystickTappedLeft = false;
            joystickTappedDown = false; joystickCenter = false;
            ADC14_clearInterruptFlag(ADC_LO_INT | ADC_HI_INT);
            ADC14_disableInterrupt(ADC_LO_INT | ADC_HI_INT);
            ADC14_clearInterruptFlag(ADC_IN_INT);
            ADC14_enableInterrupt(ADC_IN_INT);
        }
    
        if ((ADC14_getEnabledInterruptStatus() & ADC_IN_INT))
        {
            joystickTappedLeft = false; joystickTappedRight = false;
            joystickTappedUp = false; joystickTappedDown = false;
            if ((ADC14_getResult(JOYSTICK_HORX_RES_MEM) > 6500) && (ADC14_getResult(JOYSTICK_HORX_RES_MEM) < 8500) && (ADC14_getResult(JOYSTICK_VERY_RES_MEM) > 6500) && (ADC14_getResult(JOYSTICK_VERY_RES_MEM) < 8500))
            {
                joystickCenter = true;
                ADC14_disableInterrupt(ADC_IN_INT);
                ADC14_clearInterruptFlag(ADC_LO_INT | ADC_HI_INT);
                ADC14_enableInterrupt(ADC_LO_INT | ADC_HI_INT);
                ADC14_enableComparatorWindow(JOYSTICK_HORX_RES_MEM, ADC_COMP_WINDOW0);
                ADC14_enableComparatorWindow(JOYSTICK_VERY_RES_MEM, ADC_COMP_WINDOW1);
            }
            ADC14_clearInterruptFlag(ADC_IN_INT);
        }
        Start_ADC();
    }