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 }