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.

RTOS/MSP432P401R: Hwi create error.

Part Number: MSP432P401R
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

I'm working with TI RTOS to achieve the following, start an ADC conversion, convert the result to between 50 and 90, and display using printf.  I would like to use the ADC14's interrupt to trigger the hwi1Fxn but I keep getting the error.

[CORTEX_M4_0] Initializing
ti.sysbios.family.arm.m3.Hwi: line 143: E_alreadyDefined: Hwi already defined: intr# 24
HWI create failed

When first starting debugging, after the pause on main, looking at the Hwi module in ROV, the function ti_sysbios_family_arm_msp432_Timer_periodicStub__E already has the intNum 24.  I saw a similar issue in the thread e2e.ti.com/.../1604590 but that wasn't able to solve my issue.

Code as follows.  Error happens at Hwi_create.  My question is what interrupt number would be correct for ADC14 on the MSP432P401R and what hwi is already created with the interrupt number 24?

/*
 * Copyright (c) 2015, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 *  ======== empty.c ========
 */
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.h>
#include "msp.h"
#include "Nokia5110.h"

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Event.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Swi.h>
#include <ti/sysbios/hal/Timer.h>
#include <ti/sysbios/hal/Hwi.h>

/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/ADC.h>
// #include <ti/drivers/I2C.h>
// #include <ti/drivers/SDSPI.h>
// #include <ti/drivers/SPI.h>
// #include <ti/drivers/UART.h>
// #include <ti/drivers/Watchdog.h>
// #include <ti/drivers/WiFi.h>

/* Board Header file */
#include "Board.h"

#define TASKSTACKSIZE   568
#define TIMEOUT 1000

/* Global Variable */
uint16_t raw;
uint16_t tempf;
uint16_t newtempf;

Timer_Handle timer;
Swi_Handle swi;
Task_Handle task1, task2;
Event_Handle event1, event2;
Clock_Handle clk;
Clock_Struct clkStruct;
Hwi_Handle hwi;
ADC_Handle adc;


/* Here on Timer interrupt */
Void hwiFxn(UArg arg)
{
    GPIO_toggle(Board_LED1);
    Swi_post(swi);
}

/* Here on ADC interrupt */
Void hwi1Fxn(UArg arg)
{
    raw = ADC14->MEM[0];
}

/* Swi thread to handle Timer interrupt */
Void swiFxn(UArg arg1, UArg arg2)
{
    if(~(ADC14->CTL0 && ADC14_CTL0_BUSY))//check to see if not busy
    {
            raw = ADC14->MEM[0];
            Event_post(event1, Event_Id_01);
            ADC14->CTL0 |= ADC14_CTL0_SC;
    }

}

/* Task pending event1 */
Void task1Fxn(UArg arg1, UArg arg2)
{
    for(;;)
    {
        UInt posted1;

        posted1 = Event_pend(event1,Event_Id_NONE,Event_Id_01,BIOS_WAIT_FOREVER);
        if(posted1 != 0)
        {
            newtempf = ((float)raw/0x3fff)*40+50; //Scale value to 50-90 deg. F
            if(tempf != newtempf)
            {
                tempf = newtempf;
                Event_post(event2, Event_Id_01); //Notify of setpoint value available
            }
        }
        System_flush();
    }
}

/* Task pending event2 */
Void task2Fxn(UArg arg1, UArg arg2)
{
    for(;;)
    {
        UInt posted2;
        UInt key1, key2;

        posted2 = Event_pend(event2,Event_Id_NONE,Event_Id_01,BIOS_WAIT_FOREVER);
        if(posted2 != 1)
        {
            key1 = Swi_disable();
            key2 = Hwi_disable();

            System_printf("Setpt.: %u F\n", newtempf);
            Nokia5110_SetCursor(7,1);
            Nokia5110_OutUDec(tempf);

            Swi_restore(key1);
            Hwi_restore(key2);
        }
        System_flush();
    }
}

Void clkFxn(UArg arg)
{

}

/*
 *  ======== main ========
 */
