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.
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
Archaeologist said:Do you have any multiplication code in any interrupt routine? Are you using the option --disable_interrupts_around_hw_mpy?
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?
when debugging the code stopsGeorge Mock said:gerald talleyDuring debugging software breaks in MULT16_F5HW.ASMWhat do you see that makes you think something has gone wrong? Exactly how do you see it?
Thanks and regards,
-George
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?
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?
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."
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
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
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