]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/commitdiff
User configuration of the FexRay aded into RPP library.
authorMichal Horn <hornmich@fel.cvut.cz>
Thu, 15 Aug 2013 15:51:57 +0000 (17:51 +0200)
committerMichal Horn <hornmich@fel.cvut.cz>
Thu, 15 Aug 2013 15:51:57 +0000 (17:51 +0200)
rpp/src/rpp/fr.c

index 7310d3a94779bb67d110f6a85190d8cf27a33e3a..b91266f55d35b5098b48e6822232a1fed7352694 100644 (file)
 
 #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() {
@@ -65,16 +270,27 @@ 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;