int main(void)
{
    ADC14->CTL0 = ADC14_CTL0_ON |ADC14_CTL0_SHT0_2 | ADC14_CTL0_SHP;
    ADC14->CTL1 = ADC14_CTL1_RES__14BIT;            //14 bit resolution
    ADC14->MCTL[0] |= ADC14_MCTLN_INCH_0;           //A0 MEM[0]
    //ADC14->IER0 |= ADC14_IER0_IE1;                  //Interrupt enable
    ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC;

    Timer_Params timerParams;
    Task_Params taskParams;
    Swi_Params swiParams;
    Clock_Params clkParams;
    Hwi_Params hwiParams;
    Error_Block eb;
//    ADC_Params adcparams;

    Error_init(&eb);
    Timer_Params_init(&timerParams);
    Task_Params_init(&taskParams);

    /* Call init functions */
    Board_initGeneral();
    Board_initGPIO();
    Board_initADC();
    Nokia5110_Init();

    Nokia5110_Clear();
    Nokia5110_OutString("Setpt.:  F");

    System_printf("Initializing\n");
    System_flush();

    /* Create ADC Instance */
/*    ADC_Params_init(&adcparams);
    adc = ADC_open(Board_ADC0, &adcparams);
    if (adc == NULL) {
        System_abort("Error initializing ADC channel 0\n");
    }
    else {
        System_printf("ADC channel 0 initialized\n");
    }
*/
    /* Create Swi with default priority 15 */
    /* Swi handler is 'swiFxn' which runs as a Swi thread. */
    Swi_Params_init(&swiParams);
    swiParams.arg0 = 0;
    swiParams.arg1 = 0;
    swiParams.priority = 1;
    swiParams.trigger = 1;
    swi = Swi_create(&swiFxn,&swiParams,&eb);
    if (swi == NULL)
    {
        System_abort("Swi create failed");
    }

    /* Create task1 and task2 which run as a Task thread. */
    Task_Params_init(&taskParams);
    taskParams.priority = 2;
    task1 = Task_create(&task1Fxn,&taskParams,&eb);
    if (task1 == NULL)
    {
        System_abort("Task 1 create failed");
    }
    taskParams.priority = 1;
    task2 = Task_create(&task2Fxn,&taskParams,&eb);
    if(task2 == NULL)
    {
        System_abort("Task 2 create failed");
    }

    /* Create event1 and event2 for tasks to pend on */
    event1 = Event_create(NULL,&eb);
    if(event1 == NULL)
    {
        System_abort("Event 1 create failed");
    }
    event2 = Event_create(NULL,&eb);
    if(event2 == NULL)
    {
        System_abort("Event 2 create failed");
    }

    /* Set up clock to go off every 2 timer interrupts */
    Clock_Params_init(&clkParams);
    clkParams.period = 2;
    clkParams.startFlag = TRUE;

    clk = Clock_create(&clkFxn, 2, &clkParams, &eb);
    if (clk == NULL) {
     System_abort("clock create failed");
     }

    /* Configure timer with 0.5s interrupt period */
    timerParams.period = 500000;
    timer = Timer_create(Timer_ANY,&hwiFxn,&timerParams,&eb);
    if (timer == NULL)
    {
        System_abort("Timer create failed");
    }

    /* Configure HWI */
    Hwi_Params_init(&hwiParams);
    hwiParams.arg = 1;
    hwiParams.eventId = 24;//ADC interrupt number
    hwiParams.maskSetting = Hwi_MaskingOption_SELF;
    hwi = Hwi_create(24,&hwi1Fxn, &hwiParams, &eb);
    if (hwi == NULL)
    {
        System_abort("HWI create failed");
    }
  //This section of code was unsuccessful.  User manual has ADC interrupt at 24 but 24 is used by TIMER or clockTick

    System_printf("Starting Lab6v2\n");
    System_flush();

    /* Start BIOS */
    BIOS_start();

    return (0);
}

  • Hi,
    Thanks for posting your question.
    To make sure we are aligned on what software package you are using - can you tell me where the source software is from and what revision of MSP432 device (Revision B or Revision C), board (evaluation hardware) you are using?

    From you code example snippet, this seems to be the stand-alone TI RTOS package for MSP432 which has been deprecated.TI RTOS support for this device is now available via the SimpleLink MSP432 SDK. This SDK not only incorporates TI RTOS but also enables easy to use ADC functionality with high-level ADC drivers.
    It is available at: www.ti.com/.../simplelink-msp432-sdk

    You can also view the cloud version of the SDK and the associated examples at dev.ti.com--> resource explorer --> simplelink MSP432 SDK .
    Examples for the MSP432 Launchpad kit can be found under:
    Examples --> Development tools --> MSP-EXP432P401R --> TI Drivers --> adcsinglechannel

    Moving to the SDK is highly recommended, since it handles the HWI, ADC configuration etc for you.

    Regards,
    Priya
  • I'm working in CCS V7.1.0.00016. I imported an empty project from the Resource Explorer>Software>TI_RTOS for MSP430 - v:2.20.00.06>Development Tools>Driver Examples>Empty Examples.
    MSP432P401R rev. c, launchpad rev. 2.1. I will check into the SDK, unfortunately I have been using TI RTOS package the past few days so I will look into switching over. Initially I was using the ADC drivers but had issues with it enabling blocking mode. I need to call ADC start within an swi, which created a gatemutex error. So I was forced to drop the ADC driver. This is all still fairly new to me
  • ok, I understand. Switching over to the SDK is highly recommended because (a) the ADC drivers handle things like setting up the HWI so you don't have to deal with it and (b) we are deprecating support for the stand alone package in the future...so the sooner you make the switch the better.

    I opened up interrupt.h to check the interrupt numbers and I see that you are using the TA0 one. This is the timer that the Kernel uses by default so it is always "in use".

    #define INT_TA0_0 (24) /* TA0_0 IRQ */

    The ADC one should use the number 40. Try changing this to?

    #define INT_ADC14 (40) /* ADC14 IRQ */

    //example code snippet
    HwiP_Params_init(&adcHwiParams);
    adcHwiParams.arg = 0;
    adcHwiParams.priority = ~0;
    adcHwiParams.name = "ADC14";
    adcHwiHandle = HwiP_create(40, &Hwi_adc, &adcHwiParams);


    -Priya
  • That worked, great. Thank you for the follow up.

**Attention** This is a public forum