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.

Compiler/MSP430FR5959: During debugging software breaks in MULT16_F5HW.ASM

Part Number: MSP430FR5959

Tool/software: TI C/C++ Compiler

During debugging software breaks in MULT16_F5HW.ASM.

what does this means? i have no clue! Seams to be related to an interrupt im using

  • gerald talley said:
    During debugging software breaks in MULT16_F5HW.ASM

    What do you see that makes you think something has gone wrong?  Exactly how do you see it?

    Thanks and regards,

    -George

  • Is your stack big enough to handle interrupts in the worse-case stack depth?
  • Do you have any multiplication code in any interrupt routine? Are you using the option --disable_interrupts_around_hw_mpy?
  • Archaeologist said:
    Do you have any multiplication code in any interrupt routine? Are you using the option --disable_interrupts_around_hw_mpy?

    I had a modulus operation.. but when I took that out.. it causes the problem...
    also I don't see that option set anyways..
  • I never messed with the stack size before.. where do I start?
  • Look at the build console window. There you will see the complete command line for every compiler and linker invocation.

    Try adding the option --disable_interrupts_around_hw_mpy=on; if this resolves the problem, we might be able to narrow down the problem.

    Usually the linker command file sets the size of the stack. You can see which size the linker chose by looking at the linker map file for the section .stack. There should be a project property setting for stack size; perhaps under Build > MSP Linker > Basic Options ?
  • I added --disable_interrupts_around_hw_mpy=on to complier flags.. does not seem to do anything.. also under basic options stack size is 160.. I changed it to 400 had no effect.. I have been use msp430 to do all kind of things. I never seen this come up before.. not really doing much on this cpu..
  • few other things I'm finding..

    I has some ADC inputs.. I use the following code many times.. these instruction take about 2ms to run... time was never an issue this cpu is not doing much.. but I decided to rewrite with constants..

    current1 = (unsigned long) getADC(ADC_CS1) * 2500 / 0x0FFF / 6.8;
    current2 = (unsigned long) getADC(ADC_CS2) * 2500 / 0x0FFF / 6.8;
    voltage = (unsigned long) getADC(ADC_VS) * 2500 / 0x0FFF * 7.8;

    current1 = getADC(ADC_CS1) * 10 / 111; 
    current2 = getADC(ADC_CS2) * 10 / 111; 
    voltage = getADC(ADC_VS) * 14 / 3;

    some precision is lost but this code take  .75ms to run now. and code has no issues..

    next I changed it to this as a test..

    current1 = getADC(ADC_CS1) * 10 / 111; 
    current2 = getADC(ADC_CS2) * 10 / 111; 
    voltage = getADC(ADC_VS) * 4.7;

    Using floating point increase the time.. and my code breaks in MULT16_F5HW.ASM again..

    when it breaks it stops at NOP instruction.. I still don't get what is happening here.. why is CCS breaking on the NOP instruction?

  • few other things I'm finding..

    I has some ADC inputs.. I use the following code many times.. these instruction take about 2ms to run... time was never an issue this cpu is not doing much.. but I decided to rewrite with constants..

    current1 = (unsigned long) getADC(ADC_CS1) * 2500 / 0x0FFF / 6.8;
    current2 = (unsigned long) getADC(ADC_CS2) * 2500 / 0x0FFF / 6.8;
    voltage = (unsigned long) getADC(ADC_VS) * 2500 / 0x0FFF * 7.8;

    current1 = getADC(ADC_CS1) * 10 / 111; 
    current2 = getADC(ADC_CS2) * 10 / 111; 
    voltage = getADC(ADC_VS) * 14 / 3;

    some precision is lost but this code take  .75ms to run now. and code has no issues..

    next I changed it to this as a test..

    current1 = getADC(ADC_CS1) * 10 / 111; 
    current2 = getADC(ADC_CS2) * 10 / 111; 
    voltage = getADC(ADC_VS) * 4.7;

    Using floating point increase the time.. and my code breaks in MULT16_F5HW.ASM again..

    when it breaks it stops at NOP instruction.. I still don't get what is happening here.. why is CCS breaking on the NOP instruction?

  • George Mock said:

    gerald talley
    During debugging software breaks in MULT16_F5HW.ASM

    What do you see that makes you think something has gone wrong?  Exactly how do you see it?

    Thanks and regards,

    -George

    when debugging the code stops

    few other things I'm finding..
    I has some ADC inputs.. I use the following code many times.. these instruction take about 2ms to run... time was never an issue this cpu is not doing much.. but I decided to rewrite with constants..
    current1 = (unsigned long) getADC(ADC_CS1) * 2500 / 0x0FFF / 6.8;
    current2 = (unsigned long) getADC(ADC_CS2) * 2500 / 0x0FFF / 6.8;
    voltage = (unsigned long) getADC(ADC_VS) * 2500 / 0x0FFF * 7.8;

    current1 = getADC(ADC_CS1) * 10 / 111; 
    current2 = getADC(ADC_CS2) * 10 / 111; 
    voltage = getADC(ADC_VS) * 14 / 3;
    some precision is lost but this code take  .75ms to run now. and code has no issues..
    next I changed it to this as a test..
    current1 = getADC(ADC_CS1) * 10 / 111; 
    current2 = getADC(ADC_CS2) * 10 / 111; 
    voltage = getADC(ADC_VS) * 4.7;
    Using floating point increase the time.. and my code breaks in MULT16_F5HW.ASM again..
    when it breaks it stops at NOP instruction.. I still don't get what is happening here.. why is CCS breaking on the NOP instruction?

  • You really ought to avoid floating point arithmetic if you can, as the MSP430 doesn't have floating point hardware. It must simulate the floating point arithmetic in library code, which takes an extra-long time. You might be tripping the watchdog timer. Try disabling the watchdog timer to see if the problem persists.

    I have no idea why CCS is breaking on that NOP instruction; it's probably a side effect of the real problem.

    You mentioned that this problem seemed to be related to an interrupt in your system. Which interrupt? Do you have an interrupt handler for this interrupt?

    You've shown us computations for current and voltage; are any of these statements in an interrupt routine?
  • I have a interrupt routine for comm.... also have some pins for a quadrature encoder.. I still get this problem with this code disabled..
  • In your first post, you said that the problem "seems to be related to an interrupt I'm using;" what led you to suspect the problem was related to the interrupt? Do you still believe it could be related?
  • Archaeologist said:
    In your first post, you said that the problem "seems to be related to an interrupt I'm using;" what led you to suspect the problem was related to the interrupt? Do you still believe it could be related?

    i did more testing..  i tried doing this.. i set a bit high when i enter my comm interrupt..and set it low at the end.. when the code breaks the pin is low.. i did this for both interrupts... now that i removed floating point the error is less common but i still get it.. also if i leave the comm disconnected i don't seem to get the error..
    the break happens at this code
    __mpyi_f5hw:  .asmfunc  stack_usage(2 + RETADDRSZ)
     PUSH.W SR   ; Save current interrupt state
     DINT    ; Disable interrupts
     NOP    ; Account for latency <<<<<<<<<<<<<<<<<<<<<<<<<breaks here..
     MOV.W OP1,&MPY_OP1  ; Load operand 1 into multiplier
     MOV.W OP2,&MPY_OP2  ; Load operand 2 which triggers MPY
     MOV.W &RESULT, R12  ; Move result into return register 
    the break is right after Disable interrupts...but it don't appear to be in the comm or quad interrupt when it halts...
    i did the pin high low thing before and after the math code and when the code halts the pin is high...
    i am not familiar with how the cpu is handling the multiply code... is it something that occurs when it trys to disable the interrupts?
  • Very interesting... at this point we need a MSP430 hardware expert to look at the problem.  I don't think we're going to be able to help you much further on the compiler forum, as this is a hardware issue and we're compiler experts.  As a wild guess, it's plausible that using DINT forces the CPU to service some pending interrupt before disabling interrupts, which would probably appear to occur right at that NOP..

    Some MSP430 devices (such as the F5 series) have hardware multiplication hardware, but it's not done in the CPU; instead there is a multiply peripheral.  You perform a multiplication by writing to special dedicated memory-mapped registers, waiting the appropriate number of cycles, and reading the result from the RESULT register.  Because computing a multiplication requires global state, the library makes a critical region around the use of the multiply peripheral so that you can't have an interrupt occur and perform a multiplication while the multiply peripheral is already busy, which would corrupt both results.  Thus, it's important to coordinate between interrupts and the multiplication hardware.  This is described briefly in the MSP430 Compiler User's Guide section 2.3.4 "Run-Time Model Options."

    MSP430 Compiler User's Guide downloads.ti.com/.../

  • Hi Gerald,

    You are using the MSP430FR5959 device, correct? This device has a MPY32 hardware multiplier module, so what Archaeologist said in his last post about how the library handles this should apply to this device.

    Do any of your ISRs call other functions? Do you have any nested interrupts (not recommended) which would mean enabling the interrupt during the ISR? Maybe you could share your ISR code? Where in your code do your multiplies take place? 
     
    Regards,
    Katie

  • Here is my code below.. comm isr has a lot going on but its pretty fast.. and I use this code a lot.. the quad isr is really basic.. when interrupt on pin happens it check another pin and increment or decrement a counter.. timer is simple as well.. when my code halts is there a way I can see the stack? to see if my stack is overflowing? what makes the code decide to break? everytime I think I changed something and its working great.. I get a stop... I'm not doing any mult or div functions in any of the isr.. not calling any functions.. where is the collision happening I cant find it..

    //timer
    #pragma vector=TIMER1_A1_VECTOR
    __interrupt void TIMER1_A3_ISR(void) {
    switch (__even_in_range(TA1IV, 14)) {
    case 0:
    break; // No interrupt
    case 2:
    flag_50ms = 1;
    TA1CCR1 += 20000;
    break; // CCR1
    case 4:
    flag_250ms = 1;
    TA1CCR2 = 100000;
    break; // CCR2
    case 6:
    break; // reserved
    case 8:
    break; // reserved
    case 10:
    break; // reserved
    case 12:
    break; // reserved
    case 14:
    break; // overflow
    default:
    break;
    }
    }

    //quad
    #pragma vector=PORT1_VECTOR
    __interrupt void P1(void) {
    if (P1IFG & BIT0) {
    if (P1IN & BIT1)
    count1 -= 100;
    else
    count1 += 100;
    } else if (P1IFG & BIT2) {
    if (P1IN & BIT3)
    count2 -= 100;
    else
    count2 += 100;
    }
    P1IFG = 0;
    }

    #pragma vector=USCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void) {

    switch (_even_in_range(UCA0IV, 18)) {
    case 0: //vector 0 no interrupt
    break;
    case 2: //vector 2 UCRXIFG
    if ((UCA0STATW & UCADDR) == 2) {
    rx_state = 1;
    UCA0CTL1 |= UCDORM; //receives address-bit data only
    }
    switch (rx_state) {
    case 1:
    rx_address = UCA0RXBUF;
    rx_address2 = 0;
    xaddress = 0;
    if (rx_address == (camera1X_gc_adr + thisAddress)) {
    UCA0CTL1 &= ~UCDORM;
    rx_state = 2;
    } else if (rx_address == camera_gc_adr) {
    UCA0CTL1 &= ~UCDORM;
    rx_state = 3;
    } else if (rx_address == cameratilt_gc_adr) {
    UCA0CTL1 &= ~UCDORM;
    xaddress = data_Camera_Tilt;
    goto jump;
    }
    break;
    case 2: //extended address
    rx_address2 = UCA0RXBUF;
    if (rx_address2 & 0x40) {
    if (rx_address2 == 0x41) {
    lrc = rx_address ^ rx_address2;
    rx_state = 9;
    segi = 0;
    }
    break;
    } else if (rx_address2 >= 16) {
    rx_state = 0;
    UCA0CTL1 |= UCDORM; //receives address-bit data only
    break;
    }
    jump: if (data[rx_address2 + xaddress].reg & reg_writeMode) {
    rx_state = 3;
    } else {
    unsigned int v;
    v = data[rx_address2 + xaddress].value;
    tx_data[0] = (v >> 8);
    tx_data[1] = v;
    tx_data[2] = tx_data[0] ^ tx_data[1] ^ rx_address ^ rx_address2;
    tx_state = 0;
    UCA0TXBUF = 0x66;
    UCA0CTL1 |= UCDORM;
    }
    break;
    case 3: //MSB
    msb = UCA0RXBUF;
    rx_state++;
    break;
    case 4: //LSB
    lsb = UCA0RXBUF;
    rx_state++;
    break;
    case 5: //LRC
    lrc = UCA0RXBUF;
    rx_state = 0; //resets rxstate
    UCA0CTL1 |= UCDORM; //receives address-bit data only

    if (rx_address == camera_gc_adr) {
    if ((rx_address ^ msb ^ lsb) == lrc) { //compute lrc. If lrc !=0, control_data is not saved .
    data[data_Camera_Control].value = lsb;
    commgood = 1;
    }
    } else if (rx_address ^ rx_address2 ^ msb ^ lsb == lrc) { //compute lrc. If lrc !=0, control_data is not saved .
    data[rx_address2 + xaddress].value = (msb << 8) + lsb;
    commgood = 1;
    }
    break;
    case 9: { //receive code source
    seg[segi] = UCA0RXBUF;
    lrc ^= seg[segi];
    eoflrc[segi] ^= seg[segi];
    segi++;
    if (segi == 19) {
    segi++;
    if (lrc == 0) {
    if (seg[0] == code_Address) { //address
    address = (*((unsigned long*) &seg[2]));
    add = (unsigned char*) (address - 0x8000);
    data[data_Thruster_UpdateStatus].value = (((unsigned long) add) & 0x7FFF);
    } else if (seg[0] == code_Line) {
    unsigned int i;
    for (i = 0; i < seg[1]; i++)
    *add++ = seg[i + 2];
    data[data_Thruster_UpdateStatus].value = (((unsigned long) add) & 0x7FFF);
    } else if (seg[0] == code_EOF) {
    unsigned int i;
    data[data_Thruster_UpdateStatus].value = 0xFFFF;
    for (i = 2; i <= 17; i++) {
    if (eoflrc[i]) {
    data[data_Thruster_UpdateStatus].value = 0xFEEE;
    break;
    }
    }
    } else if (seg[0] == code_Deploy) {
    if (data[data_Thruster_UpdateStatus].value == 0xFFFF)
    flag_depoy = 1;
    } else if (seg[0] == code_Start) {
    unsigned int i;
    for (i = 0; i < 19; i++)
    eoflrc[i] = 0;
    data[data_Thruster_UpdateStatus].value = 0xFDDD;
    }
    }
    }
    }

    }
    case 4:
    //vector 4 UCTXIFG
    break;
    case 6:
    //start bit received

  • also I had increased the stack to 400 still has the issue.. dropped it to 80 took a really long time.. I thought if it was a stack issue making the stack small who cause it to happen more often.. does not seems so.. I don't even know if at runtime would this be a real issue... or is it only a issue debugging....
  • in the compiler options there is.. inline hardware multiply version of RTS mpy routine...
    if I set this to none.. could this disable this? does not even seem the math takes longer to compute?
  • Hi Gerald,

    There is some information here about trying to identify stack overflow or how much stack you are using: processors.wiki.ti.com/.../Stack_and_Heap_size_requirements It is for CCSv4 but I think it should still apply. There is a feature in CCS for break on stack overflow - I wonder if that might be enabled by default?

    Do you have any other breakpoints enabled when you are running these tests?

    Regards,
    Katie

  • Hi Gerald,

    Are you still encountering the issue? Is there anything else we can do to help?

    Regards,
    Katie
  • I ending up just disabling the hw multiplier.. I guess just had too many over lapping interrupts and was getting overflow..  if the math takes a little longer to run it will not matter in the application.

**Attention** This is a public forum