📄 leadapi.c
字号:
// 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<current_block_size ; i++) {
*destinationPtr++ = *codePtr++;
}
// synchronize and prepare the next step
*(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = BLOCK_READY;
dsp_address += current_block_size;
remaining_size32 -= current_block_size;
}
} while ( (size != NULL) || (size_ext != NULL) );
// Setting of the starting address if required
//---------------------------------------------
// 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.*/
destinationPtr = (SYS_UWORD16 *) BASE_API_ARM;
for (i=0 ; i<max_block_size ; i++) {
*destinationPtr++ = 0x0000;
}
if (start)
{
/* Set the last block, which is the starting address */
*(volatile SYS_UWORD16 *) DOWNLOAD_SIZE = 0;
*(volatile SYS_UWORD16 *) DOWNLOAD_ADDR = dsp_address;
*(volatile SYS_UWORD16 *) DOWNLOAD_EXT_PAGE = dsp_ext_address;
*(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = BLOCK_READY;
}
return(LA_SUCCESS);
}
else {
error = LA_BAD_VERSION;
}
}
else {
error = LA_BAD_TAG;
}
if (error != NULL) { // if an error was detected in the coff2c format,
error = LA_LoadPage16(code, page, start); // try to download a coff-v1.0 coff2c output
return(error); // and return its result
}
}
/*
* LA_LoadPage16
*
* Final LEAD boot - needs to communicate with initial LEAD Boot program
*
* Copy all sections to API
*
* Parameters : pointer to code, LEAD page, flag to start executing
* Return value : 0 for success, 1 for timeout
*/
short LA_LoadPage16(const unsigned char code[], SYS_UWORD16 page, SYS_UWORD16 start)
{
int i = 0;
int remainingSize, currentBlockSize;
volatile int j;
int t;
int max_block_size; //biggest block size used during the patch download
volatile SYS_UWORD16 *origin;
volatile SYS_UWORD16 *destination;
volatile SYS_UWORD16 *currentSection;
SYS_UWORD16 addr, size, stat;
currentSection = (SYS_UWORD16*) code; /* Take GSM application s/w */
max_block_size = 0;
// Set the data page if needed
if (page == 1)
{
// 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);
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<max_block_size ; i++) {
*destination++ = 0x0000;
}
if (start)
{
/* Set the last block, which is the starting address */
*(volatile SYS_UWORD16 *) DOWNLOAD_SIZE = 0;
*(volatile SYS_UWORD16 *) DOWNLOAD_ADDR = addr;
*(volatile SYS_UWORD16 *) DOWNLOAD_STATUS = BLOCK_READY;
}
return(LA_SUCCESS);
}
/*
* LeadBoot
*
* Start the LEAD without downloading any code
*/
short LeadBoot(SYS_UWORD16 entryPoint, SYS_UWORD16 pll)
{
SYS_UWORD16 section[2];
short res;
section[0] = 0; // null size
section[1] = entryPoint;
#if ((CHIPSET == 4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
CLKM_RELEASELEADRESET;
#else
LA_StartLead(pll);
#endif
res = LA_LoadPage((const unsigned char *) section, 0, 1);
return(res);
}
/*
* LA_ReleaseLead
*
*/
void LA_ReleaseLead(void)
{
(*(unsigned short *) CLKM_CNTL_RST) &= ~CLKM_LEAD_RST;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -