#include "rpp/rpp.h"
#include "stdio.h"
+#include "string.h"
#if rppCONFIG_INCLUDE_FR == 1
-rpp_fr_state_t rpp_fr_state = RPP_FR_NOT_INITIALIZED; /**< Stores the actual state of the FlexRay module */
+#define RPP_FR_MAX_STATIC_BUF_CNT 32
+#define RPP_FR_MAX_DYNAMIC_BUF_CNT 32
+#define RPP_FR_MAX_FIFO_BUF_DEPTH 32
+
+#define RPP_FR_USER_CONFIG_NOT_DONE 0x0
+#define RPP_FR_USER_CONFIG_CLUSTER 0x1
+#define RPP_FR_USER_CONFIG_NODE 0x2
+#define RPP_FR_USER_CONFIG_STATIC_BUF 0x4
+
+static rpp_fr_state_t rpp_fr_state = RPP_FR_NOT_INITIALIZED; /**< Stores the actual state of the FlexRay module */
+static Fr_TMS570LS_ClusterConfigType rpp_fr_cluster_config;
+static Fr_TMS570LS_NodeConfigType rpp_fr_node_config;
+static Fr_TMS570LS_MsgRAMConfig rpp_fr_msg_ram_config;
+static Fr_TMS570LS_BufferConfigType rpp_fr_static_buffer_config[RPP_FR_MAX_STATIC_BUF_CNT];
+static Fr_TMS570LS_BufferConfigType rpp_fr_dynamic_buffer_config[RPP_FR_MAX_DYNAMIC_BUF_CNT];
+static Fr_TMS570LS_BufferConfigType rpp_fr_fifo_buffer_config[RPP_FR_MAX_FIFO_BUF_DEPTH];
+static Fr_ConfigType rpp_fr_configuration;
+static uint8_t rpp_fr_static_buffer_index;
+static uint8_t rpp_fr_dynamic_buffer_index;
+static uint8_t rpp_fr_fifo_buffer_depth = 0;
+static uint8_t rpp_fr_user_configuration_state = RPP_FR_USER_CONFIG_NOT_DONE;
+
+
+#define RPP_FR_MAX_PARAM_STR_LEN 256
+
+/**
+ * Split string into numbers
+ *
+ * The function takes a string with hexadecimal numbers,
+ * separated by spaces, and converts it into an array of numbers.
+ *
+ * For example "0x2 0xA 0XDD 0xABCD" -> {0x2, 0xA, 0XDD, 0xABCD}
+ *
+ * @param [in] params Address of the string which will be converted
+ * @param [in] params_cnt A number of parameters, which should be found and converted from the string params
+ * @param [out] tmp_params Address, where converted array of numbers will be stored
+ *
+ * @return SUCCESS when all parameters were converted to the array of numbers,
+ * FAILURE when the string was too short, too long or some other error occurred.
+ */
+static int8_t rpp_fr_parse_params(const char* params, uint32_t params_cnt, uint32_t* tmp_params) {
+ char cpy_params[RPP_FR_MAX_PARAM_STR_LEN];
+ char* token;
+ int i;
+
+ if (params == NULL || tmp_params == NULL) {
+ return FAILURE;
+ }
+ strncpy(cpy_params, params, RPP_FR_MAX_PARAM_STR_LEN);
+ token = strtok(cpy_params, " ");
+ if (token == NULL) {
+ return FAILURE;
+ }
+ for (i = 0; i < params_cnt; i++) {
+ if (sscanf(token, "%x", &tmp_params[i]) == EOF) { // No number found
+ return FAILURE;
+ }
+ if ((token = strtok(NULL, " ")) == NULL && i < params_cnt-1) { // Not enough parameters in the string
+ return FAILURE;
+ }
+ }
+ return SUCCESS;
+}
int8_t rpp_fr_config_cluster_params(const char* params) {
+ uint32_t tmp_params[FR_CLUSTER_PARAMS_CNT];
+
+ if (rpp_fr_parse_params(params, FR_CLUSTER_PARAMS_CNT, tmp_params) == FAILURE) {
+ return FAILURE;
+ }
+ rpp_fr_cluster_config.gColdStartAttempts = tmp_params[0];
+ rpp_fr_cluster_config.gListenNoise = tmp_params[1];
+ rpp_fr_cluster_config.gMacroPerCycle = tmp_params[2];
+ rpp_fr_cluster_config.gMaxWithoutClockCorrectionFatal = tmp_params[3];
+ rpp_fr_cluster_config.gMaxWithoutClockCorrectionPassive = tmp_params[4];
+ rpp_fr_cluster_config.gNetworkManagementVectorLength = tmp_params[5];
+ rpp_fr_cluster_config.gNumberOfMinislots = tmp_params[6];
+ rpp_fr_cluster_config.gNumberOfStaticSlots = tmp_params[7];
+ rpp_fr_cluster_config.gOffsetCorrectionStart = tmp_params[8];
+ rpp_fr_cluster_config.gPayloadLengthStatic = tmp_params[9];
+ rpp_fr_cluster_config.gSyncNodeMax = tmp_params[10];
+ rpp_fr_cluster_config.gdActionPointOffset = tmp_params[11];
+ rpp_fr_cluster_config.gdCASRxLowMax = tmp_params[12];
+ rpp_fr_cluster_config.gdDynamicSlotIdlePhase = tmp_params[13];
+ rpp_fr_cluster_config.gdMinislot = tmp_params[14];
+ rpp_fr_cluster_config.gdMinislotActionPointOffset = tmp_params[15];
+ rpp_fr_cluster_config.gdNIT = tmp_params[16];
+ rpp_fr_cluster_config.gdSampleClockPeriod = tmp_params[17];
+ rpp_fr_cluster_config.gdStaticSlot = tmp_params[18];
+ rpp_fr_cluster_config.gdTSSTransmitter = tmp_params[19];
+ rpp_fr_cluster_config.gdWakeupSymbolRxIdle = tmp_params[20];
+ rpp_fr_cluster_config.gdWakeupSymbolRxLow = tmp_params[21];
+ rpp_fr_cluster_config.gdWakeupSymbolRxWindow = tmp_params[22];
+ rpp_fr_cluster_config.gdWakeupSymbolTxIdle = tmp_params[23];
+ rpp_fr_cluster_config.gdWakeupSymbolTxLow = tmp_params[24];
+
+ rpp_fr_user_configuration_state |= RPP_FR_USER_CONFIG_CLUSTER;
+ return SUCCESS;
}
int8_t rpp_fr_config_node_params(const char* params) {
+ uint32_t tmp_params[FR_NODE_PARAMS_CNT+2]; // +2 because two more parameters from message RAM structure are expected in the string.
+ Fr_ChannelType channels[3] = {FR_CHANNEL_A, FR_CHANNEL_B, FR_CHANNEL_AB};
+ Fr_TMS570LS_SecureBuffersType secure[4] = {FR_SB_RECONFIG_ENABLED, FR_SB_STAT_REC_DISABLED_STAT_TR_DISABLED, FR_SB_ALL_REC_DISABLED, FR_SB_ALL_REC_DISABLED_STAT_TR_DISABLED};
+ if (rpp_fr_parse_params(params, FR_NODE_PARAMS_CNT+2, tmp_params) == FAILURE) {
+ return FAILURE;
+ }
+
+ rpp_fr_node_config.pAllowHaltDueToClock = tmp_params[0];
+ rpp_fr_node_config.pAllowPassiveToActive = tmp_params[1];
+ if (tmp_params[2] > 2) return FAILURE;
+ rpp_fr_node_config.pChannels = channels[ tmp_params[2] ];
+ rpp_fr_node_config.pClusterDriftDamping = tmp_params[3];
+ rpp_fr_node_config.pDelayCompensationA = tmp_params[4];
+ rpp_fr_node_config.pDelayCompensationB = tmp_params[5];
+ rpp_fr_node_config.pExternOffsetCorrection = tmp_params[6];
+ rpp_fr_node_config.pExternRateCorrection = tmp_params[7];
+ rpp_fr_node_config.pKeySlotUsedForStartup = tmp_params[8];
+ rpp_fr_node_config.pKeySlotUsedForSync = tmp_params[9];
+ rpp_fr_node_config.pLatestTx = tmp_params[10];
+ rpp_fr_node_config.pMacroInitialOffsetA = tmp_params[11];
+ rpp_fr_node_config.pMacroInitialOffsetB = tmp_params[12];
+ rpp_fr_node_config.pMicroInitialOffsetA = tmp_params[13];
+ rpp_fr_node_config.pMicroInitialOffsetB = tmp_params[14];
+ rpp_fr_node_config.pMicroPerCycle = tmp_params[15];
+ rpp_fr_node_config.pRateCorrectionOut = tmp_params[16];
+ rpp_fr_node_config.pOffsetCorrectionOut = tmp_params[17];
+ rpp_fr_node_config.pSamplesPerMicrotick = tmp_params[18];
+ rpp_fr_node_config.pSingleSlotEnabled = tmp_params[19];
+ if (tmp_params[20] > 1) return FAILURE;
+ rpp_fr_node_config.pWakeupChannel = channels[ tmp_params[20] ];
+ rpp_fr_node_config.pWakeupPattern = tmp_params[21];
+ rpp_fr_node_config.pdAcceptedStartupRange = tmp_params[22];
+ rpp_fr_node_config.pdListenTimeout = tmp_params[23];
+ rpp_fr_node_config.pdMaxDrift = tmp_params[24];
+ rpp_fr_node_config.pDecodingCorrection = tmp_params[25];
+ rpp_fr_msg_ram_config.syncFramePayloadMultiplexEnabled = tmp_params[26];
+ if (tmp_params[27] > 3) return FAILURE;
+ rpp_fr_msg_ram_config.secureBuffers = secure[ tmp_params[27] ];
+
+ rpp_fr_user_configuration_state |= RPP_FR_USER_CONFIG_NODE;
+ return SUCCESS;
}
int8_t rpp_fr_config_static_buffer(const char* params) {
+ uint32_t tmp_params[FR_STATIC_BUF_PARAMS_CNT];
+ Fr_ChannelType channels[3] = {FR_CHANNEL_A, FR_CHANNEL_B, FR_CHANNEL_AB};
+ if (rpp_fr_static_buffer_index >= RPP_FR_MAX_STATIC_BUF_CNT) {
+ return FAILURE;
+ }
+
+ if (rpp_fr_parse_params(params, FR_STATIC_BUF_PARAMS_CNT, tmp_params) == FAILURE) {
+ return FAILURE;
+ }
+
+ if (tmp_params[0] > 2) return FAILURE;
+ rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].channel = channels[ tmp_params[0] ];
+ rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].cycleCounterFiltering = tmp_params[1];
+ rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].isTx = tmp_params[2];
+ rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].maxPayload = tmp_params[3];
+ rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].msgBufferInterrupt = tmp_params[4];
+ rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].singleTransmit = tmp_params[5];
+ rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].slotId = tmp_params[6];
+ rpp_fr_static_buffer_index++;
+
+ rpp_fr_user_configuration_state |= RPP_FR_USER_CONFIG_STATIC_BUF;
+ return SUCCESS;
}
int8_t rpp_fr_config_dynamic_buffer(const char* params) {
+ uint32_t tmp_params[FR_DYNAMIC_BUF_PARAMS_CNT];
+ Fr_ChannelType channels[3] = {FR_CHANNEL_A, FR_CHANNEL_B, FR_CHANNEL_AB};
+
+ if (rpp_fr_dynamic_buffer_index >= RPP_FR_MAX_DYNAMIC_BUF_CNT) {
+ return FAILURE;
+ }
+
+ if (rpp_fr_parse_params(params, FR_DYNAMIC_BUF_PARAMS_CNT, tmp_params) == FAILURE) {
+ return FAILURE;
+ }
+
+ if (tmp_params[0] > 1) return FAILURE;
+ rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].channel = channels[ tmp_params[0] ];
+ rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].cycleCounterFiltering = tmp_params[1];
+ rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].isTx = tmp_params[2];
+ rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].maxPayload = tmp_params[3];
+ rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].msgBufferInterrupt = tmp_params[4];
+ rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].singleTransmit = tmp_params[5];
+ rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].slotId = tmp_params[6];
+ rpp_fr_dynamic_buffer_index++;
+ return SUCCESS;
}
int8_t rpp_fr_config_fifo_buffer(const char* params) {
+ uint32_t tmp_params[FR_FIFO_BUF_PARAMS_CNT+1]; // +1 because the first parameter in the string means the depth of the buffer, and the constant means the number of items in the configuration structure.
+ Fr_ChannelType channels[3] = {FR_CHANNEL_A, FR_CHANNEL_B, FR_CHANNEL_AB};
+ Fr_TMS570LS_BufferConfigType* fifo_buffer_ptr = &rpp_fr_fifo_buffer_config[0];
+
+ if (rpp_fr_fifo_buffer_depth != 0) {
+ return FAILURE;
+ }
+
+ if (rpp_fr_parse_params(params, FR_FIFO_BUF_PARAMS_CNT+1, tmp_params) == FAILURE) {
+ return FAILURE;
+ }
+ if (tmp_params[0] > RPP_FR_MAX_FIFO_BUF_DEPTH) return FAILURE;
+ if (tmp_params[1] > 2) return FAILURE;
+
+ for (fifo_buffer_ptr = &rpp_fr_fifo_buffer_config[0]; fifo_buffer_ptr < &rpp_fr_fifo_buffer_config[tmp_params[0]]; fifo_buffer_ptr++) {
+ fifo_buffer_ptr->channel = channels[ tmp_params[1] ];
+ fifo_buffer_ptr->cycleCounterFiltering = tmp_params[2];
+ fifo_buffer_ptr->maxPayload = tmp_params[3];
+ fifo_buffer_ptr->rejectNullFrames = tmp_params[4];
+ fifo_buffer_ptr->rejectStaticSegment = tmp_params[5];
+ fifo_buffer_ptr->slotId = tmp_params[6];
+ }
+ rpp_fr_fifo_buffer_depth = tmp_params[0];
+
+ return SUCCESS;
}
int8_t rpp_fr_init() {
int8_t rpp_fr_init_driver(const Fr_ConfigType* config_ptr, uint32_t* error) {
if (rpp_fr_state <= RPP_FR_DRV_INITIALIZED) {
if (config_ptr == NULL) { // Use user configuration created before by rpp_fr_config functions
- if (rpp_fr_state == RPP_FR_CONFIGURED) {
- rpp_fr_state = RPP_FR_DRV_INITIALIZED;
- }
- else {
+ if (rpp_fr_user_configuration_state !=
+ RPP_FR_USER_CONFIG_CLUSTER|
+ RPP_FR_USER_CONFIG_NODE|
+ RPP_FR_USER_CONFIG_STATIC_BUF
+ ) {
*error = FR_INIT_ERR_BAD_PARAM;
- return FAILURE;
+ return FAILURE; // User configuration was not completed
}
+ rpp_fr_msg_ram_config.dynSegmentBufferCount = rpp_fr_dynamic_buffer_index;
+ rpp_fr_msg_ram_config.fifoBufferCount = rpp_fr_fifo_buffer_depth;
+ rpp_fr_msg_ram_config.statSegmentBufferCount = rpp_fr_static_buffer_index;
+
+ rpp_fr_configuration.clusterConfiguration = &rpp_fr_cluster_config;
+ rpp_fr_configuration.dynamicBufferConfigs = rpp_fr_dynamic_buffer_config;
+ rpp_fr_configuration.fifoBufferConfigs = rpp_fr_fifo_buffer_config;
+ rpp_fr_configuration.msgRAMConfig = &rpp_fr_msg_ram_config;
+ rpp_fr_configuration.nodeConfiguration = &rpp_fr_node_config;
+ rpp_fr_configuration.staticBufferConfigs = rpp_fr_static_buffer_config;
}
else { // Use configuration from the structure from parameter.
- Fr_Init(config_ptr);
+ Fr_Init(&rpp_fr_configuration);
}
rpp_fr_state = RPP_FR_DRV_INITIALIZED;
return SUCCESS;