]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/blobdiff - rpp/blocks/tlc_c/rpp_can_common.tlc
Change license to MIT
[jenkicar/rpp-simulink.git] / rpp / blocks / tlc_c / rpp_can_common.tlc
index ac06ad4f591eb2a4fdcdfd79cfb2251725129ffb..ba6ecad69051bf8f9456695ff0266ec0331db939 100644 (file)
 %%
 %% 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]
-