DAT290 / kod / USART / USART.c
USART.c
Raw
// USART
#include <USART.h>

#define USART1_IRQVEC		((void (**)(void)) 0x2001C0D4)

// Buffer variable for the current character.
char USART_INPUT_COLLECTOR;

// Status variable for the entire input string (up to 128 characters).
char USART_ALL_INPUT_COLLECTED[127];

// The length of the current input string.
short USART_CHAR_COUNTER = 0;

// USART Interrupt handler.
void USART_IRQ_ROUTINE(void){
	// If the RXNE flag is set, receive character to the buffer variable.
	if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET){
		USART_INPUT_COLLECTOR = (char) USART_ReceiveData(USART1);
		
		// If there's a new character input.
		if(USART_INPUT_COLLECTOR){
			// Add the character to the entire input string.
			USART_ALL_INPUT_COLLECTED[USART_CHAR_COUNTER] = USART_INPUT_COLLECTOR;
			USART_CHAR_COUNTER++;
			
			// Print the character to the USART-terminal.
			printChar(USART_INPUT_COLLECTOR);
			
			// If the enter key is pressed, check for commands and reset.
			if(USART_INPUT_COLLECTOR == '\n' && USART_CHAR_COUNTER > 0){
				checkForCommandInput();
				memset(USART_ALL_INPUT_COLLECTED, 0, 128);	
				USART_CHAR_COUNTER = 0;
			}
		}
	}
	
		
		USART_INPUT_COLLECTOR = 0;
}

// Init USART.
void initUSART(){
		
		USART_OverSampling8Cmd(USART1, ENABLE);  
	
		USART_InitTypeDef USART1_Init;
		USART1_Init.USART_BaudRate = 115200;
		USART1_Init.USART_WordLength = USART_WordLength_8b;
		USART1_Init.USART_StopBits = USART_StopBits_1;
		USART1_Init.USART_Parity = USART_Parity_No;
		USART1_Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
		USART1_Init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
		
		// Init baudrate, wordlength, parity and enable reciever/transmitter.
		USART_Init(USART1, &USART1_Init); 
		
		
		// Init NVIC
		NVIC_InitTypeDef USART1_NVIC;
		USART1_NVIC.NVIC_IRQChannel = USART1_IRQn;
		USART1_NVIC.NVIC_IRQChannelPreemptionPriority = 0;
		USART1_NVIC.NVIC_IRQChannelSubPriority = 0;
		USART1_NVIC.NVIC_IRQChannelCmd = ENABLE;
		
		NVIC_Init(&USART1_NVIC);
		
		// Interrupt when RXNEIE is set.
		USART_ITConfig(USART1, USART_IT_ORE_RX, ENABLE); 
		
		// Specify what function will be run on the interrupt.
		*USART1_IRQVEC = USART_IRQ_ROUTINE;
		
		// Enable USART1.
		USART_Cmd(USART1, ENABLE);
}


void printChar(char c){
	while((USART1->SR & (1 << 7)) == 0);
	USART_SendData(USART1, (short) c);
}

void print(char* s){
	while (*s != '\0')
		printChar(*(s++));
		
	printChar('\n');
}

CommandString* stringToCommandStringArray(char* s, CommandString* arr[]){
	
	short commandCounter = 0;
	// Index used to extract the next command/property from the string.
	short prevCommandIndex = 0;
	// Loop through input string.
	for(int i = 0; i < strlen(s); i++){
		if(s[i] == ' ' && s[i+1] != ' '){
			// Allocate memory for a new command and assign a pointer to it.
			CommandString* tmp;
			tmp = malloc(sizeof(CommandString));
			// Assign command string to the allocated command-type variable.
			assignCommandProperties(tmp, prevCommandIndex, (i - prevCommandIndex));
			
			// Put the pointer inside the array of commands.
			arr[commandCounter] = tmp;
			commandCounter++;
			
			// This is the index where the next command should start, unless there are extra spaces inbetween commands or properties.
			prevCommandIndex = i + 1; 
		}
	}
	
	// Create a pointer to the last command/property in the input string and add it to the array of commands. 
	CommandString* tmp;
	tmp = malloc(sizeof(CommandString));
	assignCommandProperties(tmp, prevCommandIndex, (USART_CHAR_COUNTER - prevCommandIndex - 1));
	arr[commandCounter] = tmp;
	return arr;
}


/*
 * assignCommandProperties() - a function used to assign a command value
 * and command length to the specified variable of type Command *. 
 * 
 * See USART.h for the "Command" type definition.
 */

void assignCommandProperties(CommandString* assignVar, int commandStartIndex, int commandLength){
		
		// Allocate enougth memory for the command string.
		assignVar->command = malloc( sizeof(char) * commandLength);
		int count = 0;
		for(int i = 0; i < commandLength; i++){
			count++;
			// Declare each character from the command string one by one.
			assignVar->command[i] = USART_ALL_INPUT_COLLECTED[commandStartIndex + i];
		}
		
		
		// Declare the command length.
		assignVar->commandLength = commandLength;
}



/*
 * checkForCommandInput - a function used to search the input string for commands and properties.
 * If a command is found, it will be executed.
 * 1 command with a maximum of 8 properties can be executed at once.
 * 
 * See USART.h for the "Command" type definition.
 */
 

void checkForCommandInput(void){
	// Counter for the total number of commands or properties (seperated by a space character);
	short commandCounter = 0;
	// Index used to extract the next command/property from the string.
	short prevCommandIndex = 0;

	
	// Initialize an array that can contain 9 command-type pointers.
	CommandString* commands[8];
	// Reset the array of commands.
  	memset(commands, 0, 8);


	// Loop through input string.
	for(int i = 0; i < USART_CHAR_COUNTER; i++){
		if(USART_ALL_INPUT_COLLECTED[i] == ' ' && USART_ALL_INPUT_COLLECTED[i+1] != ' '){
			// Allocate memory for a new command and assign a pointer to it.
			CommandString* tmp;
			tmp = malloc(sizeof(CommandString));
			// Assign command string to the allocated command-type variable.
			assignCommandProperties(tmp, prevCommandIndex, (i - prevCommandIndex));
			
			// Put the pointer inside the array of commands.
			commands[commandCounter] = tmp;
			commandCounter++;
			
			// This is the index where the next command should start, unless there are extra spaces inbetween commands or properties.
			prevCommandIndex = i + 1; 
		}
	}
	
	// Create a pointer to the last command/property in the input string and add it to the array of commands. 
	CommandString* tmp;
	tmp = malloc(sizeof(CommandString));
	assignCommandProperties(tmp, prevCommandIndex, (USART_CHAR_COUNTER - prevCommandIndex - 1));
	commands[commandCounter] = tmp;
	commandCounter++;
	
	for(int i = 0; i < commandCounter; i++){
		if((short)strlen(commands[i]->command) > commands[i]->commandLength){
			commands[i]->command[commands[i]->commandLength] = 0;
		}
	}
	

	commandHandler(commands, commandCounter);
	
	// Free the commands from the memory and set the pointers to 0;
	for(int i = 0; i < commandCounter; i++){
		free(commands[i]);
		commands[i] = 0;
	}
	
}