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/MSP-EXP432P401R: Busfault when calling `Display_printf` in interrupt callback in TIRTOS application

Part Number: MSP-EXP432P401R
Other Parts Discussed in Thread: SYSBIOS

Tool/software: Code Composer Studio

Hello everyone

I am writing an application for the MSP432 development board using TIRTOS. The structure of the application skeleton is the following (see also code below):

  • There are two GPIO interrupts set up for two buttons. When a button is pressed, the associated interrupt handler sends a message over the UART to the connected PC using the `Display_printf` library function.
  • In addition there is a timer set up which causes periodic interrupts every 1ms.

If I run the application and click the buttons sequentially a few times, the system always freezes in an exception handler. The decoded exception says `Hard Fault: FORCED: BUSFAULT: PRECISERR.Data Access Error. Address = 0x40000c04` and the exception call stack says `ti_sysbios_knl_Task_unblockI__E`. 

I'm not quite sure why this error occurs. Is there anything I need to consider or I'm not aware of when I want to call `Display_printf`?

The application code:

/* POSIX Header files */
#include <pthread.h>

/* Driver Header files */
#include <ti/drivers/ADC.h>
#include <ti/display/Display.h>
#include <ti/drivers/PWM.h>
#include <ti/drivers/Timer.h>
#include <ti/drivers/GPIO.h>

/* Driver configuration */
#include "ti_drivers_config.h"
#include "coil_control.h"


/* State machine related variables */
enum driver_state state = INIT;

/* current timer value */
/* Open the timer */
Timer_Handle timer0;
Timer_Params t_params;

uint32_t counter_value=0;

static Display_Handle display;

/*
 *  ======== controller / duty cycle thread ========
 *  measure the voltage produced by current sensor amplifier
 */
void current_controller(Timer_Handle myHandle){
    //counter_value+=1;
}

/*
 *  ======== sw1 callback ========
 *  advance state machine forward
 */
void sw1_callback(uint_least8_t ind){
    counter_value+=1;
    Display_printf(display, 0, 0, "SW1 pressed\n");
}

/*
 *  ======== cw2 callback ========
 *  advance state machine backwards
 */
void sw2_callback(uint_least8_t ind){
    counter_value+=1;
    Display_printf(display, 0, 0, "SW2 pressed\n");
}

/*
 *  ======== mainThread ========
 *  the main thread sets up a timer for
 *  - periodic currentsens_voltage_measurement (current sens thread)
 *  - periodic adjustment of duty cycle (current control thread)
 *  - periodic communication with PC (communication thread)
 */
 void *mainThread(void *arg0)
{
    //------------------------------------------------
    // GPIO 0 Setup
    //------------------------------------------------
    GPIO_setConfig(CONFIG_GPIO_S1, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
    GPIO_setConfig(CONFIG_GPIO_S2, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
    GPIO_setCallback(CONFIG_GPIO_S1, sw1_callback);
    GPIO_setCallback(CONFIG_GPIO_S2, sw2_callback);
    GPIO_enableInt(CONFIG_GPIO_S1);
    GPIO_enableInt(CONFIG_GPIO_S2);

    //------------------------------------------------
    // Timer 32 Setup
    //------------------------------------------------
    Timer_init();
    Timer_Params_init(&t_params);
    t_params.period = 1000;
    t_params.periodUnits = Timer_PERIOD_US;
    t_params.timerMode = Timer_CONTINUOUS_CALLBACK;
    t_params.timerCallback = current_controller;
    timer0 = Timer_open(CONFIG_TIMER_0, &t_params);
    if (timer0 == NULL) {
        /* Failed to initialized timer */
        while (1) {}
    }
    if (Timer_start(timer0) == Timer_STATUS_ERROR) {
        /* Failed to start timer */
        while (1) {}
    }

    /* Open the display for output */
    display = Display_open(Display_Type_UART, NULL);
    if (display == NULL) {
        /* Failed to open display driver */
        while (1);
    }

    Display_printf(display, 0, 0, "Starting the acdcsinglechannel example\n");

    return (NULL);
}

  • Hello,

    The address, 0x40000c04, that is causing the error, looks to be Timer_A3 Capture/Compare Control 1 (TA3CCTL1) peripheral register. This can be seen in Table 6-5 of the datasheet (https://www.ti.com/lit/gpn/msp432p401r).

    The  documentation for the Timer_A in section 19.2 Timer_A Operation, has the following note: 

    "It is recommended to stop the timer before modifying its operation (with exception of the interrupt enable, interrupt flag, and TACLR) to avoid errant operating conditions. When the timer clock is asynchronous to the CPU clock, any read from TAxR should occur while the timer is not operating or the results may be unpredictable"

    Are you trying to access the TA3CCTL1 register while the timer is active?

    Srinivas

**Attention** This is a public forum