# HG changeset patch # User Michael Spacefalcon # Date 1407175129 0 # Node ID 565bf963c3a2749268f8f80fd8bb5783db6e3352 # Parent 3bb11261b9fe3d9e8df5521993516bfe0a089e6c gsm-fw/L1/dsp/leadapi.[ch]: import from Leonardo semi-src diff -r 3bb11261b9fe -r 565bf963c3a2 gsm-fw/L1/dsp/leadapi.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/L1/dsp/leadapi.c Mon Aug 04 17:58:49 2014 +0000 @@ -0,0 +1,503 @@ +/******************************************************************************** + TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION + + Property of Texas Instruments -- For Unrestricted Internal Use Only + Unauthorized reproduction and/or distribution is strictly prohibited. This + product is protected under copyright law and trade secret law as an + unpublished work. Created 1987, (C) Copyright 1997 Texas Instruments. All + rights reserved. + + + Filename : leadapi.c + + Description : Boot the LEAD through the API + Target : Arm + + Project : + + Author : A0917556 + + Version number : 1.7 + + Date and time : 01/30/01 10:22:25 + + Previous delta : 12/19/00 14:27:48 + + SCCS file : /db/gsm_asp/db_ht96/dsp_0/gsw/rel_0/mcu_l1/release_gprs/RELEASE_GPRS/drivers1/common/SCCS/s.leadapi.c + + Sccs Id (SID) : '@(#) leadapi.c 1.7 01/30/01 10:22:25 ' + + +*****************************************************************************/ + + +#define LEADAPI_C 1 + +#include "l1sw.cfg" +#include "chipset.cfg" + +#if (OP_L1_STANDALONE == 0) + #include "main/sys_types.h" +#else + #include "sys_types.h" +#endif + +#include "memif/mem.h" +#include "clkm/clkm.h" +#include "leadapi.h" + + +void LA_ResetLead(void) +{ + (*(SYS_UWORD16 *) CLKM_CNTL_RST) |= CLKM_LEAD_RST; +} + +/* + * LA_StartLead + * + * Parameter : pll is the value to set in the PLL register + */ +void LA_StartLead(SYS_UWORD16 pll) +{ + volatile int j; + +#if ((CHIPSET == 2) || (CHIPSET == 3) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 9)) + // Set PLL + (*(SYS_UWORD16 *) CLKM_LEAD_PLL_CNTL) = pll; + + // Wait 100 microseconds for PLL to start + wait_ARM_cycles(convert_nanosec_to_cycles(100000)); +#endif + + (*(SYS_UWORD16 *) CLKM_CNTL_RST) &= ~CLKM_LEAD_RST; +} + + +/* + * LA_InitialLeadBoot16 + * + * For RAM-based LEAD + * + * Copy all sections to API + * Dedicated with coff2c with 16-bit size and address (used with coff version 1 until DSP v1110) + */ +void LA_InitialLeadBoot16(const unsigned char bootCode[]) +{ + int i; + SYS_UWORD16 *origin; + SYS_UWORD16 *destination; + SYS_UWORD16 *currentSection; + + (*(SYS_UWORD16 *) CLKM_CNTL_RST) |= CLKM_LEAD_RST; // Reset Lead + + currentSection = (SYS_UWORD16*) bootCode; + + while (*currentSection != 0) // *currentSection is "size" + { + origin = currentSection + 2; // origin points on 1st word of current section + destination = (SYS_UWORD16 *) + (BASE_API_ARM + ((*(currentSection+1) - BASE_API_LEAD) * 2)); + // destination is "addr" in API + // (*(currentSection+1) is "size" of current section + + for (i=0 ; i< *currentSection ; i++) + { + *destination = *origin++; + destination = destination + 1; // destination is UNSIGNED16 + } + currentSection = origin; + } +} + + +/* + * LA_InitialLeadBoot + * + * For RAM-based LEAD + * + * Copy all sections to API + * Dedicated with coff2c with 32-bit size and address (perl or v3 version used with coff version 2 from v1500) + * + */ +void LA_InitialLeadBoot(const unsigned char bootCode[]) +{ + int i; + short error = NULL; + SYS_UWORD16 size, size_ext; // dsp_addr[0:15] and dsp_addr[16:31] of the current section as specified in bootCode[] array + SYS_UWORD16 dsp_address, dsp_ext_address; // size[0:15] and size[16:31] of the current section as specified in bootCode[] array + SYS_UWORD16 *bootCodePtr, *destinationPtr; // pointer in bootCode[] array and pointer in the API (MCU addresses) + + (*(SYS_UWORD16 *) CLKM_CNTL_RST) |= CLKM_LEAD_RST; // reset Lead + + bootCodePtr = (SYS_UWORD16 *) bootCode; // initialisation of bootCodePtr on the first word of the C array + + if ( (NULL == *bootCodePtr++) && (NULL == *bootCodePtr++) ) { // NULL TAG detection + + if ( ( 3 == *bootCodePtr++) && (NULL == *bootCodePtr++) ) { // coff2c version number detection + + // initialization for the first section + size = *bootCodePtr++; + size_ext = *bootCodePtr++; + dsp_address = *bootCodePtr++; + dsp_ext_address = *bootCodePtr++; + + while (size != NULL) { // loop until last section whose size is null + if ( (NULL == size_ext) && (NULL == dsp_ext_address) ) {// size and address must 16-bit values in LA_InitialLeadBoot() + destinationPtr = (SYS_UWORD16 *) (BASE_API_ARM + (dsp_address - BASE_API_LEAD) * 2); // destination in API from the MCU side + + for (i=0 ; i LA_TIMEOUT) + return(LA_ERR_TIMEOUT); + } + while (stat != LEAD_READY); + + destinationPtr = (SYS_UWORD16 *) BASE_API_ARM; + *destinationPtr = page; + *(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = PAGE_SELECTION; + + // Code/Data download block by block + //----------------------------------- + do { // SECTION BY SECTION COPY + size = *codePtr++; + size_ext = *codePtr++; + dsp_address = *codePtr++; + dsp_ext_address = *codePtr++; + + remaining_size32 = (size_ext << 16) + size; // reconstruction of the total 32-bit size of the section + + while (remaining_size32) { // BLOCK BY BLOCK COPY + + // Wait until LEAD is ready + t = 0; + do + { + stat = *((volatile SYS_UWORD16 *) DOWNLOAD_STATUS); + t++; + if (t > LA_TIMEOUT) + return(LA_ERR_TIMEOUT); + } + while (stat != LEAD_READY); + + // DSP address managment including the extended page + remaining_size_DSPpage32 = MAX_UINT - dsp_address +1; // calculate the max available size in the current DSP page (MAX_UINT=65535) + if (NULL == remaining_size_DSPpage32) { + dsp_address = 0; // continue on the next DSP page + dsp_ext_address += 1; + } + + // partitionning of the current section into blocks + if (remaining_size32 >= MAX_BLOCK_SIZE) { + if (MAX_BLOCK_SIZE <= remaining_size_DSPpage32) + current_block_size = MAX_BLOCK_SIZE; // block by block partitioning + else + current_block_size = remaining_size_DSPpage32; + } + else { + if(remaining_size32 <= remaining_size_DSPpage32) + current_block_size = remaining_size32; // the end of the section fits and is copied + else + current_block_size = remaining_size_DSPpage32; + } + + if ( current_block_size > max_block_size ) + { + max_block_size = current_block_size; + } + + // set parameters in the share memory + *(volatile SYS_UWORD16 *) DOWNLOAD_SIZE = current_block_size; + *(volatile SYS_UWORD16 *) DOWNLOAD_ADDR = dsp_address; + *(volatile SYS_UWORD16 *) DOWNLOAD_EXT_PAGE = dsp_ext_address; + + // perform the copy + destinationPtr = (SYS_UWORD16 *) BASE_API_ARM; + for (i=0 ; i LA_TIMEOUT) + return(LA_ERR_TIMEOUT); + } + while (stat != LEAD_READY); + + /* the part of the API used for the download must be reseted at end of download */ + /* in case some values are not initialized within API before DSP start:*/ + /* DSP start after DOWNLOAD_SIZE is set to zero.*/ + destinationPtr = (SYS_UWORD16 *) BASE_API_ARM; + for (i=0 ; i LA_TIMEOUT) + return(LA_ERR_TIMEOUT); + + } + while ( stat != LEAD_READY); + + destination = (volatile SYS_UWORD16 *) BASE_API_ARM; + *destination = 1; + *(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = PAGE_SELECTION; + } + + + do + { /* while there is a section to transfer */ + origin = currentSection + 2; + size = *currentSection; + addr = *(currentSection+1); + + remainingSize = size; + + while (remainingSize) + { + if (remainingSize > MAX_BLOCK_SIZE) + currentBlockSize = MAX_BLOCK_SIZE; + else + currentBlockSize = remainingSize; + + /* Wait until LEAD is ready */ + t = 0; + do + { + stat = *((volatile SYS_UWORD16 *) DOWNLOAD_STATUS); + t++; + if (t > LA_TIMEOUT) + return(LA_ERR_TIMEOUT); + + } + while (stat != LEAD_READY); + + /* Set the block size and address in shared memory */ + *(volatile SYS_UWORD16 *) DOWNLOAD_SIZE = currentBlockSize; + *(volatile SYS_UWORD16 *) DOWNLOAD_ADDR = addr + size - remainingSize; + + if ( currentBlockSize > max_block_size ) + { + max_block_size = currentBlockSize; + } + + /* Copy the block */ + destination = (volatile SYS_UWORD16 *) BASE_API_ARM; + for (i=0 ; i< currentBlockSize ; i++) + { + *destination = *origin++; + destination += 1; // API is really 16-bit wide for MCU now ! + } + + *(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = BLOCK_READY; + + remainingSize -= currentBlockSize; + } + currentSection = origin; + } + while (size != 0); + + /* Wait until LEAD is ready */ + t = 0; + do + { + stat = *((volatile SYS_UWORD16 *) DOWNLOAD_STATUS); + t++; + if (t > LA_TIMEOUT) + return(LA_ERR_TIMEOUT); + + } + while (stat != LEAD_READY); + + + /* the part of the API used for the download must be reseted at end of download */ + /* in case some values are not initialized within API before DSP start:*/ + /* DSP start after DOWNLOAD_SIZE is set to zero.*/ + destination = (SYS_UWORD16 *) BASE_API_ARM; + for (i=0 ; i