📄 load.c
字号:
//=============================================================================
// Filename: load.c
//
// Description: Functions needed to load a program and start it on the DSP.
//
// Copyright (C) 2000 - 2002 Texas Instruments Incorporated
//
//============================================================================
#include "arm_boot.h"
#include "dsp_boot_code.h"
//============================================================================
// Function: WriteAPI()
//
// Description: This function copies one word into the API memory.
//
//============================================================================
static void WriteAPI(volatile unsigned short *Address, unsigned short Data)
{
*Address = Data;
}
//=============================================================================
// Function: move_bits()
//
// Description: Helper function for dsp_load(). Copy contents of bits_ary
// to a buffer in API memory. When the buffer becomes full, sinal to DSP via
// a handshake flag to read the bits from the buffer.
//
//=============================================================================
static int move_bits(volatile unsigned short *handshake_flag,
const unsigned short *bits_ary)
{
volatile unsigned short *api_buffer = (unsigned short*)
MAP_DSP_TO_ARM(API_BUF_START); // start of the API buffer
unsigned short api_offset = 0; // offset into API memory
unsigned short code_offset = 0; // offset into DSP Code ary
unsigned short done = 0; // flag to signal done.
long time_cnt; // loop index used for timeout
unsigned short i;
// Need outer loop in case program is larger than can be loaded in one pass
while (done == 0) {
// If the current section is not empty and there is enough buffer
// space left to write this section out, copy the section to API.
// code_offset should be pointing to the number of words
// in the this section. We need to have room for all of them,
// plus one for the count, plus one for the target address, plus
// one for the zero termination word.
unsigned short section_length = bits_ary[code_offset] + 2;
int empty_section = (bits_ary[code_offset] == 0);
int buffer_full = ((api_offset + section_length + 1) >=
API_BUF_LENGTH);
if ((!empty_section) && (!buffer_full)) {
for(i = 0; i < section_length; i++) {
WriteAPI(&api_buffer[api_offset++], bits_ary[code_offset++]);
}
}
else {
// Either this is the end of the bits_ary, or there wasn't enough
// buffer space. In both cases moves the bits we have so far to
// the DSP.
// Tack on a 0 to signal the end of the section.
WriteAPI(&api_buffer[api_offset], 0);
// Signal for DSP to read what we have so far.
WriteAPI(handshake_flag, 1);
time_cnt = 0;
while ((*handshake_flag == 1) && (++time_cnt < TIME_OUT_COUNT)) {
// Wait for DSP to finish. The DSP sets *handshake_flag
// to zero after it finishes the section it's writing.
}
// Check if timeout occurred.
if (time_cnt == TIME_OUT_COUNT) return LOAD_TIME_OUT;
// Reset pointer for next section
api_offset = 0;
if (empty_section) {
// Reached the end of the bits array
done = 1;
}
}
}
return LOAD_OK;
}
//=============================================================================
// Function: dsp_load()
//
// Description:
//
// This function loads the DSP code and data . It does this as
// a three stage process:
// 1) It loads the DSP Bootloader into API memory.
// 2) The ARM and DSP Bootloader load the DSP Code a chunk at a time using a
// small section of API memory.
// 3) The ARM and DSP Bootloader load the DSP data a chunk at a time using
// a small section of API memory.
//
//=============================================================================
int dsp_load(dsp_app_struct *dsp_app)
{
unsigned short code_offset; // Curr. offset into DSP Code ary
unsigned short section_length;// Number of words in each section
long time_cnt; // Loop index used for timeout
unsigned short *section_addr;
unsigned short i;
int status = LOAD_OK;
volatile unsigned short *dsp_ready = (unsigned short*)DSP_READY;
volatile unsigned short *prog_buf_ready = (unsigned short*)PROG_BUF_READY;
volatile unsigned short *data_buf_ready = (unsigned short*)DATA_BUF_READY;
volatile unsigned short *copy_done = (unsigned short*)COPY_DONE;
volatile unsigned short *pmst = (unsigned short*)PMST_VAL;
volatile long *clkm_cntl_reset = (long *)0xffff2f10;
volatile long *dsp_reg = (long *)0xffff2f04;
// put DSP In Reset
*clkm_cntl_reset |= 0x1; //set bit1, DSP XF LED will turn on
// set DSP in API boot mode and microcomputer mode
*dsp_reg &= ~0x0600; //clear bits 9 and 10
// clear the handshaking registers
WriteAPI(dsp_ready, 0); // The DSP is still in API mode.
WriteAPI(prog_buf_ready, 0); // Prog is not ready to load.
WriteAPI(data_buf_ready, 0); // Data is not ready to load.
WriteAPI(copy_done, 0); // We're not done.
// set the PMST for the DSP Exec to setup the memory map during bootload
WriteAPI(pmst, dsp_app->pmst);
// copy DSP Bootloader to API Ram
code_offset=0; // Current offset into DSP Program array
section_length = dsp_boot_program[code_offset++];
while(section_length != 0) {
section_addr = (unsigned short *)
(MAP_DSP_TO_ARM(dsp_boot_program[code_offset++]));
// copy this section
for (i = 0; i < section_length; i++) {
WriteAPI(section_addr++, dsp_boot_program[code_offset++]);
}
// get next section's length
section_length = dsp_boot_program[code_offset++];
}
// take the DSP out of reset
*clkm_cntl_reset &= ~0x1; //clear bit 1
time_cnt = 0;
while ((*dsp_ready == 0) && (++time_cnt < TIME_OUT_COUNT)) {
// Wait for DSP to finish. The DSP sets *dsp_ready to 1 after it
// switches from API boot mode to normal boot mode.
}
// Check if timeout occurred.
if (time_cnt == TIME_OUT_COUNT) return LOAD_TIME_OUT;
status = move_bits(prog_buf_ready, dsp_app->pprogram);
if (status == LOAD_TIME_OUT) return status;
status = move_bits(data_buf_ready, dsp_app->pdata);
return status;
}
//============================================================================
// Function: dsp_start()
//
// Description: This function starts the DSP running following a dsp_load
//
//============================================================================
void dsp_start(void)
{
// Write the register telling the DSP that the bootload is done. =====
volatile unsigned short *copy_done = (unsigned short *)COPY_DONE;
WriteAPI(copy_done, 1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -