FreeCalypso > hg > freecalypso-sw
comparison gsm-fw/L1/dsp/leadapi.c @ 558:565bf963c3a2
gsm-fw/L1/dsp/leadapi.[ch]: import from Leonardo semi-src
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Mon, 04 Aug 2014 17:58:49 +0000 |
parents | |
children | 25a3095e8a98 |
comparison
equal
deleted
inserted
replaced
557:3bb11261b9fe | 558:565bf963c3a2 |
---|---|
1 /******************************************************************************** | |
2 TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION | |
3 | |
4 Property of Texas Instruments -- For Unrestricted Internal Use Only | |
5 Unauthorized reproduction and/or distribution is strictly prohibited. This | |
6 product is protected under copyright law and trade secret law as an | |
7 unpublished work. Created 1987, (C) Copyright 1997 Texas Instruments. All | |
8 rights reserved. | |
9 | |
10 | |
11 Filename : leadapi.c | |
12 | |
13 Description : Boot the LEAD through the API | |
14 Target : Arm | |
15 | |
16 Project : | |
17 | |
18 Author : A0917556 | |
19 | |
20 Version number : 1.7 | |
21 | |
22 Date and time : 01/30/01 10:22:25 | |
23 | |
24 Previous delta : 12/19/00 14:27:48 | |
25 | |
26 SCCS file : /db/gsm_asp/db_ht96/dsp_0/gsw/rel_0/mcu_l1/release_gprs/RELEASE_GPRS/drivers1/common/SCCS/s.leadapi.c | |
27 | |
28 Sccs Id (SID) : '@(#) leadapi.c 1.7 01/30/01 10:22:25 ' | |
29 | |
30 | |
31 *****************************************************************************/ | |
32 | |
33 | |
34 #define LEADAPI_C 1 | |
35 | |
36 #include "l1sw.cfg" | |
37 #include "chipset.cfg" | |
38 | |
39 #if (OP_L1_STANDALONE == 0) | |
40 #include "main/sys_types.h" | |
41 #else | |
42 #include "sys_types.h" | |
43 #endif | |
44 | |
45 #include "memif/mem.h" | |
46 #include "clkm/clkm.h" | |
47 #include "leadapi.h" | |
48 | |
49 | |
50 void LA_ResetLead(void) | |
51 { | |
52 (*(SYS_UWORD16 *) CLKM_CNTL_RST) |= CLKM_LEAD_RST; | |
53 } | |
54 | |
55 /* | |
56 * LA_StartLead | |
57 * | |
58 * Parameter : pll is the value to set in the PLL register | |
59 */ | |
60 void LA_StartLead(SYS_UWORD16 pll) | |
61 { | |
62 volatile int j; | |
63 | |
64 #if ((CHIPSET == 2) || (CHIPSET == 3) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 9)) | |
65 // Set PLL | |
66 (*(SYS_UWORD16 *) CLKM_LEAD_PLL_CNTL) = pll; | |
67 | |
68 // Wait 100 microseconds for PLL to start | |
69 wait_ARM_cycles(convert_nanosec_to_cycles(100000)); | |
70 #endif | |
71 | |
72 (*(SYS_UWORD16 *) CLKM_CNTL_RST) &= ~CLKM_LEAD_RST; | |
73 } | |
74 | |
75 | |
76 /* | |
77 * LA_InitialLeadBoot16 | |
78 * | |
79 * For RAM-based LEAD | |
80 * | |
81 * Copy all sections to API | |
82 * Dedicated with coff2c with 16-bit size and address (used with coff version 1 until DSP v1110) | |
83 */ | |
84 void LA_InitialLeadBoot16(const unsigned char bootCode[]) | |
85 { | |
86 int i; | |
87 SYS_UWORD16 *origin; | |
88 SYS_UWORD16 *destination; | |
89 SYS_UWORD16 *currentSection; | |
90 | |
91 (*(SYS_UWORD16 *) CLKM_CNTL_RST) |= CLKM_LEAD_RST; // Reset Lead | |
92 | |
93 currentSection = (SYS_UWORD16*) bootCode; | |
94 | |
95 while (*currentSection != 0) // *currentSection is "size" | |
96 { | |
97 origin = currentSection + 2; // origin points on 1st word of current section | |
98 destination = (SYS_UWORD16 *) | |
99 (BASE_API_ARM + ((*(currentSection+1) - BASE_API_LEAD) * 2)); | |
100 // destination is "addr" in API | |
101 // (*(currentSection+1) is "size" of current section | |
102 | |
103 for (i=0 ; i< *currentSection ; i++) | |
104 { | |
105 *destination = *origin++; | |
106 destination = destination + 1; // destination is UNSIGNED16 | |
107 } | |
108 currentSection = origin; | |
109 } | |
110 } | |
111 | |
112 | |
113 /* | |
114 * LA_InitialLeadBoot | |
115 * | |
116 * For RAM-based LEAD | |
117 * | |
118 * Copy all sections to API | |
119 * Dedicated with coff2c with 32-bit size and address (perl or v3 version used with coff version 2 from v1500) | |
120 * | |
121 */ | |
122 void LA_InitialLeadBoot(const unsigned char bootCode[]) | |
123 { | |
124 int i; | |
125 short error = NULL; | |
126 SYS_UWORD16 size, size_ext; // dsp_addr[0:15] and dsp_addr[16:31] of the current section as specified in bootCode[] array | |
127 SYS_UWORD16 dsp_address, dsp_ext_address; // size[0:15] and size[16:31] of the current section as specified in bootCode[] array | |
128 SYS_UWORD16 *bootCodePtr, *destinationPtr; // pointer in bootCode[] array and pointer in the API (MCU addresses) | |
129 | |
130 (*(SYS_UWORD16 *) CLKM_CNTL_RST) |= CLKM_LEAD_RST; // reset Lead | |
131 | |
132 bootCodePtr = (SYS_UWORD16 *) bootCode; // initialisation of bootCodePtr on the first word of the C array | |
133 | |
134 if ( (NULL == *bootCodePtr++) && (NULL == *bootCodePtr++) ) { // NULL TAG detection | |
135 | |
136 if ( ( 3 == *bootCodePtr++) && (NULL == *bootCodePtr++) ) { // coff2c version number detection | |
137 | |
138 // initialization for the first section | |
139 size = *bootCodePtr++; | |
140 size_ext = *bootCodePtr++; | |
141 dsp_address = *bootCodePtr++; | |
142 dsp_ext_address = *bootCodePtr++; | |
143 | |
144 while (size != NULL) { // loop until last section whose size is null | |
145 if ( (NULL == size_ext) && (NULL == dsp_ext_address) ) {// size and address must 16-bit values in LA_InitialLeadBoot() | |
146 destinationPtr = (SYS_UWORD16 *) (BASE_API_ARM + (dsp_address - BASE_API_LEAD) * 2); // destination in API from the MCU side | |
147 | |
148 for (i=0 ; i<size ; i++) { | |
149 *destinationPtr++ = *bootCodePtr++; | |
150 } | |
151 | |
152 // next section | |
153 size = *bootCodePtr++; | |
154 size_ext = *bootCodePtr++; | |
155 dsp_address = *bootCodePtr++; | |
156 dsp_ext_address = *bootCodePtr++; | |
157 } | |
158 else { | |
159 error = LA_BAD_EXT_VALUE; | |
160 size = NULL; | |
161 } | |
162 } | |
163 } | |
164 else { | |
165 error = LA_BAD_VERSION; | |
166 } | |
167 } | |
168 else { | |
169 error = LA_BAD_TAG; | |
170 } | |
171 | |
172 if (error != NULL) { // if an error was detected in the coff2c format, | |
173 LA_InitialLeadBoot16(bootCode); // try to download a coff-v1.0 coff2c output | |
174 } | |
175 } | |
176 | |
177 | |
178 /* | |
179 * LA_LoadPage | |
180 * | |
181 * Final LEAD boot - needs to communicate with initial LEAD Boot program | |
182 * | |
183 * Copy all sections to API | |
184 * | |
185 * Parameters : pointer to code, LEAD page, flag to start executing | |
186 * Return value : 0 for success, 1 for timeout | |
187 */ | |
188 short LA_LoadPage(const unsigned char code[], SYS_UWORD16 page, SYS_UWORD16 start) | |
189 { | |
190 int t; // time counter for synchronization | |
191 SYS_UWORD16 stat; // status parameter for synchronization | |
192 int i = NULL; | |
193 short error = NULL; | |
194 SYS_UWORD16 current_block_size; // size of the current block to be copied into API | |
195 int remaining_size32; // remaining size of the current section to be copied after the last block | |
196 int remaining_size_DSPpage32; // size remaining in the current DSP page | |
197 int max_block_size; //biggest block size used during the patch download | |
198 SYS_UWORD16 size, size_ext; // size[0:15] and size[16:31] of the current section as specified in code[] array | |
199 SYS_UWORD16 dsp_address, dsp_ext_address; // dsp_addr[0:15] and dsp_addr[16:31] of the current section as specified in code[] array | |
200 SYS_UWORD16 *codePtr, *destinationPtr; // pointer in code[] array and pointer in the API (MCU addresses) | |
201 | |
202 codePtr = (SYS_UWORD16 *) code; // initialisation of codePtr on the first word of the C array | |
203 max_block_size = 0; | |
204 | |
205 if ( (NULL == *codePtr++) && (NULL == *codePtr++)) { // NULL TAG detection | |
206 | |
207 if ( (3 == *codePtr++) && (NULL == *codePtr++)) { // coff2c version number detection | |
208 | |
209 // Set the data page | |
210 //------------------- | |
211 // Wait until LEAD is ready | |
212 t = 0; | |
213 do | |
214 { | |
215 stat = *((volatile SYS_UWORD16 *) DOWNLOAD_STATUS); | |
216 t++; | |
217 if (t > LA_TIMEOUT) | |
218 return(LA_ERR_TIMEOUT); | |
219 } | |
220 while (stat != LEAD_READY); | |
221 | |
222 destinationPtr = (SYS_UWORD16 *) BASE_API_ARM; | |
223 *destinationPtr = page; | |
224 *(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = PAGE_SELECTION; | |
225 | |
226 // Code/Data download block by block | |
227 //----------------------------------- | |
228 do { // SECTION BY SECTION COPY | |
229 size = *codePtr++; | |
230 size_ext = *codePtr++; | |
231 dsp_address = *codePtr++; | |
232 dsp_ext_address = *codePtr++; | |
233 | |
234 remaining_size32 = (size_ext << 16) + size; // reconstruction of the total 32-bit size of the section | |
235 | |
236 while (remaining_size32) { // BLOCK BY BLOCK COPY | |
237 | |
238 // Wait until LEAD is ready | |
239 t = 0; | |
240 do | |
241 { | |
242 stat = *((volatile SYS_UWORD16 *) DOWNLOAD_STATUS); | |
243 t++; | |
244 if (t > LA_TIMEOUT) | |
245 return(LA_ERR_TIMEOUT); | |
246 } | |
247 while (stat != LEAD_READY); | |
248 | |
249 // DSP address managment including the extended page | |
250 remaining_size_DSPpage32 = MAX_UINT - dsp_address +1; // calculate the max available size in the current DSP page (MAX_UINT=65535) | |
251 if (NULL == remaining_size_DSPpage32) { | |
252 dsp_address = 0; // continue on the next DSP page | |
253 dsp_ext_address += 1; | |
254 } | |
255 | |
256 // partitionning of the current section into blocks | |
257 if (remaining_size32 >= MAX_BLOCK_SIZE) { | |
258 if (MAX_BLOCK_SIZE <= remaining_size_DSPpage32) | |
259 current_block_size = MAX_BLOCK_SIZE; // block by block partitioning | |
260 else | |
261 current_block_size = remaining_size_DSPpage32; | |
262 } | |
263 else { | |
264 if(remaining_size32 <= remaining_size_DSPpage32) | |
265 current_block_size = remaining_size32; // the end of the section fits and is copied | |
266 else | |
267 current_block_size = remaining_size_DSPpage32; | |
268 } | |
269 | |
270 if ( current_block_size > max_block_size ) | |
271 { | |
272 max_block_size = current_block_size; | |
273 } | |
274 | |
275 // set parameters in the share memory | |
276 *(volatile SYS_UWORD16 *) DOWNLOAD_SIZE = current_block_size; | |
277 *(volatile SYS_UWORD16 *) DOWNLOAD_ADDR = dsp_address; | |
278 *(volatile SYS_UWORD16 *) DOWNLOAD_EXT_PAGE = dsp_ext_address; | |
279 | |
280 // perform the copy | |
281 destinationPtr = (SYS_UWORD16 *) BASE_API_ARM; | |
282 for (i=0 ; i<current_block_size ; i++) { | |
283 *destinationPtr++ = *codePtr++; | |
284 } | |
285 | |
286 // synchronize and prepare the next step | |
287 *(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = BLOCK_READY; | |
288 dsp_address += current_block_size; | |
289 remaining_size32 -= current_block_size; | |
290 } | |
291 } while ( (size != NULL) || (size_ext != NULL) ); | |
292 | |
293 // Setting of the starting address if required | |
294 //--------------------------------------------- | |
295 // Wait until LEAD is ready | |
296 t = 0; | |
297 do | |
298 { | |
299 stat = *((volatile SYS_UWORD16 *) DOWNLOAD_STATUS); | |
300 t++; | |
301 if (t > LA_TIMEOUT) | |
302 return(LA_ERR_TIMEOUT); | |
303 } | |
304 while (stat != LEAD_READY); | |
305 | |
306 /* the part of the API used for the download must be reseted at end of download */ | |
307 /* in case some values are not initialized within API before DSP start:*/ | |
308 /* DSP start after DOWNLOAD_SIZE is set to zero.*/ | |
309 destinationPtr = (SYS_UWORD16 *) BASE_API_ARM; | |
310 for (i=0 ; i<max_block_size ; i++) { | |
311 *destinationPtr++ = 0x0000; | |
312 } | |
313 | |
314 if (start) | |
315 { | |
316 /* Set the last block, which is the starting address */ | |
317 *(volatile SYS_UWORD16 *) DOWNLOAD_SIZE = 0; | |
318 *(volatile SYS_UWORD16 *) DOWNLOAD_ADDR = dsp_address; | |
319 *(volatile SYS_UWORD16 *) DOWNLOAD_EXT_PAGE = dsp_ext_address; | |
320 *(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = BLOCK_READY; | |
321 } | |
322 | |
323 return(LA_SUCCESS); | |
324 } | |
325 else { | |
326 error = LA_BAD_VERSION; | |
327 } | |
328 } | |
329 else { | |
330 error = LA_BAD_TAG; | |
331 } | |
332 | |
333 /* if (error != NULL) { */ // if an error was detected in the coff2c format, | |
334 error = LA_LoadPage16(code, page, start); // try to download a coff-v1.0 coff2c output | |
335 return(error); // and return its result | |
336 /* } */ | |
337 } | |
338 | |
339 | |
340 /* | |
341 * LA_LoadPage16 | |
342 * | |
343 * Final LEAD boot - needs to communicate with initial LEAD Boot program | |
344 * | |
345 * Copy all sections to API | |
346 * | |
347 * Parameters : pointer to code, LEAD page, flag to start executing | |
348 * Return value : 0 for success, 1 for timeout | |
349 */ | |
350 short LA_LoadPage16(const unsigned char code[], SYS_UWORD16 page, SYS_UWORD16 start) | |
351 { | |
352 int i = 0; | |
353 int remainingSize, currentBlockSize; | |
354 volatile int j; | |
355 int t; | |
356 int max_block_size; //biggest block size used during the patch download | |
357 | |
358 volatile SYS_UWORD16 *origin; | |
359 volatile SYS_UWORD16 *destination; | |
360 volatile SYS_UWORD16 *currentSection; | |
361 SYS_UWORD16 addr, size, stat; | |
362 | |
363 currentSection = (SYS_UWORD16*) code; /* Take GSM application s/w */ | |
364 max_block_size = 0; | |
365 | |
366 // Set the data page if needed | |
367 if (page == 1) | |
368 { | |
369 // Wait until LEAD is ready | |
370 t = 0; | |
371 do | |
372 { | |
373 stat = *((volatile SYS_UWORD16 *) DOWNLOAD_STATUS); | |
374 t++; | |
375 if (t > LA_TIMEOUT) | |
376 return(LA_ERR_TIMEOUT); | |
377 | |
378 } | |
379 while ( stat != LEAD_READY); | |
380 | |
381 destination = (volatile SYS_UWORD16 *) BASE_API_ARM; | |
382 *destination = 1; | |
383 *(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = PAGE_SELECTION; | |
384 } | |
385 | |
386 | |
387 do | |
388 { /* while there is a section to transfer */ | |
389 origin = currentSection + 2; | |
390 size = *currentSection; | |
391 addr = *(currentSection+1); | |
392 | |
393 remainingSize = size; | |
394 | |
395 while (remainingSize) | |
396 { | |
397 if (remainingSize > MAX_BLOCK_SIZE) | |
398 currentBlockSize = MAX_BLOCK_SIZE; | |
399 else | |
400 currentBlockSize = remainingSize; | |
401 | |
402 /* Wait until LEAD is ready */ | |
403 t = 0; | |
404 do | |
405 { | |
406 stat = *((volatile SYS_UWORD16 *) DOWNLOAD_STATUS); | |
407 t++; | |
408 if (t > LA_TIMEOUT) | |
409 return(LA_ERR_TIMEOUT); | |
410 | |
411 } | |
412 while (stat != LEAD_READY); | |
413 | |
414 /* Set the block size and address in shared memory */ | |
415 *(volatile SYS_UWORD16 *) DOWNLOAD_SIZE = currentBlockSize; | |
416 *(volatile SYS_UWORD16 *) DOWNLOAD_ADDR = addr + size - remainingSize; | |
417 | |
418 if ( currentBlockSize > max_block_size ) | |
419 { | |
420 max_block_size = currentBlockSize; | |
421 } | |
422 | |
423 /* Copy the block */ | |
424 destination = (volatile SYS_UWORD16 *) BASE_API_ARM; | |
425 for (i=0 ; i< currentBlockSize ; i++) | |
426 { | |
427 *destination = *origin++; | |
428 destination += 1; // API is really 16-bit wide for MCU now ! | |
429 } | |
430 | |
431 *(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = BLOCK_READY; | |
432 | |
433 remainingSize -= currentBlockSize; | |
434 } | |
435 currentSection = origin; | |
436 } | |
437 while (size != 0); | |
438 | |
439 /* Wait until LEAD is ready */ | |
440 t = 0; | |
441 do | |
442 { | |
443 stat = *((volatile SYS_UWORD16 *) DOWNLOAD_STATUS); | |
444 t++; | |
445 if (t > LA_TIMEOUT) | |
446 return(LA_ERR_TIMEOUT); | |
447 | |
448 } | |
449 while (stat != LEAD_READY); | |
450 | |
451 | |
452 /* the part of the API used for the download must be reseted at end of download */ | |
453 /* in case some values are not initialized within API before DSP start:*/ | |
454 /* DSP start after DOWNLOAD_SIZE is set to zero.*/ | |
455 destination = (SYS_UWORD16 *) BASE_API_ARM; | |
456 for (i=0 ; i<max_block_size ; i++) { | |
457 *destination++ = 0x0000; | |
458 } | |
459 | |
460 if (start) | |
461 { | |
462 /* Set the last block, which is the starting address */ | |
463 *(volatile SYS_UWORD16 *) DOWNLOAD_SIZE = 0; | |
464 *(volatile SYS_UWORD16 *) DOWNLOAD_ADDR = addr; | |
465 *(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = BLOCK_READY; | |
466 } | |
467 | |
468 return(LA_SUCCESS); | |
469 } | |
470 | |
471 /* | |
472 * LeadBoot | |
473 * | |
474 * Start the LEAD without downloading any code | |
475 */ | |
476 short LeadBoot(SYS_UWORD16 entryPoint, SYS_UWORD16 pll) | |
477 { | |
478 SYS_UWORD16 section[2]; | |
479 short res; | |
480 | |
481 section[0] = 0; // null size | |
482 section[1] = entryPoint; | |
483 | |
484 #if ((CHIPSET == 4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12)) | |
485 CLKM_RELEASELEADRESET; | |
486 #else | |
487 LA_StartLead(pll); | |
488 #endif | |
489 | |
490 res = LA_LoadPage((const unsigned char *) section, 0, 1); | |
491 return(res); | |
492 | |
493 } | |
494 | |
495 | |
496 /* | |
497 * LA_ReleaseLead | |
498 * | |
499 */ | |
500 void LA_ReleaseLead(void) | |
501 { | |
502 (*(unsigned short *) CLKM_CNTL_RST) &= ~CLKM_LEAD_RST; | |
503 } |