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 }