]> 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 d7927af9606137f0704bbff1113cc39a60a178fe..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:
+%%     Coding Convention: refs/rtw_tlc.pdf p. 58 (TODO)
+%%
 
 %% Function: RppCANCommonBlockTypeSetup ========================================
 %%     Declares and initializes all common variables and constants.
 
 %function RppCANCommonBlockTypeSetup() void
-       %if EXISTS("::rpp_can_tx_hw_obj_cnt") == 0
-               %assign ::rpp_can_tx_hw_obj_cnt = 0
-       %endif
-       %if EXISTS("::rpp_can_rx_hw_obj_cnt") == 0
-               %assign ::rpp_can_rx_hw_obj_cnt = 0
-       %endif
-       %if EXISTS("::rpp_can_rx_cnt") == 0
-               %assign ::rpp_can_rx_cnt = 0
-       %endif
-       %if EXISTS("::rpp_can_tx_cnt") == 0
-               %assign ::rpp_can_tx_cnt = 0
-       %endif
-       %if EXISTS("::_RPP_MAX_MAILBOX_CNT") == 0
-               %assign ::_RPP_MAX_MAILBOX_CNT = 32
-       %endif
-
+  %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
+  %endif
 %endfunction
 
-%% Function: RppFindFreeMailboxNumber =========================================
-%function RppFindFreeMailboxNumber(end, module) 
-       %foreach mn = %<end>
-               %assign index = %<mn>+1
-               %if EXISTS("::rpp_can%<module>_mailbox_assigned%<index>_flag") == 0
-                       %return %<mn>
-                       %break
-               %endif
-       %endforeach
-       %return -1
+%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: RppMailboxNumberDuplicite ========================================
-%function RppMailboxNumberDuplicite(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 RppCanGetBlockInfoFromMsgObj(module, mailbox_number)
+  %return Rpp.Can.Ctrl[module-1].MsgObj%<mailbox_number>UsedBy
 %endfunction
 
-%% Function: RppAssertDirectionSpecificator ===================================
-%function RppAssertDirectionSpecificator(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: RppCreateNewBuffer ===============================================
-%function RppCreateNewBuffer(module, mailbox_num, message_type, message_id, mask, direction_sp) void
-       %<RppAssertDirectionSpecificator(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: RppPlaceAutomaticMailboxNumber ===================================
-%function RppPlaceAutomaticMailboxNumber(max_mailbox_number, module, message_type, message_id, mask, direction_sp) void
-       %<RppAssertDirectionSpecificator(direction_sp)>
+%%     Assignes an automaticaly determined mailbox number for the CAN block.
 
-       %% Find first free mailbox number
-       %assign mailbox_number = RppFindFreeMailboxNumber(max_mailbox_number, module)
-       %if %<mailbox_number> < 0 
+%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 }
-       
-       %<RppCreateNewBuffer(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 RppPlaceManualMailboxNumber(max_mailbox_number, mailbox_num, module, message_type, message_id, mask, direction_sp) void
-       %<RppAssertDirectionSpecificator(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 = RppFindFreeMailboxNumber(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  
-
-       %<RppCreateNewBuffer(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]
-