FreeCalypso > hg > fc-magnetite
comparison src/g23m-aci/gdd_dio/gdd_dio_if.c @ 162:53929b40109c
src/g23m-aci: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2016 02:02:43 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
161:4557e2a9c18e | 162:53929b40109c |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : | |
4 | Modul : | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2004 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : Implementation of the GDD interface with DIOv4 | |
18 +----------------------------------------------------------------------------- | |
19 */ | |
20 | |
21 #define GDD_DIO_IF_C | |
22 | |
23 /*==== INCLUDES =============================================================*/ | |
24 | |
25 #include <string.h> | |
26 #include <stdlib.h> | |
27 #include <stddef.h> | |
28 #include "typedefs.h" | |
29 #include "pcm.h" | |
30 #include "vsi.h" | |
31 #include "custom.h" | |
32 #include "gsm.h" | |
33 #include "pei.h" | |
34 | |
35 #include "gdd.h" | |
36 #include "gdd_dio_data.h" | |
37 #include "gdd_dio.h" | |
38 | |
39 #include "gdd_dio_con_mgr.h" | |
40 #include "gdd_dio_queue.h" | |
41 | |
42 #include "gdd_dio_dtxf.h" | |
43 #include "gdd_dio_drxf.h" | |
44 | |
45 | |
46 /*==== CONSTANTS ============================================================*/ | |
47 | |
48 /*==== TYPES ================================================================*/ | |
49 | |
50 /*==== PROTOTYPES ===========================================================*/ | |
51 | |
52 /*==== GLOBAL VARS ==========================================================*/ | |
53 | |
54 /*==== LOCAL VARS ===========================================================*/ | |
55 | |
56 /*==== LOCAL FUNCTIONS=======================================================*/ | |
57 | |
58 /*==== EXPORTED FUNCTIONS====================================================*/ | |
59 | |
60 /** gdd_init_dio - see header "gdd.h" for comment and description */ | |
61 | |
62 GDD_RESULT gdd_init_dio | |
63 ( | |
64 T_GDD_INST_ID inst, | |
65 void * mem, | |
66 U16 num_con | |
67 ) | |
68 { | |
69 T_GDD_DIO_DATA * gdd_dio_data; | |
70 | |
71 TRACE_FUNCTION("[GDD] gdd_init_dio()"); | |
72 | |
73 /* Check params */ | |
74 if(inst < GDD_INST_BAT || inst >= GDD_NUM_INSTS) | |
75 { | |
76 TRACE_ERROR("[GDD] Instance id out of bounds"); | |
77 return GDD_INVALID_PARAMS; | |
78 } | |
79 | |
80 gdd_dio_data = &gdd_dio_data_base[inst]; | |
81 | |
82 if(gdd_dio_init_flag[inst]) | |
83 { | |
84 TRACE_ERROR("[GDD] Attempted to call gdd_init_dio() twice for same instance"); | |
85 return GDD_ALREADY_INITIALIZED; | |
86 } | |
87 | |
88 if(num_con < 1 || num_con > gdd_dio_data->max_con) | |
89 { | |
90 TRACE_ERROR("[GDD] Number of connections out of bounds"); | |
91 return GDD_INVALID_PARAMS; | |
92 } | |
93 | |
94 if(mem) | |
95 { | |
96 gdd_dio_data->con_arr = mem; | |
97 gdd_dio_data->con_arr_mem_allocated = FALSE; | |
98 } | |
99 else | |
100 { | |
101 gdd_dio_data->con_arr = 0; | |
102 MALLOC(gdd_dio_data->con_arr, GDD_DIO_SIZEOF_CONDATA * num_con); | |
103 if(gdd_dio_data->con_arr EQ 0) | |
104 { | |
105 TRACE_ERROR("[GDD] memory allocation failed"); | |
106 return GDD_NO_MEMORY; | |
107 } | |
108 | |
109 gdd_dio_data->con_arr_mem_allocated = TRUE; | |
110 } | |
111 | |
112 gdd_dio_data->max_con = num_con; | |
113 | |
114 /* Initialize the connection manager */ | |
115 gdd_dio_con_mgr_init(gdd_dio_data); | |
116 | |
117 gdd_dio_init_flag[inst] = TRUE; | |
118 | |
119 return GDD_OK; | |
120 } | |
121 | |
122 | |
123 /** gdd_deinit - see header "gdd.h" for comment and description*/ | |
124 GDD_RESULT gdd_deinit_dio | |
125 ( | |
126 T_GDD_INST_ID inst | |
127 ) | |
128 { | |
129 T_GDD_DIO_DATA * gdd_dio_data = 0; | |
130 | |
131 TRACE_FUNCTION("[GDD] gdd_deinit_dio()"); | |
132 | |
133 if(inst < GDD_INST_BAT || inst >= GDD_NUM_INSTS) | |
134 { | |
135 TRACE_ERROR("[GDD] instance id out of bounds"); | |
136 return GDD_INVALID_PARAMS; | |
137 } | |
138 | |
139 gdd_dio_data = &gdd_dio_data_base[inst]; | |
140 | |
141 | |
142 /* If we allocated our own memory, free it. */ | |
143 if(gdd_dio_data->con_arr_mem_allocated EQ FALSE) | |
144 { | |
145 MFREE(gdd_dio_data->con_arr); | |
146 gdd_dio_data->con_arr = 0; | |
147 gdd_dio_data->con_arr_mem_allocated = FALSE; | |
148 } | |
149 | |
150 gdd_dio_init_flag[inst] = FALSE; | |
151 | |
152 return GDD_OK; | |
153 } | |
154 | |
155 | |
156 /** gdd_connect - see header "gdd.h" for comment and description */ | |
157 GDD_RESULT gdd_connect_dio | |
158 ( | |
159 T_GDD_INST_ID inst, | |
160 T_GDD_CON_HANDLE * con_handle, | |
161 const T_GDD_CAP * cap, | |
162 T_GDD_RECEIVE_DATA_CB rcv_cb, | |
163 T_GDD_SIGNAL_CB sig_cb | |
164 ) | |
165 { | |
166 T_GDD_DIO_DATA * gdd_dio_data; | |
167 | |
168 TRACE_FUNCTION("[GDD] gdd_connect_dio()"); | |
169 | |
170 /** | |
171 * Do the necessary checks. | |
172 */ | |
173 | |
174 if(inst < GDD_INST_BAT || inst >= GDD_NUM_INSTS) | |
175 { | |
176 TRACE_ERROR("[GDD] instance id out of bounds"); | |
177 return GDD_INVALID_PARAMS; | |
178 } | |
179 | |
180 gdd_dio_data = &gdd_dio_data_base[inst]; | |
181 | |
182 if (gdd_dio_data->ker.state NEQ GDD_DIO_KER_READY) | |
183 { | |
184 TRACE_ERROR("[GDD] DIO driver not initialized"); | |
185 return DRV_INTERNAL_ERROR; | |
186 } | |
187 | |
188 /* Check if we are already initialized. If we not, we do it ourselfs! */ | |
189 /* This is specific to the DIO implementation of GDD */ | |
190 if(gdd_dio_init_flag[inst] EQ FALSE) | |
191 { | |
192 gdd_init_dio(inst, 0, gdd_dio_data->max_con); | |
193 } | |
194 | |
195 if(con_handle EQ 0) | |
196 { | |
197 TRACE_ERROR("[GDD] Connection handle pointer cannot be 0"); | |
198 return GDD_INVALID_PARAMS; | |
199 } | |
200 | |
201 if(cap EQ 0) | |
202 { | |
203 TRACE_ERROR("[GDD] Capabilities pointer cannot be 0"); | |
204 return GDD_INVALID_PARAMS; | |
205 } | |
206 | |
207 if(rcv_cb EQ 0 || sig_cb EQ 0) | |
208 { | |
209 TRACE_ERROR("[GDD] Callback function pointer cannot be 0"); | |
210 return GDD_INVALID_PARAMS; | |
211 } | |
212 | |
213 /** | |
214 * We are ready to create the DIO connection | |
215 */ | |
216 return gdd_dio_con_mgr_new(gdd_dio_data, con_handle, cap, rcv_cb, sig_cb); | |
217 } | |
218 | |
219 /** gdd_disconnect - see header "gdd.h" for comment and description */ | |
220 GDD_RESULT gdd_disconnect_dio | |
221 ( | |
222 T_GDD_CON_HANDLE con_handle | |
223 ) | |
224 { | |
225 if(con_handle EQ 0) | |
226 { | |
227 TRACE_ERROR("[GDD] Connection handle cannot be 0"); | |
228 return GDD_INVALID_PARAMS; | |
229 } | |
230 | |
231 /* | |
232 * Inform the connection manager | |
233 */ | |
234 return gdd_dio_con_mgr_close(con_handle); | |
235 } | |
236 | |
237 | |
238 /** gdd_get_send_buffer - see header "gdd.h" for comment and description */ | |
239 GDD_RESULT gdd_get_send_buffer_dio | |
240 ( | |
241 T_GDD_CON_HANDLE con_handle, | |
242 T_GDD_BUF ** buf, | |
243 U16 data_size | |
244 ) | |
245 { | |
246 TRACE_USER_CLASS(TC_FUNC_DATA_FLOW, "[GDD] gdd_get_send_buffer_dio()"); | |
247 | |
248 if(con_handle EQ 0) | |
249 { | |
250 TRACE_ERROR("[GDD] Connection handle cannot be 0"); | |
251 return GDD_INVALID_PARAMS; | |
252 } | |
253 if(buf EQ NULL) | |
254 { | |
255 TRACE_ERROR("[GDD] buf cannot be NULL"); | |
256 return GDD_INVALID_PARAMS; | |
257 } | |
258 | |
259 return gdd_dio_dtx_get_send_buffer(con_handle, buf, data_size); | |
260 } | |
261 | |
262 | |
263 /** gdd_send_data - see header "gdd.h" for comment and description */ | |
264 GDD_RESULT gdd_send_data_dio | |
265 ( | |
266 T_GDD_CON_HANDLE con_handle, | |
267 T_GDD_BUF * buf | |
268 ) | |
269 { | |
270 TRACE_USER_CLASS(TC_FUNC_DATA_FLOW, "[GDD] gdd_send_data_dio()"); | |
271 | |
272 if(con_handle EQ 0) | |
273 { | |
274 TRACE_ERROR("[GDD] Connection handle cannot be 0"); | |
275 return GDD_INVALID_PARAMS; | |
276 } | |
277 if(buf EQ NULL) | |
278 { | |
279 TRACE_ERROR("[GDD] buf cannot be NULL"); | |
280 return GDD_INVALID_PARAMS; | |
281 } | |
282 | |
283 return gdd_dio_dtx_send_buffer(con_handle, buf); | |
284 } | |
285 | |
286 | |
287 /** gdd_signal_ready_rcv - see header "gdd.h" for comment and description */ | |
288 void gdd_signal_ready_rcv_dio( T_GDD_CON_HANDLE con_handle ) | |
289 { | |
290 TRACE_FUNCTION("[GDD] gdd_signal_ready_rcv_dio()"); | |
291 | |
292 if(con_handle NEQ 0) | |
293 { | |
294 return; | |
295 } | |
296 | |
297 gdd_dio_drx_ready_to_rcv(con_handle); | |
298 } | |
299 | |
300 | |
301 /** Exported function table for DIO implementation of GDD */ | |
302 T_GDD_FUNC gdd_func_dio = | |
303 { | |
304 gdd_init_dio, | |
305 gdd_deinit_dio, | |
306 gdd_connect_dio, | |
307 gdd_disconnect_dio, | |
308 gdd_get_send_buffer_dio, | |
309 gdd_send_data_dio, | |
310 gdd_signal_ready_rcv_dio | |
311 }; | |
312 | |
313 | |
314 /*==== EXPORTED HELPER FUNCTIONS=============================================*/ | |
315 | |
316 S32 gdd_write_buf_with_pid(const U8 * src_buf, | |
317 U16 src_size, | |
318 T_GDD_BUF * dest_buf, | |
319 U8 protocol_id) | |
320 { | |
321 int idx_seg; | |
322 int remaining; | |
323 | |
324 /* Check that we have more than one segment and that the first one | |
325 is the PID segment which. */ | |
326 TRACE_ASSERT(dest_buf->c_segment > 1); | |
327 TRACE_ASSERT(dest_buf->ptr_gdd_segment[0].c_data EQ GDD_DIO_PID_SEG_SIZE); | |
328 | |
329 if( dest_buf->c_segment < 2 || | |
330 dest_buf->ptr_gdd_segment[0].c_data NEQ GDD_DIO_PID_SEG_SIZE ) | |
331 { | |
332 return -1; | |
333 } | |
334 | |
335 /* Set the protocol ID, which is carried in the first buffer segment */ | |
336 /* Note: the DTI2 interface in the stack uses only 8 bits for the p_id. */ | |
337 dest_buf->ptr_gdd_segment[0].ptr_data[0] = 0x0;/* not used, see note above */ | |
338 dest_buf->ptr_gdd_segment[0].ptr_data[1] = protocol_id; | |
339 | |
340 | |
341 remaining = src_size; | |
342 | |
343 for(idx_seg=1; idx_seg<dest_buf->c_segment; ++idx_seg) | |
344 { | |
345 T_GDD_SEGMENT * seg = &(dest_buf->ptr_gdd_segment[idx_seg]); | |
346 int bytes_to_copy = remaining < seg->c_data ? remaining : seg->c_data; | |
347 | |
348 memcpy(seg->ptr_data, src_buf + src_size - remaining, bytes_to_copy); | |
349 remaining -= bytes_to_copy; | |
350 if(remaining EQ 0) | |
351 break; | |
352 } | |
353 | |
354 dest_buf->length = src_size - remaining + GDD_DIO_PID_SEG_SIZE; | |
355 return remaining; | |
356 } | |
357 | |
358 #define DTI_PID_IP (0x21) /* simple ip packet (IPv4) */ | |
359 | |
360 S32 gdd_write_buf(const U8 * src_buf, U16 src_size, T_GDD_BUF * dest_buf) | |
361 { | |
362 return gdd_write_buf_with_pid(src_buf, src_size, dest_buf, DTI_PID_IP); | |
363 } | |
364 | |
365 S32 gdd_read_buf(const T_GDD_BUF * src_buf, U8 * dest_buf, U16 dest_size) | |
366 { | |
367 int idx_seg; | |
368 int remaining; | |
369 | |
370 /* Check that we have more than one segment and that the first one | |
371 is the PID segment which. */ | |
372 | |
373 TRACE_ASSERT(src_buf->c_segment > 1); | |
374 TRACE_ASSERT(src_buf->ptr_gdd_segment[0].c_data EQ GDD_DIO_PID_SEG_SIZE); | |
375 if( src_buf->c_segment < 2 || | |
376 src_buf->ptr_gdd_segment[0].c_data NEQ GDD_DIO_PID_SEG_SIZE ) | |
377 { | |
378 return -1; | |
379 } | |
380 | |
381 remaining = src_buf->length - GDD_DIO_PID_SEG_SIZE; | |
382 if(remaining > dest_size) | |
383 { | |
384 remaining = dest_size; | |
385 } | |
386 | |
387 for(idx_seg=1; idx_seg<src_buf->c_segment; ++idx_seg) | |
388 { | |
389 T_GDD_SEGMENT * seg = &(src_buf->ptr_gdd_segment[idx_seg]); | |
390 int bytes_to_copy = remaining < seg->c_data ? remaining : seg->c_data; | |
391 | |
392 memcpy(dest_buf + dest_size - remaining, seg->ptr_data, bytes_to_copy); | |
393 remaining -= bytes_to_copy; | |
394 if(remaining EQ 0) | |
395 break; | |
396 } | |
397 | |
398 return remaining; | |
399 } |