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