FreeCalypso > hg > leo2moko-debug
comparison chipsetsw/drivers/drv_core/dsp_dwnld/leadapi.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
| author | Space Falcon <falcon@ivan.Harhan.ORG> |
|---|---|
| date | Mon, 01 Jun 2015 03:24:05 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:509db1a7b7b8 |
|---|---|
| 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 } |
