📄 leadapi.c
字号:
/*
/*******************************************************************************
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 "chipset.cfg"
#include "sys_types.h"
#include "mem.h"
#include "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<size ; i++) {
*destinationPtr++ = *bootCodePtr++;
}
// next section
size = *bootCodePtr++;
size_ext = *bootCodePtr++;
dsp_address = *bootCodePtr++;
dsp_ext_address = *bootCodePtr++;
}
else {
error = LA_BAD_EXT_VALUE;
size = NULL;
}
}
}
else {
error = LA_BAD_VERSION;
}
}
else {
error = LA_BAD_TAG;
}
if (error != NULL) { // if an error was detected in the coff2c format,
LA_InitialLeadBoot16(bootCode); // try to download a coff-v1.0 coff2c output
}
}
/*
* LA_LoadPage
*
* 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_LoadPage(const unsigned char code[], SYS_UWORD16 page, SYS_UWORD16 start)
{
int t; // time counter for synchronization
SYS_UWORD16 stat; // status parameter for synchronization
int i = NULL;
short error = NULL;
SYS_UWORD16 current_block_size; // size of the current block to be copied into API
int remaining_size32; // remaining size of the current section to be copied after the last block
int remaining_size_DSPpage32; // size remaining in the current DSP page
int max_block_size; //biggest block size used during the patch download
SYS_UWORD16 size, size_ext; // size[0:15] and size[16:31] of the current section as specified in code[] array
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
SYS_UWORD16 *codePtr, *destinationPtr; // pointer in code[] array and pointer in the API (MCU addresses)
codePtr = (SYS_UWORD16 *) code; // initialisation of codePtr on the first word of the C array
max_block_size = 0;
if ( (NULL == *codePtr++) && (NULL == *codePtr++)) { // NULL TAG detection
if ( (3 == *codePtr++) && (NULL == *codePtr++)) { // coff2c version number detection
// Set the data page
//-------------------
// 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);
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -