Tool/software: Code Composer Studio
Hey everyone, this is trying me absolutely mad.
I'm writing an API that is almost completely done, except for one function. This one function keeps triggering a hard fault with
NVIC_FAULT_STAT = 0x00009200
and
NVIC_FAULT_ADDR = 0x1FFFFFF4
I've looked at the diagnosing faults PDF from TI, and I still can't resolve my issue. I'd really appreciate any assistance on this, because i'm stuck.
Here is the offending function. It seems to work okay for whole numbers, but decimal values make it go haywire. It's gotta be something inside convert string to float.
clearArray(user_input, 100); getString(user_input); if(!strncmp(user_input, "setFrequency", 12)){ char out[20], intMode[3]; int out_factor, intModeDecision; double output_freq, result; unsigned short nINT; unsigned long nFRAC, nMOD; clearArray(out, 20); clearArray(intMode, 3); printString(new_line); printString(new_line); printString("Enter the desired output frequency: "); getString(out); printString(new_line); printString(new_line); printString("Integer mode? (\"y\" for integer, \"n\" for fractional): "); getString(intMode); intModeDecision = ConvertStringToBool(intMode); output_freq = ConvertStringToFrequency(out, &out_factor); result = GenerateFrequencyRatio(output_freq, out_factor, InternalReferenceValue, internalRefFactor); DetermineFeedbackValues(result, intModeDecision, &nINT, &nFRAC, &nMOD); SetFeedbackControlValues(nINT, nFRAC, nMOD); printString(new_line); printString(new_line); printString("Frequency has been set."); printString(new_line); printString(new_line); printString("Enter command: "); }
double ConvertStringToFrequency(char* string, int* factor) { // The frequency range will typically be GHz, so I wanted to avoid using large numbers since they are prone to rounding errors char value[20], unit[20]; char* value_ptr = value; char* unit_ptr = unit; int i; for (i = 0; i < 20; i++) { value[i] = '\0'; unit[i] = '\0'; } // Copy number portion into separate array (58 is the limit of the numbers inside the ASCII table) while (*string < 58) { *value_ptr = *string++; value_ptr++; } while (*string != ENTER) { *unit_ptr = *string++; unit_ptr++; } double value_flt = ConvertStringToFloat(value); if (!strncmp(unit, "GHz", 3)) { *factor = 9; // 10^9 power } else if (!strncmp(unit, "MHz", 3)) { *factor = 6; // 10^6 power } else if (!strncmp(unit, "kHz", 3)) { *factor = 3; // 10^3 power } else if (!strncmp(unit, "Hz", 3)) { *factor = 0; // 10^0 power } return value_flt; }
double ConvertStringToFloat(char* string) { char integerPart[20], decimalPart[21]; char* int_ptr = integerPart; char* dec_ptr = decimalPart; char* decimal_check = string; int i, flag = 0, decimal_flag = 0, mult = 0; unsigned long integer_portion, decimal_portion; double divider = 1, result; double intPart, decPart; // Clear out arrays for (i = 0; i < 20; i++) { integerPart[i] = '\0'; } for (i = 0; i < 21; i++) { decimalPart[i] = '\0'; } // Check for a decimal while (*decimal_check != '\0') { if (*decimal_check++ == '.') { decimal_flag = 1; } } if (decimal_flag) { // Copy integer portion into workspace while (*string != '.') { *int_ptr = *string++; int_ptr++; } // Copy decimal portion into workspace while (*string != '\0') { if (flag == 0) { string++; flag = 1; } else { *dec_ptr = *string++; dec_ptr++; mult++; } } integer_portion = ConvertStringToNumber(integerPart); decimal_portion = ConvertStringToNumber(decimalPart); intPart = (double)integer_portion; decPart = (double)decimal_portion; for (i = 0; i < mult; i++) { divider *= 10; } decPart /= divider; result = intPart + decPart; } else { // Copy integer portion (no decimal place) while (*string != '\0') { *int_ptr = *string++; int_ptr++; } integer_portion = ConvertStringToNumber(integerPart); intPart = (double)integer_portion; result = intPart; } return result; }
unsigned long ConvertStringToNumber(char* string) { // This function properly converts all legal values for an >>unsigned<< long integer: 0d - 4,294,967,295d // Number string MUST be in decimal format, this function isn't designed to accept hex values int i, digit, current_power = -1; unsigned long value = 0; char* temp_ptr; temp_ptr = string; while (*temp_ptr++ != '\0') { current_power++; } while (*string != '\0') { unsigned long multiplier = 1; for(i = current_power--; i > 0; i--) { multiplier *= 10; } switch (*string++) { case '0': digit = 0; break; case '1': digit = 1; break; case '2': digit = 2; break; case '3': digit = 3; break; case '4': digit = 4; break; case '5': digit = 5; break; case '6': digit = 6; break; case '7': digit = 7; break; case '8': digit = 8; break; case '9': digit = 9; break; } value += digit * multiplier; } return value; }