From 214617ed1fc856bb4eaf538766902ba96ce7c592 Mon Sep 17 00:00:00 2001 From: Jonas Holmberg Date: Tue, 4 Oct 2016 13:38:44 +0200 Subject: [PATCH] CLI things CLI full func and some extra eeprom --- UAV-ControlSystem/LinkerScript.ld | 19 +- UAV-ControlSystem/inc/config/cli.h | 21 + UAV-ControlSystem/inc/config/eeprom.h | 121 +++++- UAV-ControlSystem/src/config/cli.c | 549 ++++++++++++++++++++++++++ UAV-ControlSystem/src/config/eeprom.c | 30 +- UAV-ControlSystem/src/main.c | 7 +- 6 files changed, 732 insertions(+), 15 deletions(-) create mode 100644 UAV-ControlSystem/inc/config/cli.h create mode 100644 UAV-ControlSystem/src/config/cli.c diff --git a/UAV-ControlSystem/LinkerScript.ld b/UAV-ControlSystem/LinkerScript.ld index 0e2c315..d9dbc02 100644 --- a/UAV-ControlSystem/LinkerScript.ld +++ b/UAV-ControlSystem/LinkerScript.ld @@ -59,11 +59,26 @@ _Min_Heap_Size = 0; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Memories definition */ +/* Sector addresses and lengths +0x08000000 //Secotr 0, size: 16Kb +0x08004000 //Secotr 1, size: 16Kb +0x08008000 //Secotr 2, size: 16Kb +0x0800C000 //Secotr 3, size: 16Kb +0x08010000 //Secotr 4, size: 64Kb +0x08020000 //Secotr 5, size: 128Kb +0x08040000 //Secotr 6, size: 128Kb +0x08060000 //Secotr 7, size: 128Kb +0x08080000 //Secotr 8, size: 128Kb +0x080A0000 //Secotr 9, size: 128Kb +0x080C0000 //Secotr 10, size: 128Kb +0x080E0000 //Secotr 11, size: 128Kb*/ +/* Use sector 0-6 for rom and sectoer 7 for EEPROM if it should work on both the revo board and nucleo dev board */ +/* Otherwise if only to be used on the revo board use 0-7 for rom and 11 forEEPROM */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K - ROM (rx) : ORIGIN = 0x8000000, LENGTH = 512K - EEPROM (xrw) : ORIGIN = 0x80E0000, LENGTH = 128K + ROM (rx) : ORIGIN = 0x8000000, LENGTH = 384K + EEPROM (xrw) : ORIGIN = 0x08060000, LENGTH = 128K } /* Sections */ diff --git a/UAV-ControlSystem/inc/config/cli.h b/UAV-ControlSystem/inc/config/cli.h new file mode 100644 index 0000000..d510730 --- /dev/null +++ b/UAV-ControlSystem/inc/config/cli.h @@ -0,0 +1,21 @@ +/* + * cli.h + * + * Created on: 30 sep. 2016 + * Author: holmis + */ + +#ifndef CONFIG_CLI_H_ +#define CONFIG_CLI_H_ + + +/*********************************************************************** +* BRIEF: Call will start the cli loop * +* INFORMATION: Should be invoked if you want to start the cli loop, * +* will try to read instructions until told to stop. * +* Will not be part of the regular scheduler loop. * +***********************************************************************/ +void cliRun(); + + +#endif /* CONFIG_CLI_H_ */ diff --git a/UAV-ControlSystem/inc/config/eeprom.h b/UAV-ControlSystem/inc/config/eeprom.h index 6237a15..c34b9dc 100644 --- a/UAV-ControlSystem/inc/config/eeprom.h +++ b/UAV-ControlSystem/inc/config/eeprom.h @@ -18,9 +18,119 @@ #ifndef CONFIG_EEPROM_H_ #define CONFIG_EEPROM_H_ +#include "stm32f4xx.h" -/* Defines where emulated EEPROM starts from - OBS! Also defined in LinkerScript.id */ -#define EEPROM_BASE_ADDR 0x080DAC00 //0x080E0000 +/* Macros used to check if a define has no value assigned */ +#define DO_EXPAND(VAL) VAL ## 1 +#define EXPAND(VAL) DO_EXPAND(VAL) + +/* Defines the base addresses for each sector of the flash memory */ +#define FLASH_SECTOR_0_START_ADDRESS 0x08000000 //Secotr 0 +#define FLASH_SECTOR_1_START_ADDRESS 0x08004000 //Secotr 1 +#define FLASH_SECTOR_2_START_ADDRESS 0x08008000 //Secotr 2 +#define FLASH_SECTOR_3_START_ADDRESS 0x0800C000 //Secotr 3 +#define FLASH_SECTOR_4_START_ADDRESS 0x08010000 //Secotr 4 +#define FLASH_SECTOR_5_START_ADDRESS 0x08020000 //Secotr 5 +#define FLASH_SECTOR_6_START_ADDRESS 0x08040000 //Secotr 6 +#define FLASH_SECTOR_7_START_ADDRESS 0x08060000 //Secotr 7 +#define FLASH_SECTOR_8_START_ADDRESS 0x08080000 //Secotr 8 +#define FLASH_SECTOR_9_START_ADDRESS 0x080A0000 //Secotr 9 +#define FLASH_SECTOR_10_START_ADDRESS 0x080C0000 //Secotr 10 +#define FLASH_SECTOR_11_START_ADDRESS 0x080E0000 //Secotr 11 + +/* Define size gor each sector in bytes */ +#define FLASH_SIZE_16_KB 0x3FFF //16 Kb +#define FLASH_SIZE_64_KB 0xFFFF //64 Kb +#define FLASH_SIZE_128_KB 1FFFF //128 kb + +/* ToDo: Could add a check for this in the system. If the ammount of data that + * should be stored in the selected sector is larger than the size + * it could produce an error */ +#define FLASH_SECTOR_0_SIZE FLASH_SIZE_16_KB +#define FLASH_SECTOR_1_SIZE FLASH_SIZE_16_KB +#define FLASH_SECTOR_2_SIZE FLASH_SIZE_16_KB +#define FLASH_SECTOR_3_SIZE FLASH_SIZE_16_KB +#define FLASH_SECTOR_4_SIZE FLASH_SIZE_64_KB +#define FLASH_SECTOR_5_SIZE FLASH_SIZE_128_KB +#define FLASH_SECTOR_6_SIZE FLASH_SIZE_128_KB +#define FLASH_SECTOR_7_SIZE FLASH_SIZE_128_KB +#define FLASH_SECTOR_8_SIZE FLASH_SIZE_128_KB +#define FLASH_SECTOR_9_SIZE FLASH_SIZE_128_KB +#define FLASH_SECTOR_10_SIZE FLASH_SIZE_128_KB +#define FLASH_SECTOR_11_SIZE FLASH_SIZE_128_KB + + +/* Defines where emulated EEPROM starts from - OBS! Also defined in LinkerScript.id + * + * NOTE - Use sector 7 if it should work on both the revo and nucleo boards + * If only to be used on the revo board use sector 11. + * + * Important - If sectoer 7 is used, make sure the ROM only uses 0-6 in the + * LinkerScript.id file*/ +#define EEPROM_BASE_ADDR FLASH_SECTOR_7_START_ADDRESS +#if !defined(EEPROM_BASE_ADDR) || (EXPAND(EEPROM_BASE_ADDR) == 1) +#error "No valid sector address have been defined for the EEPROM" +#endif + +/* The sector to delete based on what is used as EEPROM. When the EEPROM should + * be rewritten it needs to delete the current values in the EEPROM. This is + * Based on what section is defined to be used for the EEPROM. */ +#if EEPROM_BASE_ADDR == FLASH_SECTOR_0_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_0 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_0_SIZE +#elif EEPROM_BASE_ADDR == FLASH_SECTOR_1_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_1 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_1_SIZE +#elif EEPROM_BASE_ADDR == FLASH_SECTOR_2_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_2 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_2_SIZE +#elif EEPROM_BASE_ADDR == FLASH_SECTOR_3_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_3 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_3_SIZE +#elif EEPROM_BASE_ADDR == FLASH_SECTOR_4_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_4 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_4_SIZE +#elif EEPROM_BASE_ADDR == FLASH_SECTOR_5_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_5 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_5_SIZE +#elif EEPROM_BASE_ADDR == FLASH_SECTOR_6_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_6 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_6_SIZE +#elif EEPROM_BASE_ADDR == FLASH_SECTOR_7_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_7 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_7_SIZE +#elif EEPROM_BASE_ADDR == FLASH_SECTOR_8_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_8 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_8_SIZE +#elif EEPROM_BASE_ADDR == FLASH_SECTOR_9_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_9 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_9_SIZE +#elif EEPROM_BASE_ADDR == FLASH_SECTOR_10_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_10 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_10_SIZE +#elif EEPROM_BASE_ADDR == FLASH_SECTOR_11_START_ADDRESS +#define EEPROM_SECTOR_ERASE FLASH_SECTOR_11 +#define EEPROM_SECTOR_SIZE FLASH_SECTOR_11_SIZE +#else +#error "No valid sector address have been decided for the EEPROM" +#endif + + +/* Defines for what type of value something is, system, profile etc */ +#define EEPROM_VALUE_TYPE_SYSTEM 1 +#define EEPROM_VALUE_TYPE_PROFILE 2 + + +/*********************************************************************** +* BRIEF: List of all EEPROM values * +* INFORMATION: This content of this struct will be used in EEPROM * +***********************************************************************/ +typedef enum { + EEPROM_ADC_SCALES = 0, + EEPROM_UART1_RX_INV, + + EEPROM_COUNT // Needs to be the last element as is used as counter +} EEPROM_ID_t; /*********************************************************************** * BRIEF: Writes EEPROM data to FLASH * @@ -34,5 +144,12 @@ void writeEEPROM(); ***********************************************************************/ void readEEPROM(); +/*********************************************************************** +* BRIEF: Gets the address of a value from an id * +* INFORMATION: Gets the address of a dataPtr based on a given ID. +* The val "dataType" will specify if it is a system of a * +* profile variable. * +***********************************************************************/ +void * getDataAddresFromID(uint16_t id, uint8_t dataType); #endif /* CONFIG_EEPROM_H_ */ diff --git a/UAV-ControlSystem/src/config/cli.c b/UAV-ControlSystem/src/config/cli.c new file mode 100644 index 0000000..351ebc6 --- /dev/null +++ b/UAV-ControlSystem/src/config/cli.c @@ -0,0 +1,549 @@ +/* + * cli.c + * + * Created on: 30 sep. 2016 + * Author: holmis + */ + +#include "config/cli.h" +#include "stdint.h" +#include "config/eeprom.h" +#include +#include + +#define commandValueError 0xFFFFFFFFFFFFFFFF + +#define maxStringSize 80 //Max sting size used for the messages +#define msgArraySize 3 //The number of words that a max command can contain (ex: set looptime 1000) + +#define commandSize_1 1 +#define commandSize_2 2 +#define commandSize_3 3 +#define commandSizeOffset msgArraySize +#define commandSize(x) 1 << (x-1) +#define commandMask(x, y) (commandSize(x) | (1 << (commandSizeOffset + y))) + +#define arrayPos_Action 0 //Command msg array position values: action +#define arrayPos_Command 1 //Command msg array position values: command +#define arrayPos_Value 2 //Command msg array position values: value + +typedef char typeString[maxStringSize]; +typedef struct typeStringArr { char val[maxStringSize]; } typeStringArr; + + +bool cliIsRunning = false; //Flag to tell if it is running +bool valueChanged = false; //Flag that keeps track on if any value has changed and not been saved +bool rebootSystemNeeded = false; //Flag that signifies that a value was changed that require the system to reboot + +/* ID values for the ACTIONS that CLI can perform */ +typedef enum +{ + ACTION_SET_VALUE = 0, //sets a value + ACTION_DUMP, //Writes back all the current values set + ACTION_SAVE, //Saves the all the changes + ACTION_UNDO, //Undoes all the non made changes + ACTION_HELP, //Get information on how the cli works + ACTION_GET_INFORMATION, //Get information in a specific value + ACTION_COMMANDS, //Get information on all the specific commands + ACTION_PROFILE, + + //The number of actions + ACTION_COUNT, + + ACTION_NOACTION //Not an legit action +}commandAction_t; + +/* Sting values for the corresponding ACTION_IDS from "commandAction_t". Needs to be in the same order as the enum values */ +const typeString commandAction_Strings[ACTION_COUNT] = { + "set", + "dump", + "save", + "undo", + "help", + "information", + "commands", + "profile" +}; + +const typeString commandActionInformation_Strings[ACTION_COUNT] = { + "set - Updates value for given variable.\n\r", + "dump - Gives the current information for all values.\n\r", + "save - Writes all the changes to the EEPROM.\n\r", + "undo - Undo all the unsaved changes by loading the stored values.\n\r", + "help - Gives information on how to use the CLI.\n\r", + "information - Provides information on a given value.\n\r", + "commands - Provides information on the available commands.\n\r", + "profile - Changes the active profile between the values (1-3).\n\r" +}; + +/* Size values for the values a command will require */ +typedef enum +{ + VAL_UINT_8 = 1, + VAL_INT_8, + VAL_UINT_16, + VAL_INT_16, + VAL_UINT_32, + VAL_INT_32, + VAL_UINT_64, + VAL_INT_64 +}valueTypes_t; + + +typedef struct +{ + uint32_t min; + uint32_t max; +}minMaxVal_t; + +typedef struct +{ + const char * name; //The name of the command + uint16_t commandId; //The id of the command, must be uniqe + uint16_t valueId; //The id of the value to change, given from the enum in EEPROM.h: + uint16_t valueIdLoc; //If it is part of system values, profile values, etc... + uint32_t addressValueOffset; //The offset to the value to be set, useful if the value is inside a struct, if just a standard val offset is 0 + uint8_t valueType; //The type the value will be given from the enum ValueTypes_t + minMaxVal_t valueRange; //The range the value must be inbetween, used as a failsafe check + +}cliCommandConfig_t; + +typedef enum +{ + COMMAND_ID_ADC_SCALES_VCC, + COMMAND_ID_ADC_SCALES_LEFT, + COMMAND_ID_ADC_SCALES_RIGHT, + + COMMAND_ID_COUNT, + + COMMAND_ID_NO_COMMAND +}command_Ids_t; + +//CommandId start at 1, 0 is and error value +/* expected signature of command: (OPERATON DATA VALUE) */ + +const cliCommandConfig_t commandTable[COMMAND_ID_COUNT] = { + + [COMMAND_ID_ADC_SCALES_VCC] = + { + "adc_scales_vcc", COMMAND_ID_ADC_SCALES_VCC, EEPROM_ADC_SCALES, EEPROM_VALUE_TYPE_SYSTEM, 0, VAL_UINT_32, .valueRange = {0, 200} + }, + [COMMAND_ID_ADC_SCALES_LEFT] = + { + "adc_scales_left", COMMAND_ID_ADC_SCALES_LEFT, EEPROM_ADC_SCALES, EEPROM_VALUE_TYPE_SYSTEM, 4, VAL_UINT_32, .valueRange = {0, 200} + }, + [COMMAND_ID_ADC_SCALES_RIGHT] = + { + "adc_scales_right", COMMAND_ID_ADC_SCALES_RIGHT, EEPROM_ADC_SCALES, EEPROM_VALUE_TYPE_SYSTEM, 8, VAL_UINT_32, .valueRange = {0, 200} + }, +}; + +void findSimilarCommands(char * msg) +{ + uint8_t minSimilarChars = 3; //At least 3 characters need to be similar for this to be considered + uint8_t maxSimilarCommands = 16; + uint16_t similarCommands[maxSimilarCommands]; //Max 16 values can be found to be similar + uint8_t similarCommandsCount = 0; + char localChar[32]; + + //Loop through the commandTable or until similar commands is full + for (int i = 0; i < COMMAND_ID_COUNT && similarCommandsCount <= maxSimilarCommands; i++) + { + + } + +} + +uint8_t getCommandAction(char msg[maxStringSize]) +{ + + for (int i = 0; i < ACTION_COUNT; i++) + { + if (strcmp(msg, commandAction_Strings[i]) == 0) + { + return i; + } + } + + + return ACTION_NOACTION; +} + +uint16_t getCommandId(char * msg) +{ + for (int i = 0; i < COMMAND_ID_COUNT; i++) + { + if (strcmp(msg, commandTable[i].name) == 0) + { + return commandTable[i].commandId; + } + } + + return COMMAND_ID_NO_COMMAND; +} + +bool isStringNumbers(char * msg) +{ + char c; + int i = 0; + while(c = msg[i], c != 0) + { + if (c >= 48 && c <= 57) + i++; + else + return false; + } + + return true; +} + +uint64_t parseToInt64(char * msg) +{ + uint64_t toReturn = 0; + uint64_t multiplier = 1; + int i; + + //Count the number of values in the char + for(i = 0; msg[i+1] != 0; i++); + + //iter each value from the back + for (;i >= 0; i--) + { + //switch each number value + switch((uint8_t)msg[i]) + { + case 48: //0 + toReturn = toReturn + 0 * multiplier; + break; + case 49: //1 + toReturn = toReturn + 1 * multiplier; + break; + case 50: //2 + toReturn = toReturn + 2 * multiplier; + break; + case 51: //3 + toReturn = toReturn + 3 * multiplier; + break; + case 52: //4 + toReturn = toReturn + 4 * multiplier; + break; + case 53: //5 + toReturn = toReturn + 5 * multiplier; + break; + case 54: //6 + toReturn = toReturn + 6 * multiplier; + break; + case 55: //7 + toReturn = toReturn + 7 * multiplier; + break; + case 56: //8 + toReturn = toReturn + 8 * multiplier; + break; + case 57: //9 + toReturn = toReturn + 9 * multiplier; + break; + } + multiplier = multiplier * 10; + } + + return toReturn; +} + +uint64_t getCommanValue(char * msg) +{ + //Check if the msg are only valid numbers (0-9). If they are not retun max value of 64 bit int that will serve as an error + if (!isStringNumbers(msg)) + { + return commandValueError; + } + + return parseToInt64(msg); +} + + +bool processCommand(uint8_t action, uint16_t id, uint64_t value) +{ + //check if value is within the allowed area, if not return + if ( !(value >= commandTable[id].valueRange.min && value <= commandTable[id].valueRange.max) ) + { + //usart_send("Value not within ranges: %d - %d", commandTable[id].valueRange.min, commandTable[id].valueRange.max); + return false; + } + + //Get the correct pointer to the data + void * valuePointer = getDataAddresFromID(commandTable[id].valueId, commandTable[id].valueIdLoc); + + //adjust to the correct addres with the offset + valuePointer += commandTable[id].addressValueOffset; + + //switch on the value that this command should give + switch(commandTable[id].valueType) + { + case VAL_UINT_8: + *((uint8_t *)valuePointer) = value; + break; + case VAL_INT_8: + *((int8_t *)valuePointer) = value; + break; + case VAL_UINT_16: + *((uint16_t *)valuePointer) = value; + break; + case VAL_INT_16: + *((int16_t *)valuePointer) = value; + break; + case VAL_UINT_32: + *((uint32_t *)valuePointer) = value; + break; + case VAL_INT_32: + *((int32_t *)valuePointer) = value; + break; + case VAL_UINT_64: + *((uint64_t *)valuePointer) = value; + break; + case VAL_INT_64: + *((int64_t *)valuePointer) = value; + break; + } + + + return true; +} + +uint16_t calculateStringLength (char * src, int maxSize) +{ + uint16_t toReturn = 0; + for(int i = 0; src[i] != 0 ; i++) + { + toReturn ++; + } + return toReturn; +} + +uint32_t calculateArrayArrayLength(typeString arr[], int maxSize) +{ + int i = 0; + + for(i = 0; i < maxSize && arr[i][0] != 0; i++); + + return i; +} + +bool splitStringWhitespace(char * src, typeString dst[], uint16_t stringSize, uint16_t arraySize) +{ + + char currentChar; + uint32_t iterator = 0; //iterates through the string + uint32_t arrayIterator = 0; //iterates through the array positioning + uint32_t arrayStringIterator = 0; //iterates through the string inside the array + //Loop through the values in src, until we find \r(enter) or null + while(currentChar = src[iterator], currentChar != '\r' && currentChar != 0 ) + { + //check if whitespace + if (currentChar == ' ') + { + //increase the array iterator + arrayIterator ++; + if (arrayIterator >= arraySize) //check that its not to large + { + //usart_send("To many words in the command"); + return false; + } + + arrayStringIterator = 0; + goto increment; //continue to the next iteration, with a goto the increment + } + + dst[arrayIterator][arrayStringIterator] = src[iterator]; //set the char to the correct array position + arrayStringIterator ++; + if (arrayStringIterator >=stringSize) + { + return false; + } + + //Goto statement to jump to the incrementation +increment: + iterator ++; //increment iterator + } + + return true; +} + +void writeTaskInformation(uint16_t id) +{ + /* + //Get the correct pointer to the data + void * valuePointer = getDataAddresFromID(commandTable[id].valueId, commandTable[id].valueIdLoc); + + //adjust to the correct addres with the offset + valuePointer += commandTable[id].addressValueOffset; + + switch(commandTable[id].valueType) + { + case VAL_UINT_8: + usart_send("%s - Value: %d, allowed range: %d - %d\n\r", commandTable[id].name, *((uint8_t *)valuePointer), commandTable[id].valueRange.min, commandTable[id].valueRange.min); + break; + case VAL_INT_8: + usart_send("%s - Value: %d, allowed range: %d - %d\n\r", commandTable[id].name, *((int8_t *)valuePointer), commandTable[id].valueRange.min, commandTable[id].valueRange.min); + break; + case VAL_UINT_16: + usart_send("%s - Value: %d, allowed range: %d - %d\n\r", commandTable[id].name, *((uint16_t *)valuePointer), commandTable[id].valueRange.min, commandTable[id].valueRange.min); + break; + case VAL_INT_16: + usart_send("%s - Value: %d, allowed range: %d - %d\n\r", commandTable[id].name, *((int16_t *)valuePointer), commandTable[id].valueRange.min, commandTable[id].valueRange.min); + break; + case VAL_UINT_32: + usart_send("%s - Value: %d, allowed range: %d - %d\n\r", commandTable[id].name, *((uint32_t *)valuePointer), commandTable[id].valueRange.min, commandTable[id].valueRange.min); + break; + case VAL_INT_32: + usart_send("%s - Value: %d, allowed range: %d - %d\n\r", commandTable[id].name, *((int32_t *)valuePointer), commandTable[id].valueRange.min, commandTable[id].valueRange.min); + break; + case VAL_UINT_64: + usart_send("%s - Value: %d, allowed range: %d - %d\n\r", commandTable[id].name, *((uint64_t *)valuePointer), commandTable[id].valueRange.min, commandTable[id].valueRange.min); + break; + case VAL_INT_64: + usart_send("%s - Value: %d, allowed range: %d - %d\n\r", commandTable[id].name, *((int64_t *)valuePointer), commandTable[id].valueRange.min, commandTable[id].valueRange.min); + break; + } + */ +} + +void dumpTaskInformation() +{ + for (int i = 0; i < COMMAND_ID_COUNT; i++) + { + writeTaskInformation(commandTable[i].commandId); + } + //usart_send("----------------------\n\r"); +} + +void cliRun() +{ + //set running flag to true, when it should stop it should be set to false + cliIsRunning = true; + char * msg; //msg to be read from the usart + + //temporary values assigned for testing + //msg = "set adc_scales_left 134\r"; + msg = "commands\r"; + + //Will run until it is decided to stop + while(cliIsRunning) + { + cliIsRunning = false; + //ToDo: add usart reading for the commands + //ToDo: instead of sending the text send id numbers, need to make a custom program that can run on a standard computer for this + //msg = ProcessUsart(); + + //split string, first item should be and action, if second item should be id, last if used should be value + /**/ + //typeStringArr msgArr[msgArraySize] = {0}; + typeString msgArr[msgArraySize] = {0}; + if (!splitStringWhitespace(msg, msgArr, maxStringSize, msgArraySize)) + { + //usart_send("Wrong command format"); + + //Message was invalid do not try to process it + continue; + } + + //Get the amount of words in the command + uint32_t msgArrLength = calculateArrayArrayLength(msgArr, msgArraySize); + + + uint8_t actionId = getCommandAction(msgArr[arrayPos_Action]); //First check what type of action the command is, gives an id value for the action + uint16_t commandId; //Id for the command + uint64_t commandValue; + bool processSuccessfull; //Bool for if the command was processed successfully + + switch (commandMask(msgArrLength, actionId)) + { + case commandMask(commandSize_3, ACTION_SET_VALUE): + //Obtain the command id if it is exsits, otherwise produce an error + if ((commandId = getCommandId(msgArr[arrayPos_Command])) == COMMAND_ID_NO_COMMAND ) + { + //ToDo: add so that suggestions of what could be written instead is sent back + //usart_send("ERROR: No valid command given...\n\r"); + break; + } + + //Get the value of the command + if ((commandValue = getCommanValue(msgArr[arrayPos_Value])) == commandValueError) + { + //usart_send("ERROR: The value provided are not numerical...\n\r"); + break; + } + + //Try to process a given message + processSuccessfull = processCommand(actionId, commandId, commandValue); + if (processSuccessfull) + { + //Updated value correctly + //......usart_send("Updated value correctly...\n\r") + } + else + { + //could not update value + //......usart_send("Value not updated...\n\r") + } + break; + case commandMask(commandSize_1, ACTION_DUMP): + //dump informaton for all values that can be accessed in the commandTable + dumpTaskInformation(); + break; + case commandMask(commandSize_1, ACTION_SAVE): + //Write all the values that have been changed to the eprom + writeEEPROM(); + break; + case commandMask(commandSize_1, ACTION_UNDO): + //Undp all things that have not been saved by reading the current saved values in the eeprom + readEEPROM(); + break; + case commandMask(commandSize_1, ACTION_HELP): + //usart_send("Updates the values for variables in the system. To get a list of the commands write: commands.\n\r"); + break; + case commandMask(commandSize_2, ACTION_GET_INFORMATION): + if ((commandId = getCommandId(msgArr[arrayPos_Command])) == COMMAND_ID_NO_COMMAND ) + { + //ToDo: add so that suggestions of what could be written instead is sent back + //usart_send("ERROR: No valid command given...\n\r"); + break; + } + writeTaskInformation(commandId); + break; + case commandMask(commandSize_1, ACTION_COMMANDS): + //Gives information on all the tasks + //usart_send("All the commands that can be used: \n\r"); + for(int i=0; i < ACTION_COUNT; i++) + { + //usart_send(commandActionInformation_Strings[i]); + } + break; + case commandMask(commandSize_2, ACTION_PROFILE): + //Get the value of the command + if ((commandValue = getCommanValue(msgArr[arrayPos_Value-1])) == commandValueError) + { + //usart_send("ERROR: The value provided are not numerical...\n\r"); + break; + } + + //check if the value is within the ranges for possible profiles + if (!(commandValue >= 1 && commandValue <=3)) + { + //usart_send("ERROR: A profile value must be between 1-3...\n\r"); + } + + + + break; + default: + //usart_send("No valid command was provided to the system. \n Type "commands" for information on all the possible commands... \n \n ") + break; + } + + + + + } + +} + diff --git a/UAV-ControlSystem/src/config/eeprom.c b/UAV-ControlSystem/src/config/eeprom.c index ca8d427..34d29f2 100644 --- a/UAV-ControlSystem/src/config/eeprom.c +++ b/UAV-ControlSystem/src/config/eeprom.c @@ -19,16 +19,7 @@ #include "drivers/uart1_inverter.h" -/*********************************************************************** -* BRIEF: List of all EEPROM values * -* INFORMATION: This content of this struct will be used in EEPROM * -***********************************************************************/ -typedef enum { - EEPROM_ADC_SCALES = 0, - EEPROM_UART1_RX_INV, - EEPROM_COUNT // Needs to be the last element as is used as counter -} EEPROM_ID_t; /*********************************************************************** @@ -88,7 +79,7 @@ void writeEEPROM() HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR ); //FLASH_Erase_Sector(((uint32_t)11U),VOLTAGE_RANGE_3); - FLASH_Erase_Sector(((uint32_t)FLASH_SECTOR_11),VOLTAGE_RANGE_3); + FLASH_Erase_Sector(EEPROM_SECTOR_ERASE, VOLTAGE_RANGE_3); for (int i = 0; i < EEPROM_COUNT; i ++) { @@ -125,3 +116,22 @@ void readEEPROM() } HAL_FLASH_Lock(); } + +void * getDataAddresFromID(uint16_t id, uint8_t dataType) +{ + void * toReturn = NULL; + + //switch on the dataType to return it will return from a different array of data + //one for system vars another for the profile vars etc + switch(dataType) + { + case EEPROM_VALUE_TYPE_SYSTEM: + toReturn = eepromArr[id].dataPtr; + break; + case EEPROM_VALUE_TYPE_PROFILE: + break; + default: + break; + } + return toReturn; +} diff --git a/UAV-ControlSystem/src/main.c b/UAV-ControlSystem/src/main.c index f88bb15..59e4189 100644 --- a/UAV-ControlSystem/src/main.c +++ b/UAV-ControlSystem/src/main.c @@ -18,21 +18,26 @@ #include "utilities.h" #include #include "drivers/uart1_inverter.h" +#include "config/cli.h" int main(void) { - // Initialize the Hardware Abstraction Layer HAL_Init(); // Configure the system clock to 100 MHz system_clock_config(); + + adcScaleStruct_t.vcc_scale = 20; adcScaleStruct_t.i_scale_right = 10; adcScaleStruct_t.i_scale_left = 30; + //test cli + cliRun(); + for(;;) { writeEEPROM();