summaryrefslogtreecommitdiffstats
path: root/mnsl/mns_message.h
blob: 3ca0eb74e1e11f713e97738cc9fbe424ec3dd9a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/*
 * MOST NetServices "Light" V3.2.7.0.1796 MultiInstance Patch
 *
 * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * You may also obtain this software under a propriety license from Microchip.
 * Please contact Microchip for further information.
 *
 */

/*!
 * \file
 * \brief Declaration of class message
 *
 * \cond MNS_INTERNAL_DOC
 * \addtogroup  G_MESSAGE
 * @{
 */

#ifndef MNS_MESSAGE_H
#define MNS_MESSAGE_H

/*------------------------------------------------------------------------------------------------*/
/* Includes                                                                                       */
/*------------------------------------------------------------------------------------------------*/
#include "mns_memory.h"
#include "mns_dl.h"
#include "mns_message_pb.h"

#ifdef __cplusplus
extern "C"
{
#endif

/*------------------------------------------------------------------------------------------------*/
/* Common macros                                                                                  */
/*------------------------------------------------------------------------------------------------*/
#define MSG_ADDR_INVALID    0U  /*!< \brief   The (source) address the INIC uses to declare an invalid source address.
                                 *   \details Invalid source addresses can be:
                                 *            - invalid messages from MOST: source_address = [0x0000..0x000F] 
                                 *            - invalid messages from EHC: source_address != [0x0002, 0x0003]
                                 *            .
                                 */
#define MSG_ADDR_INIC       1U  /*!< \brief The address of the local INIC */
#define MSG_ADDR_EHC_CFG    2U  /*!< \brief The address of the EHC configuration interface (ICM and RCM FIFO) */
#define MSG_ADDR_EHC_APP    3U  /*!< \brief The address of the EHC application interface (MCM FIFO) */

#define MSG_LLRBC_DEFAULT   10U /*!< \brief The default LowLevelRetry BlockCount */
#define MSG_LLRBC_MAX       100U/*!< \brief The maximum LowLevelRetry BlockCount */

/*------------------------------------------------------------------------------------------------*/
/* Types                                                                                          */
/*------------------------------------------------------------------------------------------------*/
/*! \brief  MOST message id "FBlockID.InstID.FktID.OPType" */
typedef struct Msg_MsgId_
{
    uint8_t         fblock_id;      /*!< \brief FBlockID */
    uint8_t         instance_id;    /*!< \brief InstID */
    uint16_t        function_id;    /*!< \brief FktID */
    Mns_OpType_t    op_type;        /*!< \brief Operation type */

} Msg_MsgId_t;

/*! \brief  Retry options */
typedef struct Msg_TxOptions_
{
    uint8_t     llrbc;          /*!< \brief   Low-level retry block count performed by the INIC. 
                                 *   \details The LLRBC are applicable for MCMs. ICMs don't care.
                                 *            Values exceeding the maximum value are be corrected 
                                 *            by the INIC silently to the maximum value.
                                 *            Valid range: 0..100
                                 */
    uint8_t     cancel_id;      /*!< \brief   Either "0" or label for a group of dependent telegrams. 
                                 *   \details The value determines the required action if the transmission
                                 *            has failed.
                                 *            Valid range:
                                 *            - 0: Only the failed telegram will is removed from the FIFO.
                                 *            - 1..255: All telegrams with the same cancel_id as a failed telegram 
                                 *              will be removed from the FIFO queue.
                                 */

} Msg_TxOptions_t;

/*! \brief  Most telegram data */
typedef struct Msg_TelData_
{
    uint8_t     tel_id;         /*!< \brief Telegram id which indicates the telegram as part of
                                 *          segmented message or as single transfer. */
    uint8_t     tel_len;        /*!< \brief The telegram length. 
                                 *          I.e. the number of telegram bytes starting at address
                                 *          which is referred in \c tel_data_ptr. The INIC will add
                                 *          \em one in case of \"tel_id = 1..3\". 
                                 */
    uint8_t     tel_cnt;        /*!< \brief The message count indexing the telegram within a segmented
                                 *          message.
                                 *          The respective tel_cnt is moved by the INIC to \"DATA[0]\"
                                 *          in case of \"tel_id = 1..3\". Otherwise it is ignored.
                                 */
    uint8_t    *tel_data_ptr;   /*!< \brief Points to telegram data. */

} Msg_TelData_t;

/*! \brief  Common MOST message */
typedef struct Msg_MostTel_
{
    uint16_t destination_addr;      /*!< \brief MOST destination address */
    uint16_t source_addr;           /*!< \brief MOST source address */

    Msg_MsgId_t         id;         /*!< \brief MOST message id "FBlockID.InstID.FktID.OPType" */
    Msg_TxOptions_t     opts;       /*!< \brief Message transmission options */
    Msg_TelData_t       tel;        /*!< \brief MOST telegram data */
    void               *info_ptr;   /*!< \brief Possible reference to additional data */

} Msg_MostTel_t;

/* necessary forward declaration */
struct CMessage_;
/*! \brief Common message class which provides MOST style message addressing */
typedef struct CMessage_ CMessage;

/*! \brief  Assignable function which is invoked as soon as transmission
 *          of the message object is finished. 
 *  \param  self    The instance
 *  \param  msg_ptr Reference to the message object
 *  \param  status  Transmission status
 */
typedef void (*Msg_TxStatusCb_t)(void *self, Msg_MostTel_t *tel_ptr, Mns_MsgTxStatus_t status);

/*------------------------------------------------------------------------------------------------*/
/* Macros                                                                                         */
/*------------------------------------------------------------------------------------------------*/
/*! \brief      Size in bytes of reserved message header */
#define MSG_SIZE_RSVD_HEADER  24U
/*! \brief      Size in bytes of message payload */
#define MSG_MAX_SIZE_PAYLOAD  45U
/*! \brief      Size in bytes of pre-allocated message buffer
 *  \details    Size = 24(header) + 45(payload) + 3(stuffing) = 72 */
#define MSG_SIZE_RSVD_BUFFER  72U

/*------------------------------------------------------------------------------------------------*/
/* Class CMessage                                                                                 */
/*------------------------------------------------------------------------------------------------*/
/*! \brief   Class CMessage 
 *  \details Common internal message class which embeds the public message attributes
 */
struct CMessage_
{
    Msg_MostTel_t       pb_msg;                 /*!< \brief  Public part which defines the MOST telegram 
                                                 *           structure. This attribute must be the first 
                                                 *           element inside the message structure.
                                                 */
    uint8_t rsvd_buffer[MSG_SIZE_RSVD_BUFFER];  /*!< \brief  Reserved memory space */
    Mem_IntBuffer_t     rsvd_memory;            /*!< \brief  Reserved memory which is needed at least for the
                                                 *           Port message header (24 bytes) */
    Mem_IntBuffer_t     ext_memory;             /*!< \brief  Possible user memory */

    uint8_t            *start_ptr;              /*!< \brief  Points to the start of the message buffer */
    uint8_t             header_curr_idx;        /*!< \brief  Index of the end of the current header */
    uint8_t             header_curr_sz;         /*!< \brief  Current size of header in bytes */
    uint8_t             header_rsvd_sz;         /*!< \brief  Reserved size of header in bytes */

    void               *pool_ptr;               /*!< \brief  Point to the pool the message is allocated from and released to */
    void               *lld_handle_ptr;         /*!< \brief  Possible reference to another message object */
    CDlNode             node;                   /*!< \brief  Node for usage in a doubly linked list */

    Msg_TxStatusCb_t    tx_status_fptr;         /*!< \brief  Pointer to Tx status callback */
    void               *tx_status_inst;         /*!< \brief  Reference to instance which needs Tx status notification */

    bool                tx_active;              /*!< \brief  Is \c true if the object is occupied by the LLD, otherwise \c false */
    bool                tx_bypass;              /*!< \brief  Is \c true if a message was queued as bypass message */
};


/*------------------------------------------------------------------------------------------------*/
/* Methods                                                                                        */
/*------------------------------------------------------------------------------------------------*/
extern void             Msg_Ctor(CMessage *self);
extern void             Msg_Cleanup(CMessage *self);

extern void             Msg_ReserveHeader(CMessage *self, uint8_t header_sz);
extern void             Msg_PullHeader(CMessage *self, uint8_t header_sz);
extern void             Msg_PushHeader(CMessage *self, uint8_t header_sz);

extern void             Msg_NotifyTxStatus(CMessage *self, Mns_MsgTxStatus_t status);

/*------------------------------------------------------------------------------------------------*/
/* Properties                                                                                     */
/*------------------------------------------------------------------------------------------------*/
extern Msg_MostTel_t*   Msg_GetMostTel(CMessage *self);

extern uint8_t*         Msg_GetHeader(CMessage *self);
extern uint8_t          Msg_GetHeaderSize(CMessage *self);
extern Mns_Mem_Buffer_t* Msg_GetMemTx(CMessage *self);

extern void             Msg_SetLldHandle(CMessage *self, void *handle);
extern void            *Msg_GetLldHandle(CMessage *self);
extern void             Msg_SetPoolReference(CMessage *self, void *pool_ptr);
extern void            *Msg_GetPoolReference(CMessage *self);

extern CDlNode         *Msg_GetNode(CMessage *self);

extern void             Msg_SetTxStatusHandler(CMessage *self, Msg_TxStatusCb_t callback_fptr, void *inst_ptr);
extern void             Msg_SetExtPayload(CMessage *self, uint8_t *payload_ptr, uint8_t payload_sz, void* mem_info_ptr);
extern void             Msg_SetTxActive(CMessage *self, bool active);
extern bool             Msg_IsTxActive(CMessage *self);
extern void             Msg_SetTxBypass(CMessage *self, bool bypass);
extern bool             Msg_IsTxBypass(CMessage *self);

extern bool             Msg_VerifyContent(CMessage *self);

#ifdef __cplusplus
}                                                   /* extern "C" */
#endif

#endif /* #ifndef MNS_MESSAGE_H */

/*!
 * @}
 * \endcond
 */

/*------------------------------------------------------------------------------------------------*/
/* End of file                                                                                    */
/*------------------------------------------------------------------------------------------------*/