1 %% Copyright (C) 2014 Czech Technical University in Prague
4 %% Michal Horn <hornmich@fel.cvut.cz>
6 %% This document contains proprietary information belonging to Czech
7 %% Technical University in Prague. Passing on and copying of this
8 %% document, and communication of its contents is not permitted
9 %% without prior written authorization.
11 %% File : rpp_can_common.tlc
13 %% TLC file with common functions and variables for sfunction_canreceive, sfunction_cansetup and sfunction_cantransmit
17 %% Function: RppCANCommonBlockTypeSetup ========================================
18 %% Declares and initializes all common variables and constants.
20 %function RppCANCommonBlockTypeSetup() void
21 %if EXISTS("::rpp_can_tx_hw_obj_cnt") == 0
22 %assign ::rpp_can_tx_hw_obj_cnt = 0
24 %if EXISTS("::rpp_can_rx_hw_obj_cnt") == 0
25 %assign ::rpp_can_rx_hw_obj_cnt = 0
27 %if EXISTS("::rpp_can_rx_cnt") == 0
28 %assign ::rpp_can_rx_cnt = 0
30 %if EXISTS("::rpp_can_tx_cnt") == 0
31 %assign ::rpp_can_tx_cnt = 0
33 %if EXISTS("::_RPP_MAX_MAILBOX_CNT") == 0
34 %assign ::_RPP_MAX_MAILBOX_CNT = 32
39 %% Function: RppFindFreeMailboxNumber =========================================
40 %% Finds the first mailbox number in the CAN module, which has not assignd any configuration
42 %% The search is done through an array of flags, which signals by their existance whether
43 %% the number is already assigned or not.
45 %% Params: end The mximal number of the mailboxes.
46 %% module The CAN module number. For example 1 for CAN1.
48 %% Returns the lowest possible free mailbox number.
50 %function RppFindFreeMailboxNumber(end, module)
52 %assign index = %<mn>+1
53 %if EXISTS("::rpp_can%<module>_mailbox_assigned%<index>_flag") == 0
61 %% Function: RppMailboxNumberDuplicite ========================================
62 %% If the block has manualy specified mailbox number, check whether the number is
63 %% already used by another block with manualy specified mailbox.
64 %% If the mailbox number is not duplicite, the function marks it as used.
66 %% Params: module The CAN module number. For example 1 for CAN1.
67 %% mailbox_number The number of the mailbox of the current block.
68 %% mailbox_auto The boolean value telling if the mailbox number is specified automaticaly
70 %% Returns 1 if the mailbox_number is duplicite, 0 if not.
72 %function RppMailboxNumberDuplicite(module, mailbox_number, mailbox_auto)
73 %if %<mailbox_auto> == 0U
74 %if EXISTS("::rpp_can%<module>_mailbox_number%<mailbox_number>") == 0
75 %assign ::rpp_can%<module>_mailbox_number%<mailbox_number> = 1
84 %% Function: RppAssertDirectionSpecificator ===================================
85 %% Check the direction specifyer. Invokes a fatal error if it is invalid.
86 %% The valid specifyer: r; t
88 %% Params: direction_sp The specifyer to be checked.
90 %function RppAssertDirectionSpecificator(direction_sp) void
91 %if !ISEQUAL(direction_sp, "t") && !ISEQUAL(direction_sp, "r")
92 %<LibBlockReportFatalError(block, "Illegal direction specificator: " + direction_sp)>
96 %% Function: RppCreateNewBuffer ===============================================
97 %% Created new record with initialization values for CAN TX or CAN RX record.
99 %% Params: module The CAN module number. For example 1 for CAN1.
100 %% mailbox_num The number of the mailbox.
101 %% message_type The type of the message ID. 1-11b, 2-29b, 3-mixed (for RX only)
102 %% message_id The message ID
103 %% mask The mask of the message ID
104 %% direction_sp The direction specifyer. "r" for CAN RX or "t" for CAN TX.
106 %function RppCreateNewBuffer(module, mailbox_num, message_type, message_id, mask, direction_sp) void
107 %<RppAssertDirectionSpecificator(direction_sp)>
108 %if ISEQUAL(direction_sp, "t")
109 %createrecord ::tx_buffer_%<::rpp_can_tx_cnt> {type message_type; controller module; msg_obj mailbox_num; name "%<LibGetBlockName(block)>" }
111 %createrecord ::rx_buffer_%<::rpp_can_rx_cnt> {type message_type; controller module; msg_obj mailbox_num; name "%<LibGetBlockName(block)>"; id message_id; msk mask }
115 %% Function: RppPlaceAutomaticMailboxNumber ===================================
116 %% Places an automaticaly specified mailbox number for the CAN blocks.
117 %% Finds the first free mailbox number, assigns it to the current block and creates
118 %% a record with initialization data
120 %% Params: max_mailbox_number The maximal mailbox number
121 %% module The CAN module number. For example 1 for CAN1.
122 %% message_type The type of the message ID. 1-11b, 2-29b, 3-mixed (for RX only)
123 %% message_id The message ID
124 %% mask The mask of the message ID
125 %% direction_sp The direction specifyer. "r" for CAN RX or "t" for CAN TX.
127 %function RppPlaceAutomaticMailboxNumber(max_mailbox_number, module, message_type, message_id, mask, direction_sp) void
128 %<RppAssertDirectionSpecificator(direction_sp)>
130 %% Find first free mailbox number
131 %assign mailbox_number = RppFindFreeMailboxNumber(max_mailbox_number, module)
132 %if %<mailbox_number> < 0
133 %<LibBlockReportError(block, "Too many blocks in one module!")>
135 %assign mailbox_number = mailbox_number+1
137 %% Mark the mailbox number as used and assign a record about buffer to it
138 %assign ::rpp_can%<module>_mailbox_assigned%<mailbox_number>_flag = 1
139 %createrecord ::rpp_can%<module>_mailbox_assigned%<mailbox_number> { direction "%<direction_sp>"; buffer ::rpp_can_%<direction_sp>x_cnt }
141 %<RppCreateNewBuffer(module, mailbox_number, message_type, message_id, mask, direction_sp)>
145 %% Function: RppPlaceManualMailboxNumber ======================================
146 %% Places a manualy specified mailbox number for the CAN blocks.
147 %% If the number is not used yet, just places it and marks it as used. But if it is used
148 %% already by some automaticaly assigned block, the previous one has assigned a new automaticaly
149 %% generated number and this new one takes its place.
151 %% Params: max_mailbox_number The maximal mailbox number
152 %% mailbox_num The number of the mailbox.
153 %% module The CAN module number. For example 1 for CAN1.
154 %% message_type The type of the message ID. 1-11b, 2-29b, 3-mixed (for RX only)
155 %% message_id The message ID
156 %% mask The mask of the message ID
157 %% direction_sp The direction specifyer. "r" for CAN RX or "t" for CAN TX.
159 %function RppPlaceManualMailboxNumber(max_mailbox_number, mailbox_num, module, message_type, message_id, mask, direction_sp) void
160 %<RppAssertDirectionSpecificator(direction_sp)>
162 %% Check whether the mailbox number is already used
163 %if EXISTS(::rpp_can%<module>_mailbox_assigned%<mailbox_num>_flag) == 0
164 %assign ::rpp_can%<module>_mailbox_assigned%<mailbox_num>_flag = 1
165 %createrecord ::rpp_can%<module>_mailbox_assigned%<mailbox_num> { direction "%<direction_sp>"; buffer ::rpp_can_%<direction_sp>x_cnt }
167 %% The mailbox number is already used by the automaticaly placed buffer.
168 %% The case that it is used by another manualy placed buffer is handeled by the duplication check.
169 %% Find first free mailbox number
170 %assign mailbox_number = RppFindFreeMailboxNumber(max_mailbox_number, module)
171 %if mailbox_number < 0
172 %<LibBlockReportError(block, "Too many blocks in one module!")>
174 %assign mailbox_number = %<mailbox_number>+1
176 %% Mark the mailbox number as used
177 %assign ::rpp_can%<module>_mailbox_assigned%<mailbox_number>_flag = 1
179 %% Move record with buffer information to the new slot with free mailbox number id
180 %copyrecord ::rpp_can%<module>_mailbox_assigned%<mailbox_number> ::rpp_can%<module>_mailbox_assigned%<mailbox_num>
182 %% Create new record with buffer information in the required slot
183 %createrecord ::rpp_can%<module>_mailbox_assigned%<mailbox_num> {direction "%<direction_sp>"; buffer ::rpp_can_%<direction_sp>x_cnt}
185 %% Fix mailbox number in the old buffer record
186 %copyrecord tmp_ma ::rpp_can%<module>_mailbox_assigned%<mailbox_number>
187 %copyrecord tmp_buf ::%<tmp_ma.direction>x_buffer_%<tmp_ma.buffer>
188 %if ISEQUAL(tmp_ma.direction, "t")
189 %createrecord tmp_result {type tmp_buf.type; controller tmp_buf.controller; msg_obj mailbox_number; name "%<tmp_buf.name>" }
190 %copyrecord ::tx_buffer_%<tmp_ma.buffer> tmp_result
191 %elseif ISEQUAL(tmp_ma.direction, "r")
192 %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 }
194 %<LibBlockReportFatalError(block, "Unknown block direction, this is probably a bug!")>
198 %<RppCreateNewBuffer(module, mailbox_num, message_type, message_id, mask, direction_sp)>