%%
%% Authors:
%% Michal Horn <hornmich@fel.cvut.cz>
+%% Michal Sojka <sojkam1@fel.cvut.cz>
%%
-%% This document contains proprietary information belonging to Czech
-%% Technical University in Prague. Passing on and copying of this
-%% document, and communication of its contents is not permitted
-%% without prior written authorization.
+%% Permission is hereby granted, free of charge, to any person
+%% obtaining a copy of this software and associated documentation
+%% files (the "Software"), to deal in the Software without
+%% restriction, including without limitation the rights to use,
+%% copy, modify, merge, publish, distribute, sublicense, and/or sell
+%% copies of the Software, and to permit persons to whom the
+%% Software is furnished to do so, subject to the following
+%% conditions:
+
+%% The above copyright notice and this permission notice shall be
+%% included in all copies or substantial portions of the Software.
+
+%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+%% OTHER DEALINGS IN THE SOFTWARE.
%%
%% File : rpp_can_common.tlc
%% Abstract:
%% TLC file with common functions and variables for sfunction_canreceive, sfunction_cansetup and sfunction_cantransmit
%%
%% References:
-
-%% Function: RPP_FindFreeMailboxNumber =========================================
-%% Finds the first mailbox number in the CAN module, which has not assignd any configuration
-%% record (buffer).
-%% The search is done through an array of flags, which signals by their existance whether
-%% the number is already assigned or not.
-%%
-%% Params: end The mximal number of the mailboxes.
-%% module The CAN module number. For example 1 for CAN1.
+%% Coding Convention: refs/rtw_tlc.pdf p. 58 (TODO)
%%
-%% Returns the lowest possible free mailbox number.
-%function RPP_FindFreeMailboxNumber(end, module)
- %foreach mn = %<end>
- %assign index = %<mn>+1
- %if EXISTS("::rpp_can%<module>_mailbox_assigned%<index>_flag") == 0
- %return %<mn>
- %break
- %endif
+%% Function: RppCANCommonBlockTypeSetup ========================================
+%% Declares and initializes all common variables and constants.
+
+%function RppCANCommonBlockTypeSetup() void
+ %if EXISTS("::_RPP_MAX_MAILBOX_CNT") == 0
+ %assign ::_RPP_MAX_MAILBOX_CNT = 64
+
+ /% Global data structure used in call CAN blocks %/
+ %createrecord ::Rpp { Can { ...
+ Tx { NumBlocks 0 } ...
+ Rx { NumBlocks 0 } ...
+ }}
+
+ /% Add records for helping with message object allocation %/
+ %foreach i = 3 %% We have 3 CAN controllers
+ %addtorecord Rpp.Can Ctrl {}
%endforeach
- %return -1
+ %endif
%endfunction
-%% Function: RPP_MailboxNumberDuplicite ========================================
-%% If the block has manualy specified mailbox number, check whether the number is
-%% already used by another block with manualy specified mailbox.
-%% If the mailbox number is not duplicite, the function marks it as used.
-%%
-%% Params: module The CAN module number. For example 1 for CAN1.
-%% mailbox_number The number of the mailbox of the current block.
-%% mailbox_auto The boolean value telling if the mailbox number is specified automaticaly
-%%
-%% Returns 1 if the mailbox_number is duplicite, 0 if not.
-
-%function RPP_MailboxNumberDuplicite(module, mailbox_number, mailbox_auto)
- %if %<mailbox_auto> == 0U
- %if EXISTS("::rpp_can%<module>_mailbox_number%<mailbox_number>") == 0
- %assign ::rpp_can%<module>_mailbox_number%<mailbox_number> = 1
- %else
- %return 1
- %endif
- %endif
- %return 0
-
+%function RppCanAssignMsgObj(msgObjNum, blockInfo) void
+ %if msgObjNum < 1 || msgObjNum > ::_RPP_MAX_MAILBOX_CNT
+ %<LibBlockReportError(block, "Invalid mailbox number!")>
+ %endif
+ %addtorecord Rpp.Can.Ctrl[blockInfo.Controller-1] MsgObj%<msgObjNum>UsedBy blockInfo
+ %assign blockInfo.MsgObj = msgObjNum
%endfunction
-%% Function: RPP_AssertDirectionSpecificator ===================================
-%% Check the direction specifyer. Invokes a fatal error if it is invalid.
-%% The valid specifyer: r; t
-%%
-%% Params: direction_sp The specifyer to be checked.
+%function RppCanGetBlockInfoFromMsgObj(module, mailbox_number)
+ %return Rpp.Can.Ctrl[module-1].MsgObj%<mailbox_number>UsedBy
+%endfunction
-%function RPP_AssertDirectionSpecificator(direction_sp) void
- %if !ISEQUAL(direction_sp, "t") && !ISEQUAL(direction_sp, "r")
- %<LibBlockReportFatalError(block, "Illegal direction specificator: " + direction_sp)>
- %endif
+%function RppCanIsMsgObjAssigned(module, mailbox_number)
+ %return ISFIELD(Rpp.Can.Ctrl[%<module-1>], "MsgObj%<mailbox_number>UsedBy")
%endfunction
-%% Function: RPP_CreateNewBuffer ===============================================
-%% Created new record with initialization values for CAN TX or CAN RX record.
-%%
-%% Params: module The CAN module number. For example 1 for CAN1.
-%% mailbox_num The number of the mailbox.
-%% message_type The type of the message ID. 1-11b, 2-29b, 3-mixed (for RX only)
-%% message_id The message ID
-%% mask The mask of the message ID
-%% direction_sp The direction specifyer. "r" for CAN RX or "t" for CAN TX.
-
-%function RPP_CreateNewBuffer(module, mailbox_num, message_type, message_id, mask, direction_sp) void
- %<RPP_AssertDirectionSpecificator(direction_sp)>
- %if ISEQUAL(direction_sp, "t")
- %createrecord ::tx_buffer_%<::rpp_can_tx_cnt> {type message_type; controller module; msg_obj mailbox_num; name "%<LibGetBlockName(block)>" }
- %else
- %createrecord ::rx_buffer_%<::rpp_can_rx_cnt> {type message_type; controller module; msg_obj mailbox_num; name "%<LibGetBlockName(block)>"; id message_id; msk mask }
- %endif
+%% Function: RppFindFreeMailboxNumber =========================================
+%% Returns the lowest possible free mailbox number or 0 if no mailbox is free.
+
+%function RppFindFreeMailboxNumber(module) void
+ %foreach mn = ::_RPP_MAX_MAILBOX_CNT + 1
+ %if mn == 0
+ %continue
+ %endif
+ %if RppCanIsMsgObjAssigned(module, mn) == 0
+ %return %<mn>
+ %endif
+ %endforeach
+ %return 0
%endfunction
-%% Function: RPP_PlaceAutomaticMailboxNumber ===================================
-%% Places an automaticaly specified mailbox number for the CAN blocks.
-%% Finds the first free mailbox number, assigns it to the current block and creates
-%% a record with initialization data
-%%
-%% Params: max_mailbox_number The maximal mailbox number
-%% module The CAN module number. For example 1 for CAN1.
-%% message_type The type of the message ID. 1-11b, 2-29b, 3-mixed (for RX only)
-%% message_id The message ID
-%% mask The mask of the message ID
-%% direction_sp The direction specifyer. "r" for CAN RX or "t" for CAN TX.
-
-%function RPP_PlaceAutomaticMailboxNumber(max_mailbox_number, module, message_type, message_id, mask, direction_sp) void
- %<RPP_AssertDirectionSpecificator(direction_sp)>
-
- %% Find first free mailbox number
- %assign mailbox_number = FindFreeMailboxNumber(max_mailbox_number, module)
- %if %<mailbox_number> < 0
+%% Function: RppPlaceAutomaticMailboxNumber ===================================
+%% Assignes an automaticaly determined mailbox number for the CAN block.
+
+%function RppPlaceAutomaticMailboxNumber(blockInfo) void
+ %assign msg_obj_number = RppFindFreeMailboxNumber(blockInfo.Controller)
+ %if %<msg_obj_number> == 0
%<LibBlockReportError(block, "Too many blocks in one module!")>
%endif
- %assign mailbox_number = mailbox_number+1
-
- %% Mark the mailbox number as used and assign a record about buffer to it
- %assign ::rpp_can%<module>_mailbox_assigned%<mailbox_number>_flag = 1
- %createrecord ::rpp_can%<module>_mailbox_assigned%<mailbox_number> { direction "%<direction_sp>"; buffer ::rpp_can_%<direction_sp>x_cnt }
-
- %<RPP_CreateNewBuffer(module, mailbox_number, message_type, message_id, mask, direction_sp)>
-
+ %addtorecord blockInfo ManualMsgObj 0 /% For MsgObj collision detection %/
+ %<RppCanAssignMsgObj(msg_obj_number, blockInfo)>
%endfunction
-%% Function: RPP_PlaceManualMailboxNumber ======================================
-%% Places a manualy specified mailbox number for the CAN blocks.
-%% If the number is not used yet, just places it and marks it as used. But if it is used
-%% already by some automaticaly assigned block, the previous one has assigned a new automaticaly
-%% generated number and this new one takes its place.
-%%
-%% Params: max_mailbox_number The maximal mailbox number
-%% mailbox_num The number of the mailbox.
-%% module The CAN module number. For example 1 for CAN1.
-%% message_type The type of the message ID. 1-11b, 2-29b, 3-mixed (for RX only)
-%% message_id The message ID
-%% mask The mask of the message ID
-%% direction_sp The direction specifyer. "r" for CAN RX or "t" for CAN TX.
-
-%function RPP_PlaceManualMailboxNumber(max_mailbox_number, mailbox_num, module, message_type, message_id, mask, direction_sp) void
- %<RPP_AssertDirectionSpecificator(direction_sp)>
-
- %% Check whether the mailbox number is already used
- %if EXISTS(::rpp_can%<module>_mailbox_assigned%<mailbox_num>_flag) == 0
- %assign ::rpp_can%<module>_mailbox_assigned%<mailbox_num>_flag = 1
- %createrecord ::rpp_can%<module>_mailbox_assigned%<mailbox_num> { direction "%<direction_sp>"; buffer ::rpp_can_%<direction_sp>x_cnt }
- %else
- %% The mailbox number is already used by the automaticaly placed buffer.
- %% The case that it is used by another manualy placed buffer is handeled by the duplication check.
- %% Find first free mailbox number
- %assign mailbox_number = FindFreeMailboxNumber(max_mailbox_number, module)
- %if mailbox_number < 0
- %<LibBlockReportError(block, "Too many blocks in one module!")>
- %endif
- %assign mailbox_number = %<mailbox_number>+1
-
- %% Mark the mailbox number as used
- %assign ::rpp_can%<module>_mailbox_assigned%<mailbox_number>_flag = 1
-
- %% Move record with buffer information to the new slot with free mailbox number id
- %copyrecord ::rpp_can%<module>_mailbox_assigned%<mailbox_number> ::rpp_can%<module>_mailbox_assigned%<mailbox_num>
-
- %% Create new record with buffer information in the required slot
- %createrecord ::rpp_can%<module>_mailbox_assigned%<mailbox_num> {direction "%<direction_sp>"; buffer ::rpp_can_%<direction_sp>x_cnt}
-
- %% Fix mailbox number in the old buffer record
- %copyrecord tmp_ma ::rpp_can%<module>_mailbox_assigned%<mailbox_number>
- %copyrecord tmp_buf ::%<tmp_ma.direction>x_buffer_%<tmp_ma.buffer>
- %if ISEQUAL(tmp_ma.direction, "t")
- %createrecord tmp_result {type tmp_buf.type; controller tmp_buf.controller; msg_obj mailbox_number; name "%<tmp_buf.name>" }
- %copyrecord ::tx_buffer_%<tmp_ma.buffer> tmp_result
- %elseif ISEQUAL(tmp_ma.direction, "r")
- %createrecord rx_buffer_%<tmp_ma.buffer> { type tmp_buf.type; controller tmp_buf.controller; msg_obj mailbox_number; name "%<tmp_buf.name>"; id tmp_buf.id; msk tmp_buf.msk }
- %else
- %<LibBlockReportFatalError(block, "Unknown block direction, this is probably a bug!")>
- %endif
- %endif
-
- %<RPP_CreateNewBuffer(module, mailbox_num, message_type, message_id, mask, direction_sp)>
+%% Function: RppPlaceManualMailboxNumber ======================================
+%% Assigns a manualy specified mailbox number to the CAN blocks.
+%% Reports collisions with other manually assigned blocks and optionally
+%% reassignes mailbox numbers of previously assigned automatic blocks.
+%%
+%% Params: msg_obj_num The requested number of the mailbox.
+
+%function RppPlaceManualMailboxNumber(blockInfo, msg_obj_number) void
+ %if RppCanIsMsgObjAssigned(blockInfo.Controller, msg_obj_number)
+ %assign prevBlockInfo = RppCanGetBlockInfoFromMsgObj(blockInfo.Controller, msg_obj_number)
+ %if prevBlockInfo.ManualMsgObj
+ %<LibBlockReportError(block, "Colliding mailbox number found!")>
+ %endif
+ %assign new_msg_obj_number = RppFindFreeMailboxNumber(blockInfo.Controller)
+ %if new_msg_obj_number == 0
+ %<LibBlockReportError(block, "Too many blocks in one module!")>
+ %endif
+ %<RppCanAssignMsgObj(new_msg_obj_number, prevBlockInfo)>
+ %endif
+ %addtorecord blockInfo ManualMsgObj 1 /% For MsgObj collision detection %/
+ %<RppCanAssignMsgObj(msg_obj_number, blockInfo)>
%endfunction
%% [EOF]
-