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/EK-TM4C123GXL: CCS v6 keeps triggering a hard fault that I can't diagnose. Can someone please help me out?

Part Number: EK-TM4C123GXL

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;
}