diff --git a/STM32F100_ParaTNC/makefile b/STM32F100_ParaTNC/makefile index f9ee3f0..024272a 100644 --- a/STM32F100_ParaTNC/makefile +++ b/STM32F100_ParaTNC/makefile @@ -24,8 +24,8 @@ RM := rm -rf -include system/src/cmsis/subdir.mk -include system/src/aprs/subdir.mk -include system/src/subdir.mk +-include src/stored_configuration_nvm/subdir.mk -include src/kiss_protocol/subdir.mk --include src/configuration_nvm/subdir.mk -include src/subdir.mk -include subdir.mk -include objects.mk diff --git a/STM32F100_ParaTNC/sources.mk b/STM32F100_ParaTNC/sources.mk index e5946b4..932c6df 100644 --- a/STM32F100_ParaTNC/sources.mk +++ b/STM32F100_ParaTNC/sources.mk @@ -28,8 +28,8 @@ CPP_DEPS := # Every subdirectory with source files must be described here SUBDIRS := \ src \ -src/configuration_nvm \ src/kiss_protocol \ +src/stored_configuration_nvm \ system/src/aprs \ system/src/cmsis \ system/src/cortexm \ diff --git a/include/kiss_communication/kiss_did.h b/include/kiss_communication/kiss_did.h new file mode 100644 index 0000000..7e6f089 --- /dev/null +++ b/include/kiss_communication/kiss_did.h @@ -0,0 +1,17 @@ +/* + * kiss_did.h + * + * Created on: Jul 2, 2023 + * Author: mateusz + */ + +#ifndef KISS_COMMUNICATION_KISS_DID_H_ +#define KISS_COMMUNICATION_KISS_DID_H_ + +#include + +uint8_t kiss_did_response(uint16_t identifier, uint8_t * output_buffer, uint16_t buffer_ln); + + + +#endif /* KISS_COMMUNICATION_KISS_DID_H_ */ diff --git a/include/kiss_communication/kiss_nrc_response.h b/include/kiss_communication/kiss_nrc_response.h new file mode 100644 index 0000000..e85acbd --- /dev/null +++ b/include/kiss_communication/kiss_nrc_response.h @@ -0,0 +1,16 @@ +/* + * kiss_nrc_generator.h + * + * Created on: Jul 2, 2023 + * Author: mateusz + */ + +#ifndef KISS_COMMUNICATION_KISS_NRC_RESPONSE_H_ +#define KISS_COMMUNICATION_KISS_NRC_RESPONSE_H_ + +#include + +int kiss_nrc_response_fill_unknown_service(uint8_t * buffer); +int kiss_nrc_response_fill_request_out_of_range(uint8_t * buffer); + +#endif /* KISS_COMMUNICATION_KISS_NRC_RESPONSE_H_ */ diff --git a/include/kiss_communication/kiss_xmacro_helpers.h b/include/kiss_communication/kiss_xmacro_helpers.h index 2e29bbf..4a86557 100644 --- a/include/kiss_communication/kiss_xmacro_helpers.h +++ b/include/kiss_communication/kiss_xmacro_helpers.h @@ -10,7 +10,7 @@ /** - * This macro is used to define + * This macro is used to define DIDs which return integer values */ #define DID_NUMERIC_DEFINITION_EXPANDER(id, first_data_pointer, second_data_pointer, third_data_pointer) \ { \ @@ -23,5 +23,19 @@ .third_data_size = sizeof(third_data_pointer) \ }, +/** + * Macro to define DID which return float data. Require separate handling as a size + * of single precision float number is the same than 32 bit integer + */ +#define DID_NUMERIC_FLOAT_DEFINITION_EXPANDER(id, first_data_pointer, second_data_pointer, third_data_pointer) \ + { \ + .identifier = id, \ + .first_data = (void*)first_data_pointer, \ + .first_data_size = 0, \ + .second_data = (void*)second_data_pointer, \ + .second_data_size = 0, \ + .third_data = (void*)third_data_pointer, \ + .third_data_size = 0 \ + }, #endif /* KISS_XMACRO_HELPERS_H_ */ diff --git a/include/stored_configuration_nvm/configuration_handler.h b/include/stored_configuration_nvm/configuration_handler.h index d618d6a..60fcefd 100644 --- a/include/stored_configuration_nvm/configuration_handler.h +++ b/include/stored_configuration_nvm/configuration_handler.h @@ -9,7 +9,7 @@ #define CONFIGURATION_HANDLER_H_ #include -#include "kiss_communication_nrc_t.h" +#include "kiss_communication/kiss_communication_nrc_t.h" typedef enum configuration_handler_region_t { diff --git a/src/kiss_protocol/kiss_callback.c b/src/kiss_protocol/kiss_callback.c index 7fa66d5..c5f3b9c 100644 --- a/src/kiss_protocol/kiss_callback.c +++ b/src/kiss_protocol/kiss_callback.c @@ -11,6 +11,8 @@ #include #include +#include +#include #include "main.h" #include @@ -145,15 +147,24 @@ int32_t kiss_callback_erase_startup(uint8_t* input_frame_from_host, uint16_t inp kiss_communication_nrc_t result = configuration_handler_erase_startup(); - // construct a response response_buffer[0] = FEND; response_buffer[1] = NONSTANDARD; response_buffer[2] = ERASE_STARTUP_LN; // message lenght - response_buffer[3] = KISS_ERASE_STARTUP_CFG_RESP; + + if (result == NRC_POSITIVE) { + // construct a response + response_buffer[3] = KISS_ERASE_STARTUP_CFG_RESP; + } + else { + response_buffer[3] = KISS_NEGATIVE_RESPONSE_SERVICE; + + } + response_buffer[4] = (uint8_t)result; response_buffer[5] = FEND; return ERASE_STARTUP_LN; + } /** @@ -192,7 +203,16 @@ int32_t kiss_callback_program_startup(uint8_t* input_frame_from_host, uint16_t i response_buffer[0] = FEND; response_buffer[1] = NONSTANDARD; response_buffer[2] = PROGRAM_STARTUP_LN; // message lenght - response_buffer[3] = KISS_PROGRAM_STARTUP_CFG_RESP; + + if (result == NRC_POSITIVE) { + // construct a response + response_buffer[3] = KISS_PROGRAM_STARTUP_CFG_RESP; + } + else { + response_buffer[3] = KISS_NEGATIVE_RESPONSE_SERVICE; + + } + response_buffer[4] = (uint8_t)result; response_buffer[5] = FEND; @@ -203,5 +223,30 @@ int32_t kiss_callback_read_did(uint8_t* input_frame_from_host, uint16_t input_le int32_t out = 0; + // result to be returned to the host PC + kiss_communication_nrc_t result; + + // identifier + uint16_t did = *(input_frame_from_host + 2) | (*(input_frame_from_host + 3) << 8); + + // construct DID response to an output buffer + const uint8_t response_size = kiss_did_response(did, response_buffer + 4, buffer_size - 4); + + // check if DID has been found and everyting is OK with it. + if (response_size > 0) { + // if response is correct fill the buffer with the rest of stuff + response_buffer[0] = FEND; + response_buffer[1] = NONSTANDARD; + response_buffer[2] = PROGRAM_STARTUP_LN; // message lenght + response_buffer[3] = KISS_READ_DID_RESP; + + response_buffer[response_size + 4] = FEND; + + out = response_size + 5; + } + else { + out = kiss_nrc_response_fill_request_out_of_range(response_buffer); + } + return out; } diff --git a/src/kiss_protocol/kiss_communication.c b/src/kiss_protocol/kiss_communication.c index b22d6e5..8fa4278 100644 --- a/src/kiss_protocol/kiss_communication.c +++ b/src/kiss_protocol/kiss_communication.c @@ -26,18 +26,6 @@ extern unsigned short tx10m; */ uint8_t kiss_current_async_message = 0xFF; -#define KISS_NRC_RESPONSE_UNKNOWN_SERVICE_LN 6 - -//!< Neagitve response to a request with unknown service id -uint8_t kiss_nrc_response_unknown_service[KISS_NRC_RESPONSE_UNKNOWN_SERVICE_LN] = { - FEND, - NONSTANDARD, - KISS_NRC_RESPONSE_UNKNOWN_SERVICE_LN, - KISS_COMMUNICATION_NRC_SERVICE, - NRC_SERVICE_NOT_SUPPORTED, - FEND}; - - uint8_t kiss_async_pooler(uint8_t* output, uint16_t output_len ) { int16_t pooling_result = 0; diff --git a/src/kiss_protocol/kiss_did.c b/src/kiss_protocol/kiss_did.c index 5e57ee8..3115a90 100644 --- a/src/kiss_protocol/kiss_did.c +++ b/src/kiss_protocol/kiss_did.c @@ -11,6 +11,15 @@ #include #include +#ifdef STM32F10X_MD_VL +#include +#define SRAM1_SIZE_MAX (0x00002000UL) /*!< maximum SRAM1 size (up to 96 KBytes) */ +#endif + +#ifdef STM32L471xx +#include +#endif + //!< Dummy variable used only as end of definition marker in tables char did_dummy_data; @@ -30,6 +39,131 @@ const static kiss_did_numeric_definition_t kiss_did_def[] = { DIDS_NUMERIC(DID_NUMERIC_DEFINITION_EXPANDER) }; +//!< Mapping between a result of sizeof operator and a value of sizebyte +const static uint8_t kiss_did_sizeof_to_sizebyte_mapping[4] = { + 1, // int8_t + 2, // int16_t + 0, // nothing + 3 // int32_t +}; + +/** + * Checks how many variables will be returned by this DID + * @param definition + * @return + */ +static uint8_t kiss_did_how_much_data(kiss_did_numeric_definition_t * definition) { + + int out = 0; + + if (definition != 0) { + if (definition->first_data != 0x00) { + out++; + + if (definition->second_data != 0x00) { + out++; + + if (definition->third_data != 0x00) { + out++; + } + } + } + } + + return out; +} + +/** + * Checks if DID configuration is anything valid + * @param definition + * @return + */ +static int kiss_did_validate(kiss_did_numeric_definition_t * definition, uint8_t * amount) { + + int out = 0; + + uint8_t amount_of_data = 0; + + // check if pointer is valid + if (definition != 0) { + + // check how many variables will be returned by this DID + amount_of_data = kiss_did_how_much_data(definition); + + // if first DID is defined + if (amount_of_data > 0) { + + // check if DID data size an address is correct + if ((definition->first_data_size == 0 || + definition->first_data_size == 1 || + definition->first_data_size == 4) && + (uint32_t)definition->first_data > SRAM_BASE && + (uint32_t)definition->first_data < SRAM_BASE + SRAM1_SIZE_MAX) { + + // valid + out = 1; + + // if second did is also defined + if (amount_of_data > 1) { + // check if DID data size is correct + if ((definition->second_data_size == 0 || + definition->second_data_size == 1 || + definition->second_data_size == 4) && + (uint32_t)definition->second_data > SRAM_BASE && + (uint32_t)definition->second_data < SRAM_BASE + SRAM1_SIZE_MAX) { + + // valid + out = 1; + + // if third DID source is also defined + if (amount_of_data > 2) { + + // check third DID source data size + if ((definition->third_data_size == 0 || + definition->third_data_size == 1 || + definition->third_data_size == 4) && + (uint32_t)definition->third_data > SRAM_BASE && + (uint32_t)definition->third_data < SRAM_BASE + SRAM1_SIZE_MAX) { + + // valid + out = 1; + } + else { + out = 0; + } + } + else { + ; // third data source doesn't need to be defined + } + } + else { + // not valid, zero output and do nothing more + out = 0; + } + } + else { + ; // second did source doesn't need to be defined + // so do nothing here + } + } + else { + out = 0; + } + } + else { + ; // at least one DID must be defined + // keep out set to zero + } + + } + + if (amount != 0) { + *amount = amount_of_data; + } + + return out; +} + /** * Creates a response for DID request into specified buffer. Please take into account * that this function cannot use full size of this buffer. The exact content of the @@ -39,12 +173,20 @@ const static kiss_did_numeric_definition_t kiss_did_def[] = { * @param identifier * @param output_buffer pointer to buffer where response will be generated into * @param buffer_ln a size of this buffer, please be aware of note about available buffer! + * @return Zero if DID hasn't been found in definitions, otherwise total data lenght */ -void kiss_did_response(uint16_t identifier, uint8_t * output_buffer, uint16_t buffer_ln) { +uint8_t kiss_did_response(uint16_t identifier, uint8_t * output_buffer, uint16_t buffer_ln) { + + uint8_t out = 0; // iterator to go through DID definition int i = 0; + // first byte of a DID response which defines size of each field + uint8_t size_byte = 0u; + + uint8_t number_of_data_source = 0u; + // data of a did found in configuration kiss_did_numeric_definition_t found = {.identifier = 0xFFFFu}; @@ -54,6 +196,8 @@ void kiss_did_response(uint16_t identifier, uint8_t * output_buffer, uint16_t bu if (kiss_did_def[i].identifier == identifier) { // if yes copy this data and exit the loop found = kiss_did_def[i]; + + break; } else { // if no, go to the next DID definition @@ -61,4 +205,63 @@ void kiss_did_response(uint16_t identifier, uint8_t * output_buffer, uint16_t bu } } while (kiss_did_def[i].identifier != 0xFFFFU); + // check is valid + const int is_valid = kiss_did_validate(&found, &number_of_data_source); + + // if something has been found and it is valid + if (found.identifier != 0xFFFFu && is_valid == 1) { + + // set the sign bit in size_byte to distinguish that from ASCII did. + // ASCII characters are from range 0 - 127 so they never have that + // set to one + size_byte |= 0x80u; + + // append a size of first data source + size_byte |= kiss_did_sizeof_to_sizebyte_mapping[found.first_data_size]; + + // append a size of second data source + size_byte |= (kiss_did_sizeof_to_sizebyte_mapping[found.first_data_size] << 2); + + // append a size of third data source + size_byte |= (kiss_did_sizeof_to_sizebyte_mapping[found.first_data_size] << 4); + + output_buffer[0] = size_byte; + + output_buffer++; + + //append first data source + memcpy(output_buffer, found.first_data, found.first_data_size); + + //move forward a poiner to response buffer + output_buffer += found.first_data_size; + + out += found.first_data_size; + + if (number_of_data_source > 1) { + //append second data source + memcpy(output_buffer, found.second_data, found.second_data_size); + + //move forward a poiner to response buffer + output_buffer += found.second_data_size; + + out += found.second_data_size; + } + + if (number_of_data_source > 2) { + //append third data source + memcpy(output_buffer, found.third_data, found.third_data_size); + + //move forward a poitner to response buffer + output_buffer += found.third_data_size; + + out += found.third_data_size; + } + + // also include size_byte in this calculation + out++; + + } + + return out; + } diff --git a/src/kiss_protocol/kiss_nrc_response.c b/src/kiss_protocol/kiss_nrc_response.c new file mode 100644 index 0000000..baa9cff --- /dev/null +++ b/src/kiss_protocol/kiss_nrc_response.c @@ -0,0 +1,57 @@ +/* + * kiss_nrc_response.c + * + * Created on: Jul 2, 2023 + * Author: mateusz + */ + + +#include +#include "kiss_communication/kiss_communication_nrc_t.h" +#include "kiss_communication/kiss_communication.h" +#include "kiss_configuation.h" + +#include + +#define KISS_NRC_RESPONSE_UNKNOWN_SERVICE_LN 6 +#define KISS_NRC_RESPONSE_OUT_OF_RANGE_LN 6 + +//!< Neagitve response to a request with unknown service id +static const uint8_t kiss_nrc_response_unknown_service[KISS_NRC_RESPONSE_UNKNOWN_SERVICE_LN] = { + FEND, + NONSTANDARD, + KISS_NRC_RESPONSE_UNKNOWN_SERVICE_LN, + KISS_COMMUNICATION_NRC_SERVICE, + NRC_SERVICE_NOT_SUPPORTED, + FEND}; + +static const uint8_t kiss_nrc_response_out_of_range[KISS_NRC_RESPONSE_OUT_OF_RANGE_LN] = { + FEND, + NONSTANDARD, + KISS_NRC_RESPONSE_UNKNOWN_SERVICE_LN, + KISS_COMMUNICATION_NRC_SERVICE, + NRC_REQUEST_OUT_OF_RANGE, + FEND +}; + +int kiss_nrc_response_fill_unknown_service(uint8_t * buffer) { + + if (buffer != 0x00) { + memcpy(buffer, kiss_nrc_response_unknown_service, KISS_NRC_RESPONSE_UNKNOWN_SERVICE_LN); + + return KISS_NRC_RESPONSE_UNKNOWN_SERVICE_LN; + } + + return 0; +} + +int kiss_nrc_response_fill_request_out_of_range(uint8_t * buffer) { + if (buffer != 0x00) { + memcpy(buffer, kiss_nrc_response_out_of_range, KISS_NRC_RESPONSE_OUT_OF_RANGE_LN); + + return KISS_NRC_RESPONSE_OUT_OF_RANGE_LN; + } + + return 0; +} +